File size: 10,938 Bytes
11adebb
 
 
 
c2c681e
11adebb
 
f352c0a
c2c681e
 
11adebb
 
 
c2c681e
 
11adebb
 
c2c681e
 
11adebb
 
 
 
 
 
 
 
 
c2c681e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11adebb
 
 
 
 
 
 
 
 
 
 
 
c2c681e
 
 
 
 
 
11adebb
 
c2c681e
 
 
11adebb
c2c681e
11adebb
c2c681e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11adebb
 
 
c2c681e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4518611
c2c681e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
beb215b
11adebb
 
 
 
c2c681e
 
 
11adebb
 
 
 
c2c681e
11adebb
 
 
 
 
 
 
 
 
 
 
 
 
 
c2c681e
11adebb
 
c2c681e
11adebb
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
236
237
238
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)

#st.markdown('<style>body{background-color: Blue;}</style>',unsafe_allow_html=True)
#colT1,colT2 = st.columns([2,8])
st.markdown(""" <style> .fondo {
background-image: url("https://www.google.com/url?sa=i&url=https%3A%2F%2Flasmujereseneldeportemexicano.wordpress.com%2F2016%2F11%2F17%2Fpor-que-es-importante-hablar-de-genero%2F&psig=AOvVaw0xG7SVXtJoEpwt-fF5Kykt&ust=1676431557056000&source=images&cd=vfe&ved=0CBAQjRxqFwoTCJiu-a6IlP0CFQAAAAAdAAAAABAJ");
background-size: 180%;} 
</style> """, unsafe_allow_html=True)


st.markdown(""" <style> .font {
font-size:40px ; font-family: 'Cooper Black'; color: #301E67;} 
</style> """, unsafe_allow_html=True)

st.markdown('<p class="font">Análisis de comentarios sexistas en linea</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:16px ; font-family: 'Times New Roman'; color: #5B8FB9;} 
</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)
        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.sort_values(by='Prediccion', ascending=False, inplace=True)
            df['Prediccion'] = np.where(df['Prediccion'] == 'LABEL_1', 'Sexista', 'No Sexista')
            df['Probabilidad'] = df['Probabilidad'].round(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()
            with st.container():
                resultado = df['Prediccion'].head(10).value_counts()
                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()