--Introduction
Je suis accro à l'analyse émotionnelle des données textuelles avec le traitement du langage naturel. En faisant cela, j'ai trouvé difficile de gérer l'argot net. Cette fois, j'ai donc décidé de vérifier moi-même si le service d'analyse des émotions (ci-après dénommé API Natural Language) de l'API Google Cloud Natural Language prend en charge l'argot net. (Attention) Le simple fait de le vérifier vous-même ne détermine pas nécessairement si l'API Natural Language prend en charge l'argot net.
Selon la phrase, je pensais que «rire» pouvait être remplacé par «herbe», donc je vais l'utiliser pour l'évaluation. Par exemple, les déclarations suivantes ont la même signification.
・ 3rt4 aime rire en 3 minutes ・ 3rt4 en 3 minutes Comme l'herbe
Lorsque plusieurs phrases sont préparées et évaluées à l'aide de l'API Natural Language, il est testé s'il existe une différence dans le score moyen entre «rire» et «herbe».
La procédure est la suivante.
Puisqu'une application est requise pour utiliser l'API Twitter, j'ai postulé en regardant [1]. L'application est passée en un jour.
Maintenant que l'application est passée, nous obtenons les données textuelles. Il est basé sur le code dans [2]. Puisqu'il y a un prétraitement, j'ai essayé d'écrire les données texte acquises dans un fichier texte. Je recherche avec le mot-clé de recherche "rire".
import json
from requests_oauthlib import OAuth1Session
#Partie authentification OAuth
CK = ""
CS = ""
AT = ""
ATS = ""
twitter = OAuth1Session(CK, CS, AT, ATS)
url = 'https://api.twitter.com/1.1/search/tweets.json'
keyword = 'rire'
params ={
'count' : 100, #Nombre de tweets à obtenir
'q' : keyword, #Mot-clé de recherche
}
f = open('./data/1/backup1.txt','w')
req = twitter.get(url, params = params)
print(req.status_code)
if req.status_code == 200:
res = json.loads(req.text)
for line in res['statuses']:
print(line['text'])
f.write(line['text'] + '\n')
print('*******************************************')
else:
print("Failed: %d" % req.status_code)
Les résultats de la recherche sont les suivants.
・ Bien sûr, je sors, mais la lutte sumo rit ・ Parce que c'est un endroit pour rire! Lieu de rire! !! ・ Qu'est-ce que wwww en riant wwww
Organisez les données textuelles acquises. Il y a quatre tâches à accomplir ici.
1 et 2 sont mis en œuvre comme suit. J'ai supprimé 2 car il peut y avoir une pause dans le tweet et j'ai senti que c'était très difficile à faire 3.
import re
readF = open('./data/1/backup1.txt','r')
writeF = open('./data/1/preprocessing1.txt','w')
lines = readF.readlines()
for line in lines:
if 'rire' in line:
#Suppression de "RT"
line = re.sub('RT ', "", line)
#Suppression de "@XXXX" ou "@XXXX"
line = re.sub('(@\w*\W* )|(@\w*\W*)', "", line)
writeF.write(line)
readF.close()
writeF.close()
3 était le plus difficile. ・ «Rire» est à la fin de la phrase ・ Phrase après "rire" ・ "W" après "rire" Dans un tel cas, j'ai pensé qu'il pouvait être remplacé par «herbe» avec une probabilité élevée, mais j'ai pensé que les données seraient biaisées. En fin de compte, il a été jugé manuellement. Les données textuelles dont nous avons déterminé qu'elles ne pouvaient pas être remplacées ont été supprimées.
Le nombre d'échantillons est désormais de 200.
4 a été mis en œuvre comme suit.
import csv
import pandas as pd
count = 6
lines = []
for i in range(count):
print(i)
readF = open('./data/'+ str(i+1) + '/preprocessing' + str(i+1) + '.txt')
lines += readF.readlines()
df = pd.DataFrame([],columns=['warau', 'kusa'])
replaceLines = []
for line in lines:
replaceLines.append(line.replace('rire', 'herbe'))
df["warau"] = lines
df["kusa"] = replaceLines
df.to_csv("./data/preprocessing.csv",index=False)
Le résultat du traitement jusqu'à présent est comme indiqué dans l'image ci-dessous.
Google Cloud Natural Language API Le service d'analyse des émotions de l'API Google Cloud Natural Language renvoie le score d'émotion du texte. Plus le score d'émotion est proche de 1, plus il est positif, et plus il est proche de -1, plus il est négatif [3]. Outre les services d'analyse des émotions, l'API Google Cloud Natural Language inclut également la classification du contenu.
Le programme a été mis en œuvre sur la base de [4]. Transmettez les phrases «rire» et «herbe» à l'API Natural Language et enregistrez les résultats dans une liste. Puis ajoutez-le aux pandas avec "warauResult" et "kusaResult" comme noms de colonne. Enfin, sortez le fichier csv.
from google.cloud import language
from google.cloud.language import enums
from google.cloud.language import types
import os
import pandas as pd
credential_path = "/pass/xxx.json"
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = credential_path
client = language.LanguageServiceClient()
warauResultList = []
kusaResultList = []
df = pd.read_csv('./data/preprocessing.csv')
count = 9
for index,text in df.iterrows():
#\suppression de n
text["warau"] = text["warau"].replace('\n', '')
text["kusa"] = text["kusa"].replace('\n', '')
#analyse Warau
document = types.Document(
content=text["warau"],
type=enums.Document.Type.PLAIN_TEXT)
sentiment = client.analyze_sentiment(document=document).document_sentiment
warauResultList.append(sentiment.score)
#analyse de kusa
document = types.Document(
content=text["kusa"],
type=enums.Document.Type.PLAIN_TEXT)
sentiment = client.analyze_sentiment(document=document).document_sentiment
kusaResultList.append(sentiment.score)
df["warauResult"] = warauResultList
df["kusaResult"] = kusaResultList
df.to_csv("./data/result.csv",index=False)
Le résultat du traitement jusqu'à présent est comme indiqué dans l'image ci-dessous.
L'histogramme de warauResult est le suivant.
L'histogramme de kusaResult est le suivant.
Supposons que chacun suit une distribution normale.
Comparez la valeur stockée dans warauResult avec la valeur stockée dans kusaResult. Cette fois, nous allons tester la différence moyenne lorsqu'il y a correspondance entre les échantillons. J'ai fait référence à [5] et [6].
・ Hypothèse nulle ・ ・ ・ Le score n'a pas changé même si "rire" a été changé en "herbe". ・ Hypothèse d'opposition: le score a changé en changeant «rire» en «herbe»
Le programme ressemble à ceci:
from scipy import stats
import pandas as pd
#Test de différence moyenne lorsqu'il y a correspondance entre échantillons
df = pd.read_csv('./data/result.csv')
stats.ttest_rel(df["warauResult"], df["kusaResult"])
Les résultats sont les suivants. Ttest_relResult(statistic=3.0558408995373356, pvalue=0.0025520814940409413)
La référence pour stats.ttest_rel est [7].
Citation: "Si la valeur p est inférieure au seuil, par exemple 1%, 5% ou 10%, nous rejetons l'hypothèse nulle de moyennes égales."
En d'autres termes, cette fois, la pvalue est aussi petite qu'environ 2,5%, donc l'hypothèse nulle est rejetée. Par conséquent, le score a changé en changeant «rire» en «herbe». Le spécimen n'a que des phrases avec «rire» qui peuvent être remplacées par «herbe» (subjectif). Cependant, le changement de score conclut que l'API Natural Language n'est pas compatible avec l'argot net.
Estimez l'intervalle moyen pour chacun des warauResult et kusaResult. J'ai fait référence à [8].
\begin{aligned}
\bar{X}-z_{\frac{\alpha}{2}}\sqrt{\frac{s^2}{n}}
< \mu <
\bar{X}+z_{\frac{\alpha}{2}}\sqrt{\frac{s^2}{n}}
\end{aligned}
Le programme ressemble à ceci:
from scipy import stats
import math
print("exemple de moyenne de warauResult",df['warauResult'].mean())
print("Exemple de moyenne de kusaResult",df['kusaResult'].mean())
#.var()Trouve une dispersion non biaisée
print("Estimation de l'intervalle WarauResult",stats.norm.interval(alpha=0.95,
loc=df['warauResult'].mean(),
scale=math.sqrt(df['warauResult'].var() / len(df))))
print("Estimation d'intervalle de kusaResult",stats.norm.interval(alpha=0.95,
loc=df['kusaResult'].mean(),
scale=math.sqrt(df['kusaResult'].var() / len(df))))
Les résultats sont les suivants. Exemple de moyenne de warauResult 0.0014999993890523911 Moyenne de l'échantillon de kusaResult -0,061000001728534696 Estimation de l'intervalle WarauResult (-0,0630797610044764, 0,06607975978258118) Estimation de l'intervalle de kusaResult (-0.11646731178466276, -0.005532691672406637)
Plage d'erreur ・ WarauResult: environ ± 0,06458 ・ KusaResult: environ ± 0,05546
La plage des scores émotionnels renvoyés par l'API Natural Language va de 1 à -1. Je pensais que l'erreur ± 0,06 dans cette plage était petite.
En passant, vous pouvez obtenir le nombre d'échantillons requis en fonction de la plage d'erreur comme indiqué dans [9]. ・ À propos de warauResult ・ Coefficient de confiance 95% ・ Plage d'erreur ± 0,06458 À ce stade, le nombre d'échantillons est de 200.
import numpy as np
#Puisque nous ne connaissons pas l'écart type de la population, nous substituons la racine carrée de la variance sans biais.
rutoN = (1.96 * np.sqrt(df['warauResult'].var()))/ 0.06458
N = rutoN * rutoN
print(N)
Les résultats sont les suivants. 200.0058661538003
・ Ce n'est pas objectif car il est jugé par une personne si c'est «rire» qui peut être remplacé par «herbe». → Évaluer avec plusieurs personnes
・ La méthode actuelle de collecte de données ne peut pas collecter un grand nombre d'échantillons. → Si vous avez besoin d'un grand nombre d'échantillons, trouvez un motif et envisagez l'automatisation
・ Comment déterminer la plage d'erreur → Je veux une raison pour quelle devrait être la plage d'erreur
J'aimerais également participer au calendrier de l'Avent l'année prochaine.
[1]https://qiita.com/kngsym2018/items/2524d21455aac111cdee [2]https://qiita.com/tomozo6/items/d7fac0f942f3c4c66daf [3]https://cloud.google.com/natural-language/docs/basics#interpreting_sentiment_analysis_values [4]https://cloud.google.com/natural-language/docs/quickstart-client-libraries#client-libraries-install-python [5]https://bellcurve.jp/statistics/course/9453.html [6]https://ohke.hateblo.jp/entry/2018/05/19/230000 [7]https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.stats.ttest_rel.html [8]https://ohke.hateblo.jp/entry/2018/05/12/230000 [9]https://toukeigaku-jouhou.info/2018/01/23/how-to-calculate-samplesize/
Recommended Posts