前回のおさらい
前回の記事ではEDINET API でdocIDの取得とそれに紐づく有価証券報告書を取得することができました。2024年3月決算の有価証券報告書のデータを 2403有報.csv に書き出しました。最終目標は この経営方針の文書 の TF-IDF 値を求めてワードクラウドを作成することです。ワードクラウドのイメージはこんな感じ!
ヤエリさんの記事から画像を引用しました!
https://note.com/ikesala/n/n5cc7c30710a4
前回は2403有報.csv読み込みの所で終わりました。
import pandas as pd
df = pd.read_csv("/content/Result/2403有報.csv",index_col=0,encoding='utf-8')
df
TF-IDF値の計算手順
下の手順を踏んで進めていきます。
1.MeCab(形態素解析ツール)の導入と辞書(NEologd)の適用
2.ストップワードの除去
3.TF-IDF値の計算
1.対象文書の形態素解析
形態素解析ツールで名を馳せているMeCabを利用します。また、辞書として有名なNEologdを導入することで固有名詞の認識できるようになります。
!pip install mecab-python3
!apt install aptitude
!aptitude install mecab libmecab-dev mecab-ipadic-utf8 git make curl xz-utils file -y
!git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
!echo yes | mecab-ipadic-neologd/bin/install-mecab-ipadic-neologd -n
# シンボリックリンクによるエラー回避
!ln -s /etc/mecabrc /usr/local/etc/mecabrc
# 辞書が格納されているパスを確認
!echo `mecab-config --dicdir`"/mecab-ipadic-neologd"
具体例 『約束のネバーランド』
import MeCab
tagger = MeCab.Tagger('-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd')
result = tagger.parse('私が最近見た映画は、約束のネバーランドでした。')
print(result)
#結果
#私 が 最近 見 た 映画 は 、 約束のネバーランド でし た 。
NEologdの特徴である固有名詞『約束のネバーランド』を認識できていることがわかります。
一方、辞書を適用させない場合
import MeCab
tagger = MeCab.Tagger('')
result = tagger.parse('私が最近見た映画は、約束のネバーランドでした。')
print(result)
#結果
#私 が 最近 見 た 映画 は 、 約束 の ネバー ランド でし た 。
『約束』『の』『ネバー』『ランド』と一つの固有名詞として認識しないことがわかります。
2.ストップワードの除去
ストップワードというのは自然言語処理する際に一般的で役に立たない等の理由で処理対象外とする単語のことです。たとえば、助詞や助動詞などの機能語(「は」「の」「です」「ます」など)が挙げられます。これらの単語は出現頻度が高い割に役に立たず、計算量や性能に悪影響を及ぼすため除去されます。
!pip install ja_stopword_remover
2403有報.csvの経営方針文書にMeCabと辞書の適用、ストップワードの除去をします。まとめたのが下のコードです。
from ja_stopword_remover.remover import StopwordRemover
import MeCab
import re
import numpy as np
import pprint
from pandas.core.common import flatten
def mecab_tokenizer(text):
#print(text)
replaced_text = text.lower()
replaced_text = re.sub(r'[【】]', ' ', replaced_text) # 【】の除去
replaced_text = re.sub(r'[ ()()]', ' ', replaced_text) # ()の除去
replaced_text = re.sub(r'[ [] \[\]]', ' ', replaced_text) # []の除去
replaced_text = re.sub(r'[@@]\w+', '', replaced_text) # メンションの除去
replaced_text = re.sub(r'\d+\.*\d*', '', replaced_text) # 数字を0にする
#print(replaced_text)
path = "-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd"
mecab = MeCab.Tagger(path)
parsed_lines = mecab.parse(replaced_text).split("\n")[:-2]
#print(parsed_lines)
#原形を取得
token_list = [l.split("\t")[1].split(",")[6] for l in parsed_lines]
#品詞を取得
pos = [l.split('\t')[1].split(",")[0] for l in parsed_lines]
# 名詞,動詞,形容詞のみに絞り込み
target_pos = ["名詞","動詞","形容詞"]
token_list = [t for t, p in zip(token_list, pos) if p in target_pos]
#print(token_list)
#token_list = np.arange()
token_block = [token_list]
# stopwordsの除去 (2次元化して処理)
stopwordRemover = StopwordRemover()
token_list = stopwordRemover.remove(token_block)
pprint.pprint(token_list)
# 1次元に戻す
token_list = list(flatten(token_list))
# ひらがなのみの単語を除く
kana_re = re.compile("^[ぁ-ゖ]+$")
token_list = [t for t in token_list if not kana_re.match(t)]
return ' '.join(token_list)
#df全体に対してmecab_tokenizerを適用し、形態素解析を行なったリストを返す関数
def make_docs(df,column_number):
docs=[]
for i in range(len(df)):
text = df.iloc[i,column_number]
docs.append(mecab_tokenizer(text))
return docs
#dfの経営方針に対して関数を実行し、計算結果をdocs_keiei_2403のリストに格納する
docs_keiei_2403 = make_docs(df,6)
3.TF-IDF値の計算
scikit-learnでTF-IDFの計算をします。
from sklearn.feature_extraction.text import TfidfVectorizer
def tf_idf(docs):
vectorizer = TfidfVectorizer(smooth_idf=False)
X = vectorizer.fit_transform(docs)
values = X.toarray()
feature_names = vectorizer.get_feature_names_out()
tfidf_df = pd.DataFrame(values, columns = feature_names)
return values,feature_names,tfidf_df
# valuesはTF-IDF値、feature_namesは単語、tfidfはデータフレームになります。
values, feature_names, tfidf = tf_idf(docs_keiei_2403)
# feature_names を文字列に統一
feature_names = [str(word) for word in feature_names]
# values をfloat32に変換
values = np.array(values, dtype=np.float32)
values = np.nan_to_num(values, nan=0.0) # NaNなら0に
それぞれの会社の経営方針文書のTF-IDF値が計算できたので、例として「トヨタ自動車株式会社」、「ソニーグループ株式会社」、「株式会社三菱UFJフィナンシャル・グループ」のTF-IDF値を見ていきます。
トヨタ自動車のTF-IDF値
index = df.query('会社名=="トヨタ自動車株式会社"').index[0]
print(index)
dft = pd.DataFrame(tfidf.T[index].sort_values(ascending=False)[:25]).rename(columns={index:df.iloc[index,1]})
dft
このコードでは、上位25単語を表示しますが上10と下1つの単語で省略させていただきます。
トヨタ自動車株式会社 | |
---|---|
トヨタ | 0.400325 |
ダイハツ工業 | 0.308630 |
トヨタグループ | 0.245616 |
日野自動車 | 0.240046 |
モビリティ | 0.212146 |
豊田自動織機 | 0.171461 |
不正 | 0.148501 |
認証 | 0.140555 |
風土 | 0.128435 |
クルマ | 0.127627 |
・・・ | ・・・・・ |
考える | 0.075759 |
ソニーグループのTF-IDF値
index = df.query('会社名=="ソニーグループ株式会社"').index[0]
print(index)
dft = pd.DataFrame(tfidf.T[index].sort_values(ascending=False)[:25]).rename(columns={index:df.iloc[index,1]})
dft
ソニーグループ株式会社 | |
---|---|
ソニー | 0.495548 |
ip | 0.294228 |
制作 | 0.216081 |
エンタテインメント | 0.215087 |
リアルタイム | 0.184960 |
creation | 0.168438 |
creator | 0.167854 |
cmosイメージセンサー | 0.149063 |
games | 0.124219 |
entertainment | 0.117988 |
・・・ | ・・・・・ |
キャピタル | 0.072468 |
三菱UFJフィナンシャル・グループのTF-IDF値
index = df.query('会社名=="株式会社三菱UFJフィナンシャル・グループ"').index[0]
print(index)
dft = pd.DataFrame(tfidf.T[index].sort_values(ascending=False)[:25]).rename(columns={index:df.iloc[index,1]})
dft
株式会社三菱UFJフィナンシャル・グループ | |
---|---|
本部 | 0.312409 |
立国 | 0.149532 |
法人 | 0.142696 |
リテール顧客 | 0.126334 |
加速 | 0.124003 |
お客様 | 0.121096 |
日銀 | 0.118120 |
揺る | 0.115500 |
財政支援 | 0.115500 |
中期経営計画 | 0.114022 |
・・・ | ・・・・・ |
金融引き締め | 0.086182 |
それぞれの会社のTF-IDF値が求められました。どうでしょうか?会社のイメージに合った単語が出現していると思います!
次回はこれらのTF-IDF値を用いてワードクラウドを作成します!
次回の記事はこちら!
自然言語処理TF-IDFの応用Part4(ワードクラウドの作成)
参考資料
@osn_Lofiさんの資料がとても参考になりました。ありがとうございます!
【自然言語処理】【Python】TF-IDFを使って文書の特徴をつかもう
NEologdの有効性について
Windows環境でMeCabとNEologDを使用してPythonで形態素解析を行う方法(環境構築)