2019年6月23日日曜日

データの理解

最近、データサイエンスの本質は「データを理解すること」にあるように思えてなりません。

機械学習がいくら優れていても、与えるデータの質が悪ければ、それなりの結果にしかなりません。質が悪ければ良いデータに加工して、または質の良いデータを加えて、良いデータのみを選別して、与えるデータを見極める。「前処理」「特徴量エンジニアリング」と呼ばれる過程です。データを解釈する感覚と、多くの処理手法を知り置く必要があります。

これ、地味に難しいですよね。
データを見て、分離性や相関性を見極め、機械学習に与える。Random Forest では予想通りの重要度を示すのですが、LightGBM では真逆の重要度として出てくることも。
最初に多くの機械学習手法にかけて、重要な特徴量を選別する方が良いのかもしれません。プロはどうされているのでしょう?

機械学習に限らないのですが、「データをよく見て理解する」というのは重要なのに難しい。機械学習では、それについても一部で自動化が進みつつあるようですが、まだまだ人の感覚・判断も重要でしょう。感覚を掴み、磨きたいですね。

2019年6月22日土曜日

Print Word & EXCEL Files

この時期に珍しく、後輩君が遅くまで頑張っていました。

どうも、複数のフォルダに分かれた大量の Word, EXCEL ファイルの印刷を命じられたようです。

これは機械の得意分野。機械にまかせるべき作業です。

方法はいくつかあるでしょう。
今回はテスト感覚で Pythonを選択。COM 等を使用したコードはネットに転がっていましたので、それを利用。

動かしてみると、意外と速い。
昔、EXCEL+VBA で同じようなマクロを組んだことがありましたが、それよりも速いように感じました。

10年後、Python が使い続けられているかは疑問です。が、今、何らかの言語+アルゴリズムを身に着けることは技術者にとって必須です(変化に柔軟に対応することは、それ以上に重要です)。
常に手を動かし、今も、将来も困らないようなレベルに身を置くことができるよう、行動しましょう。

2019年6月20日木曜日

再現期間、確率降水量の計算

カーネル法では、カーネル×重みを足し合わせて既知の値にフィッティングしました。

これは、予想される形状が複雑な場合に有効です。
では、予想される形状が単純な場合、一つのカーネルを調整するだけでフィッティングできるかもしれません。コレ、曲線近似、曲線回帰に属するようです。

数種類のカーネル関数で試行し、もっとも適合したものを選択する、というのは常套手段。例えば、コチラ↓。

国交省気象庁「確率降水量の推定方法」
https://www.data.jma.go.jp/cpdinfo/riskmap/cal_qt.html

(1) グンベル分布
(2) 一般化極値(GEV)分布
(3) 平方根指数型最大値分布
(4) 対数ピアソンⅢ型分布
(5) 対数正規分布

これらの関数を降雨量にあてはめ、もっともフィットしたものを選択する、というのが大まかな計算の流れ。
後半のSLSCというのが経験的というのは、今回初めて知りました。情けないことですが、ツール任せの部分であり、残差等で比較しているものと勘違いしていました。しっかり読まなくては。

実務で何度か計算していますが、回数は片手で足りるほど。上記の反省 & 理解を深めるために、前半の計算を追ってみました。使ったのは Python。

計算や図化は簡単だったのですが、水文統計ユーティリティーでの結果と差異が生じます。試算ではヒストグラムを作る時のビン数によりフィッティング結果が変わるのですが、ユーティリティーではどのビン数で計算したのかが不明(後のヒストグラム表示でビン数を変えても分布は変化しないので、内部である程度決めた値を使っているのかもしれません)。フィッティング後の係数も不明な点は、以前から疑問視していた通り。

また、確率紙についてもこれまで真剣に見ておらず、対数軸と誤認していました。反省。
計算を追う過程で先輩の古い(50年以上前の)教科書をお借りし、ようやく理解しました(Rには確率紙のライブラリがあったのですが、Python にはなかったので計算・図化しました)。
が、この図で経験的にフィットの良し悪しを判別する必要があるのでしょうか?
ヒストグラムを作った段階で何らかの最適化手法によるフィッティングをかけているので、残差の小さいカーネル関数を選択すれば良いのではないでしょうか?不都合があるのでしょうか?
確立紙プロットは確認程度でも良いですよね。確かに、50年以上前だと確率紙にプロットするしかなかったのかもしれません。が、今は容易に計算できます。

得られた知識はあったものの、新たな疑問も増えました。
解決するのは、まだ先のようです。

***********************************
20190626追記
河川砂防技術基準に以下の内容があります。
解析対象水文資料を用いて候補モデルの母数を求める際には、標本の大きさに応じて適切な推定法を用いるなどの手法があり、積率法、L 積率法、最尤法等の手法が用いられている。なお、小標本(標本サイズ<30)については、L 積率法がよく用いられている。 
なぜか Win + Anaconda が動かないので追認できませんが、おそらく、これですね。

***********************************
20190627追記
L積率法でパラメーターを固定すると、ユーティティーの値に近づきました。
ただ、先輩たちも昔からこの手の検算はされてきたようで「ユーティリティと答えが一致しない」というのは知られていたようです。いくつか理由が考えられるそうですが。
検算するなら、水理公式集が良さそうです。

2019年6月19日水曜日

カーネル法とニューラルネット

「カーネル密度推定」と「カーネル法」。言葉は似ていますが異なります。
\begin{align*}\hat{f}(x) = \sum_{i=1}^n w_i K(x_i,x)\end{align*}
なぜ重みwを付けたのか?
フィッテイングしたいからです。既知の値に。

この辺が分かりやすく、詳しいです。↓
https://qiita.com/wsuzume/items/09a59036c8944fd563ff

既知の値と計算値との残差+正則化項を最小にする重みを計算し、決定します。ニューラルネットに似ています。

ニューラルネットでカーネルに2次元のガウス関数を用いている例が身近にありますね。これです。
国土交通省河川局砂防部「国土交通省河川局砂防部と気象庁予報部の連携による土砂災害警戒避難基準雨量の設定手法(案)」平成17年6月
https://www.mlit.go.jp/river/shishin_guideline/sabo/dsk_tebiki_h1706.pdf

統計、避けては通れないようです。

2019年6月17日月曜日

カーネル密度推定(KDE)多次元

p次元のカーネル密度推定式
https://web.as.uky.edu/statistics/users/pbreheny/621/F10/notes/10-28.pdf
\begin{align*}\hat{f}(x) = \frac{1}{n} \sum_{i=1}^n\prod_{j=1}^p \frac{1}{h_j}K\bigg(\frac{x_j-X_{ij}}{h_j}\bigg)\end{align*}
Pythonだと、例えばこれだけ。便利。

sns.kdeplot(x, y, shade=True, shade_lowest=False)

2019年6月16日日曜日

カーネル密度推定(KDE)直感的理解

KDEの直感的な解釈です。
厳密でなくとも、概略イメージを先に持つことができると、後に数式がすっと頭に入りますし忘れ難いと思います。以下、個人的な解釈です。

「家の裏山が崩れた」時、ある観測値が0.5だったとします。

観測値0.5であれば、崩れる確率が高いと事後解釈できるかもしれません。が、0.4だとどうか?0.2だとどうか?わかりません。実は、1.0の方が崩壊しやすいのかもしれません。

ひとまずデータが集まるまでは、0.5周辺で崩壊確率がかなり高く、離れるほど低くなると捉えましょう。たとえば、以下のように。


この形は「正規分布(ガウス分布)」。
山のような形でなく、どのような形(三角でも矩形でも)を選んで良いのですが、モデル化では連続(なめらか)かつ数式(関数)として扱える方が便利。
縦軸は確率密度と呼ばれています。横軸の特定範囲でたせば(面積)、その範囲で発生する確率になります(これが確率密度関数の定義。全て足せば1.0)。なお、バンド幅h=0.05を考慮した形にしていますが、そこはひとまず気にしないことにします。

しばらくすると、また崩壊が発生。この時の観測値が0.06。
この時、崩壊を導く値(ピーク)が2つあるのでは、と考えた場合、こうなります。

次の観測値が0.45、0.95。
重なっているところがあるので、単純に足してデータ数4(とバンド幅0.05)で割って、ならしておきましょう。破線で表示される密度分布で、3つのピークができました。


観測を続けて足し合わせると、このような形になりました。0.05、0.5、0.9付近で崩壊する確率が高いと判断できます。

このような尤もらしい破線を推定する作業をカーネル密度推定(KDE)と呼びます。
上記の場合、カーネルとしてガウス分布を採用し、不明な母集団の関数を推定したという作業になります(正しく推定できているかどうかは別問題)。

そういえば、先日読んでいたベイズ統計の教科書にも似たような記述がありました。
カーネルを使った推定手法は、他にもいくつかあるようです。それらは理解できていませんが、必要になった際に覚えましょう。

2019年6月15日土曜日

カーネル密度推定(KDE)数式

カーネル密度推定を試行。

手元に数式がなかったので、ひとまずネットで検索。数式は微妙に違いましたが、だいたいこんな感じ(それで良いのか?)

一次元のカーネル密度推定式
\begin{align*}\hat{f}(x) = \frac{1}{nh} \sum_{i=1}^n K\bigg(\frac{x-x_i}{h}\bigg)\end{align*}
n:データ数
h:バンド幅
x:計算位置
xi:i番目のデータ(例えばi番目の観測値)
K():カーネル関数

x位置でのK()を足してnhで割っています。

カーネル関数K()の例:正規分布(ガウス分布)の確率密度関数
\begin{align*}\ K(\nu)=\frac{1}{\sqrt{2\pi \sigma^2}}\exp{\left\{-\frac{(\nu-\mu)^2}{2\sigma^2}\right\}}
\end{align*}

EXCELだと、手間。面倒。

そもそも、EXCELでは約105万行までのデータしか扱えません。1000万データなど、開くこともできません。

Pythonだと、簡単。
sns.kdeplot(X,bw=0.05)

seabornだけでなく、他にも複数のライブラリが KDE に対応しています。
ひとまず、700万行×13列のデータは一気に処理できました。便利。



2019年6月14日金曜日

エラー修復 (GEORAMA 2019)

CTC さんの GEORAMA 2019を使用している際に遭遇する問題です。

ユーザー側で対処に迫られる(かなり厳しい)事項のみ、経験的対処法を備忘録として残しておきます(サポートさんに伺っても、GEORAMA が原因ではないという見解のようです)。

Q1:図面を存できません。
コマンド: _QSAVE Object(s) added to DB too late during save. Handles 32C1AD to 32C1AF
32C1AD: type AcDbBlockTableRecord, owner 1 (AcDbBlockTable)
32C1AE: type AcDbBlockBegin, owner 32C1AD (AcDbBlockTableRecord)
32C1AF: type AcDbBlockEnd, owner 32C1AD (AcDbBlockTableRecord)

A1: GEORAMA で境界関連図を再作画しましょう。
保存できるようになります。
昔はこのエラーはなかったのですが、最近よく遭遇します。


Q2:dwgを開いても、GEORAMAパネルにデータが表示されません。

A2:GEORAMAのデータが(なぜか)飛んでしまいます。2019からではなく、過去のバージョンからシバシバ遭遇します。
対処法1:悲しいですが「GEORAMAデータはいつか失われるもの」という認識で、バックアップをこまめに取るというのが経験的な対処法。
対処法2:設定のやり直し。
直近のバックアップがない場合、作り直すしか選択肢は残っていません。
が、初期データ登録から順番に追っていくと、地質テーブル、境界テーブルは容易に復活します。ボーリングデータリストは「ボーリングデータチェック」で認識してくれます。
ここまでで一度保存し、ファイルを閉じて再度図面を開くと、「鉛直断面図」が復活します。残念ながら境界ポイントは認識してくれません。一度削除し、再設定が必要です。


2019年6月12日水曜日

機械学習とCAE

機械学習とCAEの融合が進んでいるようです。
http://www.cae21.org/kansai_cae/konwakai/kansai_67/kansai67_annai.shtml

表題をみても、まったくわかりません。
想像もできません。知りたいのですが、雲の上。

うーん。ついて行きたい。

Docker イメージの更新

LightGBM を GPU で動かすには、コンパイルしかないとのこと。

そこで、RAPIDS ベースの Docker イメージを更新することに。
https://phreeqc.blogspot.com/2019/02/tensorflow-docker.html

Git を使い始めているので不要かな?と思いつつ、備忘録としてコピペ。
OpenCL の箇所で何度か引っ掛かりましたが、基本は公式通りでコンパイルできました。

***********************************
RAPIDS コンテナベースにTFインストール
https://hub.docker.com/r/rapidsai/rapidsai/

$ docker run --runtime=nvidia --rm -it -p 8888:8888 \
-v /(クローン先):/rapids/notebooks/my_data \
rapidsai/rapidsai:cuda10.0-runtime-ubuntu18.04

必要ライブラリインストール(tensorflow-gpu1.13)
$ conda install -c conda-forge mlxtend scikit-optimize imbalanced-learn
$ conda install -c eumetsat tree
$ conda install Pillow scikit-image openpyxl matplotlib pytables seaborn xlrd tensorflow-gpu keras

最新版にup
$ conda update -n base conda
$ conda update --all
$ apt-get update
$ apt-get upgrade

LightGBM-GPU コンパイル
$ git clone --recursive https://github.com/Microsoft/LightGBM
$ cd LightGBM
$ mkdir build ; cd build
$ cmake -DUSE_GPU=1 -DOpenCL_LIBRARY=/usr/local/cuda/lib64/libOpenCL.so -DOpenCL_INCLUDE_DIR=/usr/local/cuda/include/ ..
$ make -j$(nproc)
$ cd ../python-package
$ python setup.py install --precompile
$ cd ../..

Jupyter起動し、稼働確認
$ bash utils/start-jupyter.sh
0.0.0.0:8888

***********************************
アップデート後の Docker イメージを保存。
次回からは保存したイメージ起動でOK。




***********************************
20190614追記
OpenCLデバイスが見つからないと叱られます。
CPUだと動くのですが。
もう少し時間がかかりそうです。

2019年6月3日月曜日

Git

GitHub 始めました。

といっても、これまで個人で書き貯めていたソースの一部を整理しただけで、管理はこれからです。
いくつかの矛盾する機能を追加し、それぞれソースを残しておくことがあります。これらをブランチで管理しながら運用できることに期待しています。

GUI は GitHub Desktop を使用しました。HP で Linux 版がないの?と危惧したものの、Ubuntu 側でアプリ検索すれば出てきました。使い方も簡単。
残念なのは、1ファイル当たりのサイズ制限があったこと。知りませんでした。ま、非公開リポを無制限に作成できるだけでも、ありがたいですね。

GitHub にパブリッシュしておけば、notebook の内容を確認できます。text editor ではわかりにくかったので、楽になりました。

Microsoft さんの意向次第ですが、今後も利用環境が維持されることに期待しましょう。