2018年6月26日火曜日

janomeの形態素情報を保存する。(python、自然言語処理、形態素解析、pandas)

前回エネルギー基本計画案から名詞(代名詞、非自立名詞)だけを取り出してwordcloudを作ってみましたが、同じ文章を分析するのに、何度もjanomeで形態素解析を繰り返すのが無駄な気がしてきました。

このため、今回はjanomeで解析した形態素情報を丸ごと取り出し、pandasデータフレームとして保存したいと思います。これだと一度、形態素解析をかけると後で再利用が楽になるはずです。

janomeでの形態素解析、形態素情報については下記記事をご参照ください。

Janomeで形態素解析をやってみる。(python,自然言語処理,分かち書き

・インポート
from janome.tokenizer import Tokenizer
from wordcloud import WordCloud
import matplotlib.pyplot as plt

import pandas as pd

・形態素情報を取り出す
t = Tokenizer()
text="エネルギー"

tokens = t.tokenize(text)
for token in tokens:
    print(token)

print(type(token))
str(token)
エネルギー	名詞,一般,*,*,*,*,エネルギー,エネルギー,エネルギー
<class janome.tokenizer.token="">
'エネルギー\t名詞,一般,*,*,*,*,エネルギー,エネルギー,エネルギー'

janomeの形態素解析で出力される形態素情報の形式をみてみます。

janome.tokenizer.Tokenというタイプで、「表層形(タブ区切り),品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用型,活用形,原形,読み,発音」という並びになっています。strで文字列にすることで丸ごと保存できそうです。

・形態素情報をpandasデータフレームに保存
t = Tokenizer()

text="はじめに\n\n2011年3月の東日本大震災及び東京電力福島第一原子力発電所事故を受けて、政府は、2014年4月、2030年を念頭に、第4次エネルギー基本計画を策定し、原発依存度の低減、化石資源依存度の低減、再生可能エネルギーの拡大を打ち出した。"

tokens = t.tokenize(text)

partofspeech_pd=pd.DataFrame()
for token in tokens:
    str_token=str(token).replace("\t",",")
    token_list=str_token.split(",")
    partofspeech_pd= partofspeech_pd.append(pd.Series(token_list),ignore_index=True)

partofspeech_pd.columns = ["単語","品詞","品詞細分類1","品詞細分類2","品詞細分類3","活用型","活用形","原形","読み","発音"]
partofspeech_pd[:20]
単語品詞品詞細分類1品詞細分類2品詞細分類3活用型活用形原形読み発音
0はじめ名詞副詞可能****はじめハジメハジメ
1助詞格助詞一般***
2\n\n記号空白****\n\n**
3名詞****
4名詞****ゼロゼロ
5名詞****イチイチ
6名詞****イチイチ
7名詞接尾助数詞***ネンネン
83月名詞副詞可能****3月サンガツサンガツ
9助詞連体化****
10東日本名詞固有名詞地域一般**東日本ヒガシニッポンヒガシニッポン
11大震災名詞一般****大震災ダイシンサイダイシンサイ
12及び接続詞*****及びオヨビオヨビ
13東京電力名詞固有名詞組織***東京電力トウキョウデンリョクトーキョーデンリョク
14福島名詞固有名詞地域一般**福島フクシマフクシマ
15接頭詞数接続****ダイダイ
16名詞****イチイチ
17原子力名詞一般****原子力ゲンシリョクゲンシリョク
18発電名詞サ変接続****発電ハツデンハツデン
19名詞接尾一般***ショショ

表層形と品詞などの形態素情報を区切っているタブをコンマに置換後、コンマを区切り文字にして分割しリストに保管。リストをpandasのseriesにしてデータフレームに行追加しています。最後に列名をつけて完成です。

これで形態素情報を全て保存したデータフレームができました。

が、エネルギー基本計画(案)全てを変換するのに約1時間かかり、できたCSVは約2.7MBあります(もとのtxtは330KB)。さらに時間短縮、データ要量削減の工夫が必要なようです。

さて、このデータフレームをどう使うのか。前回の名詞(代名詞、非自立名詞をのぞく)でwordcludを作る例をやってみます。dfにエネルギー基本計画(案)全ての形態素情報が入っています。

・名詞(代名詞、非自立名詞をのぞく)を抽出
noun = df[df["品詞"]=="名詞"]
noun2=noun[(noun["品詞細分類1"] != "代名詞") & (noun["品詞細分類1"] != "非自立")]
noun2
単語品詞品詞細分類1品詞細分類2品詞細分類3活用型活用形原形読み発音
0はじめ名詞副詞可能****はじめハジメハジメ
3名詞****
4名詞****ゼロゼロ
5名詞****イチイチ
6名詞****イチイチ
7名詞接尾助数詞***ネンネン
83月名詞副詞可能****3月サンガツサンガツ
10東日本名詞固有名詞地域一般**東日本ヒガシニッポンヒガシニッポン
11大震災名詞一般****大震災ダイシンサイダイシンサイ
13東京電力名詞固有名詞組織***東京電力トウキョウデンリョクトーキョーデンリョク
14福島名詞固有名詞地域一般**福島フクシマフクシマ
16名詞****イチイチ
17原子力名詞一般****原子力ゲンシリョクゲンシリョク
18発電名詞サ変接続****発電ハツデンハツデン
19名詞接尾一般***ショショ
20事故名詞一般****事故ジコジコ
25政府名詞一般****政府セイフセイフ
28名詞****
29名詞****ゼロゼロ
30名詞****イチイチ

"品詞"列から値が"名詞"の行を抽出した後、"品詞細分類1"列が"代名詞"、"非自立"の行を除きました。pandasの複数条件抽出では、"and"の代わりに"&"を使うことに注意(and、orを使うとエラーになる)。
・半角スペースで文字列連結
noun_df=" ".join(list(noun2["単語"])) 

条件に適した行を取り出した後、"単語"列を抽出し、リストに変換してjoinで半角スペース区切りの文字列を作ります。これで前回と同様にwordcloudが作れます。

1回ずつ形態素解析をする必要がなくなり、品詞ごとなどの抽出や集計など試行錯誤がやりやすくなりました。

↓こちらはエネルギー基本計画(案)から動詞の原形で作ったwordclud


「する」「進める」が大きく表示され、計画への意欲(?)が現れているようです。

参考:
wordcloudライブラリ
https://amueller.github.io/word_cloud/index.html

資源エネルギー庁:エネルギー基本計画(案)
http://www.enecho.meti.go.jp/committee/council/basic_policy_subcommittee/pdf/basic_policy_subcommittee_002.pdf

修正:PDFMinerでpdfからtxtを抽出する。
http://eneprog.blogspot.com/2018/05/pdfminerpdftxtpythonpdfminersix.html
正規表現を使って、エネルギー基本計画のテキストを整形する。
http://eneprog.blogspot.com/2018/06/pythonresplit.html
Janomeで形態素解析をやってみる。
http://eneprog.blogspot.com/2018/06/janomepython.html
エネルギー基本計画(案)の特徴を見てみる。その1 wordcloud
https://eneprog.blogspot.com/2018/06/wordcloudpythonjanome.html
エネルギー基本計画(案)の特徴を見てみる。その2 名詞でwordcloud
https://eneprog.blogspot.com/2018/06/2-pythonjanomewordcloud.html

2018年6月22日金曜日

エネルギー基本計画(案)の特徴を見てみる。その2 名詞でwordcloud(python,janome,wordcloud,自然言語処理)

2018/9/5 更新。janomeの初期化を書き忘れていました。修正していますm(__)m
---
エネルギー基本計画(案)の特徴を見てみるの続きです。前回はエネルギー基本計画(案)のpdfから抽出したテキストを使って、janomeで形態素解析しwordcloudを作りました。


(collocations=True、連語を考慮した例)

出現頻度が多い「する」「なる」などの動詞、「について」「による」などの助詞が大きく表示されています。これらはエネルギー基本計画(案)の特徴とは言いがたいので、名詞だけを取り出してみます。

・形態素情報取り出し
from janome.tokenizer import Tokenizer

word='寄り添い'

t = Tokenizer()
tokens = t.tokenize(word)

for token in tokens:
    print("表層形:",token.surface,"\n"
          "品詞:",token.part_of_speech.split(',')[0],"\n"
          "品詞細分類1:",token.part_of_speech.split(',')[1],"\n"
          "品詞細分類2:",token.part_of_speech.split(',')[2],"\n"
          "品詞細分類3:",token.part_of_speech.split(',')[3],"\n"
          "活用型:",token.infl_type,"\n"
          "活用形:",token.infl_form,"\n"
          "原形:",token.base_form,"\n"
          "読み:",token.reading,"\n"
          "発音:",token.phonetic)
表層形: 寄り添い 
品詞: 動詞 
品詞細分類1: 自立 
品詞細分類2: * 
品詞細分類3: * 
活用型: 五段・ワ行促音便 
活用形: 連用形 
原形: 寄り添う 
読み: ヨリソイ 
発音: ヨリソイ

Janomeで形態素解析をやってみる。の記事でjanomeの使い方を書きましたが、janomeで形態素解析を行うと上の例のように形態素情報を返してくれます。名詞、動詞などの品詞は.part_of_speech.split(',')[0]で取り出せます。

・インポートとファイル読み込み
from janome.tokenizer import Tokenizer
from wordcloud import WordCloud
import matplotlib.pyplot as plt 

text_file = open("enegy_plan.txt")
full_text = text_file.read()

・名詞のみを取り出し
word_list=[]
tokens = t.tokenize(full_text) 

for token in tokens:
    word = token.surface
    partOfSpeech = token.part_of_speech.split(',')[0]
    if partOfSpeech == "名詞":
        word_list.append(word)

token.part_of_speech.split(',')[0]で品詞を取り出し、名詞のみをリストに保存しています。

・半角スペース区切りの分かち書きに
words_noun=" ".join(word_list)
words_noun
出力(一部)
はじめ 2 0 1 1 年 3月 東日本 大震災 東京電力 福島 一 原子力 発電 所 事故 政府 2 0 1 4 年 4月 2 0 3 0 年 念頭 4 次 エネルギー 基本 計画 策定 原発 依存 度 低減 化石 資源 依存 度 低減 再生 可能 エネルギー 拡大 4 次 エネルギー 基本 計画 策定 4 年 2 0 3 0 年 計画 見直し 2 0 5 0 年 パリ 協定 対応 長期 化石 資源 枯渇 長期 対応 変化 エネルギー 情勢 対応 今 一 度 我が国 エネルギー 選択 構想 時期 ため 今回 エネルギー 基本 計画 見直し 2 0 3 0 年 長期 エネルギー 需給 見通し 2 0 1 5 年 7月 経済 産業 省 決定 以下 エネルギー ミックス 実現 2 0 5 0 年 シナリオ 設計 構成

・wordcloudの設定・描画
stop_words = []
fpath = "C:\Windows\Fonts\msgothic.ttc"

wordcloud2 = WordCloud(
    font_path=fpath,
    width=900, height=500,
    background_color="white",
    stopwords=set(stop_words),
    max_words=500,
    max_font_size=150
    ).generate(words_noun)

#グラフ表示する処理
plt.figure(figsize=(15,12))
plt.imshow(wordcloud2)
plt.axis("off")
plt.show()


名詞だけにしてwordcloudを描いてみましたが、「こと」「ため」という言葉が大きく出ました。これほど大きくはないですが、「これ」「よう」というのも見えます。

元の文書をみてみると、「このようなこと」「実現するため」「これに加え」「このように」などとして多く使われているようです。

・例文を形態素解析
t = Tokenizer()
text="これに加え、このようなことを実現するため"
    
tokens = t.tokenize(text)
 
for token in tokens:
    print(token)
これ 名詞,代名詞,一般,*,*,*,これ,コレ,コレ
に 助詞,格助詞,一般,*,*,*,に,ニ,ニ
加え 動詞,自立,*,*,一段,連用形,加える,クワエ,クワエ
、 記号,読点,*,*,*,*,、,、,、
この 連体詞,*,*,*,*,*,この,コノ,コノ
よう 名詞,非自立,助動詞語幹,*,*,*,よう,ヨウ,ヨー
な 助動詞,*,*,*,特殊・ダ,体言接続,だ,ナ,ナ
こと 名詞,非自立,一般,*,*,*,こと,コト,コト
を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
実現 名詞,サ変接続,*,*,*,*,実現,ジツゲン,ジツゲン
する 動詞,自立,*,*,サ変・スル,基本形,する,スル,スル
ため 名詞,非自立,副詞可能,*,*,*,ため,タメ,タメ

「これに加え、このようなことを実現するため」という例文を作って、形態素解析してみました。「これ」は名詞-代名詞、「よう」「こと」「ため」は名詞-非自立になっています。これらを除外するため、品詞細分類1の「代名詞」「非自立」をのぞいた名詞を取り出してみます。

・名詞(代名詞、非自立名詞は除外)を取り出し
word_list2=[]
tokens = t.tokenize(full_text) 

for token in tokens:
    word = token.surface
    partOfSpeech = token.part_of_speech.split(',')[0]
    partOfSpeech2 = token.part_of_speech.split(',')[1]
    
    if partOfSpeech == "名詞":
        if (partOfSpeech2 != "非自立") and (partOfSpeech2 != "代名詞"):
            word_list2.append(word)

words_noun2=" ".join(word_list2)
words_noun2


token.part_of_speech.split(',')[1]で品詞細分類1を取り出し、"非自立"と"代名詞"は除外した上で名詞のみをリストに保存しています。

出力(一部)
はじめ 2 0 1 1 年 3月 東日本 大震災 東京電力 福島 一 原子力 発電 所 事故 政府 2 0 1 4 年 4月 2 0 3 0 年 念頭 4 次 エネルギー 基本 計画 策定 原発 依存 度 低減 化石 資源 依存 度 低減 再生 可能 エネルギー 拡大 4 次 エネルギー 基本 計画 策定 4 年 2 0 3 0 年 計画 見直し 2 0 5 0 年 パリ 協定 対応 長期 化石 資源 枯渇 長期 対応 変化 エネルギー 情勢 対応 今 一 度 我が国 エネルギー 選択 構想 時期 今回 エネルギー 基本 計画 見直し 2 0 3 0 年 長期 エネルギー 需給 見通し 2 0 1 5 年 7月 経済 産業 省 決定 エネルギー ミックス 実現 2 0 5 0 年 シナリオ 設計 構成

あまり変わっていませんが、「ため」という言葉がなくなっています。

・wordcloud設定・描画
stop_words = []
fpath = "C:\Windows\Fonts\msgothic.ttc"

wordcloud2 = WordCloud(
    font_path=fpath,
    width=900, height=500,
    background_color="white",
    stopwords=set(stop_words),
    max_words=500,
#    max_font_size=150
    ).generate(words_noun2)

#グラフ表示する処理
plt.figure(figsize=(15,12))
plt.imshow(wordcloud2)
plt.axis("off")
plt.show()


名詞(代名詞、非自立名詞を除く)のみ、連語を考慮(デフォルトでcollocation=True)でのwordcloudです。今回は最大フォントサイズの指定をしていません。

技術とエネルギーが2大単語となりました。「再生 可能」と「可能 エネルギー」も大きくありますが、wordcloudの連語考慮では2語のつながり(bigram)のみなので、再生可能エネルギーが「再生 可能」と「可能 エネルギー」に分かれてしまっているようです。「炭素」「地域」「水素」なども比較的大きく見えています。



こちらは連語を考慮せず、単語のみで作ったwordcloud。最大フォントは指定していません。「エネルギー」が中央に大きくありますが、あまりフォントの大きさが変わらず、混沌とした感じになりました。「必要」「利用」「活用」などの普通によく使われそうな言葉も見えます。

名詞のみにすることで前回よりは文章の特徴が見えてきましたが、一般的によく使われる語句の除外と3語以上の連語・複合語を考慮した方がよさそうです。

つづく

参考:
wordcloudライブラリ
https://amueller.github.io/word_cloud/index.html
先端技術研究所:AnacondaとWordCloudを用いたテキストマイニング
http://cadenza-lab.com/2018/02/04/textmining/
見習いデータサイエンティストの隠れ家:Pythonでトピックモデル Word Cloud と LDA
http://www.dskomei.com/entry/2018/04/11/001944
wordcloudのほかに、トピックモデルによる分類あり。

資源エネルギー庁:エネルギー基本計画(案)
http://www.enecho.meti.go.jp/committee/council/basic_policy_subcommittee/pdf/basic_policy_subcommittee_002.pdf

修正:PDFMinerでpdfからtxtを抽出する。
http://eneprog.blogspot.com/2018/05/pdfminerpdftxtpythonpdfminersix.html
正規表現を使って、エネルギー基本計画のテキストを整形する。
http://eneprog.blogspot.com/2018/06/pythonresplit.html
Janomeで形態素解析をやってみる。
http://eneprog.blogspot.com/2018/06/janomepython.html
エネルギー基本計画(案)の特徴を見てみる。その1 wordcloud
https://eneprog.blogspot.com/2018/06/wordcloudpythonjanome.html

2018年6月19日火曜日

プログラミング学習:edx UCバークレー データサイエンス基礎講座、第2弾受講中(python)

前に、プログラミング学習:edx UCバークレー データサイエンス基礎講座の紹介(python)という記事を書きました。このコースは引き続き学習を続けており、現在、第1弾を修了し、第2弾を受講しているところです。学習記録としてどんなことをやっているか書いておきます。

edx UC Berkeley Foundations of Data Science(UCバークレー データサイエンス基礎講座)
https://www.edx.org/professional-certificate/berkeleyx-foundations-of-data-science

前回も書きましたが、このコースは3段階に分かれていて、第1弾がComputational Thinking with Python(pythonによるプログラミング的思考)、第2弾がInferential Thinking by Resampling(リサンプリングによる推論的思考)です。

このコースではpythonを使って演習を行っていきますが、ここではpandasなどの一般的なものではなく「datascience」という独自モジュールを使います。

datascienceモジュール ドキュメント
http://data8.org/datascience/index.html
コースinfrastructure
http://data8.org/#infrastructure

datascienceモジュールはpandas、Matplotlib、Foliumを簡単に使えるようにしたものという感じで、pandasのスライスなど複雑な処理はできない代わりに、分かりやすく迷わず使えるようになっています。一般的なモジュールを使わないことには賛否両論ありそうですが、このコースはデータサイエンスの基礎を学ぶものであり、pythonなど特定の言語を学ぶものではないという方針のようです。

ただ、独自モジュールを使うことで、プログラミング方法による混乱や学習についていけなくなる可能性を減らすという効果がある反面、学習したことを応用するのは難しくなってしまいます。このため、私はpandasなどの一般的なモジュールを使って演習をやり直ししています。

各国の女性の平均就学期間をグラフ化する。(python,pandas)
http://eneprog.blogspot.com/2018/05/pythonpandas.html
サンフランシスコのレンタサイクルのデータを見てみる(基本統計量ヒストグラム)
http://eneprog.blogspot.com/2018/05/pythonpandas_17.html
サンフランシスコのレンタサイクルのデータを見てみる その2。よく使われているステーションを調べる
https://eneprog.blogspot.com/2018/05/pythonpandasgroupbypivottable.html
サンフランシスコのレンタサイクルのデータを見てみる その3。地図上に可視化
https://eneprog.blogspot.com/2018/05/pythonpandasgroupbypivottable.html

これらは全てコース演習ではdatascienceを使って解いたもの。datascienceを使うと簡単にできていたものがpandas等ではできなかったりと意外と苦労しました。datascienceモジュールはpipでインストールできますので、興味のある方は使ってみてください。

第1弾ではプログラミング的思考ということで、データ処理の方法や可視化などがありましたが、第2弾では標本、ランダム化、検定など統計の話が主になっています。データの見方や有効性の判断などの学習になっていて、プログラミング学習と思ってやると期待はずれになるかもしれません。プログラミング学習のコンテンツは多いですが、こういった統計などの講義は少なく、これから役に立つのではないかと思っています

講義では、上記の女性の就学期間、レンタサイクルのデータのほか、乳幼児死亡率の推移、死刑制度による重犯罪の抑止など社会科学的な題材を多く扱っています。実際のデータを見て動かしながら解説しており、興味深いです。

このコースの講義は英語で行われていて、第1弾ではそれほど難しい話もなく付いていけていたのですが、第2弾では統計用語などが多くなり、一度聞いただけでは理解できなくなってきました。分からない語があるたびに動画を止め、調べたりしているので時間がかかってしまっています。

また、このコースでは一つ一つの講義にdiscussionがあり活発に使われています。



ちょっと分からないなと思うところがあれば、ほとんどの場合discussionに質問や回答があり、助けられています。ティーチングアシスタントも時々回答に加わっていて、このような教え合いの場はオンライン学習にはとても有効だと感じています。

オンライン学習というのはなかなか続けるのは難しく、さらに英語というのはハードルが高いですが、何とかこのコースを続けていけているのは内容が面白いからというのが大きいように思います。カリキュラムや学習方法がよく練られている上に、動画講義自体も退屈ではなく、興味を持続させる工夫がされているようです。

まとまりのない記事になってしまいましたが、コースの内容と現状の記録です。7月10日からは第3弾 Prediction and Machine Learning(予測と機械学習)が始まります。最後までやり遂げられるようにがんばります。

参考:
edx
https://www.edx.org/
UCバークレー データサイエンス基礎講座
https://www.edx.org/professional-certificate/berkeleyx-foundations-of-data-science

プログラミング学習:edx UCバークレー データサイエンス基礎講座の紹介(python)
https://eneprog.blogspot.com/2018/04/edx-uc-python.html

各国の女性の平均就学期間をグラフ化する。(python,pandas)
http://eneprog.blogspot.com/2018/05/pythonpandas.html
サンフランシスコのレンタサイクルのデータを見てみる(基本統計量ヒストグラム)
http://eneprog.blogspot.com/2018/05/pythonpandas_17.html
サンフランシスコのレンタサイクルのデータを見てみる その2。よく使われているステーションを調べる
https://eneprog.blogspot.com/2018/05/pythonpandasgroupbypivottable.html
サンフランシスコのレンタサイクルのデータを見てみる その3。地図上に可視化
https://eneprog.blogspot.com/2018/05/pythonpandasgroupbypivottable.html

2018年6月15日金曜日

エネルギー基本計画(案)の特徴を見てみる。その1 wordcloud(python,janome,自然言語処理)

2018/9/5 更新。janomeの初期化を書き忘れていました。修正していますm(__)m
---
エネルギー基本計画(案)のpdfからテキストを抽出形態素解析janomeの使い方とやってきましたが、ここからが本題。エネルギー基本計画(案)の特徴を見てみたいと思います。

まずは、最近よく見られるwordcloudを作ってみます。
wordcloudとは、文章中で出現頻度が高い単語を複数選び出し、その頻度に応じた大きさで図示する手法。ウェブページやブログなどに頻出する単語を自動的に並べることなどを指す。文字の大きさだけでなく、色、字体、向きに変化をつけることで、文章の内容をひと目で印象づけることができる。デジタル大辞泉より
ということで、文章中に多く出てくる単語ほど大きく表示して、文章の内容を一目で分かるように可視化するという手法です。

wordcloudの作り方は下記ページを参考にしました。

github:amuller wordcloud
https://amueller.github.io/word_cloud/index.html
先端技術研究所:AnacondaとWordCloudを用いたテキストマイニング
http://cadenza-lab.com/2018/02/04/textmining/
見習いデータサイエンティストの隠れ家:Pythonでトピックモデル Word Cloud と LDA
http://www.dskomei.com/entry/2018/04/11/001944

さっそくやってみます。まずはライブラリをインストール。

・wordcloudインストール
!pip install wordcloud
error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": 

pip一発でインストールできるはずが、エラーが出ました。エラーログに出ている下記リンクからMicrosoft Visual C++ Build Toolsを先にインストールしました。(結構時間がかかります)

Microsoft Visual Studio のダウンロード
https://www.visualstudio.com/ja/downloads/

C++をインストールした後にpipで再度インストールすると正常に終了しました。

・インポート
from janome.tokenizer import Tokenizer
from wordcloud import WordCloud

import matplotlib.pyplot as plt

・テキストファイル読み込み
t = Tokenizer()
tokens = t.tokenize(text)

text_file = open("enegy_plan.txt")
full_text = text_file.read()
full_text= full_text.replace("\n","")

・分かち書き
wakati_list = t.tokenize(full_text, wakati=True)

tokenのオプションで"wakati=True"をつけ、テキストを表層形で分かち書きします。ここまでは前回やったところ。

・リストを結合
words_wakati=" ".join(wakati_list)
words_wakati
出力(一部)
はじめ に 2 0 1 1 年 3月 の 東日本 大震災 及び 東京電力 福島 第 一 原子力 発電 所 事故 を 受け て 、 政府 は 、 2 0 1 4 年 4月 、 2 0 3 0 年 を 念頭 に 、 第 4 次 エネルギー 基本 計画 を 策定 し 、 原発 依存 度 の 低減 、 化石 資源 依存 度 の 低減 、 再生 可能 エネルギー の 拡大 を 打ち出し た 。 第 4 次 エネルギー 基本 計画 の 策定 から 4 年 、 2 0 3 0 年 の 計画 の 見直し のみ なら ず 、 2 0 5 0 年 を 見据え た パリ 協定 へ の 対応 、 より 長期 に は 化石 資源 枯渇 に 備え た 超 長期 の 対応 、 変化 する エネルギー 情勢 へ の 対応 など 、 今 一 度 、 我が国 が その エネルギー 選択 を 構想 す べき 時期 に 来 て いる 。 この ため 、 今回 の エネルギー 基本 計画 の 見直し は 、 2 0 3 0 年 の 長期 エネルギー 需給 見通し ( 2 0 1 5 年 7月 経済 産業 省 決定 。 以下 「 エネルギー ミックス 」 と いう 。 ) の 実現 と 2 0 5 0 年 を 見据え た シナリオ の 設計 で 構成 する こと と し た 。

wakatiオプションの分かち書きは各単語がリストに格納されているので、wordcloudで読み込めるようにスペース区切りで結合します。

前回も書きましたが、「再生可能エネルギー」が「再生」「可能」「エネルギー」に、「経済産業省」が「経済」「産業」「省」などに分割されてしまっています。

・wordcloud設定・描画
stop_words = []
fpath = "C:\Windows\Fonts\msgothic.ttc"

wordcloud = WordCloud(
    font_path=fpath,
    width=900, height=500, #default width=400, height=200
    background_color="white", #default=”black”
    stopwords=set(stop_words),
    max_words=500, #default=200
    max_font_size=150, #default=None,height of the image
    min_font_size=4, #default=4
    collocations = True #default = True
).generate(words_wakati)

plt.figure(figsize=(15,12))
plt.imshow(wordcloud)
plt.axis("off")
plt.show()

wordcloudの設定をして、描画します。ストップワードはwordcloudに描画ない単語("です"、"ます"など普通の文章によく出てくる単語など)をリスト形式で指定します。今回はストップワードは指定していないので省略可。

font_pathは日本語フォントのパスを指定します。これは指定しないと日本語は文字化けしてしまいます。

max_wordsは描画させる単語の数(デフォルトは200)です。

max_font_size、min_font_sizeはフォントの最大サイズと最小サイズ。max_font_sizeはデフォルトでは出力画像の高さ(height)になるようです(実質どこまでも大きくなる)。極端に出現回数が多い単語があると、それに対応して文字サイズが大きくなってしまうので制限するのもいいかもしれません。

collocationsは連語を考慮するかどうか。デフォルトは"True"で、頻出する2つの単語の並び(bigram:バイグラム)が表示されます。

他のオプションはリファレンスをご参照ください。(デフォルトのままでよいオプションは省略可)

・出力


「する」「なる」などの一般的な言葉が最も大きくなってしまいました。そのほか、「エネルギー」「技術」などが大きく表示されています。よく見ると、「水素」「エネルギー 需給」「蓄電池」などの言葉も表示されています。

「再生可能エネルギー」が「再生 可能」と「可能 エネルギー」の両方で現れているのはwordcludでは2単語の連語(bigram)までしか考慮しないためですね。惜しいです。

↓こちらは collocation=False にし、連語を考慮しない(頻出単語のみ)にしたもの。



「こと」「する」「ある」などの単語が目立って、文章の特徴が見えにくくなってしまいました。次回以降、改善を図ります。

参考:
github:amuller wordcloud
https://amueller.github.io/word_cloud/index.html
先端技術研究所:AnacondaとWordCloudを用いたテキストマイニング
http://cadenza-lab.com/2018/02/04/textmining/
見習いデータサイエンティストの隠れ家:Pythonでトピックモデル Word Cloud と LDA
http://www.dskomei.com/entry/2018/04/11/001944
wordcloudのほかに、トピックモデルによる分類あり。

資源エネルギー庁:エネルギー基本計画(案)
http://www.enecho.meti.go.jp/committee/council/basic_policy_subcommittee/pdf/basic_policy_subcommittee_002.pdf

修正:PDFMinerでpdfからtxtを抽出する。(python、PDFMiner.six、エネルギー基本計画)
http://eneprog.blogspot.com/2018/05/pdfminerpdftxtpythonpdfminersix.html
正規表現を使って、エネルギー基本計画のテキストを整形する。(python、re、split)
http://eneprog.blogspot.com/2018/06/pythonresplit.html
Janomeで形態素解析をやってみる。(python,自然言語処理,分かち書き)
http://eneprog.blogspot.com/2018/06/janomepython.html

2018年6月11日月曜日

Janomeで形態素解析をやってみる。(python,自然言語処理,分かち書き)

前々回前回、でエネルギー基本計画(案)のpdfからテキストを抽出しましたが、これを分析しようとすると文章を単語に分解(形態素解析)する必要があります。
形態素解析とは、言語学においてある言葉が変化・活用しない部分を最小単位の「素」と捉え、その素ごとに言葉を分解してゆく手法のことである。言語学者のチョムスキーによって考案されたもので、かな漢字変換を初めとする自然言語処理機能などに応用されている。 weblio:IT用語辞典バイナリより

日本語の形態素解析ライブラリとしてはMecabが有名ですが、windowsでは環境構築が難しいようなのでJanomeを使ってみます。

Janome v0.3 documentation (ja)

Janomeのドキュメンテーション。(当然ながら)日本語で書かれており、とても分かりやすいです。

下記ページもとても参考になりました。

コード7区:python で形態素解析。Janome が簡単。pip 一発でインストール

・インストール
!pip install janome

janomeのインストールは、pipで一発でできます。辞書も同時に入ります。

from janome.tokenizer import Tokenizer

t = Tokenizer()
text='原発依存度については、省エネルギー・再生可能エネルギーの導入や火力発電所の効率化などにより、可能な限り低減させる。'

tokens = t.tokenize(text)
 
for token in tokens:
    print(token)

とりあえず使ってみます。janomeをインポート、Tokenizerオブジェクトを作って、形態素解析したい文章を渡します。戻り値は Tokenオブジェクトのリストで、各単語に品詞や読みなどの情報が含まれています。

出力
原発 名詞,一般,*,*,*,*,原発,ゲンパツ,ゲンパツ
依存 名詞,サ変接続,*,*,*,*,依存,イゾン,イゾン
度 名詞,接尾,一般,*,*,*,度,ド,ド
について 助詞,格助詞,連語,*,*,*,について,ニツイテ,ニツイテ
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
、 記号,読点,*,*,*,*,、,、,、
省エネルギー 名詞,一般,*,*,*,*,省エネルギー,ショウエネルギー,ショーエネルギー
・ 記号,一般,*,*,*,*,・,・,・
再生 名詞,サ変接続,*,*,*,*,再生,サイセイ,サイセイ
可能 名詞,形容動詞語幹,*,*,*,*,可能,カノウ,カノー
エネルギー 名詞,一般,*,*,*,*,エネルギー,エネルギー,エネルギー
の 助詞,連体化,*,*,*,*,の,ノ,ノ
導入 名詞,サ変接続,*,*,*,*,導入,ドウニュウ,ドーニュー
や 助詞,並立助詞,*,*,*,*,や,ヤ,ヤ
火力 名詞,一般,*,*,*,*,火力,カリョク,カリョク
発電 名詞,サ変接続,*,*,*,*,発電,ハツデン,ハツデン
所 名詞,接尾,一般,*,*,*,所,ショ,ショ
の 助詞,連体化,*,*,*,*,の,ノ,ノ
効率 名詞,一般,*,*,*,*,効率,コウリツ,コーリツ
化 名詞,接尾,サ変接続,*,*,*,化,カ,カ
など 助詞,副助詞,*,*,*,*,など,ナド,ナド
により 助詞,格助詞,連語,*,*,*,により,ニヨリ,ニヨリ
、 記号,読点,*,*,*,*,、,、,、
可能 名詞,形容動詞語幹,*,*,*,*,可能,カノウ,カノー
な 助動詞,*,*,*,特殊・ダ,体言接続,だ,ナ,ナ
限り 名詞,非自立,副詞可能,*,*,*,限り,カギリ,カギリ
低減 名詞,サ変接続,*,*,*,*,低減,テイゲン,テイゲン
さ 動詞,自立,*,*,サ変・スル,未然レル接続,する,サ,サ
せる 動詞,接尾,*,*,一段,基本形,せる,セル,セル
。 記号,句点,*,*,*,*,。,。,。

文章が単語に分解され、単語ごとに形態素情報付きで保存されています。形態素情報はコンマ区切りで、

 表層形,品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用型,活用形,原形,読み,発音 

の下記の順序になっています。

この文章例では、「省エネルギー」は1つの単語とみなされているのに対し、「再生可能エネルギー」は「再生」「可能」「エネルギー」と3つに分解されました。「効率化」も1単語にしたいところですが、「効率」「化」と2つの単語になっています。辞書によるのでしょうが、複合語には注意が必要なようです。

・情報取り出し
word='寄り添い'

tokens = t.tokenize(word)

for token in tokens:
    print("表層形:",token.surface,"\n"
          "品詞:",token.part_of_speech.split(',')[0],"\n"
          "品詞細分類1:",token.part_of_speech.split(',')[1],"\n"
          "品詞細分類2:",token.part_of_speech.split(',')[2],"\n"
          "品詞細分類3:",token.part_of_speech.split(',')[3],"\n"
          "活用型:",token.infl_type,"\n"
          "活用形:",token.infl_form,"\n"
          "原形:",token.base_form,"\n"
          "読み:",token.reading,"\n"
          "発音:",token.phonetic)
表層形: 寄り添い 
品詞: 動詞 
品詞細分類1: 自立 
品詞細分類2: * 
品詞細分類3: * 
活用型: 五段・ワ行促音便 
活用形: 連用形 
原形: 寄り添う 
読み: ヨリソイ 
発音: ヨリソイ

形態素情報を個別に取り出しました。品詞はtokenオブジェクトの戻り値からコンマ区切りで分割して取り出しです。詳細は下記リファレンス参照。

janome リファレンス :
class janome.tokenizer.Token(node, extra=None)[source]

これらの形態素情報を使って、名詞のみ、原型のみのなどの抽出ができます。(こちらはまた後日書く予定)

・分かち書き
t = Tokenizer()

text_file = open("enegy_plan.txt")
full_text = text_file.read()
full_text= full_text.replace("\n","")

wakati_list = t.tokenize(full_text, wakati=True)
wakati_list[:13]
['はじめ', 'に', '2', '0', '1', '1', '年', '3月', 'の', '東日本', '大震災', '及び', '東京電力']

品詞が必要なく単語に分解するだけなら、"wakati"オプションを付けることで簡単にできます。

ここでは、エネルギー基本計画(案)から抽出したテキストを読み込み、改行記号(\n)を削除した上で形態素解析を行っています。戻り値はリストで、各単語が表層形で格納されています。

この例では、「3月」はひとつの単語なのに、「2011年」は各数字と年に分けられています。「大震災」、「東京電力」は1単語ですね。この辺りも微妙な感じで調整が必要になりそうです。


参考:
Janome v0.3 documentation (ja)
http://mocobeta.github.io/janome/
janome リファレンス
class janome.tokenizer.Token(node, extra=None)[source]

コード7区
python で形態素解析。Janome が簡単。pip 一発でインストール

当ブログ内
修正:PDFMinerでpdfからtxtを抽出する。(python、PDFMiner.six、エネルギー基本計画)
正規表現を使って、エネルギー基本計画のテキストを整形する。(python、re、split)
//SyntaxHighlighter CDNより https://cdnjs.com/libraries/SyntaxHighlighter // 対応言語