File size: 10,642 Bytes
a86ebfe
074b087
4f600ec
 
123a2a5
64547bc
4c1a7b2
eb03325
4913bb4
edb53bb
074b087
336e489
4c1a7b2
a76f382
4913bb4
a86ebfe
336e489
a76f382
 
 
336e489
a86ebfe
 
 
 
 
 
 
1b4e97e
bfaf0da
4913bb4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0e521b1
e5f8353
 
 
 
 
 
 
bc97bc5
074b087
 
 
e7fc6e7
457d41e
1b4e97e
 
 
 
9641669
074b087
1b4e97e
 
 
074b087
1b4e97e
 
 
074b087
1b4e97e
457d41e
 
bfaf0da
0eaa842
bfaf0da
d0e7d06
 
bfaf0da
 
d0e7d06
 
 
 
 
4913bb4
 
 
 
bfaf0da
4913bb4
 
 
 
 
 
 
 
 
d0e7d06
 
cfaf805
7386027
2ba6811
70da8b4
 
 
9091676
7386027
d8e3643
7386027
 
f9ed481
7386027
bfaf0da
7386027
0e521b1
3e92edb
1bf00e3
dc1887d
 
 
ec5e9ed
9ffd42a
dad8f09
bb0de7f
485e4eb
d5291cb
4f31ce9
dad8f09
 
bfaf0da
6de011c
dad8f09
6de011c
fe0b968
a7ff4ae
46ac277
b57da8c
485e4eb
6de011c
7386027
 
6de011c
46ac277
ce8c102
46ac277
ce8c102
 
 
 
1333876
7386027
284507d
b65d150
ae4c78e
ce8c102
ca81fbf
 
 
6de011c
 
 
 
 
3580d3c
20e5edc
 
 
 
 
3580d3c
20e5edc
 
 
bb0de7f
46ac277
7386027
 
dad8f09
7386027
bb0de7f
 
33f003a
eb4e7e0
7386027
 
4913bb4
89d7f96
 
 
 
 
 
 
33f003a
dfcadc4
 
89d7f96
b9decf4
bb0de7f
074b087
 
 
 
19aeb3f
aa1a517
19aeb3f
074b087
3e92edb
074b087
3e92edb
938d354
074b087
0567ede
38110be
074b087
 
38110be
 
fc3e5ca
 
 
 
0e521b1
1c9fb4e
fc3e5ca
bfaf0da
be5e499
8d37970
2f14689
074b087
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
import tweepy as tw
import streamlit as st
import pandas as pd
import regex as re
import numpy as np
import pysentimiento
import geopy
import matplotlib.pyplot as plt
import langdetect


from pysentimiento.preprocessing import preprocess_tweet
from geopy.geocoders import Nominatim
from transformers import pipeline
from langdetect import detect


model_checkpoint = "hackathon-pln-es/twitter_sexismo-finetuned-robertuito-exist2021" 
pipeline_nlp = pipeline("text-classification", model=model_checkpoint)

    
consumer_key = "BjipwQslVG4vBdy4qK318KnoA"
consumer_secret = "3fzL70v9faklrPgvTi3zbofw9rwk92fgGdtAslFkFYt8kGmqBJ"
access_token = "1217853705086799872-Y5zEChpTeKccuLY3XJRXDPPZhNrlba"
access_token_secret = "pqQ5aFSJxzJ2xnI6yhVtNjQO36FOu8DBOH6DtUrPAU54J"
auth = tw.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tw.API(auth, wait_on_rate_limit=True)
   
def limpieza_datos(tweet):
    # Eliminar emojis
    tweet = re.sub(r'[\U0001F600-\U0001F64F]', '', tweet)
    tweet = re.sub(r'[\U0001F300-\U0001F5FF]', '', tweet)
    tweet = re.sub(r'[\U0001F680-\U0001F6FF]', '', tweet)
    tweet = re.sub(r'[\U0001F1E0-\U0001F1FF]', '', tweet)
    # Eliminar arrobas
    tweet = re.sub(r'@\w+', '', tweet)
    # Eliminar URL
    tweet = re.sub(r'http\S+', '', tweet)
    # Eliminar hashtags
    tweet = re.sub(r'#\w+', '', tweet)
    # Eliminar caracteres especiales
    #tweet = re.sub(r'[^a-zA-Z0-9 \n\.]', '', tweet)
    tweet = re.sub(r'[^a-zA-Z0-9 \n\áéíóúÁÉÍÓÚñÑ.]', '', tweet)
    return tweet

def highlight_survived(s):
    return ['background-color: red']*len(s) if (s.Sexista == 1) else ['background-color: green']*len(s)

def color_survived(val):
    color = 'red' if val=='Sexista' else 'white'
    return f'background-color: {color}'


st.set_page_config(layout="wide")
st.markdown('<style>body{background-color: Blue;}</style>',unsafe_allow_html=True)

#colT1,colT2 = st.columns([2,8])
    
#st.title('Analisis de comentarios sexistas en Twitter') 
st.markdown(""" <style> .font {
font-size:40px ; font-family: 'Cooper Black'; color: #06bf69;} 
</style> """, unsafe_allow_html=True)
st.markdown('<p class="font">Detectando el Sexismo en Línea: Un Proyecto de Investigación</p>', unsafe_allow_html=True)
    
st.markdown(""" <style> .font1 {
font-size:28px ; font-family: 'Times New Roman'; color: #8d33ff;} 
</style> """, unsafe_allow_html=True)

st.markdown(""" <style> .font2 {
font-size:18px ; font-family: 'Times New Roman'; color: #00000;} 
</style> """, unsafe_allow_html=True)

st.markdown('<p class="font2">Este proyecto consiste en una aplicación web que utiliza la biblioteca Tweepy de Python para descargar tweets de Twitter, permitiendo buscar Tweets por usuario y por localidad. Luego, utiliza modelos de lenguaje basados en Transformers para analizar los tweets y detectar comentarios sexistas. Los resultados se almacenan en un dataframe para su posterior visualización y análisis. El objetivo del proyecto es identificar y proporcionar información sobre el discurso sexista en línea para combatir la discriminación y el acoso hacia las mujeres y otros grupos marginados, y así informar políticas y prácticas que promuevan la igualdad de género y la inclusión.</p>',unsafe_allow_html=True)


def tweets_usuario(usuario, cant_de_tweets):
  tabla = []
  if(cant_de_tweets > 0 and usuario != "" ):
      try:
          # Buscar la información del perfil de usuario
          user = api.get_user(screen_name=usuario)
          tweets = api.user_timeline(screen_name = usuario,tweet_mode="extended", count= cant_de_tweets)
          result = []
          for tweet in tweets:
              if (tweet.full_text.startswith('RT')):
                  continue
              else:
                  text = tweet.full_text
                  try:
                      language = detect(text)
                      if language == 'es':
                          datos=limpieza_datos(text)
                          if datos == "":
                              continue
                          else:
                              prediction = pipeline_nlp(datos)
                              for predic in prediction:
                                etiqueta = {'Tweets': datos, 'Prediccion': predic['label'], 'Probabilidad': predic['score']}
                                result.append(etiqueta)
                  except:
                      pass   
          df = pd.DataFrame(result)
          if df.empty:
              muestra= st.text("No hay tweets Sexistas a analizar")
              tabla.append(muestra)
          else:
              df.sort_values(by=['Prediccion', 'Probabilidad'], ascending=[False, False], inplace=True)
              df['Prediccion'] = np.where(df['Prediccion'] == 'LABEL_1', 'Sexista', 'No Sexista')
              df['Probabilidad'] = df['Probabilidad'].apply(lambda x: round(x, 3))
              muestra = st.table(df.reset_index(drop=True).head(30).style.applymap(color_survived, subset=['Prediccion']))
              tabla.append(muestra)
      except Exception as e:
          muestra = st.text(f"La cuenta {search_words} no existe.") 
          tabla.append(muestra) 
  else:
      muestra= st.text("Ingrese los parametros correspondientes")
      tabla.append(muestra)      
  return tabla

def tweets_localidad(buscar_localidad):
    tabla = []
    try:
        geolocator = Nominatim(user_agent="nombre_del_usuario")
        location = geolocator.geocode(buscar_localidad)
        radius = "15km"
        tweets = api.search_tweets(q="",lang="es",geocode=f"{location.latitude},{location.longitude},{radius}", count = 1000, tweet_mode="extended")
        result = []
        for tweet in tweets:
            if (tweet.full_text.startswith('RT')):
                continue
            elif not tweet.full_text.strip():
                continue
            else:
                datos = limpieza_datos(tweet.full_text)
                prediction = pipeline_nlp(datos)
                for predic in prediction:
                    etiqueta = {'Tweets': datos,'Prediccion': predic['label'], 'Probabilidad': predic['score']}
                    result.append(etiqueta)
        df = pd.DataFrame(result)
        
        #muestra = st.table(df.reset_index(drop=True).head(5).style.applymap(color_survived, subset=['Prediccion']))
        
        if df.empty:
            muestra=st.text("No se encontraron tweets sexistas dentro de la localidad")
            tabla.append(muestra)
        else:
            #tabla.append(muestra)
            df.sort_values(by=['Prediccion', 'Probabilidad'], ascending=[False, False], inplace=True)
            df['Prediccion'] = np.where(df['Prediccion'] == 'LABEL_1', 'Sexista', 'No Sexista')
            #df = df[df["Prediccion"] == 'Sexista']
            #df = df[df["Probabilidad"] > 0.5]
            #df = df.sort_values(by='Probabilidad', ascending=False)
            df['Probabilidad'] = df['Probabilidad'].apply(lambda x: round(x, 3))
            muestra = st.table(df.reset_index(drop=True).head(10).style.applymap(color_survived, subset=['Prediccion']))
            tabla.append(muestra)
            resultado=df.groupby('Prediccion')['Probabilidad'].sum()
            colores=["#EE3555","#aae977"]
            fig, ax = plt.subplots()
            fig.set_size_inches(2, 2)
            plt.pie(resultado,labels=resultado.index,autopct='%1.1f%%',colors=colores,  textprops={'fontsize': 4})
            ax.set_title("Porcentajes por Categorias", fontsize=5, fontweight="bold")
            plt.rcParams.update({'font.size':4, 'font.weight':'bold'})
            ax.legend()
            # Muestra el gráfico
            plt.show()
            st.set_option('deprecation.showPyplotGlobalUse', False)
            st.pyplot()
            
            #plt.bar(resultado.index, resultado, color=colores)
            #ax.set_title("Porcentajes por Categorias", fontsize=5, fontweight="bold")
            #plt.rcParams.update({'font.size':4, 'font.weight':'bold'})
            #ax.set_xlabel("Categoría")
            #ax.set_ylabel("Probabilidad")
            # Muestra el gráfico
            #plt.show()
            #st.set_option('deprecation.showPyplotGlobalUse', False)
            #st.pyplot()
        
    except AttributeError as e:
        muestra=st.text("No existe ninguna localidad con ese nombre") 
        tabla.append(muestra)
                 
    return tabla 
    
def analizar_frase(frase):
    language = detect(frase)
    if frase == "":
        tabla = st.text("Ingrese una frase")
        #st.text("Ingrese una frase")
    elif language == 'es':
        predictions = pipeline_nlp(frase)
        # convierte las predicciones en una lista de diccionarios
        data = [{'Texto': frase, 'Prediccion': prediction['label'], 'Probabilidad': prediction['score']} for prediction in predictions]
        # crea un DataFrame a partir de la lista de diccionarios
        df = pd.DataFrame(data)
        df['Prediccion'] = np.where( df['Prediccion'] == 'LABEL_1', 'Sexista', 'No Sexista')
        # muestra el DataFrame
        tabla = st.table(df.reset_index(drop=True).head(1).style.applymap(color_survived, subset=['Prediccion']))
    else:
        tabla = st.text("Solo Frase en español")
        
    return tabla
    
def run():   
 with st.form("my_form"):
   col,buff1, buff2 = st.columns([2,2,1])
   st.write("Escoja una Opción")
   search_words = col.text_input("Introduzca la frase, el usuario o localidad para analizar y pulse el check correspondiente")
   number_of_tweets = col.number_input('Introduzca número de tweets a analizar del usuario Máximo 50', 0,50,0)
   termino=st.checkbox('Frase')
   usuario=st.checkbox('Usuario')
   localidad=st.checkbox('Localidad')
   submit_button = col.form_submit_button(label='Analizar')
   error =False
  
   if submit_button:
            # Condición para el caso de que esten dos check seleccionados
            if ( termino == False and usuario == False and localidad == False):
                st.text('Error no se ha seleccionado ningun check')
                error=True
            elif ( termino == True and usuario == True and localidad == True):
                st.text('Error se han seleccionado varios check')
                error=True
                
            if (error == False):
                if (termino):
                  analizar_frase(search_words)
                    
                elif (usuario):
                    tweets_usuario(search_words,number_of_tweets)
                elif (localidad):
                    tweets_localidad(search_words)
     
run()