ProfRod100 commited on
Commit
9a9ecdb
Β·
verified Β·
1 Parent(s): da1c707

Upload 3 files

Browse files
Files changed (3) hide show
  1. README.md +28 -7
  2. app.py +117 -0
  3. requirements.txt +13 -0
README.md CHANGED
@@ -1,14 +1,35 @@
 
1
  ---
2
- title: Teste Modelo Amazon
3
- emoji: 🐠
4
- colorFrom: purple
5
- colorTo: pink
6
  sdk: gradio
7
- sdk_version: 5.49.1
8
  app_file: app.py
9
  pinned: false
10
  license: mit
11
- short_description: Modelo Teste Projeto Final
12
  ---
13
 
14
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
  ---
3
+ title: Projeto Final - Chatbot de Sentimentos (ML + IA Generativa)
4
+ emoji: 🧠
5
+ colorFrom: yellow
6
+ colorTo: blue
7
  sdk: gradio
8
+ sdk_version: 5.7.1
9
  app_file: app.py
10
  pinned: false
11
  license: mit
 
12
  ---
13
 
14
+ # Projeto Final - Chatbot de Sentimentos (Discriminativo + Generativo)
15
+
16
+ Curso: Machine Learning e Deep Learning
17
+ Data: 2025-11-12
18
+ Autor(es): _(preencher)_
19
+
20
+ ## O que este Space demonstra
21
+ - Classificacao de Sentimentos (ML): TF-IDF + Regressao Logistica.
22
+ - IA Generativa (LLM): `google/flan-t5-base` (PT-BR) para redigir respostas educadas.
23
+ - Interface: Gradio com duas abas (Analise e Chatbot).
24
+
25
+ ## Como funciona
26
+ - Se `baseline_pipe.pkl` nao estiver nos *Files*, o Space treina automaticamente um baseline pequeno (aprox. 0.5% do `amazon_polarity`) e salva localmente.
27
+ - Para pular o autotrain, envie `baseline_pipe.pkl` gerado no notebook ou defina `DISABLE_AUTOTRAIN=1` em Settings -> Variables.
28
+
29
+ ## Como usar
30
+ 1) Aba "Analise de Sentimento" -> digite um texto -> Analisar.
31
+ 2) Aba "Chatbot" -> clique em "1) Analisar sentimento" e depois "2) Gerar resposta".
32
+
33
+ ## Trocas e extensoes
34
+ - Mude o gerador via env var `GEN_MODEL_ID` (ex.: `pierreguillou/gpt2-small-portuguese`).
35
+ - Substitua o baseline por transformer de classificacao (custo maior, melhores metricas).
app.py ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import os
3
+ import json
4
+ import numpy as np
5
+ import gradio as gr
6
+
7
+ # ---------- 1) Sentiment Baseline (TF-IDF + LogisticRegression) ----------
8
+ import joblib
9
+ from sklearn.pipeline import Pipeline
10
+ from sklearn.feature_extraction.text import TfidfVectorizer
11
+ from sklearn.linear_model import LogisticRegression
12
+
13
+ BASELINE_PATH = os.getenv("MODEL_PATH", "baseline_pipe.pkl")
14
+
15
+ def train_small_baseline(save_path=BASELINE_PATH, sample_pct="train[:0.5%]"):
16
+ from datasets import load_dataset
17
+ import pandas as pd
18
+ ds = load_dataset("amazon_polarity", split=sample_pct)
19
+ df = pd.DataFrame({"text": ds["content"], "label": ds["label"]})
20
+ pipe = Pipeline([
21
+ ("tfidf", TfidfVectorizer(max_features=30000, ngram_range=(1,2))),
22
+ ("clf", LogisticRegression(max_iter=1000)),
23
+ ])
24
+ pipe.fit(df["text"], df["label"])
25
+ joblib.dump(pipe, save_path)
26
+ return pipe
27
+
28
+ def load_or_bootstrap_baseline():
29
+ if os.path.exists(BASELINE_PATH):
30
+ return joblib.load(BASELINE_PATH)
31
+ if os.getenv("DISABLE_AUTOTRAIN", "0") == "1":
32
+ return None
33
+ return train_small_baseline()
34
+
35
+ baseline = load_or_bootstrap_baseline()
36
+
37
+ def classify_only(text):
38
+ if not text or not text.strip():
39
+ return {"erro": "Digite um texto."}
40
+ if baseline is None:
41
+ return {"erro": "Modelo baseline nao encontrado. Envie baseline_pipe.pkl ou remova DISABLE_AUTOTRAIN."}
42
+ proba = baseline.predict_proba([text])[0]
43
+ pred = int(np.argmax(proba))
44
+ label = "positivo" if pred == 1 else "negativo"
45
+ conf = float(np.max(proba))
46
+ return {"sentimento": label, "confianca": round(conf, 3)}
47
+
48
+ # ---------- 2) Generative Assistant (FLAN-T5) ----------
49
+ from transformers import pipeline
50
+ GEN_MODEL_ID = os.getenv("GEN_MODEL_ID", "google/flan-t5-base")
51
+ generator = pipeline("text2text-generation", model=GEN_MODEL_ID)
52
+
53
+ SYSTEM_PROMPT = (
54
+ "Voce e um atendente virtual educado que responde em portugues do Brasil. "
55
+ "Use poucas frases, tom empatico e pratico."
56
+ )
57
+
58
+ def generate_reply(user_text, sentimento_json):
59
+ if not user_text or not user_text.strip():
60
+ return "Digite uma mensagem."
61
+ sentimento = None
62
+ if isinstance(sentimento_json, dict) and "sentimento" in sentimento_json:
63
+ sentimento = sentimento_json["sentimento"]
64
+
65
+ if sentimento == "negativo":
66
+ intent = (
67
+ "A avaliacao do cliente e NEGATIVA. "
68
+ "Peca desculpas, reconheca o problema, ofereca ajuda objetiva e solicite informacoes adicionais."
69
+ )
70
+ elif sentimento == "positivo":
71
+ intent = (
72
+ "A avaliacao do cliente e POSITIVA. "
73
+ "Agradeca de forma calorosa, reforce pontos fortes mencionados e convide para novas compras."
74
+ )
75
+ else:
76
+ intent = "O sentimento nao foi identificado. Responda de forma neutra, util e cordial."
77
+
78
+ prompt = (
79
+ f"{SYSTEM_PROMPT}\n\n{intent}\n\n"
80
+ f"Mensagem do cliente:\n\"{user_text}\"\n\n"
81
+ f"Escreva uma resposta curta (2-4 frases)."
82
+ )
83
+ out = generator(prompt, max_length=128, do_sample=True, temperature=0.6, top_p=0.9)[0]["generated_text"]
84
+ return out
85
+
86
+ # ---------- 3) Gradio UI ----------
87
+ with gr.Blocks(title="Classificador + Chatbot (Sentimentos)") as demo:
88
+ gr.Markdown(
89
+ \"\"\"
90
+ # Chatbot de Sentimentos (ML + IA Generativa)
91
+ Professor Rodrigo - Projeto Final ML & DL
92
+
93
+ - Classificacao: TF-IDF + Regressao Logistica (autotreino minimo se nao houver `baseline_pipe.pkl`).
94
+ - Geracao: `google/flan-t5-base` para redigir respostas educadas em PT-BR.
95
+
96
+ > Dica: Envie `baseline_pipe.pkl` em *Files* para pular o autotrain.
97
+ \"\"\"
98
+ )
99
+
100
+ with gr.Tab("Analise de Sentimento"):
101
+ in_text = gr.Textbox(label="Digite uma avaliacao de produto", lines=4, placeholder="Ex.: O produto chegou rapido e funciona muito bem.")
102
+ out_json = gr.JSON(label="Resultado")
103
+ btn = gr.Button("Analisar")
104
+ btn.click(classify_only, inputs=in_text, outputs=out_json)
105
+
106
+ with gr.Tab("Chatbot (Analise + Resposta)"):
107
+ chat_in = gr.Textbox(label="Mensagem do cliente", lines=4)
108
+ with gr.Row():
109
+ analyze_btn = gr.Button("1) Analisar sentimento")
110
+ gen_btn = gr.Button("2) Gerar resposta")
111
+ analysis_box = gr.JSON(label="Sentimento detectado")
112
+ reply_box = gr.Textbox(label="Resposta gerada", lines=6)
113
+ analyze_btn.click(classify_only, inputs=chat_in, outputs=analysis_box)
114
+ gen_btn.click(generate_reply, inputs=[chat_in, analysis_box], outputs=reply_box)
115
+
116
+ if __name__ == "__main__":
117
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ datasets==3.0.1
3
+ pandas==2.2.2
4
+ numpy==2.1.3
5
+ scikit-learn==1.5.2
6
+ matplotlib==3.9.2
7
+ joblib==1.4.2
8
+ torch==2.4.1
9
+ tqdm==4.66.5
10
+ gradio==5.7.1
11
+ transformers==4.45.2
12
+ sentencepiece==0.2.0
13
+ accelerate==0.34.2