こんにちは。最近自然言語処理を勉強していますが、今回は、形態素解析を行って分割した各単語を原型に戻す方法について整理しておきたいと思います。どうやら形態素解析を行った後に、単語の種類数を減らすために単語を原型に変換するといった前処理をかけることもあるようです。
これによって動詞の種類数などはかなり減りそうですね。
早速試してみたいと思います。実は、単語の原型は、MeCabのParseToNode()メソッドが返す情報の中に含まれているため、これを取得するようにすれば良いです。
Contents
形態素解析+単語の原型を取得するコード
以下、実験です。
import MeCab
text = '新型コロナウイルス感染症の治療につながるか? 回復した患者の「血しょう」を用いた治験が、ついに始まった'
tagger = MeCab.Tagger('-Owakati -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd')
node = tagger.parseToNode(text)
while node:
print(node.surface+" : "+node.feature)
node = node.next
実行結果の一部を下に示します。ParseToNodeが返すNodeオブジェクトのfeatureプロパティの6番目の要素が原型を表しています。
## 名詞の場合
治療 : 名詞,サ変接続,*,*,*,*,治療,チリョウ,チリョー
## 動詞の場合
し : 動詞,自立,*,*,サ変・スル,連用形,する,シ,シ
ので、パース関数を標準形に変換しないバージョンの関数から、以下のように変更しておきます。
########################################
## 形態素解析を実行する関数(Before)
########################################
def textParser_class(text, category):
## 分かち書きのみ
tagger = MeCab.Tagger('-Owakati -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd')
## バージョン2:品詞毎に取得
word_count = 0
sentense = ""
node = tagger.parseToNode(text)
while node:
#指定した品詞(category)のみ原型で抽出
if node.feature.split(",")[0] == category:
sentense += " "+node.surface
else:pass
node = node.next
return sentense
########################################
## 形態素解析を実行する関数(After)
########################################
def textParser_class(text, category):
## 分かち書きのみ
tagger = MeCab.Tagger('-Owakati -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd')
## バージョン2:品詞毎に取得
word_count = 0
sentense = ""
node = tagger.parseToNode(text)
while node:
#指定した品詞(category)のみ原型で抽出
if node.feature.split(",")[0] == category:
sentense += " "+node.feature.split(",")[6] #★変更点
else:pass
node = node.next
return sentense
大きなデータで実験
ここで、前回の記事で利用していた”新型コロナ”を含む数千件のツイートデータを使って、上記の標準化を行った場合と行わなかった場合で頻出・重要語の抽出結果に変化が出るか試してみたいと思います。
標準化を行わない場合
%%time
## データの絞り込み(リツイートは除外)
df_tweet = df_tweet[df_tweet["retweeted_status"].isna()].reset_index(drop=True)
## テキスト前処理(正規化、数字・記号控除等)
df_tweet["text_前処理後"] = df_tweet["text"].apply(lambda x: preProcessor(x))
#textParser_class関数の中を、上記の通りそのまま/原形取得の2種類用意した。
df_tweet["text_形態素解析後_名詞"] = df_tweet["text_前処理後"].apply(lambda x: textParser_class(x,"名詞"))
df_tweet["text_形態素解析後_動詞"] = df_tweet["text_前処理後"].apply(lambda x: textParser_class(x,"動詞"))
df_tweet["text_形態素解析後_形容詞"] = df_tweet["text_前処理後"].apply(lambda x: textParser_class(x,"形容詞"))
## Bag-Of-Wordsで単語数のベクトル化・カウント
def Vectorization_BOW(df):
vectorizer = CountVectorizer(token_pattern=u'(?u)\\b\\w+\\b',max_features=100000,stop_words=stop_words)
vecs = vectorizer.fit_transform(df)
header = vectorizer.get_feature_names()
return vecs, header
vecs, header = Vectorization_BOW(df_tweet["text_形態素解析後_形容詞"])
df_result = pd.DataFrame(vecs.toarray(), columns=header)
df_summarized = df_result.fillna(0).sum(axis=0)
df_summarized = df_summarized.sort_values(ascending=False)
print(len(df_summarized.index.unique())
それぞれの品詞で得られたユニークな単語数を数えてみると以下の通りだった。
- 名詞:6451語
- 動詞:1246語
- 形容詞:211語
具体的な出現ひど上位15単語は以下の通りでした。
名詞
(割愛)
動詞
し 981
さ 345
する 297
いる 247
れ 237
い 215
せ 154
てる 110
なっ 106
受け 99
おり 98
いたし 95
なり 94
いただき 91
れる 87
形容詞
ない 70
いい 36
良い 21
多い 21
なく 18
早く 18
多 18
詳しく 14
無い 14
怖い 12
悪い 11
少ない 11
ほしい 11
新しい 11
高い 10
標準化を行った(原型に変換した)場合
コードの流れは上と同じ。結果は以下の通りであった。
- 名詞:6324語
- 動詞:806語
- 形容詞:129語
続いて、具体的な出現頻度上位15単語をみてみます。
名詞
(割愛)
動詞
する 1673
いる 466
れる 326
なる 304
てる 180
ある 179
せる 164
いただく 120
伴う 118
思う 109
受ける 103
おる 103
いたす 95
できる 84
くださる 77
形容詞
ない 97
多い 49
いい 36
良い 29
早い 28
少ない 21
詳しい 19
無い 19
怖い 16
新しい 16
高い 15
ほしい 14
遅い 12
悪い 12
大きい 12
名詞がほとんど減らないことは想定通り(むしろなぜ減った・・?笑)ですが、動詞や形容詞は、かなり単語の種類数が減らせました。頻出単語の上位もより分かりやすいものになりました。
これからの分析では、必要な場合はなるべくこの原型変換は前処理として実施しておこうと思いました!
以上、この記事では分かち書きした単語の原型変換の方法と、その効果を簡単に検証してみました。
最後までご覧いただきありがとうございました!この記事が少しでもお役に立ちましたら、下のいいねボタンをポチっていただけますと励みになります。
関連記事
Python×自然言語処理では、以下のような記事も書いていますので、ご興味あればご覧いただけると嬉しいです。
PythonとTwitter APIでデータ分析を行ってみた記事。
テキストデータに対して感情分析をしてみた記事。
以下は、そのAzure利用版。Azureを使うと、Azureで事前構築済の日本語の感情分析エンジンが使えてとても簡単で便利です!
(おまけ)自然言語処理をもっと学ぶなら・・・
Udemyを見てみると、自然言語処理系の講座も結構あるようだったので、もしもっと勉強されたい方がいれば、気になるものを受講してみてはいかがでしょうか。
Udemyは自分もよく使うのですが、世界中のその道のエキスパートの方が講師をされており、ボリュームの割に値段も安く、また万が一コンテンツが自分に合わなかった場合は30日の返金保証がある点が魅力で、お勧めです!
日本語コンテンツでは、以下がベストセラーになっていますので、ご興味ある方はぜひ!
自然言語処理とチャットボット: AIによる文章生成と会話エンジン開発
今からでも基礎から学べるPythonによる自然言語処理(NLP):現役データサイエンティストが教える「日本語」文書分類
BERTによる自然言語処理を学ぼう! -Attention、TransformerからBERTへとつながるNLP技術-
コメントを残す