2017年11月8日水曜日

Imbalanced Data

偏りの極端なデータセットを扱わざるを得ないという状況は頻繁にあるようで、対応策も研究されているようです。

H2Oの場合、FAQ に掲載されていました。
http://docs.h2o.ai/h2o/latest-stable/h2o-docs/data-science/deep-learning.html
・How does class balancing work?
The max_after_balance_size parameter defines the maximum size of the over-sampled dataset. For example, if max_after_balance_size = 3, the over-sampled dataset will not be greater than three times the size of the original dataset.
For example, if you have five classes with priors of 90%, 2.5%, 2.5%, and 2.5% (out of a total of one million rows) and you oversample to obtain a class balance using balance_classes = T, the result is all four minor classes are oversampled by forty times and the total dataset will be 4.5 times as large as the original dataset (900,000 rows of each class). If max_after_balance_size = 3, all five balance classes are reduced by 3/5 resulting in 600,000 rows each (three million total).
To specify the per-class over- or under-sampling factors, use class_sampling_factors. In the previous example, the default behavior with balance_classes is equivalent to c(1,40,40,40,40), while when max_after_balance\size = 3, the results would be c(3/5,40*3/5,40*3/5,40*3/5).

H2O の FLOW では、そのオプションを見つけらませんでした。R か Python に移行しないといけない?と思いつつ、CSV の段階でマイナーデータの数を増やしてみました。単純に、コピペで崩壊したデータを非崩壊と同じ数まで増やすだけ。学習・検証させた結果は以下の通り。


うーん、ダメですね。過学習というべきなのでしょうか?
一見、高精度の判別器に見えますが、繰り返し入力された異常パターンを覚えすぎ、汎用性を喪失している可能性大。こうなると、既知の異常パターンにしか対応できなくなります。異常検出型でなく、正常から外れた場合に異常と判断する判別器に育てる方針の方が有利でしょう。

まさに、そのような方法も検討されているようです。
https://www.gputechconf.jp/assets/files/1029.pdf
AutoEncoder:固定長、または正規化可能な可変長データで、正常が圧倒的に多く、異常が少ない場合。正常なパター ンのみを学習し、正常なパターンを再現可能な特徴量を抽出する。異常なパターンが入力された場合、異常パターンの特徴量 は学習していないため、異常パターンを再現することができない。再現されたデータの類似度で異常判定を行う。
deep なのか shallow なのか分かりません。が、H2O でも deep learning のオプションに「Auto-Encoder」がありました。R や Python のコードも googling に出てきます。
が、使い方がわかりません。いえ、使っても、良い答えになりません。使い方を見極めていないため、宝の持ち腐れ、猫に小判状態です。うーん、どこにヒントがあるのでしょう?

2017年11月7日火曜日

Metrics in H2O

H2O で得られる metrics はコチラ。
http://docs.h2o.ai/h2o/latest-stable/h2o-py/docs/metrics.html

出力される confusion matrix のTPが右下なので注意。ここを高めるは F1、F2 に注視。F1 score などは医療統計でなく機械学習分野で引っ掛かることが多いように感じます。こちらの分野の言葉なのかもしれません。

F値の具体的な意味については、案外、説明がない。この程度↓
https://qiita.com/TaskeHAMANO/items/74cf2b6170066adee13f
https://abicky.net/2010/11/21/002415/

2017年11月5日日曜日

Medical Statistics + Deep Learning + Landslide = ?

ROC curveやcutoff valueで検索すると、医療統計学に関する話題が多く引っ掛かります(というかほぼそれ)。確かに、検査の値で陽性・陰性を判定するには、どこかで線引きが必要になるケースが多いというのは容易に想像できます。

まずは、そちらの分野の情報を仕入れましょう、ということで、図書館で以下の本を借りてきました。

千葉康敬「「医療統計力」を鍛える!」2015.4
奥田千恵子「たったこれだけ!医療統計学 改訂第2版」2015.4

前者は素人向けの図書で、概要の理解に非常に役立ちました。昨日のように NG が非常に少ない場合のデータセットを扱う際の留意点にも触れられており、ありがたい本でした。
後者では用語の重要度について「10%の論文に出てくるだけであるが、スクリーニングの研究論文を読むには、実用的な知識を身につけている必要がある」と述べられています。基礎力なのでしょう。

では、整理。まず、用語の定義。
おおざっぱには下表のようになります(率とか度とか、 value とか rate の有無とか細かいところがたくさん気になりますが、ひとまず置いておきます)。

 
test results
Machine Learning, AI prediction
True condition
TP
FN
感度:Sensitivity
 = TP / (TP+FN)
再現率
Recall
FP
TN
特異度:Pecificity
 = TN / (TN+PF)
陽性的中度 :PPV
Positive Predictive Value
 = TP / (TP+FP)
陰性的中度 :NPV
Negative Predictive Value
 = TN / (TN+FN)
正答率:Accuracy Rate
 = (TP+TN) / (TP+TN+FP+FN)
F値 :F−measure
=2RecallPrecision/(Recall+Precision)
適合率 precision

人命にかかわる判定では、感度を高める必要があるのでしょう。Wikipediaでは狂牛病の判定で感度を高めたと書かれています。
たとえば日本の狂牛病の全数検査では、まず最初に、ELISA法でスクリーニング検査を行うが、これは安価な検査ながら感度を非常に高め、陽性の見逃しの可能性を極力減らし、特異度を犠牲にした検査である(すなわち偽陽性が出やすい)

次にROC 曲線やカットオフ値。
これは googling で理解できました。前者の図書にもわかりやすく解説してあります。
このあたりを参考に。


これまでは、n個の試験についてROC 曲線をn個書き出し比較し、一番AUCの良いものを採用してカットオフ値を設定したり、各々のカットオフ値を組み合わせて判定していたようです。

comparison
test result 1 > ROC 1 > AUC 1 
test result 2 > ROC 2 > AUC 2 > cutoff value 2 adopted
test result 3 > ROC 3 > AUC 3 
test result n > ROC n > AUC n
Or
combination
test result 1 > ROC 1 ┓
test result 2 > ROC 2 ┣ cutoff value 1 & 2 & 3…&n
test result 3 > ROC 3 ┃ 
test result n > ROC n ┛

人が判断するにはせいぜい5~10個程度の属性組み合わせ、数十個のデータ数までしか対応できないでしょうね。今回のように千を越えるデータ数、30以上の次元を縮約するような取り扱いを求められた場合、人では太刀打ちできません。ましてや数千万単位となると、手を付ける気にもならないでしょう。が、今回のような機械学習(統計といった方が良いのか?)では数千万のビッグデータにも対応できます(将来的にはAIになるでしょう)。
昨日の崩壊・非崩壊の判定は deep learning を使いましたので以下のようになります。

Machine Learning, AI
test result 1 ━━┓
test result 2 ━━┫ 
test result 3 ━━╋ deep learning prediction > ROC > cutoff value
test result 100    ┫
test result 1000  ┫
test result n ━━┛

既に医療分野ではお試し済みかもしれませんね。IBM の Watson が「二次性白血病」といった病名を抽出したのは既に1年以上前ですから、さらに進んでいるでしょう。残念ながら土木分野ではこれからです。

斜面の崩壊・非崩壊の予測も人命にかかわるので、単に正答率を上げるのではなく、感度を上げるようにしないといけません。それに伴う避難指示の空振りに慣れないように PPV も高めないといけないでしょう。機械学習で崩壊・非崩壊を扱う場合はそのような点に意識してパラメーターを調整する必要があるということでしょうね。

ま、いずれにしても、崩壊・非崩壊のスクリーニングとして機械学習(deep learning)を利用する利点が見えてきました。もう少し、詰めましょう。


ROC 曲線

H2O で 崩壊/非崩壊 の2値分類を学習・予測させてみました。

正答率はそれなりに上がるのですが、それに伴い NG(崩壊) を OK(非崩壊) とする「誤診」が増えます。データの種類として NG が圧倒的に少ないことも大きく影響しているでしょう。

H2O での検証結果を見て驚いたのが、先の土軟硬区分と表示が変わっていること。2値分類だとこのようなグラフ↓も書いてくれるのですね。賢い。
ROC曲線と呼ぶようです。知りませんでした。統計の知識が足りない。うーん。



調べてみると、医学分野では使われているそうですね。
https://www.jmp.com/ja_jp/medical-statistics/column/non-series/roc-curve.html
医学論文や学会のポスター発表で、ROC曲線とカットオフ値を記載しているものをよく見かけるかと思います。
実際ROC曲線は、診断法がどれぐらい有用なのかを知るときに使われ、曲線下の面積(AUC)によって定量化されます。
さらに、この値以上は”陽性”だと診断する閾値をどのように設定するかによって感度と特異度は変化していくので、陽性と陰性を分ける最適なカットオフ値を見つけることが重要になってきます。

なるほど、統計の基礎と、医学分野での一般的な利用法を学べば、前に進めそうですね。H2O に課題と解決への道筋を与えてもらったような気がします。


2017年11月3日金曜日

深層学習で土軟硬区分

ここ1年で、機械学習・深層学習の環境や認知度がかなり向上したように感じます。

土木分野でも、導入・開発を進められている企業があります。雑誌やNHKでの特集も見ましたが、「人口減少、働き手不足といった将来のリスクに今から備える」と考えられている会社もあるようですね(良い会社だと思います)。

この3連休はゆっくりできるので、この間に最近の動向を追っておきましょう、とweb を見ていると、このようなものがありました。

H2O
https://www.h2o.ai/

早速、DL してみました。
以前、地下水位の時系列予測を deep learning で実施した際には、Python の コードを修正しながら利用しました。が、これ、コードを組む必要がありません。コマンドプロンプトから jar ファイルをロードさせておけば、あとは WebUI で作業できます。(Ver.3.14.0.7ですので、数年前からあったのでしょうね)。
しかも、R や Python でも使えるようです(今回は試用せず)。Rでラフセットかけて、その結果(重要属性のみ)を H2O に投げる、なんてこともインタラクティブにできそうです。

今回の題材は、「柱状図の土砂・軟岩・中硬岩区分」。
使用する属性はコアの「硬軟・形状・割れ目・風化・変質」。いずれも基準書でカテゴライズされており、利用しやすい指標です。相関性も土軟硬区分と高いのは明らかで、(ラフセットで事前に選別しなくても)良い結果が得られると思い選定しました。今回は泥質岩のみで実施しましたが、多くの地質に対応させるなら、地質を属性に加えて学習させれば良いでしょう。(今回は単一地質かつ5属性ですので、わざわざ deep learning を使わなくても良いのですが。)

まずは柱状図からデータを集めて CSV に整理し、それを H2O に読ませます。
あとは、WebUI で指示のあるまま進めるだけでした。以前の時系列予測の経験が役に立ち、マニュアルを見なくても入力の流れを理解できましたし、入力する項目も迷いませんでした(手を動かしていて良かった)。
H2O は多くのアルゴリズムを実装していましたが、今回は deep learning を選択。

結果は上々。正答率86%
MR:中硬岩、SR1:軟岩I、SR2:軟岩II、WS:土砂(風化土)

TRAINING METRICS - CONFUSION MATRIX ROW LABELS: ACTUAL CLASS; COLUMN LABELS: PREDICTED CLASS
MR
SR1
SR2
WS
Error
Rate
MR
24
0
0
0
0
0 / 24
SR1
1
22
4
1
0.2143
6 / 28
SR2
5
1
44
0
0.1200
6 / 50
WS
0
0
0
45
0
0 / 45
Total
30
23
48
46
0.0816
12 / 147

VALIDATION METRICS - CONFUSION MATRIX ROW LABELS: ACTUAL CLASS; COLUMN LABELS: PREDICTED CLASS

MR
SR1
SR2
WS
Error
Rate
MR
6
0
1
0
0.1429
1 / 7
SR1
0
9
1
0
0.1000
1 / 10
SR2
2
0
5
0
0.2857
2 / 7
WS
0
1
0
12
0.0769
1 / 13
Total
8
10
7
12
0.1351
5 / 37



このような情報も参考に表示してくれます↓



これ、良い判別器が作れるでしょうね。部署全体で入力すれば、部署全体のナレッジが集結し、かつそれを反映した判別器が作れます。将来的には新人の良い教育材料になるでしょうし、現場での判別にも使えるでしょう。掘削現場での土軟硬区分は「音が必要」などと考えていましたが、「コア形状(長さ)」を「亀裂間隔」に読み替える等工夫すると、容易に適用できると思います(見る距離によって1:1ではないので補正は必要でしょうが)。
また、国交省さんは Kunijiban で大量のデータをお持ちですから、国交省標準の判別器が作れそうです(柱状図の質を判断する必要はあると思いますが)。あるいは、スクレイピング可能なら、各社独自に利用されるかもしれません。

いずれにしても、H2O のようなソフトは今後も改善・提供されると思われます。当分は環境も劇的に変わり続けるでしょうから、executives にとってはリスク管理が大変になるでしょう。
私も置いて行かれないよう、手を動かし続けなければなりませんね。


2017年11月2日木曜日

解決:VPNを張るとネットが切れる件(Windows10)

VPNを張るとインターネットが切れる件について。
Windows 8 を使い始めてからあきらめていた(最近は慣れていた)のですが、ひょっこり解決しました。

問題:
Windows 10 で「リモートネットワークでデフォルトゲートウェイを使用する」のチェックを外すと、インターネットにつながった状態でVPNを張れるのですが、リモートデスクトップが確立しません。

答え:コチラの方がわかりやすく解説されていました。
https://erirun.net/2012/01/windows-vpn-autoroute/
「VPNの向こうに別のネットワークセグメントがあったりするとそこにはアクセスできなくなります。そのセグメントへのルーティングがないからです。」
解決法:
「リモートネットワークでデフォルトゲートウェイを使用する」のチェックを外した状態で(デフォのゲートウェイを変えずに)VPNを張った後、アクセスしたいセグメントへの route を追加すること。

具体的な手順は上記HPに記載されています。リモート接続したいセグメントを PowerShell スクリプトに記載しておき、 VPNを張った時点でタスクスケジューラーから自動実行するといった流れ。

私の場合は VPN 接続を バッチファイルでまとめていたので、そこにPowerShell 起動を加えてみました。
https://phreeqc.blogspot.jp/2017/06/vpn-rd.html
が、管理者権限で実行させると UAC のダイアログが出て1手間増えることに。route add も同じなので、結局、上記のHPの方法を採用しました。
そのままではセグメントへのルーティング完了を待たずに RD 接続が始まってしまい、つながりませんでした。で、バッチファイルに 2秒の sleep 時間を確保。

TIMEOUT /T 2

これでOK。
リブートした後の初回起動時に2秒だと躓くことがありますが、当面はコチラで運用する予定。
1タッチでの VPN 接続~ RD ~ VPN 切断をネットにつなげたままでできるようになりました。


2017年11月1日水曜日

崩壊と違和感

先の台風で、複数の法面が崩壊。

その中には数年前に私が見た法面も含まれていました。吹付の亀裂は1か所だけで、他は正常だったのですが違和感があったのでよく覚えています。のり面のその部分が崩れたのではないか?と見てみるとビンゴ。まさにその部分が崩れていました。何か、気持ち悪い感じだったのでしっかり記憶に残っていた箇所でした。

別の法面ですが、先輩が事前に見ておられ、滑落するであろうブロックを決められていました。で、同様に崩壊したのですが、こちらもビンゴ。まさにそのブロックが落ちていたようです。

「気持ち悪い」とか「違和感がある」とか曖昧なのですが、数年内に落ちそうな箇所は感覚的にわかりやすいのかもしれません。形状と地質を見れば、人は判別できるのでしょう。説明は後付けなのかもしれません。
一方、次に崩壊する場所をなかなか抽出できないのも事実です。なにが違うのかな?と思います。素因は見やすいけど、誘因(豪雨時の水の流れ)は想像しにくいということでしょうか?

説明できないけど判別できる点は、ディープラーニングにもってこいです。ま、システムを構築・ブラッシュアップして実用化するまでには、まだ時間がかかるでしょう。
その間、もう少し、感覚を磨いておく必要があるでしょうね。システムに供する材料も集めておく必要があるでしょう。