from transformers import pipeline import torch import streamlit as st from textblob import TextBlob from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer import os import re import pandas as pd def translate_text_blob(text): blob = TextBlob(text) return str(blob.translate(from_lang="pt", to="en")) def sentiment_vader(text): vader_object = SentimentIntensityAnalyzer() sentiment_dict = vader_object.polarity_scores(text) negative = sentiment_dict['neg'] neutral = sentiment_dict['neu'] positive = sentiment_dict['pos'] compound = sentiment_dict['compound'] if sentiment_dict['compound'] >= 0.05 : overall_sentiment = "Positive" elif sentiment_dict['compound'] <= - 0.05 : overall_sentiment = "Negative" else : overall_sentiment = "Neutral" return overall_sentiment.upper() def classify_by_company(text): path = os.path.dirname(os.path.realpath(__file__)) + "/Companies" for filename in os.listdir(path): with open(path + '/' + filename, 'r') as f: companies = [word[:-1] for word in f.readlines()] companies = "|".join(companies) companies = "/" + companies + "/gm" if re.search(companies, text): return filename[:-4] + " - Infered by company name in text" return "" def run_models(parameters_list): translation_map = { #Translation PT to EN "TextBlob" : "TextBlob", "M2M100" : "facebook/m2m100_418M", "OPUS" : "Helsinki-NLP/opus-mt-mul-en", "T5" : "unicamp-dl/translation-pt-en-t5", "mBART" : "Narrativa/mbart-large-50-finetuned-opus-en-pt-translation", } sentiment_map = { #Sentiment Analysis "VADER" : "VADER", "FinBERT" : "ProsusAI/finbert", "DistilBERT" : "distilbert-base-uncased-finetuned-sst-2-english", "BERT" : "nlptown/bert-base-multilingual-uncased-sentiment", } zeroshot_map = { #Zeroshot Classification "RoBERTa" : "joeddav/xlm-roberta-large-xnli", "mDeBERTa" : "MoritzLaurer/mDeBERTa-v3-base-mnli-xnli", "DistilroBERTa" : "cross-encoder/nli-distilroberta-base", } candidate_labels = [ "Industrial Goods", "Communications", "Cyclic Consumption", "Non-cyclical Consumption", "Financial", "Basic Materials", #"Others", "Oil, Gas and Biofuels", "Health", #"Initial Sector", "Information Technology", "Public utility" ] device_num = 0 if torch.cuda.is_available() else -1 if parameters_list[0] == "TextBlob": out_translation = translate_text_blob(parameters_list[3]) else: translation = pipeline("translation_pt_to_en", model=translation_map[parameters_list[0]], tokenizer=translation_map[parameters_list[0]], device=device_num) out_translation = translation(parameters_list[3])[0]["translation_text"] if parameters_list[1] == "VADER": out_sentiment = sentiment_vader(out_translation) else: sentiment = pipeline("sentiment-analysis", model=sentiment_map[parameters_list[1]], tokenizer=sentiment_map[parameters_list[1]], device=device_num) out_sentiment = sentiment(out_translation)[0]["label"].upper() company_classification = classify_by_company(parameters_list[3].upper()) if company_classification: out_classification = company_classification else: classification = pipeline("zero-shot-classification", model=zeroshot_map[parameters_list[2]], tokenizer=zeroshot_map[parameters_list[2]], device=device_num) out_classification = classification(out_translation, candidate_labels)["labels"][0] + " - Infered by {}".format(parameters_list[2]) return out_translation, out_sentiment, out_classification sheet_id = "1TjDuF6dmirgdpuG_o5Y4CBPQdfmkksS1" sheet_name = "Sheet1" url = f"https://docs.google.com/spreadsheets/d/{sheet_id}/gviz/tq?tqx=out:csv&sheet={sheet_name}" df = pd.read_csv(url) header = st.container() model = st.container() model_1, model_2 = st.columns(2) dataset = st.container() analysis = st.container() analysis_1, analysis_2 = st.columns(2) with header: st.title("IC 2022 Classificação de Dados Financeiros") st.write("Este trabalho de Iniciação Científica visa criar uma *interface web* que integre diversas funcionalidades de *machine learning*, essas funcionalidades cooperam entre si para realizar um processamento automático de textos financeiros com o fim de aplicar técnicar de Tradução Automática, Análise de Sentimentos e Classificação ZeroShot de textos em português sobre artigos do ramo financeiro. \n \n Este projeto também visa incluir novas técnicas ao leque de opções desta ferramenta, voltados principalmente para o Processamento de Linguagem Natural (PLN) tanto para fins de estudo e conhecimento dos modelos pautados como estado-da-arte, como também aperfeiçoamento dos módulos e saídas já implementados.") with model: st.header("Modelo para Tradução e Classificação!") with model_1: translation_pt_to_en = st.selectbox('Qual modelo você deseja usar para tradução?', ('TextBlob', 'M2M100', 'OPUS', 'T5', 'mBART')) sentiment_analysis = st.selectbox('Qual modelo você deseja usar para análise de sentimento?', ('VADER', 'FinBERT', 'DistilBERT', 'BERT')) zero_shot_classification = st.selectbox('Qual modelo você deseja usar para classificação?', ('RoBERTa', 'mDeBERTa', 'DistilroBERTa')) text = st.text_input(label="Coloque seu texto sobre mercado financeiro em português!", value=r"As ações da Raia Drogasil subiram em 98% desde o último bimestre, segundo as avaliações da revista!") submit = st.button('Gerar análises!') with model_2: if submit: with st.spinner('Wait for it...'): parameters = [translation_pt_to_en, sentiment_analysis, zero_shot_classification, text] outputs = run_models(parameters) st.write("Translation..................................................................: \n {} \n \n".format(outputs[0])) st.write("Sentiment...................................................................: \n {} \n \n".format(outputs[1])) st.write("Classification...............................................................: \n {} \n \n".format(outputs[2])) with dataset: st.header("Dados utilizados no projeto") st.write("Os dados abaixo foram obtidos através de *web scrapping* dos sites Valor Globo, Infomoney e Exame para o fim de aplicação dos modelos selecionados, para a confecção dos dados abaixo foram utilizados o TextBlob para Tradução Automática, VADER para a Análise de Sentimentos, Inferição por empresas presentes no texto e Roberta para a Classificação.") st.dataframe(df) st.subheader("Descrição das colunas:") st.write("\t**- date:.........** Coluna de entrada contendo as datas em que os textos foram publicados") st.write("\t**- url:..........** Coluna de entrada contendo os links para as páginas *web* das quais os textos foram retirados") st.write("\t**- texts:........** Coluna de entrada contendo os textos financeiros propriamente ditos") st.write("\t**- is_title:.....** Coluna de entrada contendo os se os textos são, ou não, pertencentes ao título da notícia") st.write("\t**- translated:...** Coluna de saída contendo os textos financeiros que foram traduzidos utilizando o TextBlob") st.write("\t**- theme:........** Coluna de saída contendo as classificações em áreas financeiras, das quais metade foram obtidas pelo nome de empresas presentes no texto e a outra metade obtidos por classificação zeroshot do modelo RoBERTa") st.write("\t**- sentiment:....** Coluna de saída contendo as análises de sentimentos dos textos utilizando VADER") with analysis: st.header("Visualização dos dados utilizados através de WordClouds") with analysis_1: wordcloud = st.selectbox('Qual wordcloud você deseja ver?', ( "Health", "Financial", "Industrial Goods", "Public utility", "Others", "Communications", "Cyclic Consumption", "Information Technology", "Oil, Gas and Biofuels", "Non-cyclical Consumption", "Basic Materials", ))