はじめに
機械学習超初心者が、自然言語処理に挑戦してみた。
動作環境
- Google Colaboratory
- Python 3.7.13
- MeCab - 0.996
- Pandas - 1.3.5
- NumPy - 1.21.6
!apt install aptitude
!aptitude install mecab libmecab-dev mecab-ipadic-utf8 git make curl xz-utils file -y
!pip install mecab-python3==0.7
import MeCab
import pandas as pd
import numpy as np
自然言語とは
「自然言語」とは、わたしたち人間が日常的に話したり書いたりしている「自然発生的に生まれた言語(自然な言語)」のこと。例として、日常会話に使われるような言葉が挙げられる。
「自然言語」に対して、「人工言語」が存在する。例として、「プログラミング言語」が挙げられる。
「プログラミング言語」には一切の曖昧性がなく、すべてのコンピュータが同じ解釈をすることができる。
自然言語処理とは
「自然言語処理」とは、「自然言語」を機械が処理し、その内容を抽出していく作業のこと。文章・言葉などのコミュニケーションで用いられる「話し言葉」や、論文に用いられるような「書き言葉」といった自然言語を対象に、言葉が持っている意味を解析する。
機械は「自然言語」をそのまま解析することはできないため、「自然言語」を数値化してから機械に渡す。単語の出現頻度や意味合いを数値の基準にしたする。
感情分析手法
- 文章を形態素解析する
- 極性辞書と比較し、単語を数値化する
- 文章の感情を判定する
1. 文章を形態素解析する
形態素解析とは
形態素解析とは、文章を形態素に分解し、その形態素に品詞などの情報を付与すること。
本記事では、形態素解析ツールとしてMeCabを用いる
使用するツイートは、アカウントのアーカイブのダウンロードを申請することで取得した。
ダウンロードファイルを解凍して、data\tweet.jsがツイートの一覧である。
データの前処理として、jsonファイルに記載されているツイート箇所を抜き出し、csvに変換している。
# tweetを読み込む
my_tweet_df = pd.read_csv(r"my_tweets.csv", header=0, index_col=0)
# Mecabで形態素解析する
mecab = MeCab.Tagger("-Ochasen")
word_list = []
for data in my_tweet_df['text']:
temp = []
if data is not np.nan:
for v in mecab.parse(data).splitlines():
if len(v.split()) >= 3:
if v.split()[3][:2] in ['名詞','形容詞','動詞','副詞']:
temp.append(v.split()[2])
word_list.append(temp)
word_stop_list = []
# 空の要素とストップワードを削除
stop_words = ['形態素解析に必要ない単語を記載する','例えばwとか']
for sentence in word_list:
if sentence != None:
temp = []
for word in sentence:
if word not in stop_words:
temp.append(word)
word_stop_list.append(temp)
2. 極性辞書と比較し、単語を数値化する
極性辞書とは
極性
ネガティブ、ポジティブのこと
極性辞書
単語ごとに極性を付けたもの
極性は数値や文字で表される
お借りした極性辞書
日本語評価極性辞書(名詞編)ver.1.0(2008年12月版)
pd.set_option('display.unicode.east_asian_width', True)
pn_dic_df = pd.read_table(r"極性辞書のパス",names=["基本形","感情"],header=None,usecols=[0,1])
3. 文章の感情を判定する
極性辞書の感情を単語に置換する
- p(ポジティブ) = 1
- n (ネガティブ) = -1
- e (ニュートラル) = 0
# 辞書をn, p, eの3種類に絞る
pn_dic_npe_df = pn_dic_df[(pn_dic_df['感情']=="p")|(pn_dic_df['感情']=="n")|(pn_dic_df['感情']=="e")]
# 感情を数値に変換する
pn_dic_npe_num_df = pn_dic_npe_df.copy()
pn_dic_npe_num_df.loc[:,"感情"] = pn_dic_npe_num_df.loc[:,"感情"].replace({"p":1, "e":0, "n":-1})
# dfをdictに変換する
keys = pn_dic_npe_num_df["基本形"].to_list()
values = pn_dic_npe_num_df["感情"].to_list()
pn_dic_npe_num_dic = dict(zip(keys, values))
# ツイートごとに、(単語,スコア)のリストを作る
result = []
for sentence in word_stop_list:
temp = []
for word in sentence:
word_score = []
score = pn_dic_npe_num_dic.get(word)
word_score = (word, score)
temp.append(word_score)
result.append(temp)
# 文単位の平均値を計算する
mean_list = []
for i, score in enumerate(result):
temp = []
for j in score:
if not j[1] == None:
temp.append(float(j[1]))
if temp:
mean = (sum(temp) / len(temp))
else:
mean = float(0.0)
mean_dic = [my_tweet_df.iloc[i,0],mean]
mean_list.append(mean_dic)
mean_listの中身を見ると、ツイートから算出したスコアが間違っている。
時間が取れた時に上記コードを見直す予定である。
結果
import seaborn
seaborn.displot(mean_list_df['score'],kde=False)
ツイートから算出したスコアが間違っているので、この結果も修正される予定である。
おわりに
初めてネガポジ分析をした。
やはり、ものができるのはとても嬉しいことである。
ある程度できるようになったら、モデルを作成しようと思っている。
お借りした素材