File size: 5,007 Bytes
fcc1cf1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import gradio as gr
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from transformers import pipeline, AutoModelForCausalLM, AutoTokenizer

# Configuração do modelo local
def load_model():
    model_name = "TheBloke/Mistral-7B-Instruct-v0.1-GGUF"
    model = AutoModelForCausalLM.from_quantized(
        model_name,
        model_file="mistral-7b-instruct-v0.1.Q4_K_M.gguf",
        device="cpu",
        trust_remote_code=True
    )
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    return pipeline('text-generation', model=model, tokenizer=tokenizer)

# Questões DISC
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(pipe, resultados, respostas_brutas):
    # Prepara o prompt para o LLM
    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:
"""

    # Adiciona respostas com pontuações altas ao prompt
    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]"""

    # Gera a análise usando o modelo local
    resposta = pipe(
        prompt,
        max_new_tokens=1024,
        temperature=0.7,
        top_p=0.95,
        repetition_penalty=1.15
    )[0]['generated_text']
    
    # Remove o prompt da resposta
    analise = resposta.split("[/INST]")[1].strip()
    
    return analise

class DiscAnalyzer:
    def __init__(self):
        self.pipe = load_model()
    
    def avaliar_disc(self, values):
        # Converte os valores do slider para um dicionário
        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]
        
        # Calcula os resultados
        resultados = calcular_disc(respostas)
        
        # Cria o gráfico
        fig = criar_grafico(resultados)
        
        # Gera a análise detalhada
        analise = gerar_analise_llm(self.pipe, resultados, respostas)
        
        return fig, analise

# Interface Gradio
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")
    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")
    
    btn.click(
        fn=analyzer.avaliar_disc,
        inputs=sliders,
        outputs=[plot, analise]
    )

if __name__ == "__main__":
    app.launch()