<jupyter_start><jupyter_text><jupyter_code>import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import os
from io import open
pd.options.display.max_columns = 150<jupyter_output><empty_output><jupyter_text>Carregando a base de dados<jupyter_code>data = pd.read_csv('data-final.csv', sep='\t')<jupyter_output><empty_output><jupyter_text>Vizualizando o header da base de dados<jupyter_code>data.head()<jupyter_output><empty_output><jupyter_text>Iremos agora exlcuir alguns dados, isso pq temos algumas informaçoes irrelevantes. Como temos 50 questoes ( como informa a descriçao do Keggle ) podemos excluit apartir da coluna 50 ate a 110 que é o total<jupyter_code>data.drop(data.columns[50:], axis=1, inplace=True) #Removera da 50 em diante
#data.drop(data.columns[50:110], axis=1, inplace=True)<jupyter_output><empty_output><jupyter_text>Verificando para validar que foi feito corretamente ...<jupyter_code>data.head()<jupyter_output><empty_output><jupyter_text>Para uma mehor visualizaçao dos numeros irei formatar cada numero da tabela para o tipo float com duas cassas decimais<jupyter_code>pd.options.display.float_format = '{:.2f}'.format<jupyter_output><empty_output><jupyter_text>Usando o describe irei obter algumas informaçoes de valores medios e estatisticos sobre a base de dado total<jupyter_code>data.describe()<jupyter_output><empty_output><jupyter_text>Informaçoes obtidas pelo describe:  - Possuimos um ruido (erro) ja que as notas vao de 1-5 mas o valor minimo descrito é 0. Vamos Entao identificar a quantidade de registros com valor 0<jupyter_code>data['EXT1'].value_counts()<jupyter_output><empty_output><jupyter_text>POdemos observar a quantidade de valores para cada nota atribuida, Descobrindo assim que temos 347 notas 0 (zero) ou seja 347 ruidos. Vamos primeiros exibir as infos que foram atribuidas como zero antes de remove-los<jupyter_code># infos_com_valores_zero = (data == 0.00).all(axis=1) 
infos_com_valores_zero = (data == 0.00).all(axis=1)
ruidos = data[infos_com_valores_zero]
ruidos.describe()<jupyter_output><empty_output><jupyter_text>Agora que ja vimos os dados zerados, podemos retira-los<jupyter_code>condition = ((data > 0.00).all(axis=1))
data = data[condition]
#Agora vamos ver se realemnte nos livramos dos ruidos ...
data.EXT1.value_counts()<jupyter_output><empty_output><jupyter_text>Agora nos certificamos que nao temos mais os ruidos gerados pelas notas zeros (0) Agora Precisaremos definir o numero de Clusters, ou seja definir/ agrupar os semelhantesMas para isso precisaremos de um ML nao supervisionado, nos nao temos uma classe e sim um grupo para ser agrupadoiremos trabalhar com a tecnica de agrupamento de dados, e uma das perguntas mais inportantes é 'Qual a quantidade de agrupamentos iremos trabalhar?'isso é uma otima discussao, esse numero varia dependendo do problema, o ideal é conhecer a regra de negocio e suas caracteristicas para saber como analisar adequadamente. Para essa pesquisa baseada no OCEAN que sao 5 tipos de compormantos iremos agrupar as informaçoes de acordo com esses grupos (poderia ser agrupado de forma diferente, porem essa seria a maneira mais adequada).OBS: A discussao da quantidade de clusters como ja foi dita é extensa e exitem metodos que podem nos direcionar para um numero adequado de acordo com a variabilidade dos dados. Irei rodar os metodos para isso so para fins de estudo<jupyter_code>#Metodo Euba para definir a quantidade aproxima de clusters adequados 
!pip install yellowbrick
from sklearn.cluster import KMeans
from yellowbrick.cluster import KElbowVisualizer
kmeans = KMeans()
vizualizer = KElbowVisualizer(kmeans, k=(2,10)) #O k, ira indicar a quantidade de testes de agrupamento que o vizualizador ira tentar agrupar para esse caso sera com 2, 3, 4 .... 10 clousters<jupyter_output><empty_output><jupyter_text>como seria contra produtivo gerar a analise com todos os dados do banco ja que temos mais de 1M de informaçoes e custaria muito tempo, vamos pegar apenas algumas informacoes de maneira aleatoria<jupyter_code>data_sample = data.sample(n=5000, random_state=1)
# Entao vamos apresentar essas informaçoes:
vizualizer.fit(data_sample)
vizualizer.poof()<jupyter_output><empty_output><jupyter_text>O teste nos apontou que de fato o ideal e agrupar em 5 grupos (podemos ver isso pelo K indicado no canti superios direito do grafico Vamos entao agora fazer o nosso agrupamento com os 5 grupos<jupyter_code>kmeans = KMeans(n_clusters=5)
k_fit = kmeans.fit(data)
predicoes = k_fit.labels_
data['Clusters'] = predicoes
data.head()<jupyter_output><empty_output><jupyter_text>podemos observar que apareceram alguns ruidos, entao vamos retiralos Agora vamos analisar os grupos<jupyter_code>data['Clusters'].value_counts()
#vamos calcular a media de cada grupo de respostas
col_list = list(data)
ext = col_list[0:10]
est = col_list[10:20]
agr = col_list[20:30]
csn = col_list[30:40]
opn = col_list[40:50]
data_soma = pd.DataFrame()
#criando as colunas do OCEAN
data_soma['Extroversions'] = (data[ext].sum(axis=1)/10)
data_soma['Neurotic'] = (data[est].sum(axis=1)/10)
data_soma['Agreeable'] = (data[agr].sum(axis=1)/10)
data_soma['Concientuous'] = (data[csn].sum(axis=1)/10)
data_soma['Open'] = (data[opn].sum(axis=1)/10)
data_soma['Clusters'] = predicoes
#Exibindo o valor medio por grupo
data_soma.groupby('Clusters').mean()
#armazenando a media
data_media = data_soma.groupby('Clusters').mean()
#vamos plotar o graficom com essa medias
plt.figure(figsize=(22, 3))
for i in range(0, 5):
  plt.subplot(1, 5, i+1)
  plt.bar(data_media.columns, data_media.iloc[:, i], color='green', alpha=0.2)
  plt.plot(data_media.columns, data_media.iloc[:, i], color='red')
  plt.title('Grupo' + str(i))
  plt.xticks(rotation=45)
  plt.ylim(0,4)<jupyter_output><empty_output><jupyter_text>Vamos criar uma interface visual para tornar mais intuitivo o teste<jupyter_code>!pip install gradio
dic_questoes = open('docs.txt').read().split('\n')
dic_questoes
questions = []
for question in dic_questoes:
  q = str(question)
  index_do_t_na_linha = question.find('\t')
  frase_apartir_do_ponto = question[index_do_t_na_linha : ]
  info_com_vazios_removidos = frase_apartir_do_ponto.lstrip()
  questions.append(info_com_vazios_removidos)

#Agora vamos ver como ficou
questions
import gradio as gr
input_questions = []
for q in questions:
  obj_input = gr.inputs.Slider(minimum=1, maximum=5, step=1, default=3, label=q)
  input_questions.append(obj_input)

input_questions
def predict(*outputs_questions):
  outputs_questions = np.array(outputs_questions).reshape(1, -1)
  return 'Você pertence ao grupo: ' + str(k_fit.predict(outputs_questions))

iface = gr.Interface(
    fn = predict,
    title = "Big five personality",
    description = "Sistema para datecçao de traços de persobalidades.",
    inputs = input_questions,
    outputs = "text"
)

iface.launch(share=True)<jupyter_output>Colab notebook detected. To show errors in colab notebook, set `debug=True` in `launch()`
Running on public URL: https://54460.gradio.app

This share link expires in 72 hours. For free permanent hosting, check out Spaces (https://huggingface.co/spaces)
{'fraction_non_alphanumeric': 0.09283113973676842, 'fraction_numerical': 0.017782133856062726, 'mean_word_length': 6.402072538860104, 'pattern_counts': {'":': 0, '<': 60, '<?xml version=': 0, '>': 61, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '15', 'dir': 'jupyter-structured-clean-dedup', 'id': '445793', 'license': 'MIT', 'n_tokens_mistral': 2693, 'n_tokens_neox': 2581, 'n_words': 731, 'path': 'personality_test_machine_learning.ipynb', 'repo_name': 'PaoloProdossimoLopes/python-machine-learning-personality-grouping-study', 'size': '7142'}