2020年7月21日火曜日

LSTMによる卸電力価格(スポット価格)の変化点検知(時系列データ、異常検知、ディープラーニング)

前回の続き、東京大学松尾研ディープラーニング講座 DL4US 3rdの最終課題(自由課題)についてです。

最終課題
「講座で学んだ技術を利用する独自プロジェクトに取り組み、その結果をレポートせよ」

ということで、私は卸電力価格(スポット価格)の変化点検知と予測に取り組みました。


背景と目的

電力スポット市場(一日前市場)とは
卸電力取引所が開催する最もポピュラーな電力取引市場の一つであり、翌日に発電または販売する電気を前日までに入札し、売買を成立(マッチング)させるものです。https://pps-net.org/glossary/5072

スポット市場の約定価格(以下、スポット価格)は発電事業者にとっては電気の卸販売価格、小売電気事業者等にとっては調達価格として重要なものとなっています。

スポット価格の一般的な特徴
・日変動(昼間、夜間などの時間帯による変動)
・季節変動
・平日・休日による差
・需要・供給力による変動
・気温による変動

スポット価格1週間の変動例

上記の一般的な特徴のほかに、中長期でトレンドが変化しています。最近では太陽光発電が増加したことなどの影響で特に西日本で昼間のスポット価格の低下が大きくなってきました。


ススポット価格 時間別平均値の変化

今回のスポット価格の変化点検知の目的は、変化を早めに察知することで戦略見直しの必要性を明確にするということです。また、政策立案者にとっては介入効果の検証やある事象による影響を知ることもできるかと思います。

目標:スポット価格のトレンドの変化(変化点)を検出する。


変化点検知の手法

変化点を検出するにあたり、LSTMで特定の時点までの時系列データのモデルを作成し、その後の時点での実測値と予測とのずれをトレンドの変化とすることとしました。

異常検知として外れ値を検出するという手法が取り上げられていますが、瞬間的にスポット価格が高騰することはよくあります。このため、外れ値だけではなく変化は比較的小さくても一定期間続く傾向を検出したいことから、予測誤差の集合による異常度の判定としました。



データ

日本卸取引所(JEPX)のスポット市場取引結果(2005年~2019年12月 エリアプライス)
気象データ:気象庁過去データより代表1地点の気温、日射量の1時間値

スポット市場は対象期間の1日前に取引を行うため、本来は天気予報のデータを用いるべきですが、過去の予報データが手に入らなかったため過去気象の実測値を用いました。


変数候補としては供給力、需要、連系線の混雑状況、燃料価格など様々考えられますが、今回は気温、日射量、平日・休日フラグ、時間のみを使っています。

異常度は1週間単位の予測誤差の平均値の二乗としました。


モデル・学習

モデルの構築はPython Kerasを使いました。下記を参考にしています。

深層学習を用いた時系列データにおける異常検知 Kabuku Developers Blog
https://www.kabuku.co.jp/developers/time_series_anomaly_detect_deep_learning


スポット市場では前日10時を締め切りに翌日の24時間分を取引します。このため、学習データのスポット価格は48時間前の価格としました。24時間分のデータから1時間値を予測します。



trainデータで実測値と予測値の誤差が正規分布に近くなるまで(過学習気味になるまで)学習を行い、testデータで前述誤差の差から異常度を計算します。


結果

<結果1:train:2005年4月~2010年12月、test:2011年1月~2019年12月>


2005年4月~2010年12月までを学習し、2011年から2018年までの変化点を見た結果です。青色がスポット価格の実測値、オレンジが予測値、緑色が異常度(右軸)です。

2011年3月の東日本大震災後、2012年1月に異常度が非常に高くなり、2015年まで高い状態が継続しています。2016年ごろからは元の傾向(2010年まで)に近くなったことがわかります。

<結果2:train:2005年4月~2010年12月、test:2011年1月~2019年12月>


こちらは2005年4月~2018年を学習し、2019年1月~12月の変化点を見た結果です。

2019年2月から4月中ごろに異常度が比較的高くなっており、太陽光発電の増加により晴れた昼間にスポット価格が大きく下落するようになった時期と一致しています。結果1の2012年ごろと比べると異常度は小さくなっていて、変化の大きさも反映されています。


考察など

簡易的でありますが、LSTMによるモデルと誤差集合を用いることでトレンドの変化を検知することができました。ただし、気象データを予報値ではなく実測値を使っていること、ごく限られた変数のみを用いていることなどからあくまで参考という形です。また、異常度の判定方法や評価指標としてはもっと一般的な方法があるかと思います。

先にも述べましたが、変化点とその度合いを見ることで事業戦略転換の判断をしやすくなったり、政策等の介入効果、状態変化による影響などを明確にすることができ、適用範囲は広いと思います。最近ではコロナの影響で電力需要の減少が言われていますが、同様の手法で影響を図ることができそうです。

以前行った、エネルギー基本計画での新語・複合語を探すというのも政策での変化を見たかったという動機でした。自然言語処理を用いた変化点検知というのもやってみたいと思っています。


参考
東京大学松尾研 DeepLearning実践開発講座「DL4US」3rd
https://deeplearning.jp/lectures/dl4us_3rd
DL4US コンテンツ公開ページ
https://weblab.t.u-tokyo.ac.jp/dl4us/

東京大学松尾研ディープラーニング講座 DL4USを修了しました。
https://eneprog.blogspot.com/2020/06/dl4us.html

ReNom:LSTMによる時系列データの異常検知
https://www.renom.jp/ja/notebooks/tutorial/time_series/lstm-anomalydetection/notebook.html
Kabuku Developers Blog :深層学習を用いた時系列データにおける異常検知
https://www.kabuku.co.jp/developers/time_series_anomaly_detect_deep_learning

日本卸電力取引所(JEPX)
http://www.jepx.org/
新電力ネット スポット市場
https://pps-net.org/glossary/5072
JEPX プライスチェッカー
https://enechange.jp/jepx_checker/

日本経済新聞 :電力スポット価格、土日昼間は「ほぼ0円」
https://www.nikkei.com/article/DGKKZO58525810X20C20A4TJ3000/

エネルギー基本計画の特徴を見てみる。その4 複合語を考慮してwordcloud
https://eneprog.blogspot.com/2018/09/4-wordcloudpythonjanome.html
エネルギー基本計画から新語・複合語を探す。その2 複合語を判定する
https://eneprog.blogspot.com/2018/08/2-pythonjanome.html


謝辞
DL4USの運営スタッフのみなさま、大変有用な講座を(無料で!)提供し、サポートしていただき本当にありがとうございました。ご一緒いただいた受講者のみなさまとの交流も大変励みになりました。感謝です。

2020年6月13日土曜日

東京大学松尾研ディープラーニング講座 DL4USを修了しました。

ずいぶん久しぶりの投稿になります。2019年10月から東京大学松尾研ディープラーニング講座 DL4US 3rdを受講し、2020年2月に無事修了しました。

東京大学松尾研 DeepLearning実践開発講座「DL4US」3rd
DL4US コンテンツ公開ページ

私はDL4USの3期生になるようです。講座の内容は上記公開コンテンツで見ることができますが、ただ、コンテンツで自習するのと講座を受講するのでは大きく異なる点があります。

・1受講者 – 1GPUサーバ、ブラウザのみで構築済みの環境が使える。
・毎週の課題提出(コンペ形式)
・SLACKでほかの受講者・TAとのコミュニケーション
・コンペ課題上位者の解法の共有

講座募集のページにも書かれていますが、

第3期では、”受講生コミュニティ” の価値最大化を目指して、1)コンペ形式の課題を通じた競争、2)受講生フォーラムでの議論・助け合い、3)講座期間中・後の交流、に重点を置いた運営を行います。

ということで、この運営が非常に効果的だったと思います。

特に毎週課題提出があることで締め切りに追われながらもスケジュール通りに講座を進めるができる、受講者同士で教えあいや励ましあい、解法の共有など、学習の継続と理解を深める工夫がありました。

正直、仕事をしながらの毎週課題をこなすのはかなりきついものがありましたが、課題コンペでの競いあいや受講者同士でコミュニケーションが取れる場があることで何とか継続できたと思っています。

DL4USの特徴にはもう一つ、最終課題があります。

最終課題
「講座で学んだ技術を利用する独自プロジェクトに取り組み、その結果をレポートせよ」

テーマは自由。データも自分で集める必要があります。

何をするか、自分の実力で何ができるか非常に悩みましたが、私は「LSTMによる電力卸価格(スポット価格)の変化点検知と予測」というテーマにしました。時系列の電力卸価格と気象データ等から変化点とその度合いを見る(さらに予測を行う)というものです。

実は自然言語処理を試してみたかったのですが、テーマも絞り切れず、一からやるには難易度が高すぎることから、やはり少しでもドメイン知識のある分野の方がやりやすいだろうという選択です(これは正解でした)。

最終課題に取り組んだのは1か月弱(一度締め切りが延びた)という短期間で、非常に苦労しましたが何とかレポートにまとめ、提出することができました。予測としての精度はあまりよくなかったものの、最終課題の評価は修了者の平均程度となり個人的には満足しています。

今まで、Andrew先生のcoursera machine learningedx UCバークレーデータサイエンス基礎講座とデータ解析系の講座を受講しましたが、DL4USは技術の習得はもとより、継続の面でとてもよく設計された講座だと感じました。受講者の修了率は半分程度だったそうですが、オンライン講座でこの修了率は高いと思います。何より、スタッフの方の対応や受講者同士のコミュニケーションが取れる仕組みやよかったです。

修了者の懇親会はコロナの影響で延期となっていますが、開催される場合はぜひ参加したいと思います。

*実はこの後、同じく東京大学松尾研のGCIデータサイエンティスト育成講座も受講しました。こちらについてもそのうち書きます。

追記:2020年7月21日 最終課題について書きました。
LSTMによる卸電力価格(スポット価格)の変化点検知(DL4US最終課題)
https://eneprog.blogspot.com/2020/07/lstmdl4us.html

参考
東京大学松尾研 DeepLearning実践開発講座「DL4US」3rd
https://deeplearning.jp/lectures/dl4us_3rd
DL4US コンテンツ公開ページ
https://weblab.t.u-tokyo.ac.jp/dl4us/

Coursera machine learningコース
https://www.coursera.org/learn/machine-learning
coursera machine learningコース修了しました。
https://eneprog.blogspot.com/2018/06/edx-uc-2python.html
Coursera machine learning コースを始めました。edX UCバークレーFoundations of Data Scienceとの違いなど
https://eneprog.blogspot.com/2018/07/coursera-machine-learning-edx-ucmooc.html
edX UCバークレー Data Science: Computational Thinking with Python
https://www.edx.org/course/foundations-of-data-science-computational-thinking
プログラミング学習:edx UCバークレー データサイエンス基礎講座の紹介(python)
https://eneprog.blogspot.com/2018/04/edx-uc-python.html
プログラミング学習:edx UCバークレー データサイエンス基礎講座、第2弾受講中(python)
https://eneprog.blogspot.com/2018/06/edx-uc-2python.html

2018年9月27日木曜日

pythonで全角⇔半角変換する。unicodedateを使う方法とdict登録で文字種ごとに設定する方法。(文字列操作,正規化,unicodedata,ユニコード)

過去のエネルギー基本計画と最新分を比較しようとしたところ、文字の全角半角にばらつきがあることに気がつきました。

平成30年 第5次エネルギー計画(最新版)
平成22年 第3次エネルギー計画


最新の第5次エネルギー基本計画では、略語、数字は全角(CO2、IoT、2030年など)、英単語・熟語、単位は半角(Energy Security、klなど)。第3次エネルギー基本計画では略語、数字(1文字の数字を除く)は半角(CO2、2002 年など)、一桁の数字は全角です(9月、9割など)。各文書内では文字種ごとに全角半角は統一されているようです。

このままでは自然言語処理をする際に別の単語と認識してしまうので統一していきます。

すべて正規化する場合(全角アルファベット・数字・記号→半角、半角カタカナ→全角)はunicodedateを使うと簡単です。

・unicodedateで全角を半角に
import unicodedata

text = u'ABCabc123カキク①(!%@#$¥~ ABCabc123カキク(!%@#$\~'
unicodedata.normalize("NFKC", text)
'ABCabc123カキクガギグ1(!%@#$¥~ ABCabc123カキクガギグ(!%@#$\\~'

unicodedate.nomalizeではformを指定して文字列を正規化します。ここではNFKC(Normalization Form Compatibility Composition)を指定しています。下記に詳しい解説があります。(あまり理解できていません)

Pythonドキュメント unicodedata — Unicode データベース
文字コード地獄秘話 第3話:後戻りの効かないUnicode正規化


unicodedateの正規化(NFKC)を使うと、全角アルファベット・数字・カタカナは半角になります。全角記号も半角になりますが、正規化されて、違う記号になったりするので要注意です。上の例では丸囲み数字①が1に、~は˜に、¥は¥¥になってしまいました。これでは困ることがあるので、違う方法を考えます。

参考にしたのはこちら↓

pythonで半角英数字から全角英数字へ変換


目的の文字のユニコードを辞書登録して、translateで変換するという方法。

ユニコードを調べるのは下記ページが便利です。逆引きもできます。

うにこ~ど2/


数字、英字のユニコード範囲:
---
数字半角[0-9] 0x30~0x39
数字全角[0-9] 0xFF10~0xFF19

英字半角・大文字[A-Z] 0x41~0x5A
英字全角・大文字[A-Z] 0xFF21~0xFF3A
英字半角・小文字[a-z] 0x61~0x7A
英字全角・小文字[a-z] 0xFF41~0xFF5A
---

ユニコードは計算(足し算、引き算)ができるので、これを利用してアルファベット、数字の一覧が生成できます。

・全角アルファベット一覧の作成
for ch in range(26):
    print(chr(0xFF21 + ch))
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

大文字全角Aのユニコード[0xFF21]に26までの数字を足して、AからZまでの英字を作りました。次にこれらを辞書に登録します。

・全角半角のセットを辞書に登録
upper = dict((0xFF21 + ch, 0x0041 + ch) for ch in range(26))
lower = dict((0xFF41 + ch, 0x0061 + ch) for ch in range(26))
number= dict((0xFF10 + ch, 0x0030 + ch) for ch in range(10))

t = {**upper, **lower,**number}

大文字(upper)、小文字(lower)、数字(number)をそれぞれ全角をキーに、半角を値にして辞書を作成し、ひとつに結合しました。変換が必要な文字種だけを辞書登録するのがポイント。辞書の結合は**を使っていますが、これができるのはPython3.5以上のようです。

Python で2つの辞書をマージした新しい辞書を作りたいとき


あとはtranslateで文字列を変換するだけ。

・全角英字、数字を半角に変換
text = u'ABCabc123カキク①(!%@#$¥~ ABCabc123カキク(!%@#$\~'
print(text.translate(t))
ABCabc123カキク①(!%@#$¥~ ABCabc123カキク(!%@#$\~

全角英字・数字のみが半角に変換されました(記号・半角カタカナはそのまま)。これを使うと、半角を全角に、全角数字のみを半角数字になどもできます。ただ、記号の場合はユニコードが連続していないので、目的のユニコードを探して辞書登録する必要があります。


参考:
Pythonドキュメント unicodedata — Unicode データベース
https://docs.python.jp/3/library/unicodedata.html
文字コード地獄秘話 第3話:後戻りの効かないUnicode正規化
http://tech.albert2005.co.jp/501/
うにこ~ど2
http://unicode.ninpou.jp/

pythonで半角英数字から全角英数字へ変換
http://cuio.blog2.fc2.com/blog-entry-2165.html
[Java] 全角半角変換(英数字の場合)
https://ameblo.jp/archive-redo-blog/entry-10376390355.html
Python で2つの辞書をマージした新しい辞書を作りたいとき
https://utgwkk.hateblo.jp/entry/2017/08/04/013507

2018年9月24日月曜日

coursera machine learningコース修了しました。(機械学習,オンライン学習)

7月から始めたcoursera machine learningコースを修了しました。

Coursera machine learning コースを始めました。edX UCバークレーFoundations of Data Scienceとの違いなど

約3ヶ月かけて期限のぎりぎりで修了です。何とか終われたというのが感想です。

コースの内容はほかの方が詳しく書かれていますが、機械学習に必要なことは一通り習ったという感じでしょうか。主な項目は単回帰、重回帰、ロジスティック回帰、ニューラルネットワーク、サポートベクターマシン(SVM)、K-means、主成分分析(PCA)、異常値検知など。そのほか、機械学習が上手くいっているかの確認方法、こんなときにはこれを使う、ビッグデータを扱う場合などのコツも教えてくれています。

カリキュラムとしては、5週目までで単回帰からニューラルネットワークまで進み、かなりのスピードと分量でついていくのがやっとという状態でした。私は特に5週目のニューラルネットワークの誤差逆伝播法(Backpropagation)が理解できず、他のHPや本を見て参考にしました(今でも理解できているとは言いがたいですが)。ニューラルネットワークまでは自分でアルゴリズムを組んで実装しますが、その後は既存のライブラリを使ったりするので比較的簡単に感じました(Octave、行列の計算に慣れたというのもある)。

プログラミング課題はOctaveを使いますが、これは特に問題ではなかったです。とてもシンプルで理解しやすい言語だと思います。

機械学習では数学の知識が必要といわれていますが、このコースでは初歩の行列の計算(足し算、引き算、内積など)は最初に解説があります。その他は数式も出てきますが、理解できなくてもいい。覚えなくてもいい(覚える必要はない)などとコメントがありました。もちろん理解できたほうがいいですが、何となく分かった程度でもついていけます。

このコースでは基本的に日本語字幕がついていますが、何項目かは日本語なしのものもありました。日本語字幕は複数人のボランティアが担当して作成されているようで、質にムラがあります。日本語では分かりにくいときがあるので、その場合は英語スクリプトを確認したほうがいいです。

全体としてとてもよくできたコースだと思いますが、なんといっても講師のAndrew先生が人気の秘密だと感じました。これは難しいから理解しなくても大丈夫、僕も最近やっと分かったところだよ。ここまで良く頑張ったね。おめでとう。シリコンバレーの多くのエンジニアより君のほうが機械学習を分かっている。などというコメントがところどころにあり、この言葉に励まされながら受講を続けました。修了して最後の先生の言葉にはちょっと感動しました。

ほぼ感想になりましたが、オンライン学習というのはリタイア率が高く、修了まで続けるのは容易ではありません。興味が続くようなコース設計はもとより、励ましというか声かけ、コーチングが重要なのだと思いました(私はAndrew先生の励ましを受けてなんとか修了できた感じです)。日本のオンライン学習でもこれらの仕組みを取り入れて、続けやすい仕組みを整えてほしいと思います。

最後に。これから受講される方へ
さまざまなブログなどで紹介されている人気コースですが、分量も多く、やさしくはないです。ただ、難易度は3週目までと6週目までが山です。あとは全体に簡単になるので、まずは3週目までやってみることをお勧めします。機械学習とは何なのかという話を平易な言葉を使って解説されていて、興味深く続けられました。なんといってもAndrew先生の言葉と笑顔がよいです。ぜひ受講してみてください。

参考:
Coursera machine learningコース
https://www.coursera.org/learn/machine-learning
Coursera machine learning コースを始めました。edX UCバークレーFoundations of Data Scienceとの違いなど
https://eneprog.blogspot.com/2018/07/coursera-machine-learning-edx-ucmooc.html
edX 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
プログラミング学習:edx UCバークレー データサイエンス基礎講座、第2弾受講中(python)
https://eneprog.blogspot.com/2018/06/edx-uc-2python.html

2018年9月1日土曜日

エネルギー基本計画の特徴を見てみる。その4 複合語を考慮してwordcloud(python,janome,自然言語処理)

前回までに、エネルギー基本計画から複数回出現する単語の組み合わせをgensim Phrasesで取り出し名詞とみなせるか判定した上で複合語・新語をjanomeのユーザー辞書に登録しました。

今回は、作成したユーザー辞書を使って複合語を考慮した上でwordcloudを作ってみます。

ちなみに、複合語を考慮しない場合はこのようになりました。



エネルギー基本計画(案)の特徴を見てみる。その2 名詞でwordcloudより。 名詞(代名詞、非自立名詞を除く)のみ、連語を考慮せず。

「エネルギー」が大きく表示されていますが、「必要」「利用」「活用」などの普通に使われそうな言葉が目立ち、エネルギー基本計画としての特徴があまり出ていません専門用語として複合語・新語を登録したユーザー辞書を使うことで、どう変化するでしょうか。

・インポートとデータ読み込み
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()
full_text= full_text.replace("\n","")
出力(一部)
はじめに2011年3月の東日本大震災及び東京電力福島第一原子力発電所事故を受けて、政府は、2014年4月、2030年を念頭に、第4次エネルギー基本計画を策定し、原発依存度の低減、化石資源依存度の低減、再生可能エネルギーの拡大を打ち出した。第4次エネルギー基本計画の策定から4年、2030年の計画の見直しのみならず、パリ協定の発効を受けた2050年を見据えた対応、より長期には化石資源枯渇に備えた超長期の対応、変化するエネルギー情勢への対応など、今一度、我が国がそのエネルギー選択を構想すべき時期に来ている。

・ユーザー辞書を指定
tokenizer = Tokenizer('energywords_dic.csv', udic_enc='cp932')
tokens = tokenizer.tokenize(full_text) 

前回作成したユーザー辞書を指定します。

・形態素解析を行い、指定した品詞のみを取り出す。
word_list=[]
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 != "代名詞") and (partOfSpeech2 != "数"):
            word_list.append(word)

words_wakati=" ".join(word_list)
words_wakati

出力(一部)
はじめ 年 3月 東日本大震災 東京電力 福島 原子力発電所 事故 政府 年 4月 年 念頭 次 エネルギー 基本 計画 策定 原発依存度 低減 化石資源 依存度 低減 再生可能エネルギー 拡大 次 エネルギー 基本 計画 策定 年 年 計画 見直し パリ協定 発効 年 対応 長期 化石資源 枯渇 長期 対応 変化 エネルギー情勢 対応 今 度 我が国 エネルギー 選択 構想 時期

形態素情報から名詞(非自立、代名詞、数を除く)のみを取り出しています。janomeを使った品詞での単語抽出についてはこちらをご覧ください。

・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 = False #default = True
).generate(words_wakati)

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

最大フォントを指定せず、連語を考慮せずで作成しています。wordcloudの設定についてはこちらをご覧ください。

出力

(クリックで少し大きく見られます)

「エネルギー」「技術」「開発」「事業」「取組」が大きく表示され、「再生可能エネルギー」「脱炭素化」「水素」「地域」も大きめです。よく見ると「エネルギー需給」「LPガス」「温室効果ガス」などもあります。

作成したユーザー辞書を使うことで、専門用語を考慮することができるようになり、前よりは特徴が見えてきました。

次回以降、「技術」「開発」「取組」などのこういう文書によく使われる単語を除いて、特定の文書での特徴を現す言葉のみの抽出をやってみようと思います。

参考:
資源エネルギー庁:第5次エネルギー基本計画
http://www.enecho.meti.go.jp/category/others/basic_plan/pdf/180703.pdf
Janomeドキュメント:ユーザー定義辞書を使う
http://mocobeta.github.io/janome/#id7
MeCab 単語の追加方法
http://taku910.github.io/mecab/dic.html
コード7区:gensim の Phrases の使い方。頻出する単語ペアを検出-python
http://ailaby.com/phrases/
コード7区:ツイートからユーザ辞書(MeCab や Janome 用)をpython で作ってみる http://ailaby.com/tweet_dict/
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

gensim Phrasesで新語・複合語を探す(python、自然言語処理、機械学習)
https://eneprog.blogspot.com/2018/07/gensim-phrasespython.html
エネルギー基本計画から新語・複合語を探す。その1
https://eneprog.blogspot.com/2018/07/1-pythongensimphrasesjanome.html
エネルギー基本計画から新語・複合語を探す。その2 複合語を判定する
https://eneprog.blogspot.com/2018/08/2-pythonjanome.html
Janomeでユーザー辞書を使う
https://eneprog.blogspot.com/2018/08/janomepython.html

2018年8月21日火曜日

Janomeのユーザー辞書を作る(python,自然言語処理,エネルギー基本計画)

前回の続きです。前回はエネルギー基本計画からgensim Phrasesを使って、複数回出現する単語の組み合わせを複合語候補として取り出し、名詞とみなせるかどうか判定しリストを作りました。

今回は、このリストを新語としてjanomeのユーザー辞書に登録します。 下記の記事を参考にしました。

Janomeドキュメント:ユーザー定義辞書を使う
http://mocobeta.github.io/janome/#id7
コード7区:ツイートからユーザ辞書(MeCab や Janome 用)をpython で作ってみる
http://ailaby.com/tweet_dict/


・インポートとデータの確認
from janome.tokenizer import Tokenizer
import pandas as pd

words_judge
複合語候補回数単語判定
0再生_可能_エネルギー171再生可能エネルギーTrue
1する_こと154することFalse
2。_\r\r\r\r\n135
3し_た128
4的_な118
5について_は91について
6事業_者78事業者True
7する_ため72するためFalse
8脱_炭素_化65脱炭素化True
9し_て65

・データ抽出
words_dic=words_judge[(words_judge["判定"]==True) & (words_judge["回数"] >= 6)]
words_dic

判定が"True"、回数が6以上のものを抽出。

複合語候補回数単語判定
0再生_可能_エネルギー171再生可能エネルギーTrue
6事業_者78事業者True
8脱_炭素_化65脱炭素化True
14技術_開発56技術開発True
15可能_性55可能性True
27安定_供給38安定供給True

このデータの"単語"列をユーザー辞書に登録します。janomeのユーザー辞書はMeCab 辞書と同じです。ユーザー辞書のフォーマットについては下記を参照ください。

MeCab 単語の追加方法
http://taku910.github.io/mecab/dic.html

ユーザー辞書はカンマ区切りCSVファイルで、「表層形,左文脈ID,右文脈ID,コスト,品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用型,活用形,原形,読み,発音」という形式です。

今回は、左文脈ID、右文脈IDを-1、コストを1000に、品詞、品詞細分類1を名詞、一般名詞に固定し、そのほかは"*"にします。

・ユーザー辞書のフォーマットを作る
words_dic["paramater"]="-1,-1,1000,名詞,一般,*,*,*,*,%s,*,*"

words_dic=pd.concat(
    [words_dic['単語'],words_dic['paramater']
     .str.split(',', expand=True)], axis=1)

words_dic[9]=words_dic["単語"]
words_dic 

フォーマットの表層形以外をカンマ区切りでparamater列に格納した後、カンマで列を分割、原形(列名"9")に"単語"列をコピーしています。

単語01234567891011
0再生可能エネルギー-1-11000名詞一般****再生可能エネルギー**
6事業者-1-11000名詞一般****事業者**
8脱炭素化-1-11000名詞一般****脱炭素化**
14技術開発-1-11000名詞一般****技術開発**
15可能性-1-11000名詞一般****可能性**

これでユーザー辞書のフォーマットが完成。

・ユーザー辞書をCSVで保存
words_dic.to_csv("energywords_dic.csv", sep=",",index=False,header=False,encoding='cp932') 

できたユーザー辞書をCSVで保存します。この時、列名、インデックスともにFalseとし、保存しないようにます。

・ユーザー辞書を使う
janomeでユーザー辞書を使ってみます。エネルギー基本計画より、下記の文章を分かち書きします。
電源構成は、特定の電源や燃料源への依存度が過度に高まらないようにしつつ、低廉で安定的なベースロード電源を国際的にも遜色のない水準で確保すること、安定供給に必要な予備力、調整力を堅持すること、環境への適合を図ることが重要であり、バランスのとれた電源構成の実現に注力していく必要がある。一方、東京電力福島第一原子力発電所事故後、電力需要に変化が見られるようになっている。こうした需要動向の変化を踏まえつつ、節電や、空調エネルギーのピークカットなどピーク対策の取組を進めることで電力の負荷平準化を図り、供給構造の効率化を進めていくことが必要である。
text="電源構成は、特定の電源や燃料源への依存度が過度に高まらないようにしつつ、低廉で安定的なベースロード電源を国際的にも遜色のない水準で確保すること、安定供給に必要な予備力、調整力を堅持すること、環境への適合を図ることが重要であり、バランスのとれた電源構成の実現に注力していく必要がある。一方、東京電力福島第一原子力発電所事故後、電力需要に変化が見られるようになっている。こうした需要動向の変化を踏まえつつ、節電や、空調エネルギーのピークカットなどピーク対策の取組を進めることで電力の負荷平準化を図り、供給構造の効率化を進めていくことが必要である。"

・ユーザー辞書なし
tokenizer = Tokenizer()

words=[]
tokens = tokenizer.tokenize(text)
for word in tokens:
    words.append(word.surface)
    
print(" ".join(words))
電源 構成 は 、 特定 の 電源 や 燃料 源 へ の 依存 度 が 過度 に 高まら ない よう に し つつ 、 低廉 で 安定 的 な ベース ロード 電源 を 国際 的 に も 遜色 の ない 水準 で 確保 する こと 、 安定 供給 に 必要 な 予備 力 、 調整 力 を 堅持 する こと 、 環境 へ の 適合 を 図る こと が 重要 で あり 、 バランス の とれ た 電源 構成 の 実現 に 注力 し て いく 必要 が ある 。 一方 、 東京電力 福島 第 一 原子力 発電 所 事故 後 、 電力 需要 に 変化 が 見 られる よう に なっ て いる 。 こうした 需要 動向 の 変化 を 踏まえ つつ 、 節電 や 、 空調 エネルギー の ピーク カット など ピーク 対策 の 取組 を 進める こと で 電力 の 負荷 平準 化 を 図り 、 供給 構造 の 効率 化 を 進め て いく こと が 必要 で ある 。

・ユーザー辞書あり
tokenizer = Tokenizer('energywords_dic.csv', udic_enc='cp932')


words=[]
tokens = tokenizer.tokenize(text)
for word in tokens:
    words.append(word.surface)
    
print(" ".join(words))
電源構成 は 、 特定 の 電源 や 燃料 源 へ の 依存度 が 過度 に 高まら ない よう に し つつ 、 低廉 で 安定的 な ベースロード電源 を 国際的 に も 遜色 の ない 水準 で 確保 する こと 、 安定供給 に 必要 な 予備 力 、 調整力 を 堅持 する こと 、 環境 へ の 適合 を 図る こと が 重要 で あり 、 バランス の とれ た 電源構成 の 実現 に 注力 し て いく 必要 が ある 。 一方 、 東京電力 福島 第 一 原子力発電所 事故 後 、 電力 需要 に 変化 が 見 られる よう に なっ て いる 。 こうした 需要動向 の 変化 を 踏まえ つつ 、 節電 や 、 空調 エネルギー の ピーク カット など ピーク 対策 の 取組 を 進める こと で 電力 の 負荷 平準 化 を 図り 、 供給構造 の 効率化 を 進め て いく こと が 必要 で ある 。

ユーザー辞書の設定は、Tokenizerの初期化時にユーザー辞書のCSVファイル名とエンコードを指定するだけ。

ユーザー辞書ありでは、電源構成、依存度、安定的、ベースロード電源、国際的、安定供給、調整力、原子力発電所、需要動向、供給構造、効率化が一つの単語となりました。

一方、予備力、電力需要、ピークカットは「予備 力」「電力 需要」「ピーク カット」と分かれたままです。これはエネルギー基本計画で6回以上出現したものを複合語候補として抽出したためです。複数の資料から辞書に載っていない組み合わせを抽出するようにすれば、新語の検出精度が上がりそうです。

参考:
資源エネルギー庁:第5次エネルギー基本計画
http://www.enecho.meti.go.jp/category/others/basic_plan/pdf/180703.pdf
Janomeドキュメント:ユーザー定義辞書を使う
http://mocobeta.github.io/janome/#id7
MeCab 単語の追加方法
http://taku910.github.io/mecab/dic.html
コード7区:gensim の Phrases の使い方。頻出する単語ペアを検出-python
http://ailaby.com/phrases/
コード7区:ツイートからユーザ辞書(MeCab や Janome 用)をpython で作ってみる http://ailaby.com/tweet_dict/
Janomeで形態素解析をやってみる。
http://eneprog.blogspot.com/2018/06/janomepython.html
janome Analayzerで複合語(複合名詞)を考慮して形態素解析を行う。
http://eneprog.blogspot.com/2018/07/janome-analayzerpython.html
gensim Phrasesで新語・複合語を探す(python、自然言語処理、機械学習)
https://eneprog.blogspot.com/2018/07/gensim-phrasespython.html
エネルギー基本計画から新語・複合語を探す。その1
https://eneprog.blogspot.com/2018/07/1-pythongensimphrasesjanome.html
エネルギー基本計画から新語・複合語を探す。その2 複合語を判定する(python,自然言語処理,janome)
https://eneprog.blogspot.com/2018/08/2-pythonjanome.html

2018年8月7日火曜日

エネルギー基本計画から新語・複合語を探す。その2 複合語を判定する(python,自然言語処理,janome)

前回、gensim phrasesを使って、エネルギー基本計画の文章から複数回出現した単語の組み合わせを複合語候補として取り出しました。

今回はここから複合語(名詞)と見なせるかどうか判定し、新語(エネルギー用語)として抽出します。下記のブログを参考にしました。

コード7区:ツイートからユーザ辞書(MeCab や Janome 用)をpython で作ってみる
http://ailaby.com/tweet_dict/

・インポート、janome Tokenizer初期化
from janome.tokenizer import Tokenizer
import pandas as pd
#from tqdm import tqdm
import re

tokenizer = Tokenizer()

・データ確認(一部)
words_df
複合語候補回数
0再生_可能_エネルギー171
1する_こと154
2。_\n135
3し_た128
4的_な118
5について_は91
6事業_者78
7する_ため72
8脱_炭素_化65
9し_て65
10し_て_いく65

助詞や句読点などが含まれているものがあります。これらを下記のように判定し、名詞と見なせるものを抽出しました。

  • 名詞+名詞=名詞 
  • 接頭詞+名詞=名詞 
  • 最後に助詞、助動詞がつくものはこれらを削除して判定 
  • 空白文字が含まれているものは除外 
  • 最初に「年」または「年度」とつくものは除外 
  • 数や助数詞が含まれているものは除外

最後に助詞、助動詞がつくものとは、「安定_的_な」のように、助詞、助動詞も含めて複合語候補となっているものです。この場合は最後の「な」を削除し「安定_的」で判定に回します。

その際、複合語ではなく1単語となってしまった場合、判定せずに空白を返すことにします(「重要_な」で「な」を削除すると「重要」の1単語となり複合語ではなくなる)。

・判定関数
def judge(word):
    
    word_list=word.split("_")
    word=word.replace("_","")

    tokens = tokenizer.tokenize(word)

    if len(tokens)==1 or re.search("\s+", word): #空白文字が含まれていたら除外
        return pd.Series(["",""])
    
    if word_list[0]=="年" or word_list[0]=="年度": #最初が「年」または「年度」であれば除外
        return pd.Series(["",""])

    part0 = tokens[-1].part_of_speech.split(',')[0]

    if part0 == "助詞" or part0=="助動詞": #最後が助詞または助動詞であればその単語を削除
        del tokens[-1]
        del word_list[-1]
        
        word="".join(word_list)
        
        if len(tokens)==1:
            return pd.Series([word,""])
        
    for num, token in enumerate(tokens):
        
        surFace = token.surface 
        part0 = token.part_of_speech.split(',')[0]
        part1 = token.part_of_speech.split(',')[1]
        part2 = token.part_of_speech.split(',')[2]
        reading = token.reading
        baseForm = token.base_form
        inflForm = token.infl_form
        

        if num==0: 
            if part0 ==u"接頭詞": #最初が接頭詞であれば、次の単語へ
                continue  
        
        if part0 != u'名詞':
            return pd.Series([word,False])
        elif part0 =="名詞" and (part1 == u'数' or part2=="助数詞"): #数、助数詞が含まれていれば除外
            return pd.Series([word,False])
        else:
            continue

    return pd.Series([word,True]) 


試行錯誤の結果こうなりました。戻り値はpandasのSeriesで、単語と判定結果(True または False)を返します。

・データフレームの列に関数適用
words_df=(
    pd.concat([words_df, words_df["複合語候補"].apply( judge )], axis=1 )
    .rename(columns={0:"単語",1:"判定"}))

applyで"複合語候補"列にjudge関数を適用し、戻り値2つをpd.concatで新しい列に格納します。複数の戻り値でそれぞれ新しい列を作る方法が分からず苦労しました。。。

・出力(一部)
複合語候補回数単語判定
0再生_可能_エネルギー171再生可能エネルギーTrue
1する_こと154することFalse
2。_\r\r\r\r\n135
3し_た128
4的_な118
5について_は91について
6事業_者78事業者True
7する_ため72するためFalse
8脱_炭素_化65脱炭素化True
9し_て65

「再生可能エネルギー」「事業者」「脱炭素化」はTrue、「すること」「するため」はFalseと判定されました。「して」「した」など最後の助詞、助動詞を取り除くと1単語になるものは空白としています。

・重複除去
words_judge=(words_df.groupby(["単語","判定"])["回数"].sum()
        .reset_index()
        .rename(columns={0:"回数"})
        .sort_values(by="回数", ascending=False))

複合語候補、最後の助詞、助動詞を取り除く処理により、重複が出てくるためこれをgroupbyで取り除き、sum()で回数を足し合わせました。

・抽出
words_judge[(words_judge["判定"]==True) & (words_judge["回数"] >= 6)]

判定がTrue、出現回数が6回以上のものを抽出します。これらを新語・複合語とします。

・出力
単語判定回数
250再生可能エネルギーTrue171
215事業者True78
503脱炭素化True77
384技術開発True56
291可能性True55
162エネルギー源True45
480積極的True41
348安定供給True38
581需要家True38
266効率的True37
351安定的True36
474研究開発True35
172エネルギー需給構造True35
366廃炉True34
269化石燃料True32
338天然ガスTrue31
345安全性True31
666LPガスTrue29
385技術革新True28
313国際的True28
228使用済燃料True28
395新興国True27
153エネルギー供給True26
447燃料電池True26
264効率化True25
440温室効果ガスTrue25
208中長期的True24
524調整力True24
257分散型エネルギーシステムTrue24
169エネルギー選択True23
665FIT制度True23
160エネルギー消費True22
573電力システム改革True22
332多様化True22
173エネルギー需要True22
359導入拡大True21
336大規模True21
484競争力True21
471石油製品True21
187パリ協定True21
165エネルギー転換True20
157エネルギー安全保障True20
177サプライチェーンTrue20
225低炭素化True20
159エネルギー政策True20
499総合的True20
430活性化True19
595高度化True19
389排出量True19
244具体的True19
383戦略的True18
255分散型True18
401最終処分True17
152エネルギーミックスTrue17
155エネルギー分野True17
164エネルギー産業True17
230供給構造True17
327基本計画True16
278原子力発電所True16
369強靱化True16
465省エネ法True16
567長期的True16
592高効率True15
367建築物True15
508自由化True15
456発電コストTrue15
176コスト低減True14
265効率性True14
224低炭素True14
445災害時True14
185バイオマスTrue14
270化石資源True14
528資源国True14
495継続的True14
492経済性True14
324地球温暖化対策True14
505脱炭素化エネルギーシステムTrue14
312国際展開True14
203世界全体True13
243具体化True13
569関係者True13
241先進国True13
386抜本的True13
388排出削減True13
274原子力事業者True13
263効果的True13
150エネルギーシステムTrue13
444火力発電True13
449環境整備True13
171エネルギー需給True12
232依存度True12
158エネルギー情勢True12
510自給率True12
397方向性True12
229供給体制True12
586風力発電True12
182トップランナー制度True12
408東日本大震災True12
337大量導入True12
292各エネルギー源True12
566鉱物資源True11
247再処理True11
170エネルギー関連True11
396新規参入True11
398日米True11
493経済成長True11
470石油産業True11
393放射性廃棄物True11
582需要量True11
523課題解決True11
463相手国True11
387持続可能True11
457発電効率True11
267包括的True10
557運輸部門True10
565金属鉱物True10
277原子力発電True10
321地熱発電True10
308国民生活True10
574電気料金True10
319地政学的リスクTrue10
482立地地域True10
441温室効果ガス排出True10
509自立化True10
591高レベル放射性廃棄物True10
202不確実性True10
585顕在化True10
530資源開発True10
576電源構成True10
489系統制約True10
584革新的True10
469石油化学True9
473石炭火力発電True9
333多角化True9
459発電設備True9
496緊急時True9
506自主開発True9
450環境負荷True9
405本格化True9
350安定性True9
402有効利用True9
403有効活用True9
349安定化True9
339太陽光発電True9
411柔軟性True9
415核燃料サイクルTrue9
531賦存True9
306国家備蓄True9
189ベースロード電源True9
214事業環境True9
273危機時True9
259利活用True9
564野心的True9
572電力システムTrue9
204世界的True9
498総合エネルギー企業True9
309国民負担True9
578需給調整True9
234信頼性True9
311国際協力True9
223低コスト化True9
222低コストTrue8
211主要国True8
526貯蔵施設True8
210主力電源化True8
412核セキュリティTrue8
423気候変動True8
316国際連系線True8
494経済的True8
479科学的レビューメカニズムTrue8
476社会的True8
154エネルギー供給構造True8
468石油コンビナートTrue8
462相対的True8
453産油国True8
180デジタル化True8
448環境変化True8
514製油所True8
437消費者True8
191ロードマップTrue8
392支援策True8
251再稼働True8
342委員会True8
536送配電ネットワークTrue8
379情勢変化True8
279原子力規制委員会True8
538送電網True8
315国際競争力True8
534輸送システムTrue8
483立地自治体True7
179システム改革True7
186バイオ燃料True7
515複線シナリオTrue7
570関係自治体True7
478科学的True7
464省エネルギー対策True7
161エネルギー消費効率True7
174ガスシステム改革True7
537送配電網True7
254分散化True7
501脆弱性True7
314国際社会True7
380情報共有True7
356実用化True7
220人材育成True7
248再構築True7
231供給網True7
246円滑化True7
260制度改革True7
593高効率化True7
364廃棄物True7
357家庭用True7
305国内需要True7
535送配電True7
424水素ステーションTrue7
365廃止措置True7
542連系True7
568関係省庁True6
579需要サイドTrue6
527貯蔵能力True6
529資源外交True6
571関係閣僚会議True6
580需要動向True6
540途上国True6
664CO2削減True6
563重要性True6
507自家消費True6
221企業群True6
184ネットワークコストTrue6
200不安定化True6
207中下流True6
212予見可能性True6
235信頼関係True6
239元売True6
253出力変動True6
323地球温暖化問題True6
276原子力損害賠償True6
280原油価格True6
282原発依存度True6
283収益力True6
294合理的True6
297商用化True6
178シェール革命True6
156エネルギー協力関係True6
151エネルギーマネジメントTrue6
149インフラ輸出True6
307国民各層True6
358将来世代True6
455用燃料True6
418機動的True6
368式洋上True6
420次世代自動車True6
422民間企業True6
362年度比True6
427汚染水対策True6
446熱電True6
451産業活動True6
360小売全面自由化True6
452産業界True6
381情報提供True6
400最優先True6
458発電所True6
490系統増強True6
346安全性向上True6

計263語が複合語として抽出されました。

積極的、国際的など一般的な言葉も含まれていますが、再生可能エネルギー、脱炭素化、FIT制度、エネルギー安全保障、シェール革命、自家消費などエネルギー用語(新語?)と言えそうな言葉が多く見つかりました。

参考:
資源エネルギー庁:第5次エネルギー基本計画 http://www.enecho.meti.go.jp/category/others/basic_plan/pdf/180703.pdf
gensim Phrase
https://radimrehurek.com/gensim/models/phrases.html
gensim Phrase
https://radimrehurek.com/gensim/models/phrases.html
コード7区:gensim の Phrases の使い方。頻出する単語ペアを検出-python
http://ailaby.com/phrases/
コード7区:ツイートからユーザ辞書(MeCab や Janome 用)をpython で作ってみる http://ailaby.com/tweet_dict/
Janomeで形態素解析をやってみる。
http://eneprog.blogspot.com/2018/06/janomepython.html
janome Analayzerで複合語(複合名詞)を考慮して形態素解析を行う。
http://eneprog.blogspot.com/2018/07/janome-analayzerpython.html
gensim Phrasesで新語・複合語を探す(python、自然言語処理、機械学習)
https://eneprog.blogspot.com/2018/07/gensim-phrasespython.html
エネルギー基本計画から新語・複合語を探す。その1
https://eneprog.blogspot.com/2018/07/1-pythongensimphrasesjanome.html
//SyntaxHighlighter CDNより https://cdnjs.com/libraries/SyntaxHighlighter // 対応言語