notrito commited on
Commit
c5947ee
·
0 Parent(s):
.gitattributes ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ model-last/** filter=lfs diff=lfs merge=lfs -text
2
+ *.json filter=lfs diff=lfs merge=lfs -text
3
+ model-last/vocab/vectors filter=lfs diff=lfs merge=lfs -text
4
+ model-last/vocab/*.json filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Detector de Dialecto Español
3
+ emoji: 🗣️
4
+ colorFrom: blue
5
+ colorTo: red
6
+ sdk: gradio
7
+ sdk_version: 4.44.0
8
+ app_file: app.py
9
+ pinned: false
10
+ ---
11
+
12
+ # 🗣️ Detector de Dialecto Español: Argentino vs Español
13
+
14
+ Modelo de NLP basado en spaCy para detectar y clasificar dialectos del español (argentino 🇦🇷 vs español peninsular 🇪🇸).
15
+
16
+ ## 🎯 Descripción
17
+
18
+ Este proyecto utiliza un modelo NER (Named Entity Recognition) entrenado con spaCy para identificar palabras y expresiones características de dos variantes del español:
19
+
20
+ - **Argentinismos**: Palabras y expresiones típicas de Argentina (che, boludo, vos, bondi, etc.)
21
+ - **Españolismos**: Palabras y expresiones típicas de España (tío, coño, guay, etc.)
22
+
23
+ ## 🚀 Cómo funciona
24
+
25
+ El modelo detecta automáticamente:
26
+
27
+ ### Argentinismos 🇦🇷
28
+ - **Vocabulario característico**: che, boludo, pibe, guita, bondi, quilombo
29
+ - **Voseo**: vos, tenés, sos, querés, sabés, podés, hacés
30
+ - **Expresiones**: pileta, remera, laburo, morfar
31
+
32
+ ### Españolismos 🇪🇸
33
+ - **Vocabulario característico**: tío/tía, coño, ostras, hostia
34
+ - **Jerga**: molar, curro, guay, flipar, gilipollas
35
+ - **Expresiones**: botellón, me parto, chaval/chavala
36
+
37
+ ## 📊 Métricas del Modelo
38
+
39
+ - **F-score**: 99.90%
40
+ - **Precision**: 99.90%
41
+ - **Recall**: 99.90%
42
+ - **Ejemplos de entrenamiento**: 10,000 (balanceado 50/50)
43
+ - **Dataset**: pysentimiento/spanish-tweets
44
+
45
+ ## 🛠️ Tecnologías
46
+
47
+ - **spaCy 3.8.2**: Framework de NLP
48
+ - **Gradio 4.44.0**: Interfaz web interactiva
49
+ - **Pipeline**: tok2vec + ner
50
+ - **Modelo base**: es_core_news_sm
51
+
52
+ ## 💡 Casos de Uso
53
+
54
+ - Análisis de dialectos en redes sociales
55
+ - Estudios sociolingüísticos
56
+ - Clasificación automática de contenido por región
57
+ - Herramienta educativa para aprender variantes del español
58
+
59
+ ## ⚠️ Limitaciones
60
+
61
+ - El modelo está optimizado para **texto informal** (tweets, mensajes)
62
+ - Puede tener falsos positivos con:
63
+ - Palabras ambiguas fuera de contexto
64
+ - Vocabulario compartido entre dialectos
65
+ - Solo distingue entre **argentino** y **español peninsular** (no otros dialectos latinoamericanos)
66
+
67
+ ## 🔍 Ejemplos
68
+
69
+ **Argentino:**
70
+ > "Che boludo, ¿vos sabés dónde dejé las llaves del bondi?"
71
+
72
+ **Español:**
73
+ > "Tío, este curro es una pasada, chaval"
74
+
75
+ ## 📝 Notas Técnicas
76
+
77
+ El modelo utiliza reglas de contexto para evitar falsos positivos en palabras ambiguas:
78
+ - "che" vs "Che Guevara"
79
+ - "mate" (bebida) vs "maté" (verbo)
80
+ - "colectivo" (autobús) vs "colectivo" (grupo)
81
+
82
+ ## 👨‍💻 Autor
83
+
84
+ Desarrollado como proyecto educativo de NLP con spaCy.
85
+
86
+ ## 📄 Licencia
87
+
88
+ MIT License
app.py ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import spacy
3
+ import json
4
+ import random
5
+ from collections import Counter
6
+
7
+ # Cargar modelo
8
+ print("Cargando modelo...")
9
+ nlp = spacy.load("./model")
10
+ print("✓ Modelo cargado")
11
+
12
+ # Función de detección
13
+ def detectar_dialectismos(texto):
14
+ doc = nlp(texto)
15
+ colors = {
16
+ "ARGENTINISMO": "#75aadb", # Azul celeste argentino
17
+ "ESPAÑOLISMO": "#c60b1e" # Rojo español
18
+ }
19
+ options = {
20
+ "colors": colors
21
+ }
22
+
23
+ html = spacy.displacy.render(
24
+ doc,
25
+ style="ent",
26
+ jupyter=False,
27
+ options=options
28
+ )
29
+ return html
30
+
31
+ # Ejemplos predefinidos
32
+ ejemplos = [
33
+ "Che boludo, ¿vos sabés dónde dejé las llaves del bondi?",
34
+ "Tío, este curro es una mierda, me voy a flipar",
35
+ ]
36
+
37
+
38
+ # Cargar tweets al inicio (fuera de las funciones)
39
+ with open('tweets_sample.json', 'r', encoding='utf-8') as f:
40
+ TODOS_LOS_TWEETS = json.load(f)
41
+
42
+ def generar_muestra_y_estadisticas():
43
+ """
44
+ Genera muestra de 1000 tweets y retorna estadísticas + la muestra misma
45
+ """
46
+ # Samplear 1000 tweets aleatorios
47
+ muestra = random.sample(TODOS_LOS_TWEETS, min(1000, len(TODOS_LOS_TWEETS)))
48
+
49
+ # Calcular estadísticas (mismo código de antes)
50
+ total_argentinismos = 0
51
+ total_españolismos = 0
52
+ palabras_arg = []
53
+ palabras_esp = []
54
+ tweets_argentinos = 0
55
+ tweets_españoles = 0
56
+
57
+ for tweet in muestra:
58
+ argentinismos = tweet['argentinismos']
59
+ españolismos = tweet['españolismos']
60
+
61
+ total_argentinismos += len(argentinismos)
62
+ total_españolismos += len(españolismos)
63
+
64
+ palabras_arg.extend(argentinismos)
65
+ palabras_esp.extend(españolismos)
66
+
67
+ if len(argentinismos) > len(españolismos):
68
+ tweets_argentinos += 1
69
+ elif len(españolismos) > len(argentinismos):
70
+ tweets_españoles += 1
71
+
72
+ top_arg = Counter(palabras_arg).most_common(10)
73
+ top_esp = Counter(palabras_esp).most_common(10)
74
+
75
+ # HTML con estadísticas
76
+ html_stats = f"""
77
+ <div style="font-family: Arial, sans-serif; padding: 20px;">
78
+ <h2>📊 Estadísticas de 1000 tweets aleatorios</h2>
79
+
80
+ <div style="display: flex; gap: 20px; margin: 20px 0;">
81
+ <div style="flex: 1; background: #75aadb; color: white; padding: 20px; border-radius: 10px;">
82
+ <h3>🇦🇷 Argentinismos</h3>
83
+ <p style="font-size: 32px; margin: 10px 0;"><strong>{total_argentinismos}</strong></p>
84
+ <p>detectados en total</p>
85
+ <p style="font-size: 20px;"><strong>{tweets_argentinos}</strong> tweets argentinos</p>
86
+ </div>
87
+
88
+ <div style="flex: 1; background: #c60b1e; color: white; padding: 20px; border-radius: 10px;">
89
+ <h3>🇪🇸 Españolismos</h3>
90
+ <p style="font-size: 32px; margin: 10px 0;"><strong>{total_españolismos}</strong></p>
91
+ <p>detectados en total</p>
92
+ <p style="font-size: 20px;"><strong>{tweets_españoles}</strong> tweets españoles</p>
93
+ </div>
94
+ </div>
95
+
96
+ <div style="display: flex; gap: 20px; margin-top: 30px;">
97
+ <div style="flex: 1;">
98
+ <h3>🔝 Top 10 Argentinismos</h3>
99
+ <ol>
100
+ {"".join(f'<li><strong>{palabra}</strong>: {count} veces</li>' for palabra, count in top_arg)}
101
+ </ol>
102
+ </div>
103
+
104
+ <div style="flex: 1;">
105
+ <h3>🔝 Top 10 Españolismos</h3>
106
+ <ol>
107
+ {"".join(f'<li><strong>{palabra}</strong>: {count} veces</li>' for palabra, count in top_esp)}
108
+ </ol>
109
+ </div>
110
+ </div>
111
+ </div>
112
+ """
113
+
114
+ # Retornar HTML de stats y la muestra para usarla después
115
+ return html_stats, muestra
116
+
117
+
118
+ def obtener_5_tweets_aleatorios(muestra):
119
+ """
120
+ Obtiene 5 tweets aleatorios de la muestra
121
+ """
122
+ if not muestra:
123
+ return gr.Radio(choices=[], label="Primero genera una muestra")
124
+
125
+ tweets_sample = random.sample(muestra, min(5, len(muestra)))
126
+
127
+ # Crear lista de opciones (texto truncado para visualización)
128
+ opciones = []
129
+ for i, tweet in enumerate(tweets_sample):
130
+ texto = tweet['text']
131
+ # Truncar si es muy largo
132
+ preview = texto[:100] + "..." if len(texto) > 100 else texto
133
+ opciones.append((preview, texto)) # (label, value)
134
+
135
+ return gr.Radio(choices=opciones, label="Selecciona un tweet", value=opciones[0][1] if opciones else None)
136
+
137
+
138
+
139
+ # Variable global para almacenar la muestra actual
140
+ muestra_actual = []
141
+
142
+ def wrapper_generar_muestra():
143
+ global muestra_actual
144
+ html_stats, muestra_actual = generar_muestra_y_estadisticas()
145
+ return html_stats
146
+
147
+ def wrapper_5_tweets():
148
+ global muestra_actual
149
+ return obtener_5_tweets_aleatorios(muestra_actual)
150
+
151
+ # Interfaz Gradio
152
+ with gr.Blocks() as demo:
153
+ gr.Markdown("# 🗣️ Detector de Dialecto Español: Argentino 🇦🇷 vs Español 🇪🇸")
154
+ gr.Markdown("Analiza una muestra de 1000 tweets aleatorios del dataset y explora ejemplos individuales.")
155
+
156
+ # Botón para generar muestra
157
+ btn_generar = gr.Button("🎲 Generar Muestra de 1000 Tweets", variant="primary", size="lg")
158
+ output_stats = gr.HTML()
159
+
160
+ gr.Markdown("---")
161
+ gr.Markdown("### Explorar ejemplos de la muestra")
162
+
163
+ # Botón para obtener 5 tweets
164
+ btn_samplear = gr.Button("📋 Mostrar 5 Tweets Aleatorios")
165
+ radio_tweets = gr.Radio(choices=[], label="Selecciona un tweet para analizar")
166
+
167
+ # Botón para analizar el tweet seleccionado
168
+ btn_analizar = gr.Button("🔍 Analizar Tweet Seleccionado", variant="secondary")
169
+ output_analisis = gr.HTML()
170
+
171
+ # Eventos
172
+ btn_generar.click(
173
+ fn=wrapper_generar_muestra,
174
+ inputs=None,
175
+ outputs=output_stats
176
+ )
177
+
178
+ btn_samplear.click(
179
+ fn=wrapper_5_tweets,
180
+ inputs=None,
181
+ outputs=radio_tweets
182
+ )
183
+
184
+ btn_analizar.click(
185
+ fn=detectar_dialectismos,
186
+ inputs=radio_tweets,
187
+ outputs=output_analisis
188
+ )
189
+
190
+
191
+ if __name__ == "__main__":
192
+ demo.launch()
model-last/config.cfg ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0f47c08d6562cd88bfe379fdc95a2d3e02a6c5a9980c2c455de7219c3f9573fc
3
+ size 2727
model-last/meta.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:49cde1bdf1a001d04b7e85543624fd15d1f0f31dcea1dc0ef8bf64f4e3aa8b6b
3
+ size 918
model-last/ner/cfg ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a7172edadafba9f472e9ac0f2660eec04b6405e471be9e20267b79c67288d22d
3
+ size 221
model-last/ner/model ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c2a63b5af4610f2430f1222d2228ab8d207a5ca0ba88a19fffd8b7cacd0fae18
3
+ size 128548
model-last/ner/moves ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f5539fd26b49eefe62ff03861278c9d5e6110829d4fc8fcb91f838210f71da03
3
+ size 247
model-last/tok2vec/cfg ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f8a5a26e3056eb6fb06deeb3dbccfd88ae74900200c98c70b5966bbb7ec9d4de
3
+ size 4
model-last/tok2vec/model ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:db3c800e8c3bd8563d2041359079a980c7cb2edd306c0229e4285932302579e2
3
+ size 6009091
model-last/tokenizer ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b59b7b576c81115906b8fcf07f331a84846f77b431676a0803906c94c817462f
3
+ size 36912
model-last/vocab/key2row ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e8671a09a41a5b75945090b0587993eff21adca55f626dae7bb36f159a6eb5f7
3
+ size 5994249
model-last/vocab/lookups.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:76be8b528d0075f7aae98d6fa57a6d3c83ae480a8469e668d7b0af968995ac71
3
+ size 1
model-last/vocab/strings.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d35a44de283505c654dd72c891eb71e1d2b72f9b0e995ca6143b26f25962bc60
3
+ size 10789527
model-last/vocab/vectors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e62c4610ae1cf28f17f80020f38ac20d3f8c57b10c348d4403141e16e79b7664
3
+ size 24000128
model-last/vocab/vectors.cfg ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ff4359091952c8cd16f1f0482f5770fb82d1707368d5cca3c46aa501f552e3c5
3
+ size 22
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ gradio>=5.49.0
2
+ spacy==3.8.2
3
+ huggingface-hub<1.0.0
tweets_sample.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:aff909d13d9dabe99f2ca5cd137686d81d1c216f8a2a2dddf7e925983434d731
3
+ size 406177