CoolFace
Apppublic

Matt-CB/TwitterAccountAnalyzer

sourceHugging Faceupdated 3y agoView on Hugging Face
0likes
app.py229 linesDownload Raw Back to root
1import os2import csv3import openai 4import random5from dotenv import load_dotenv6from nltk.corpus import stopwords7from nltk.tokenize import word_tokenize8from nltk import pos_tag9from collections import Counter10import nltk11nltk.download('punkt')12from transformers import pipeline13from mtranslate import translate14import pandas as pd15import streamlit as st16from PIL import Image17import time18 19 20                        #Para actualizar las librerias de requirements.txt en caso de error, escribir esto en consola: pip install --upgrade -r requirements.txt21load_dotenv()22st.sidebar.title("Configuración")23OPENAI_API_KEY = st.sidebar.text_input("API KEY:")24st.write("Ingresa los datos ")25IDIOMAS = ['Alemán', 'Español', 'Francés', 'Inglés', 'Italiano']26idioma = st.sidebar.selectbox("Idioma:", IDIOMAS)27 28 29 30 31class AnalizadorTwitter:32    def __init__(self):33        self.TWEETS_DIR = 'tweets'34        nltk.download('averaged_perceptron_tagger')35        nltk.download('stopwords')36 37    def generar_tweets(self, usuario:str, num_tweets:int=10, max_tokens:int=50, aleatoriedad:float=1):38        openai.api_key = OPENAI_API_KEY39        os.makedirs(self.TWEETS_DIR, exist_ok=True)40        archivo_csv = os.path.join(self.TWEETS_DIR, f"{usuario}_tweets.csv")41        archivo_existente = os.path.exists(archivo_csv)42 43        temas = ["Deportes", "Entretenimiento", "Política", "Tecnología", "Moda y belleza", "Viajes", "Negocios y finanzas", "Redes sociales e internet", "Comida y restaurantes", "Música", "Arte y cultura", "Ciencia y naturaleza", "Educación", "Videojuegos", "Humor y memes", "Tecnología e innovación", "Hogar y diseño de interiores", "Relaciones y citas", "Espiritualidad y religión", "Mascotas y animales"]44        emociones = ["Felicidad", "Tristeza", "Emoción", "Miedo", "Amor", "Asombro", "Enojo", "Sorpresa", "Diversión", "Paz"]45 46        tema = random.choice(temas)47        print(idioma, tema)48 49        with open(archivo_csv, 'a', newline='', encoding='utf-8') as archivo:50            writer = csv.writer(archivo)51 52            if not archivo_existente:53                writer.writerow(['user', 'tweet'])54 55            for i in range(num_tweets):56                emocion = random.choice(emociones)57                prompt = f"Generar un tweet corto #{i+1} centrado en el tema de {tema}. El tweet debe expresar una emoción de {emocion} con una intensidad alta y que se noten las palabras expresivas hacia ese sentimiento, pero sin dejar de ser realista. Debe ser redactado si o si todo en {idioma}, que sea nivel nativo de {idioma}. Evita incluir emojis en el contenido del tweet. Asegúrate de que el tweet esté completamente en {idioma}, y que las emociones y los sentimientos reflejen la intensidad solicitada antes de proporcionar la respuesta."58 59                response = openai.Completion.create(60                    engine='text-davinci-003',61                    prompt=prompt,62                    max_tokens=max_tokens,63                    temperature=aleatoriedad,64                    n=1,65                    stop=None,66                )67 68                tweet = response.choices[0].text.strip()69 70                writer.writerow([usuario, tweet])71 72    def identificar_tema_principal(self, dataframe, idioma):73        tweets = dataframe['tweet'].tolist()74         # Seleccionar stopwords según el idioma75        if idioma == "Alemán":76            stop_words = set(stopwords.words('german'))77        elif idioma == "Español":78            stop_words = set(stopwords.words('spanish'))79        elif idioma == "Francés":80            stop_words = set(stopwords.words('french'))81        elif idioma == "Inglés":82            stop_words = set(stopwords.words('english'))83        elif idioma == "Italiano":84            stop_words = set(stopwords.words('italian'))85        else:86            raise ValueError("Idioma no soportado")87 88        # Tokenización de palabras y eliminación de stopwords89        palabras = [word for tweet in tweets for word in word_tokenize(tweet.lower()) if word.isalpha() and word not in stop_words]90 91        # Etiquetado de partes del discurso92        tagged_words = pos_tag(palabras)93 94        # Contar la frecuencia de cada palabra95        frecuencia_palabras = Counter(tagged_words)96 97        # Ordenar las palabras por frecuencia98        palabras_ordenadas = sorted(frecuencia_palabras.items(), key=lambda x: x[1], reverse=True)99 100        # Obtener el tema principal como la palabra más frecuente con etiqueta de sustantivo101        tema_principal = None102        for palabra, frecuencia in palabras_ordenadas:103            if 'NN' in palabra[1]:  # Verificar si la palabra tiene etiqueta de sustantivo104                tema_principal = palabra[0]105                break106 107        return tema_principal108 109    def traducir_columna(self, df, idioma):110        df_traducido = df.copy()111        if idioma == 'inglés':112            return df_traducido113        else:114            df_traducido['tweet_ingles'] = df_traducido['tweet'].apply(lambda x: translate(x, 'en'))115            return df_traducido116 117    def agregar_columna_emociones(self, df, idioma):118        clasificador = pipeline("text-classification", model="thoriqfy/indobert-emotion-classification")119        emociones_detectadas = []120        if idioma != 'inglés':121            data = self.traducir_columna(df, idioma)122            for texto in data['tweet_ingles']:123                outputs = clasificador(texto)124                emocion = outputs[0]['label']125                emociones_detectadas.append(emocion)126        else:127            data = df128            for texto in data['tweet']:129                outputs = clasificador(texto)130                emocion = outputs[0]['label']131                emociones_detectadas.append(emocion)132        data['emocion_detectada'] = emociones_detectadas133 134        #menciona todas las columnas de data135 136 137        return data138 139    140    @staticmethod141    def obtener_sentimiento(score):142        if score < 0.4:143            return 'Negativo'144        elif score < 0.6:145            return 'Neutro'146        else:147            return 'Positivo'148 149        150    def identificar_sentimiento(self, dataframe, idioma):151        modelo = ''152        if idioma.lower() == "alemán".lower():153            modelo = "oliverguhr/german-sentiment-bert"154        elif idioma.lower() == "español".lower():155            modelo = "dccuchile/bert-base-spanish-wwm-uncased"156        elif idioma.lower() == "francés".lower():157            modelo = "nlptown/bert-base-multilingual-uncased-sentiment"158        elif idioma.lower() == "inglés".lower():159            modelo = "bert-base-uncased"160        elif idioma.lower() == "italiano".lower():161            modelo = "Musixmatch/umberto-commoncrawl-cased-v1"162 163        clasificador_sentimiento = pipeline("sentiment-analysis", model=modelo)164        sentimientos = []165        for texto in dataframe['tweet']:166            resultado = clasificador_sentimiento(texto)167            etiqueta = resultado[0]['label']168            score = resultado[0]['score']169            sentimiento = self.obtener_sentimiento(score)170            sentimientos.append(sentimiento)171        dataframe['sentimiento'] = sentimientos172        return dataframe173            174 175 176 177 178def main():179 180 181    column1, column2 = st.columns([1.5, 1])182    column1.markdown("<h1 style='text-align: left; color: white;'>Análisis de <span style='color: #1DA1F2;'>Twitter</span></h1>", unsafe_allow_html=True)183    column2.image("images/Logo_of_Twitter.png", width=100)184 185 186    usuario = st.sidebar.text_input("Nombre de usuario:", "usuario_ejemplo")187    st.sidebar.markdown('<p style="font-size:12px;color:#1DA1F2;">No dejar espacios en el nombre y apellido</p>', unsafe_allow_html=True)188    st.sidebar.title('Configuración de parametros para el generador de tweets')189    num_tweets = st.sidebar.number_input("Número de tweets:", 1, 100, 10)190    st.sidebar.markdown('<p style="font-size:12px;color:#1DA1F2;">Colocar como min 5 tweets</p>', unsafe_allow_html=True) #191    max_tokens = st.sidebar.number_input("Máximo de tokens:", 1, 100, 50)192    aleatoriedad = st.sidebar.slider("Aleatoriedad:", 0.0, 1.0, 1.0)193    #idioma = st.sidebar.selectbox("Idioma:", IDIOMAS)194    tema = None195    sentimientos = ["Todos", "Positivo", "Neutro", "Negativo"]196    sentimiento = st.sidebar.selectbox("Sentimientos:", sentimientos)197    analizador = AnalizadorTwitter()198    if st.sidebar.button("Analizar"):199        with st.spinner("Generando tweets..."):200            analizador.generar_tweets(usuario, num_tweets, max_tokens, aleatoriedad)201        with st.spinner("Identificando tema principal..."):202            archivo_csv = os.path.join(analizador.TWEETS_DIR, f"{usuario}_tweets.csv")203            df = pd.read_csv(archivo_csv)204            tema = analizador.identificar_tema_principal(df, idioma)205        with st.spinner("Traduciendo tweets (si es necesario)..."):206            df_traducido = analizador.traducir_columna(df, idioma)207        with st.spinner("Detectando sentimientos..."):208            df_sentimiento = analizador.identificar_sentimiento(df, idioma)209        with st.spinner("Detectando emociones..."):210            df_emociones = analizador.agregar_columna_emociones(df_traducido, idioma)211        st.write("Cuenta: ", usuario)212        st.write("Tema principal: ", tema)213        st.write("Tabla de sentimientos:")214        st.dataframe(df_sentimiento)215        st.write("Tabla de emociones:")216        st.dataframe(df_emociones)217        st.markdown("# Tweets:")218        for i in df_emociones.index:219            row_emocion = df_emociones.loc[i]220            row_sentimiento = df_sentimiento.loc[i]221            if sentimiento == "Todos" or row_sentimiento["sentimiento"] == sentimiento:222                st.write(usuario, ':', row_emocion["tweet"])223                st.write("Emoción detectada: ", row_emocion["emocion_detectada"], f"- Sentimiento detectado: {row_sentimiento['sentimiento']}")224 225 226if __name__ == "__main__":227    main()228 229