Análise de sentimento com Flume e Twitter

QUARTA PARTE

Link da documentação oficial do Hadoop:

http://hadoop.apache.org/

Link do meu Github:

https://github.com/toticavalcanti

CONTINUANDO COM A CONSTRUÇÃO DA APLICAÇÃO DE ANÁLISE DE SENTIMENTO.

CONSTRUÇÃO DO SCRIPT PYSPARK

PARA A ANÁLISE FOI UTILIZADO O SPARK, UMA TECNOLOGIA DE COMPUTAÇÃO DISTRIBUÍDA EM CLUSTER, EXTREMAMENTE RÁPIDA. EXISTEM MUITOS MÉTODOS E ABORDAGENS DIFERENTES PARA A ANÁLISE DE SENTIMENTOS. PARA SIMPLIFICAR, NÓS UTILIZAREMOS UMA ABORDAGEM MAIS BÁSICA. NO ENTANTO, NADA IMPEDE QUE VOCÊ ADOTE UMA ABORDAGEM MAIS SOFISTICADA USANDO PNL E OUTRAS FERRAMENTAS. O DIAGRAMA A SEGUIR ILUSTRA A ABORDAGEM ADOTADA NESTE TUTORIAL. O RESULTADO SERÁ UMA MEDIDA APROXIMADA DE QUÃO POSITIVOS OU NEGATIVOS OS TWEETS SÃO SOBRE O ASSUNTO. OS RETWEETS SÃO CONSIDERADOS COMO "TENDO O MESMO SENTIMENTO" - OBVIAMENTE, ISSO PODE NÃO SER VERDADE, MAS SIMPLIFICA A MANEIRA COMO OS TWEETS SÃO PROCESSADOS. A PRESENÇA DO ASSUNTO IRÁ “ASSUMIR” O SENTIMENTO DO TWEET. ISSO SIGNIFICA QUE, SE O SAMSUNG S7 É MENCIONADO NO TWEET, O SENTIMENTO DO TWEET É ATRIBUÍDO AO "SAMSUNG S7". OBVIAMENTE, PARA SERMOS MAIS PRECISOS, PRECISARÍAMOS FAZER RESOLUÇÃO DE NOME DE ENTIDADE, ANÁLISE DE SENTENÇA E ANÁLISE DE SENTIMENTO BASEADA EM ASPECTOS. INFLEXÕES DE SARCASMO E PALAVRA NÃO SÃO LEVADAS EM CONTA E PODEM LEVAR A UMA PONTUAÇÃO INCORRETA DE SENTIMENTO.

ARQUIVOS USADOS PELO SCRIPT PYSPARK

  • AFINN (FINN ÅRUP NIELSEN) - UMA LISTA DE PALAVRAS EM INGLÊS CLASSIFICADAS POR VALOR NUMÉRICO INTEIRO ENTRE MENOS CINCO (NEGATIVO) E MAIS CINCO (POSITIVO). O ARQUIVO FOI ADAPTADO PARA O PORTUGUÊS PARA REALIZAÇÃO DESSE EXPERIMENTO
  • CANDIDATE MAPPING.TXT
LINK PARA DOWNLOAD DOS ARQUIVOS:

Arquivos_extras

PARA SIMPLIFICAR COMO DETERMINAMOS SE UM TWEET DEVE SER ATRIBUÍDO A UM CANDIDATO / ASSUNTO É FAZENDO REFERÊNCIA AO MANIPULADOR CANDIDATO / ASSUNTO. POR EXEMPLO: Tweet #1 @CiroGomes concedeu a uma entrevista... Tweet #2 @CiroGomes trava grande luta.... Tweet #3 @JoãoDoria diz que São Paulo é... NO EXEMPLO ACIMA, O SENTIMENTO PELOS TWEETS #1 E #2 SERÁ ATRIBUÍDO A CIRO GOMES, ENQUANTO O TWEET #3 SERÁ ATRIBUÍDO A JOÃO DORIA.

PASSOS DA ANÁLISE

ETAPA 1: CRIA UM MAPEAMENTO SIMPLES PARA ROTULAR O NOME DO TWEET. COMO CANDIDATOS DIFERENTES SERÃO REFERENCIADOS NO TWEET DE MANEIRA DIFERENTE, É PRECISO MAPEAR CADA NOME DE CANDIDATO PARA OS DIFERENTES NOMES PELOS QUAIS ELES SÃO REFERIDOS. ETAPA 2: CRIA UM DICIONÁRIO DE PALAVRAS DE SENTIMENTO E SUAS PONTUAÇÕES ASSOCIADAS. ISSO SERÁ USADO PARA CALCULAR A PONTUAÇÃO GERAL DO SENTIMENTO DO TWEET. PASSO 3: PARA CADA TWEET, CALCULA A PONTUAÇÃO DO SENTIMENTO E SOMA A PONTUAÇÃO DE CADA CANDIDATO. A COMPUTAÇÃO PRINCIPAL OCORRE NOS TRECHOS DE CÓDIGO MOSTRADOS A SEGUIR: sentimentTuple = tweets.rdd.map(lambda r: [r.id, r.text, r.name]) \                .map(lambda r: [sentiment(r[1]),r[2]]) \                .flatMapValues(lambda x: x) \                .map(lambda y: (y[1],y[0])) \                .reduceByKey(lambda x, y: x+y) \                .sortByKey(ascending=True) scoreDF = sentimentTuple.join(candidates) \             .map(lambda (x, y): (y[1],y[0])) \             .reduceByKey(lambda a, b: a + b) \             .toDF()   DESTRINCHANDO sentimentTuple = tweets.rdd.map(lambda r: [r.id, r.text, r.name]) O CONJUNTO DE RESULTADOS DA CONSULTA DE TWEETS É REFERENCIADO COMO UM CONJUNTO DE DADOS RESILIENTE (.RDD) E, EM SEGUIDA, A FUNÇÃO LAMBDA É APLICADA A TODAS AS LINHAS NO RDD USANDO O MÉTODO MAP. COM A LISTA DE 3-TUPLAS, NOVAMENTE APLICAMOS A FUNÇÃO LAMBDA EM CADA LINHA (AGORA UMA 3-TUPLA) QUE CHAMA A FUNÇÃO SENTIMENT ANTERIORMENTE DEFINIDA E RETORNA UM 2-TUPLE  COM O SENTIMENT SCORE E R.TEXT (R [2]) O RESULTADO DE: .map(lambda r: [sentiment(r[1]),r[2]]) \ [1.0012610959381487, [u'Jaime Soares']], [-13.599376521158035], [u'Jair Bolsonaro']], [-0.47868277536822768], [u'Jairo Jorge', u'Janaina Paschoal']] ... COM O CONJUNTO DE DADOS DE 2-TUPLAS, APLICAMOS UMA FUNÇÃO FlatMapValues() PARA NIVELAR A ESTRUTURA DENTRO DE R [2]. ISSO FACILITARÁ O PROCESSAMENTO NAS ETAPAS SUBSEQUENTES ENTÃO O RESULTADO DE .flatMapValues(lambda x: x) \ É: (1.0012610959381487, u'Jaime Soares') (-13.599376521158035, u'Jair Bolsonaro') (-0.47868277536822768, u'Jairo Jorge') (-0.47868277536822768, u'Janaina Paschoal') ... ESTA É UMA ETAPA SIMPLES PARA TROCAR OS CAMPOS PARA QUE A PRIMEIRA COLUNA SEJA O NOME E A SEGUNDA SEJA A PONTUAÇÃO DE SENTIMENTO ENTÃO O RESULTADO DE .map(lambda y: (y[1],y[0])) \ É: (u'Jaime Soares', 1.0012610959381487) (u'Jair Bolsonaro', -13.599376521158035) (u'Jairo Jorge', -0.47868277536822768) (u'Janaina Paschoal', -0.47868277536822768) ... O reduceByKey() É UMA FUNÇÃO ONDE OS VALORES DAS 2-TUPLAS SÃO SOMADOS. POR PADRÃO, A PRIMEIRA COLUNA NO CONJUNTO DE DADOS SERÁ A CHAVE,  PORTANTO, ESSA INSTRUÇÃO ADICIONARÁ TODOS OS Y [0] COM O MESMO VALOR DE CHAVE EM Y [1]. O RESULTADO É A SOMA DE CADA NOME ENCONTRADO EM TODO O CONJUNTO DE TWEETS, COMO MOSTRADO ABAIXO. O reduceByKey()  RESULTA EM: (u'#1deAbril #DiaDoLula', -0.10222859593214292) (u'#BolsonaroPresidente\U0001f1e7\U0001f1f7', -0.71155785495028201) (u'#Givanildo \U0001f1e7\U0001f1f7', -1.0878299881551272) (u'#LulaliderdoPT', -0.42560277789377526) (u'#SomostodosMoro', 0.26211121699831136) (u'#VotoImpresso #Direita #Bolsonaro', 0.43759497449368367) ... FINALMENTE, O MÉTODO sortByKey() CLASSIFICARÁ O RDD DE 2-TUPLAS EM ORDEM CRESCENTE POR NOME. ÚLTIMO PASSO, FAZ UM LEFT JOIN COM O DATAFRAME DO CANDIDATO Row(_1=u’CiroGomes’,_2=1.3068750447223945) Row(_1=u’Álvaro Dias’, _2=0.20299071319474044) Row(_1=u’ JairBolsonaro’, _2=-13.599376521158035) PARA QUE O SPARK ENXERGUE AS TABELAS HIVE, DIGITE O COMANDO: rm -r /etc/spark/conf/hive.xml PODE SER QUE NÃO ENCONTRE, NÃO TEM PROBLEMA. AGORA RODE O COMANDO: sudo ln -s /etc/hive/conf/hive-site.xml /etc/spark/conf/hive-site.xml BAIXE O SCRIPT PYSPARK EM:

Link para download do script SentimentAnalysis.py

AGORA ENTRE NA PASTA ONDE O ARQUIVO SE ENCONTRA E DIGITE: spark-submit SentimentAnalysis.py O SCRIPT PYSPARK SENTIMENTANALYSIS.PYPREENCHE A TABELA CANDIDATE_SCORE. ENTRE NO HIVE E FAÇA UMA CONSULTA A TABELA E VEJA O RESULTADO: select * from candidate_score; LEMBRE QUE QUANTO MAIS ARQUIVOS VOCÊ DEIXAR O FLUME COLETAR, MELHOR PARA O RESULTADO.

Obrigado

Até a próxima