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)

2018年6月5日火曜日

正規表現を使って、エネルギー基本計画のテキストを整形する。(python、re、split)

前回、エネルギー基本計画(案)のPDFからテキストを抽出しました。

修正:PDFMinerでpdfからtxtを抽出する。(python、PDFMiner.six、エネルギー基本計画)


今回はこのテキストデータを整形します。

元データ
エネルギー基本計画(案)平成30年5月16日
http://www.enecho.meti.go.jp/committee/council/basic_policy_subcommittee/pdf/basic_policy_subcommittee_002.pdf

抽出したテキスト(一部)
はじめに 2011年3月の東日本大震災及び東京電力福島第一原子力発電所事故を受けて、政府は、2014年4月、2030年を念頭に、第4次エネルギー基本計画を策定し、原発依存度の低減、化石資源依存度の低減、再生可能エネルギーの拡大を打ち出した。 第4次エネルギー基本計画の策定から4年、2030年の計画の見直しのみならず、2050年を見据えたパリ協定への対応、より長期には化石資源枯渇に備えた超長期の対応、変化するエネルギー情勢への対応など、今一度、我が国がそのエネルギー選択を構想すべき時期に来ている。このため、今回のエネルギー基本計画の見直しは、2030年の長期エネルギー需給見通し(2015年7月経済産業省決定。以下「エネルギーミックス」という。)の実現と2050年を見据えたシナリオの設計で構成することとした。 エネルギー選択を構想するに際して、常に踏まえるべき点がある。 第一に、東京電力福島第一原子力発電所事故の経験、反省と教訓を肝に銘じて取り組むことが原点であるという姿勢は一貫して変わらない。 東京電力福島第一原子力発電所事故で被災された方々の心の痛みにしっかりと向き合い、寄り添い、福島の復興・再生を全力で成し遂げる。政府及び原子力事業者は、いわゆる「安全神話」に陥り、十分な過酷事故への対応ができず、このような悲惨な事態を防ぐことができなかったことへの深い反省を一時たりとも放念してはならない。発生から約7年が経過する現在も約2.4万人の人々が避難指示の対象となっている。原子力損害賠償、除染・中間貯蔵施設事業、廃炉・汚染水対策や風評被害対策などへの対応を進めていくことが必要である。また、使用済燃料問題、最終処分問題など、原子力発電に関わる課題は山積している。これらの課題を解決していくためには、事業者任せにするのではなく、国が前面に立って果たすべき役割を果たし、国内外の叡智を結集して廃炉・汚染水問題を始めとする原子力発電の諸課題の解決に向けて、予防的かつ重層的な取組を実施しなければならない。 東京電力福島第一原子力発電所事故を経験した我が国としては、2030年のエネルギーミックスの実現、2050年のエネルギー選択に際して、原子力については安全を最優先し、再生可能エネルギーの拡大を図る中で、可能な限り原発依存度を低減する。 第二に、戦後一貫したエネルギー選択の思想はエネルギーの自立である。膨大なエネルギーコストを抑制し、エネルギーの海外依存構造を変えるというエネルギー自立路線は不変の要請である。今回のエネルギー選択には、これにパリ協定\x0c 3 発効に見られる脱炭素化への世界的なモメンタムが重なる。 こうした課題への取組は、いつの日か化石資源が枯渇した後にどのようにエネルギーを確保していくかという問いへの答えにつながっていく。
抽出したテキストでは、改行がスペースになっていたり、ページ番号が入っていたりします(最後から2番目の文章、「パリ協定」と「発行」の間に"\x0c 3 "という形でページ番号が入っています)

これを、正規表現(re)を使って整えていきます。正規表現については、下記のページが参考になりました。

忘れっぽい人のための正規表現チートシート
超絶簡単 Pythonでの正規表現


まずは正規表現モジュール、reをインポートします。データは、前回pdfから抽出したテキスト(str)を使います。

import re

str
出力(一部)
'        エネルギー基本計画(案)                平成30年5月16日        \x0c 1  目次  はじめに・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・2  第1章 構造的課題と情勢変化、政策の時間軸 第1節 我が国が抱える構造的課題・・・・・・・・・・・・・・・・・・・・・・・・・・4 1.資源の海外依存による脆弱性 2.中長期的な需要構造の変化(人口減少等) 3.資源価格の不安定化(新興国の需要拡大等) 4.世界の温室効果ガス排出量の増大 第2節 エネルギーをめぐる情勢変化・・・・・・・・・・・・・・・・・・・・・・・・・7 1.脱炭素化に向けた技術間競争の始まり 2.技術の変化が増幅する地政学的リスク 3.国家間・企業間の競争の本格化 第3節 2030年エネルギーミックスの実現と2050年シナリオとの関係・・・・・・10 

str2=re.split("\x0c 2\s+",str) 
str2=str2[1]

表紙と目次は必要ないので、2ページ目までを削除します。"\x0c 2"がページ番号なので、re.splitでこの記号で文字列を分割します。

\sはスペース、改行などの空白文字です。ページ番号記号の後ろに空白文字が1個以上含まれているという指定になります。分割された文字列はリストに格納されていて、始めの部分(表紙と目次)が[0]、残りが[1]に入っているので、[1]のみを取り出しました。

str3=re.sub(r"\x0c(\s\d+|\d+)\s+","",str2)
str3

ページ番号の記号を消します。re.subで正規表現での置換です。\dは数字、|はor(または)です。

"\x0c"のページ番号記号の後に、空白文字または空白文字+数字、その後に空白文字が続いた場合は、""で置換する(削除)という意味になります。

str4=re.split("\x0c",str3) 
str4=str4[0]

文章の最後に委員名簿とこれまでの経緯が入っていますが、これも必要ないので削除します。本文の最後になぜかページ番号記号だけが残っていたので、これを目印に分割し、最初の部分だけを取り出しました。

str5=re.sub("\s","\n",str4)
str6=re.sub(r"([a-zA-Z])\n",r"\1 ",str5)
print(str6)

半角スペースが改行を表しているようなので、空白文字を改行に変換します。\nが改行です。ただし、数箇所にある英文(Energy Securityなど)の間のスペースも改行に変換されてしまうので、2行目でこれを戻しています。

[a-zA-Z]でアルファベット(大文字、小文字を含む)です。()で囲むことでグループ化され、\1、\2などとして後で参照できます。この場合は置換後の文字列として"\1 "で元の文字+スペースに設定しています。

str7=re.sub(r"([①-⑳])\n",r"\1",str6)
str8=re.sub(".\n",".",str7)
print(str8)

同様に、丸囲み数字や、項目文字(1.など)の後にスペースが入っており、改行に変換されたものがあったので、こちらも改行を削除して戻します。

f = open('enegy_plan.txt','w')
f.write(str8)

f.close()

最後にテキストファイルとして保存して終了です。ページ番号は削除され、改行もほぼ復元できたようです。思ったよりも手間がかかりました。

テキストファイル(一部)
はじめに

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

エネルギー選択を構想するに際して、常に踏まえるべき点がある。

第一に、東京電力福島第一原子力発電所事故の経験、反省と教訓を肝に銘じて取り組むことが原点であるという姿勢は一貫して変わらない。
東京電力福島第一原子力発電所事故で被災された方々の心の痛みにしっかりと向き合い、寄り添い、福島の復興・再生を全力で成し遂げる。政府及び原子力事業者は、いわゆる「安全神話」に陥り、十分な過酷事故への対応ができず、このような悲惨な事態を防ぐことができなかったことへの深い反省を一時たりとも放念してはならない。発生から約7年が経過する現在も約2.4万人の人々が避難指示の対象となっている。原子力損害賠償、除染・中間貯蔵施設事業、廃炉・汚染水対策や風評被害対策などへの対応を進めていくことが必要である。また、使用済燃料問題、最終処分問題など、原子力発電に関わる課題は山積している。これらの課題を解決していくためには、事業者任せにするのではなく、国が前面に立って果たすべき役割を果たし、国内外の叡智を結集して廃炉・汚染水問題を始めとする原子力発電の諸課題の解決に向けて、予防的かつ重層的な取組を実施しなければならない。
東京電力福島第一原子力発電所事故を経験した我が国としては、2030年のエネルギーミックスの実現、2050年のエネルギー選択に際して、原子力については安全を最優先し、再生可能エネルギーの拡大を図る中で、可能な限り原発依存度を低減する。

第二に、戦後一貫したエネルギー選択の思想はエネルギーの自立である。膨大なエネルギーコストを抑制し、エネルギーの海外依存構造を変えるというエネルギー自立路線は不変の要請である。今回のエネルギー選択には、これにパリ協定発効に見られる脱炭素化への世界的なモメンタムが重なる。


参考:
資源エネルギー庁:エネルギー基本計画について
http://www.enecho.meti.go.jp/category/others/basic_plan/

忘れっぽい人のための正規表現チートシート
https://qiita.com/tossh/items/635aea9a529b9deb3038
超絶簡単 Pythonでの正規表現
http://yut.hatenablog.com/entry/20110204/1296750892

github:pdfminer/pdfminer.six
https://github.com/pdfminer/pdfminer.six
PDFMiner HP

修正:PDFMinerでpdfからtxtを抽出する。(python、PDFMiner.six、エネルギー基本計画) https://eneprog.blogspot.com/2018/05/pdfminerpdftxtpythonpdfminersix.html

2018年6月4日月曜日

修正:PDFMinerでpdfからtxtを抽出する。(python、PDFMiner.six、エネルギー基本計画)

2018年6月4日更新:誤りがあったため、修正しました。
----

エネルギー基本計画の改訂案(第5次エネルギー基本計画(案))が公表されました。

エネルギー基本計画(案)平成30年5月16日
http://www.enecho.meti.go.jp/committee/council/basic_policy_subcommittee/pdf/basic_policy_subcommittee_002.pdf

今回はこのpdfからtxtを抽出したいと思います。

使うのはPDFMiner.sixです。PDFMinerには他にもバージョンなどがあるようですが、pdfminer.sixはpython2/3系共通であり、現在も更新されているということでこれにしました。

github:pdfminer/pdfminer.six

検索するとPDFMinerを使ったコードがいろいろ出てくるのですが、バージョンが違うためかほとんどがエラーとなりました。下記のページが大変参考になりました。

アラカン"BOKU"のITな日常:PDF形式で受取り、テキストデータを抜いて使うのは現実的な選択肢になるのか?(pdfminer.six)

インストールはpipで入ります。
!pip install pdfminer.six

インストールすると、pdf2txt.pyというツールも保存されます。Anacondaを使っている場合は、Anacondaフォルダ > Scriptフォルダに入っているはずです。
このファイルをテキストに変換したいpdfと同じフォルダに保存します。

今回は前述のエネルギー基本計画(案)をenerg.pdfとしてダウンロード・保存したファイルを使います。

Jupyter notebookでのpdf2txt.pyの実行
%run pdf2txt.py energy.pdf

jupyter notebookでスクリプトを実行する場合は、%runを付けます。これで、pdfからテキストを抽出して画面上に出力されます。

出力をtxtファイルとして保存する場合は、-0 のオプションを付けてoutputファイルを指定します。
%run pdf2txt.py -o energy.txt energy.pdf

出力(一部)
はじめに 

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

らず、2050年を見据えたパリ協定への対応、より長期には化石資源枯渇に備

えた超長期の対応、変化するエネルギー情勢への対応など、今一度、我が国がそ

のエネルギー選択を構想すべき時期に来ている。このため、今回のエネルギー基

本計画の見直しは、2030年の長期エネルギー需給見通し(2015年7月経

済産業省決定。以下「エネルギーミックス」という。)の実現と2050年を見

据えたシナリオの設計で構成することとした。 

妙なところに改行が入ったり、空白が入ったりしています。ちょっと分かりにくいですが、各行の最後にも半角スペースが入っています。

これでは使いにくいので、pdf2txt.pyを使うのではなく、pythonで抽出してみます。

いろいろ調べていたのですが、PDFMinerは非常に高機能なツールのようですが、高機能なために分かりにくくなっている気がします。今回はシンプルに最低限のコードでテキスト化することを目指します。

参考にしたのは、前述のブログ記事と下記の質問サイトのコードです。

stackoverflow
How do I use pdfminer as a library

コード

from pdfminer.pdfparser import PDFParser, PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
#from pdfminer.layout import LAParams

import urllib
import io

fp = urllib.request.urlopen('http://www.enecho.meti.go.jp/committee/council/basic_policy_subcommittee/pdf/basic_policy_subcommittee_002.pdf')
retstr = io.StringIO()

parser = PDFParser(fp)
doc = PDFDocument()
parser.set_document(doc)
doc.set_parser(parser)

rsrcmgr = PDFResourceManager()
device = TextConverter(rsrcmgr, retstr)
interpreter = PDFPageInterpreter(rsrcmgr, device)

for page in doc.get_pages():
    interpreter.process_page(page)

fp.close()
device.close()
    
str = retstr.getvalue()

retstr.close()

str

urllibを使って、インターネット上のpdfを直接読み込んでいます。

パラメーター指定はしないので、layoutのインポートはコメントアウトしています。PDFドキュメントの作成と初期化、リソースマネージャ、デバイス、インタープリターを指定して、forループでページ読み込みテキスト抽出、getvalueでテキストを全て読み出すようです(よく分かっていません)。

このコードでは全てのページからテキストを抽出します。縦書きには対応してません。(layoutで指定が必要)

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

改行、空白文字が消えた状態でテキスト抽出できました。通常の(必要な)改行も消えているので若干読みにくいです。

ここでは表示されていませんが、ページ番号が ¥x0c 7 という形式で入っています。この辺りもPDFMinerの設定で変更できるのかもしれません。

今回試したエネルギー基本計画のpdfは単純な文章ファイルなので比較的簡単にテキスト抽出ができましたが、複雑な段組などが入ると難しくなりそうです。逆に複雑なものほど、PDFMinerの本領発揮なのかもしれません。

参考:
資源エネルギー庁:エネルギー基本計画について
http://www.enecho.meti.go.jp/category/others/basic_plan/

github:pdfminer/pdfminer.six
https://github.com/pdfminer/pdfminer.six
PDFMiner HP
https://www.unixuser.org/~euske/python/pdfminer/index.html
アラカン"BOKU"のITな日常:PDF形式で受取り、テキストデータを抜いて使うのは現実的な選択肢になるのか?(pdfminer.six)
http://arakan-pgm-ai.hatenablog.com/entry/2018/01/07/080000
stackoverflow:How do I use pdfminer as a library
https://stackoverflow.com/questions/5725278/how-do-i-use-pdfminer-as-a-library
//SyntaxHighlighter CDNより https://cdnjs.com/libraries/SyntaxHighlighter // 対応言語