Pythonで動く形態素解析ツール「nagisa」を使ってみた
はじめに
PyCon2018でポスター展示があったらしく、フォロワーさんの投稿で存在を知りました。
形態素解析ライブラリ「nagisa」のポスター
— nadare (@Py2K4) September 18, 2018
pip一つでインストールできる手軽さと
一単語として認識したい単語を簡単に追加できる便利さがあって
mecabより小回りの効く分析ツールって感じ
後で試したい #PyConJP pic.twitter.com/3c9zMQw8Nq
使ってみた
インストールはこれだけ。
pip install nagisa
簡単に形態素解析ができます。
>>> import nagisa [dynet] random seed: 1234 [dynet] allocating memory: 32MB [dynet] memory allocation done. >>> text = 'pythonで手軽に使えるツールです' >>> words = nagisa.tagging(text) >>> print(words) python/名詞 で/助詞 手軽/形状詞 に/助動詞 使える/動詞 ツール/名詞 です/助動詞 >>> print(words.words) ['python', 'で', '手軽', 'に', '使える', 'ツール', 'です'] >>> print(words.postags) ['名詞', '助詞', '形状詞', '助動詞', '動詞', '名詞', '助動詞']
nagisaの利点
文字単位の双方向LSTMを採用しており、URLや顔文字に頑健
>>> text = 'ブログのURLはhttps://upura.hatenablog.com/です' >>> words = nagisa.tagging(text) >>> print(words.words) ['ブログ', 'の', 'URL', 'は', 'https://upura.hatenablog.com/', 'です']
ちなみに、MeCabの MeCab.Tagger("-Owakati") を使うと、URLの中身がバラバラに分割されてしまいます。
>>> import MeCab >>> t = MeCab.Tagger("-Owakati") >>> result = t.parse(text) >>> print(result) ブログ の URL は https :// upura . hatenablog . com / です
単語分割の方法を調整できる
辞書にない固有名詞は、形態素解析ツールを使うと一般に過度に分割されます。
>>> text = '日本経済新聞を読んでいます' >>> words = nagisa.tagging(text) >>> print(words.words) ['日本', '経済', '新聞', 'を', '読ん', 'で', 'い', 'ます']
この時の辞書の登録方法もお手軽です。
>>> new_tagger = nagisa.Tagger(single_word_list = ['日本経済新聞']) >>> words = new_tagger.tagging(text) >>> print(words.words) ['日本経済新聞', 'を', '読ん', 'で', 'い', 'ます']
nagisaの課題
上記の資料によると、解析速度に課題があるとのことです。
おわりに
インストールが簡単で手軽に使えるので、速度を必要としない解析の際には便利だと思いました。
ランダムフォレストなど木系のアンサンブルモデルの解釈性を高める「Feature Tweaking」
はじめに
今回は、ランダムフォレストなど木系のアンサンブルモデルの解釈性を高める「Feature Tweaking」について紹介します。Pythonによる実装や使い方をGitHubにて公開しています。
手法の概要
機械学習アルゴリズムは世間一般で「ブラックボックス」だと評されますが、解釈性に関する研究も盛んになっている印象があります。今回紹介する「Feature Tweaking」はKDDという著名な国際会議に2017年に採択された論文で提唱された手法で、著者はYahoo!とFacebookに所属しています。
Tweakingは日本語で「微調整」の意です。「Feature Tweaking」は、木系のアンサンブルモデルの予測結果を変える方向に、入力を微調整します。「入力の中のどの変数をどう改善すれば良いかが分かる」といった意味で、解釈性が高まるといった具合です。
著者による紹介動画
日本語文献
今回の実装・記事執筆に当たって、下記2つの日本語の資料・記事を参照しました。
www.slideshare.net
setten-qb.hatenablog.com
特に後者の記事では既にPythonによる実装が公開されており、非常に参考になりました。上記で公開した私のGitHubは、こちらの記事に多少の修正と説明を加えたものになります。実装内容の理論的な概要については、こちらの記事をご参照ください。
I fixed some codes and added some explanations:
Quoted from featureTweakPy/README.md
「featureTweakPy」の使い方
今回、GitHubでは以下のような形で関数を読み込めるような形式にしました。
from featureTweakPy import feature_tweaking
以降、具体的な使い方を流れに沿って紹介します。
Download
git clone して、当該フォルダに移動します。上記で示したパッケージのインストールが必要な場合は適宜 pip install などをお願いします。
git clone git@github.com:upura/featureTweakPy.git cd featureTweakPy
Package import
最初に、必要なパッケージをインポートします。今回は木系のアンサンブルモデルとしてランダムフォレストを、データセットとしては有名なアヤメを利用します。
import numpy as np from sklearn import datasets from sklearn.ensemble import RandomForestClassifier from featureTweakPy import feature_tweaking iris = datasets.load_iris() x_arr = iris['data'] y_arr = iris['target']
Random Forest Prediction
「Feature Tweaking」は木系のアンサンブルモデルの予測結果を微調整する手法なので、まずは普通にモデルを学習させておく必要があります。
rfc = RandomForestClassifier() rfc.fit(x_arr, y_arr)
Using function()
まずはハイパーパラメータの設定です。
Hyper Parameters Setting
アヤメのデータセットは3種類のラベルがあり、今回はそのうち2の付いたラベルに変化する方向に微調整させたいと思います。
class_labels = [0, 1, 2] aim_label = 2 epsilon = 0.1
Cost Function Setting
この手法では最も「コスト」が小さいような微調整方法を探索するので、何を「コスト」とするか定義する必要があります。コスト関数として今回は、単純にユークリッド距離を採用しました。他にもコサイン距離などが想定できます。
def cost_func(a, b): return np.linalg.norm(a-b)
Sample Data for Demonstration
いよいよ feature_tweaking() 関数を使います。
x = x_arr[0]
x
array([5.1, 3.5, 1.4, 0.2])
x_new = feature_tweaking(rfc, x, class_labels, aim_label, epsilon, cost_func) x_new
array([5.1 , 2.9999999 , 4.75000038, 0.90000001])
微調整された x_new を元々の x と比べると、第一成分では変更がなく、それ以外の要素では値が変わっていると分かります。この方向に微調整すると定義した枠組みの中で最適なコストでランダムフォレストの予測結果を目的のラベル方向に変化させられるということです。
ここで、著者による紹介動画でも言及されていますが、今回の手法は「あくまでアンサンブルモデルの中の個々の決定木の結果を改善している」に過ぎず、必ずしも「ランダムフォレストとしての予測結果が目的のラベルに変わる」というわけではないことには注意が必要です。
おわりに
ランダムフォレストをはじめとした木系のアンサンブルモデルは、手軽に高精度な予測結果を得られることから、特にテーブルデータを扱う際に頻繁に利用されています。
活躍の場はKaggleだけでなく広範に渡りつつあるかと思いますが、特にビジネスにおいては単に高精度を出すだけではなく、予測から得られた知見をどのように活用するかも同様に重要です。この手法は少し間接的な気もしますが、木系のアンサンブルモデルの解釈性を高められるという意味で、大きな価値があると思いました。
2週間のシアトル出張に行きます
明日14日から27日までの2週間、会社の都合でシアトルに出張します。弊社のR&D部署が主導する出張で、米国の最新技術動向の視察として、2週間にわたって技術系のイベント参加や現地企業訪問などを実施予定です。
私は昨年の10月に入社したので、期せずして帰国時には(ほぼ)1年在籍したことになります。
もちろん若干の不安もある中での入社でしたが、1年経過した段階で「こういう案件で出張に行かせてもらえるくらいには自己発信できた」ことを素直に嬉しく思います。まだまだ力不足な点ばかりですが、今後も社内外で成果を出し続けられるよう精進します。
まずはこの2週間、英語力や技術力で苦戦する点もあるかと思いますが、多くを糧にして社に還元できるよう頑張っていきたいです。
Udemy講座「手を動かしながら2週間で学ぶAWS基本から応用まで」を修了したので感想など
Udemyの講座「手を動かしながら2週間で学ぶAWS基本から応用まで」を修了した*1ので、受講の動機や感想などをまとめます。
講座の概要
本講座は、オンライン学習プラットフォームの「Udemy」で先日*2にリリースされた講座です。タイトルの通りAWSを基礎から応用まで体系的に学ぶ内容となっています。
詳細は講師による下記ブログをご参照ください。
受講の動機
筆者の会社での主の業務はデータアナリストですが、合わせてAmazon API Gateway + AWS Lambdaで構築したサーバーレスアーキテクチャのエンジニアとしての業務も担当しています。
正直なところ、後者の仕事に関わるまではAWSをほとんど触ったことがない状況でした。会社での研修や開発チームの猛者の方々のサポートを受けながら業務に取り組んでいますが、業務に直結する知見だけではなく体系的にAWSを学ぶ必要があると感じていました。
そんな折に上記のブログを拝見し、1200円のクーポンも発行されていたので、体系的に学ぶ良い契機だと思い購入に至った次第です。
受講の感想
全講座を閲覧し終わっての感想は多岐にわたりますが、ここでは良かった点を3つと気になった点1つを挙げたいと思います。
良かった点
AWSへの「怖さ」が拭える
筆者の場合、最初にAWSのコンソールを触ったときの感想は「なんかゴチャゴチャしてて何をイジれば良いか分からない」「既存の設定を壊してしまわないだろうか」「この操作では課金が発生しないだろうか」というものでした。これらはAWSへの無知から生じるもので、AWSに対する名状しがたい「怖さ」があったように思います。
本講座は最初に自分自身のAWSアカウントを作成するところから始め、課金アラートの設定も実施します。ほぼ全ての画面操作を動画で確認できるので初心者でも追従でき、個人のアカウントなので好き勝手に触ることができ、課金アラートがあるので安心して講座にない設定も試すことができます。
タイトル通り、実際に「手を動かしながら」学ぶことで、AWSへの「怖さ」をある程度払拭できたと思いました。
各サービスの立ち位置が分かる
AWSを学ぶ上での障壁の一つに、サービスの豊富さがあると思います。「たくさんサービスがあるけれど、何から勉強すれば良いのだろうか」「何がどういう役目を果たしているのだろうか」と感じていました。業務で触れたサービスに関しては当然理解が深まっていくのですが、AWS全体の中で個々のサービスがどういう位置付けなのかは漠然としか把握できない状況でした。
本講座では簡単なブログサービスを作っていく流れの中で、全体の中で優先的に学ぶべきサービスは何なのか確認できます。本講座で登場するのは講師が考えた「使われるシーンが多いであろうサービス」で、2018年現在においてAWS全体を理解する上で重要な順番になっているということです。
さらに本講座の中で新しく登場するAWSの各サービスについて、これまで登場したサービスとの関係性や位置付けが丁寧に説明されている印象を受けました。例えば、最初はAmazon EC2ベースで作成し、後にマネージドサービスに置き換えていくなど、各サービスの繋がりがつかみやすい構成になっていると感じました。
気になった点
ここまで、講師の回し者のような内容になっている気がしたので、気になった点についても少し言及しておきます。
Linux操作
「受講における必要条件」として「基本的な Linux の操作ができること(ls, cp, mv といったコマンド、vim 基本操作)」と記載されています。実際、本講座の中でLinuxの操作自体の解説はほとんどありませんでした。
一つの動画を多人数が閲覧するという仕様上、ある水準の知識を仮定するのは当然のことだと思います。とはいえ、もう少しLinux操作などが分からない人に向けて、せめて「検索ワード」の提供があると良いのではないかと思いました。
例えばセクション: 3「Day2: EC2を使ってサーバを立てる」において、EC2インスタンスにSSH接続しミドルウェアを導入するパートがあります。ここで下記のようにパーミッション設定を変更する流れがあるのですが、パーミッションの権限の表現方法が分かっていない人や慣れていない人には、口頭での説明が不十分なように感じました。
~/project/udemy ❯ ll total 8 -rw-r--r--@ 1 USERNAME staff 1.7K 9 4 20:32 udemy.pem ~/project/udemy ❯ chmod 400 udemy.pem ~/project/udemy ❯ ll total 8 -r--------@ 1 USERNAME staff 1.7K 9 4 20:32 udemy.pem
もちろん本講座の大きな目的から考えると本筋ではないのですが、口頭で「この辺りの表現が分からない場合は、『○○○』で調べてみてください」などと補足があると、より親切なのではないかと思いました。
筆者の進め方
最後に、本講座を筆者がどのように進めたかを述べておきます。
筆者は今回、講師がブログで「おすすめの受講方法」として提案している①まずは講座を聞く②動画を流しながら手を動かすーーという2回聴講方式を実施しました。
①については、夜寝る前に横になりながらタブレットに入れたUdemyアプリで閲覧しました。音声や滑舌が明瞭なので、ほとんど2倍速で閲覧していましたが問題ありませんでした。十分に理解できていないと感じた部分は、動画コンテンツの強みを活かして何回か繰り返し確認しました。
②については、退社後の18〜21時など比較的集中してパソコンに向かえる時間帯に取り組んでいました。PC本体に動画を流し、液晶モニタではブラウザやターミナルを開いて操作していました。こちらも操作に手間取った場合には動画を巻き戻せるのがありがたかったです。
1日1セクション全14日想定のコンテンツでしたが、筆者の場合はある程度集中的に取り組みたかったこともあり、半分の7日間で修了することになりました。
Adversarial Validationのメモ
Adversarial Validationとは
いつ使う?
- TrainデータとTestデータの分布が異なる場合
- → Trainデータから適切にValidationデータを作成するのが難しい
- → Kaggleの場合、LocalCVとLBのスコアが一致しないなどの問題が生じる
解決策
1. 「TrainデータかTestデータかを判定する分類器」を作る
2. Trainデータを、Testデータに似ている順にソートする
3. 似ている順に、Trainデータからデータを抽出し、Validationデータとする
応用例 "stochastic adversarial blending"
KaggleのHome Credit Default Riskコンペの2nd place solutionに使われた手法。
2nd place solution ( team ikiri_DS ) | Kaggle
The process is as follows,
- Sample data with a sampling ratio by using adversarial validation as a sampling weight.
- Optimize the weights with train prediction.
- Iterate 1~2 process to get converged weights.
皆さん、聞きなれないお言葉ということで、質問を受けることがありますので、簡単にですが、この場を借りてご説明させていただきます。
— HoxoMaxwell (@Maxwell_110) 2018年9月4日
kaggle ですと、train data と test data が与えられているのが通常でして、test data はさらに、public と private にある割合で分割されています。(続
【論文メモ】29組のデータアナリストに同じデータセットと同じ質問を与えても、分析結果がバラバラだったという研究
どんなもの?
29グループ(計61人)のデータアナリストに、同じデータセットと同じ質問を与えたときの分析アプローチのバラツキを分析。質問は「サッカーの主審は、肌の白い選手に比べて肌の黒い選手にレッドカードを与える可能性が高いですか?」。
分析アプローチはチーム間で大きく異なり、オッズ比で0.89から2.93の範囲だった(中央値は1.31)。20チーム(69%)が統計的に有意な正の結果を示した一方で、9チーム(31%)は有意な関係を示さなかった。
これらの知見は、たとえ真摯な専門家集団であっても、複雑なデータの分析結果に主観的な要素が入り込むのは避け難いことを示唆している。 分析を透明化する手段として、同じ研究課題を同時に調査するために多数の研究チームを採用する「クラウドソーシング」が有用であると提言している。
論文リンク
- http://journals.sagepub.com/doi/10.1177/2515245917747646
- https://www.researchgate.net/publication/320041452_Many_analysts_one_dataset_Making_transparent_how_variations_in_analytical_choices_affect_results
著者/所属機関
R. Silberzahn et.al
媒体
SAGE Journals
投稿日付
First Published August 23, 2018
所感
単純にバラツキの大きさに驚き。自分も同じデータセットで追実験して、オッズがどういう結果になるか確認したい。
データアナリストとして真摯に受け止めて熟読すべきは、論文の結論に含まれた考察部分。どうやっても完全に「客観的」はあり得ないので、その中でどうやって意思決定に値する分析をしていくかを考えさせられる論文だった。
阪神タイガース、今季初の八回から逆転勝利 昨日までの「0勝50敗」は他チームと比べ酷い数字か検証する
はじめに
本日朝、サンスポに次の記事が掲載されました。阪神タイガースは今季、「七回終了時にリードを許している試合で0勝50敗」という少し衝撃的なデータです。
この記事に刺激されたか否かは分かりませんが、阪神は本日の試合で八回表に一挙6得点。今季初の八回からの逆転勝利を収めました。
今回は「七回終了時にリードを許している試合で0勝50敗」という数字が他チームと比べてどれほど突出している数字なのか(はたまた特に驚くべき数字ではないのか)、他チームも含めたデータ分析を通じて検証してみたいと思います。
データの取得
どこかに良さげなデータベースがあるかと思い10分程度探しましたが見つからなかったので、Pythonを用いて自分で収集しました。
import pandas as pd from tqdm import tqdm result = [] match_id = [] for i in tqdm(range(330, 826)): for j in range(6): url = 'https://baseball.yahoo.co.jp/npb/game/20180' + str(i) + '0' + str(j+1)+ '/top' try: fetched_dataframes = pd.io.html.read_html(url) result.append(fetched_dataframes[0]) match_id.append('20180' + str(i)) except: pass
データの前処理
最初に、分析に必要な情報をデータから抽出します。今回は、resultというリストにpandas.DataFrame形式でスコアボードが格納されています。
result[0]
このデータから「七回終了時にリードを許している試合か否か」の情報を取り出します。具体的な処理については、雑なpandasの処理をしてしまったので割愛しますが、興味のある方はGitHubのipynbをご参照ください。
前処理を終えた後のDataFrameの最初の10行を、下記に示します。上から2行ずつ区切りの情報になっており、例えば最初の2行は「阪神ー巨人戦で、阪神も巨人も八回から逆転勝利しなかった(False)」という意味です。9, 10行目は「楽天ーロッテ戦で、楽天は八回から逆転勝利した(True)」ことを表しています。
データの分析
本題の分析に入る前に、きちんと全データが抽出できているかを確認しておきます。
データをチーム名でまとめ上げて(groupby)、合計を出力した結果を、実際の試合数を比較しました。オールスター戦2試合も含めて、昨日(2018年8月25日)までの全試合の情報がデータに含まれていると確認できました。
オリックス 114 ソフトバンク 108 ヤクルト 109 ロッテ 109 中日 115 全セ 2 全パ 2 巨人 117 広島 110 日本ハム 112 楽天 112 西武 111 阪神 106 DeNA 11
そしていよいよ、「七回終了時にリードを許していた試合」に関する情報を出してみます。ここではオールスター戦の情報は省きました。
冒頭のサンスポの記事通り、阪神は「0勝50敗」でした。
「割合」を見ると、巨人が「1勝48敗」でワースト2位。本日阪神が1勝目を挙げたので、本日時点では阪神と並んでワーストになりました。
個人的に、広島は終盤の逆転が多いイメージがありましたが、3試合のみで割合はワースト4位でした。しかし、そもそも「七回終了時にリードを許していた試合数」が38と、他チームと比べて圧倒的に少ないです。序盤から優位に試合を進めている様子がうかがえます。
DeNAは「七回終了時にリードを許していた試合数」が64で12チーム中最多。広島の約1.7倍もありました。
楽天は55試合中8試合で八回から逆転勝利に成功。順位ではパ・リーグ最下位に沈んでいますが、逆転した試合数・割合ともに12チーム中1位になりました。