|
import gradio as gr |
|
import pandas as pd |
|
import matplotlib.pyplot as plt |
|
import seaborn as sns |
|
from ctransformers import AutoModelForCausalLM |
|
import json |
|
import os |
|
|
|
|
|
COUNTER_FILE = "disc_usage_counter.json" |
|
|
|
|
|
def load_counter(): |
|
if os.path.exists(COUNTER_FILE): |
|
with open(COUNTER_FILE, 'r') as f: |
|
return json.load(f) |
|
return {"total_uses": 0} |
|
|
|
def save_counter(counter): |
|
with open(COUNTER_FILE, 'w') as f: |
|
json.dump(counter, f) |
|
|
|
def increment_counter(): |
|
counter = load_counter() |
|
counter["total_uses"] += 1 |
|
save_counter(counter) |
|
return f"Total de avaliações realizadas: {counter['total_uses']}" |
|
|
|
|
|
def load_model(): |
|
return AutoModelForCausalLM.from_pretrained( |
|
'TheBloke/Mistral-7B-Instruct-v0.1-GGUF', |
|
model_file='mistral-7b-instruct-v0.1.Q4_K_M.gguf', |
|
model_type='mistral', |
|
gpu_layers=0 |
|
) |
|
|
|
|
|
perguntas = { |
|
'D': [ |
|
"Eu sou direto e vou direto ao ponto", |
|
"Eu gosto de estar no controle", |
|
"Eu sou competitivo e gosto de vencer", |
|
"Eu tomo decisões rapidamente" |
|
], |
|
'I': [ |
|
"Eu sou extrovertido e sociável", |
|
"Eu gosto de conhecer novas pessoas", |
|
"Eu sou entusiasta e otimista", |
|
"Eu gosto de trabalhar em equipe" |
|
], |
|
'S': [ |
|
"Eu sou paciente e calmo", |
|
"Eu prefiro ambientes estáveis", |
|
"Eu sou bom ouvinte", |
|
"Eu ajudo os outros sempre que posso" |
|
], |
|
'C': [ |
|
"Eu sou detalhista e preciso", |
|
"Eu sigo regras e procedimentos", |
|
"Eu analiso todas as opções antes de decidir", |
|
"Eu gosto de qualidade e excelência" |
|
] |
|
} |
|
|
|
def calcular_disc(respostas): |
|
resultados = {'D': 0, 'I': 0, 'S': 0, 'C': 0} |
|
|
|
for tipo, valor in respostas.items(): |
|
perfil = tipo[0] |
|
resultados[perfil] += valor |
|
|
|
total = sum(resultados.values()) |
|
for perfil in resultados: |
|
resultados[perfil] = (resultados[perfil] / total) * 100 |
|
|
|
return resultados |
|
|
|
def criar_grafico(resultados): |
|
plt.figure(figsize=(10, 6)) |
|
sns.barplot(x=list(resultados.keys()), y=list(resultados.values())) |
|
plt.title('Seu Perfil DISC') |
|
plt.xlabel('Dimensões') |
|
plt.ylabel('Porcentagem') |
|
|
|
for i, v in enumerate(resultados.values()): |
|
plt.text(i, v, f'{v:.1f}%', ha='center', va='bottom') |
|
|
|
return plt |
|
|
|
def gerar_analise_llm(llm, resultados, respostas_brutas): |
|
prompt = f"""<s>[INST] Como um especialista em análise comportamental DISC, faça uma análise detalhada do seguinte perfil: |
|
|
|
Resultados percentuais: |
|
Dominância (D): {resultados['D']:.1f}% |
|
Influência (I): {resultados['I']:.1f}% |
|
Estabilidade (S): {resultados['S']:.1f}% |
|
Conformidade (C): {resultados['C']:.1f}% |
|
|
|
Respostas com pontuações mais altas: |
|
""" |
|
|
|
for tipo, valor in respostas_brutas.items(): |
|
if valor >= 4: |
|
dimensao = tipo[0] |
|
num_questao = int(tipo[1]) - 1 |
|
questao = perguntas[dimensao][num_questao] |
|
prompt += f"- Pontuação {valor}/5 para: {questao}\n" |
|
|
|
prompt += """ |
|
Forneça: |
|
1. Análise geral do perfil |
|
2. Pontos fortes e áreas de desenvolvimento |
|
3. Sugestões de desenvolvimento profissional |
|
4. Como este perfil pode interagir melhor com outros perfis |
|
5. Ambientes de trabalho mais adequados |
|
[/INST]""" |
|
|
|
return llm(prompt, max_new_tokens=1024, temperature=0.7) |
|
|
|
class DiscAnalyzer: |
|
def __init__(self): |
|
self.llm = load_model() |
|
|
|
def avaliar_disc(self, values): |
|
|
|
counter_text = increment_counter() |
|
|
|
|
|
respostas = {} |
|
for i, (tipo, perguntas_tipo) in enumerate(perguntas.items()): |
|
for j, pergunta in enumerate(perguntas_tipo): |
|
respostas[f"{tipo}{j+1}"] = values[i*4 + j] |
|
|
|
resultados = calcular_disc(respostas) |
|
fig = criar_grafico(resultados) |
|
analise = gerar_analise_llm(self.llm, resultados, respostas) |
|
|
|
return fig, analise, counter_text |
|
|
|
|
|
analyzer = DiscAnalyzer() |
|
|
|
with gr.Blocks(title="Avaliação DISC com LLM Local") as app: |
|
gr.Markdown("# Avaliação de Perfil DISC com Análise Avançada") |
|
|
|
|
|
counter_text = gr.Markdown(load_counter()["total_uses"]) |
|
|
|
gr.Markdown("### Avalie cada afirmação em uma escala de 1 a 5") |
|
|
|
sliders = [] |
|
for tipo, perguntas_tipo in perguntas.items(): |
|
with gr.Group(): |
|
gr.Markdown(f"## Dimensão {tipo}") |
|
for pergunta in perguntas_tipo: |
|
sliders.append(gr.Slider(1, 5, value=3, label=pergunta)) |
|
|
|
btn = gr.Button("Avaliar Perfil") |
|
|
|
with gr.Row(): |
|
plot = gr.Plot() |
|
|
|
analise = gr.Markdown(label="Análise Detalhada do Perfil") |
|
uso = gr.Markdown(label="Contador de Uso") |
|
|
|
btn.click( |
|
fn=analyzer.avaliar_disc, |
|
inputs=sliders, |
|
outputs=[plot, analise, uso] |
|
) |
|
|
|
if __name__ == "__main__": |
|
app.launch() |