2019年2月26日火曜日

XGBoost メモ

XGBoostのメモです。

xgboost.cv
戻り値は evaluation history(リスト)

xgboost.train
戻り値は booster(モデル)

XGBClassifer
Scikit-Learn ラッパー


categorical_crossentropy VS. sparse_categorical_crossentropy
https://jovianlin.io/cat-crossentropy-vs-sparse-cat-crossentropy/
categorical_crossentropy: one-hot encodings
[1,0,0]
[0,1,0]
[0,0,1]
sparse_categorical_crossentropy: integer encodings
1
2
3

2019年2月25日月曜日

機械学習モデルの性能評価指標

機械学習モデルの一般的な評価指標について整理しました。

まずは confusion matrix (混同行列)を作成。
https://phreeqc.blogspot.com/2017/11/deep-learning.html

Error(ERR、誤分類率)
Accuracy(ACC、正解率)=1-ERR
全数を使った指標は imbalance データで注意。

Precision(PRE、適合率、精度)
予測 positive で当たった割合

Recall(REC、再現率)
=True Positive Rate(TPR、真陽性率)
実際 positive で当たった割合

全部 Positive と予測すれば REC 100%、Precision低。
スクリーニングで Rec、詳細調査で Precision の高い手法を組み合わせるとよさそう。


F-measure(F値、F1値(F1-score))
h(PRE, REC)
PRE と REC の調和平均(harmonic mean)
相加平均、相乗平均でなく、なぜ調和平均なのでしょうか?


multi-class の場合も基本は binary と同じです。
macro・・・各クラスの結果を平均
micro・・・各クラスのTP等を集計して算出
各クラスの結果を等価に評価してくれるのがマクロ。良し悪しですが、レアクラスの結果を重視したい場合には良いでしょう。


計量分野を除き、言葉としての「精度」は人によって指す意味の異なる場合があります。英語で言う方が正しく伝わるでしょうね。

2019年2月24日日曜日

だいち防災WEBポータル

Tellus OS Ver.1.0 が公開されました。

Google Earth Engine と同様のコンセプトで作られているようです。
まだデータセットは十分といえませんが。

残念ながら、将来的に公開される ALOS-2 データは画像だけのようです。
DInSAR 等に使えるデータを、というのは難しいようです。すでに商売になっていますから、それを無料で、というのは難しいのでしょう。商売に支障のない範囲での公開。ま、当然でしょう。

では、災害時の緊急観測後の機械学習はだれが担当するのか?

宇宙村の方々のようですね。
だいち防災webで完結しているようです。
村外に住む技術者は、指をくわえて予測結果が出てくるのを待つしかありません。

だいち防災WEBポータル
https://jaxa-dis.maps.arcgis.com/home/index.html
http://www.sapc.jaxa.jp/work/antidisaster/


整備された Tellus 。それでも、何かしら必要になる時が来るかもしれません。
考えてみましょう。

2019年2月17日日曜日

Python3 Jupyter notebook:実行時間、日本語表示

#セル実行時間
%%time

#日本語フォント(matplotlib で inline表示)
#Windows10
fp = FontProperties(fname='C:\WINDOWS\Fonts\HGRGE.TTC', size=11)
#Linux
#https://launchpad.net/takao-fonts
fp = FontProperties(fname='./fonts/TakaoPGothic.ttf', size=11)

Python3 ファイル操作

#tree表示
#Linuxでは sudo apt-get install tree
#dataフォルダ以下をツリー表示
!tree data

#ファイルリスト取得1
import glob

path = './data/**/*.csv'
files = glob.glob(path)
csv_list = pd.Series(files)

#取得したリストをもとに、csv結合
df = pd.DataFrame()
csv_data = []

for csv in csv_list:
    df_temp=pd.read_csv(csv,
                        usecols=[0,5,10],
                        index_col=None,
                        header=0) 
    csv_data.append(df_temp)
df= pd.concat(csv_data)
df=df.reset_index(drop=True)
df

#ファイルリスト取得2
import os

dir = os.path.join('111','222','333')
files = os.listdir(dir)

#データフレームに格納されているパスを使って、
#1行毎にデータコピー
import os
import shutil

for column_name, itm in files.iterrows():
    #文字列型でjoin
    dst = os.path.join(itm[1],itm[0],str(itm[2]))
    src = itm[3]
    if not os.path.exists(dst):
        os.makedirs(dst) #sub_foldersまで作る
    shutil.copy(src,dst)

20210218追記

Python3 画像操作

import os
#Pillow
from PIL import Image, ImageOps

#変換後の画像データ保存先作成
os.makedirs('./images_converted/', exist_ok=True)
for path in os.listdir('./images'):
    img = Image.open('./images/'+ path)
    img = img.convert('RGB') #RGBに変換
    img = img.convert('L') #グレースケールに変換
    img = ImageOps.invert(img) #ネガポジ変換
    img_resize = img.resize((25,25)) #サイズ変更
    img_resize.save('./images_converted/'+ path)

Python3 データ型

#dataframe 内のデータ型確認
df.dtypes

#型変換
df=df.astype({'111': np.int32,
              '222':np.float32,
              '333':np.int8,})

Python3 cuDF

https://github.com/rapidsai/cuml/issues/26

import cudf

# convert numpy array to cuDF dataframe
def np2cudf(df):
    df = pd.DataFrame({'fea%d'%i:df[:,i] for i in range(df.shape[1])})
    pdf = cudf.DataFrame()
    for c,column in enumerate(df):
      pdf[str(c)] = df[column]
    return pdf

img_cudf = np2cudf(img_array)
print("input:")
print(img_cudf)


Python3 データフレーム操作

データフレーム操作。
*******************************************************
20200215
更新・拡充しました。こちら↓
https://phreeqc.blogspot.com/2020/02/python3-pandas.html
*******************************************************


import pandas as pd

#値を検索して該当行削除
df=df[df['111'] != -1]#カラム名111が-1の行を削除
df=df[df['222'] <= 1000]#カラム名222が1000以上の行を削除

#値を検索して該当行入れ替え
#aaa列が0の時は0、それ以外は1で行全体を置き換え
df=df.where(df['aaa'] == 0, 1)
#aaa列が0の時は0、それ以外は1でaaa列のみ置き換え
df['aaa']=df['aaa'].where(df['aaa'] == 0, 1)

#不要列削除
df = df.drop(columns=[0,3,4,5,7])

#dfを結合
df = pd.concat([df1, df2.drop(columns=[1])], axis=1)#列追加
#aaa列をキーにして結合
#left指定で最初(左側)のデータフレームは全て残す
df1=pd.merge(df1, df2, on='aaa', how='left')

#カラム名変換
df= df.rename(columns={'111': 'AAA', '222': 'bbb'})#111をAAAに変換
df.columns = ['AAA', 'BBB', 'CCC']

#不要データフレーム削除
del(df1,df2)

Python3 データフレーム内容確認

データフレーム内容確認。
import pandas as pd

#先頭5行表示
df.head()

#基本統計量表示
df.describe()

#ヒストグラム表示
#全体のヒストグラム
df.hist()
#A列のヒストグラム。ビン数指定。
df['A'].hist(bins=50)

#個数カウント→データフレーム化
array=df['A'].value_counts()
df=pd.DataFrame(array.describe())

#ピボットテーブル
df_pivot = df.pivot_table(values = ['A'],  #値
                          index = ['B'],   #行
                          columns = ['C'], #列・カラム
                          aggfunc = 'max', #集計方法
                          fill_value = 0,
                          margins = True)

20200215追記修正

Python3 データI/O

Jupyter 上で多様なコードを書いていますが、同じコマンド・ルーチンを必要とする場面に多く遭遇します。
毎回探しに行くのも面倒ですので、辞書代わりに、まとめておきます。

まずは、データI/O。pandas 主体。
import pandas as pd

#csv読み込み
df=pd.read_csv('./aaa.csv',
               index_col=[0],
               usecols=[0, 1,3,4],
               header=None,
               dtype={'A': 'uint32', 'date':'datetime64'},
               encoding='cp932')
       
#csv書き込み
df.to_csv('./aaa.csv',encoding='cp932')

#EXCEL読み込み
df=pd.read_excel('./aaa.xlsx',
   sheet_name=0,
   skiprows=[0,1],
   header=2,
   usecols=[0, ,1, 2],
   index_col=0)
       
#EXCEL書き込み
excel_writer = pd.ExcelWriter('./aaa.xlsx')
df1.to_excel(excel_writer, '111',index=False)
df2.to_excel(excel_writer, '222')
excel_writer.save()
 
#hdf書き込み
df1.to_hdf('./aaa.h5', key='b', mode='w')
df2.to_hdf('./aaa.h5', key='b')
df3.to_hdf('./aaa.h5', key='c')

#hdf読み込み・・・key毎に読み込み、df化して処理
import h5py
f = h5py.File('./aaa.h5', 'r') 
list=list(f.keys()) 
for i,keyname in enumerate(list):
    df=pd.read_hdf('./aaa.h5', key=keyname)

20200215追記修正

2019年2月10日日曜日

Tellus Satellite Boot Camp 2日目

2日目。

このセミナーに申し込んだのは、昨年の経産省主催のコンペ結果が披露されると踏んだからでした。

期待通りではなかったですが、素人向けのレベルで同内容を御披露頂きました。具体的には、SAR 画像から土砂崩壊位置を Deep Learning で抽出する疑似コンペ。参加してよかったです。
この疑似コンペ、プロが頑張っていました。土木のプロでなく、機械学習のプロ。限られた時間に、事前に教えていただいたこと以上のテクニックを活用され、優れた結果を残されていました。さすがです。勉強になりました。

精度向上を求めると、このようにテクニックを駆使することになるのでしょう。が、機械が立てた仮説はより分かりにくくなるでしょう。
ふと思ったのですが、これ、機械学習のプロが提示した結果なら、土木のプロのオジサマたちも案外受け入れるのではないでしょうか?
災害が発生し、この学習モデルから新たな予測を行った。その結果を受け取ったオジサマたちは飛行計画を立て現地を確認しに行く。機械学習をスクリーニングに使い、土木のプロが判断するという使い方。現在の医療分野と同じ扱い。
もし、土木のプロが予測結果を提示したなら、スクリーニングとは扱わず「ブラックボックス」「本当に当たっているのか?」と非難するかもしれません。

いずれにせよ、衛星データと機械学習のコラボで、短時間に発生個所を予測できる未来を経産省さんは望まれているようです。この未来はすぐに来るでしょう。楽しみですね。

2019年2月9日土曜日

Tellus Satellite Boot Camp 1日目

Tellus Satellite Boot Camp に参加中。

東京会場では、50名の枠に690名が応募していたとのこと。ラッキーでしたね。
参加者の中には機械学習系エンジニアも多いようです。主催の経産省の方も来られていました。

内容は、Google Earth Engine を除けば、ほぼ復讐。1日目は基礎的な内容が主体でした。

あらためて、GEE は凄い。
各種衛星データが登録済み & 表示が容易である点だけでも十分使えるのですが、それに加え機械学習アルゴリズムまで実装しています。
ポイントを衛星画像上の崩壊個所・非崩壊個所のいくつかに設け、そこの特徴を教師データとして学習。で、ポイントを設けていない箇所の予測を行います。簡単。
パラメータ調整等もできるそうですので、マニュアルを読まないと。

さあ、本番は明日かな。


2019年2月6日水曜日

TensorFlow + Docker

TensorFlow をDocker で動かそうとして、はまりました。

公式のイメージを使っているにも関わらず、ライブラリのインポートでエラーが出ます。
Dockerfile をビルドすれば大丈夫か?と試すも、ビルド途中でエラー。使えません。

時間をかけて触ってみましたが修正できず。
最終的にはRAPIDS のイメージをベースに、tensorflow-gpu と keras 、その他必要なライブラリを全て conda で入れて、ライブラリ間の依存関係を解決。tensorflow は 1.9、CUDA は 9.0 まで落ちました。が、tensorflow を import できました。
ただ、RAPIDS の必要条件(9.2)を満足していません。CUDA 10 でのビルドもエラーですので、現段階では共存をあきらめざるを得ません。本当に面倒。

このコンテナから、新たなイメージを作成し終了。再現はできるようになりましたが、きちんと働いてくれるのでしょうか?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20190209追記
$ conda update --all をかけなければ、tf1.12、CUDA9.2 を維持できました。どこかで引っ掛かるまでは、このイメージで動かしましょう。

2019年2月3日日曜日

小型 SAR 衛星

現在、日本では深層崩壊や土石流等の大規模土砂移動発生個所の検知システムとして、振動センサー等による観測網の活用が期待されています。
これに衛星データ加え、天然ダム形成個所や崩壊個所を抽出することで情報の補強、位置精度向上を図る流れのようです。
https://www.eorc.jaxa.jp/ALOS/conf/workshop/SKEws2/2-2-2_yamamoto.pdf

後者のネックは時間。
初動に使用したいのですが、衛星データの取得には時間がかかります。例えば、上記資料によれば SAR 緊急観測オーダーから地上受信まで16時間。その後の判読を含めると24時間。もっと早く結果を得たいところです。

先日、この「時間」の課題が数年後に解消される話を聞きました。災害後2~3時間で衛星データを取得できるようになるとのこと。小型観測衛星を利用するそうです。例えばコチラ↓
内閣府 革新的研究開発推進プログラム:ImPACT
「オンデマンド即時観測が可能な小型合成開口レーダ衛星システム」
http://www.jst.go.jp/impact/program/13.html
今世界が注目!小型レーダー衛星とは?~日本の可能性~
https://sorabatake.jp/387/

災害が発生してから打ち上げる話を聞いた時には「ここまで進んでいるのか!」と驚かされるとともに「既に取り残されている」「今更、参入できるのか」などと考えてしまいました。が、ベンチャーからデータを購入できる可能性が生まれると、検知システムとして構築できる道筋が生まれます(高そうですが)。
災害発生後に打ち上げた場合には、発災前後の2時期の合成が難しくなるでしょうが。

なお、判読「時間」の課題に対しては、すでに解決済みとのこと。
機械学習を適用しているそうです。これは、経産省主催のコンペにも出ていましたし、週末のセミナーでも選択されている内容。個人レベルでも解決できそうな内容です。

機械学習ブームに 小型 SAR 衛星打ち上げ技術の進展、AWS Ground Station の発表、Google Earth Engine 等の統合環境整備、政府衛星データのオープン&フリー化。宇宙ビジネス参入を容易にする要素が揃いつつあり、ベンチャーにとってはもちろん、防災分野でも影響を受ける時代が来たようです。
数年先、個人的には食い込んでいたいのですが、supervisor には内容すら判断つかないみたい。どうなっているでしょうか?

2019年2月2日土曜日

Google Earth Engine で二時期カラー合成

来週末のセミナーで実施予定の、Google Earth Engine を予習。

これは使ったことがなく、知識のない Java ということもあり予習しておこうと考えていました。

で、ログイン。

でも、画面には何も出てきません。いえ、コードエディタ内に分割された欄は出てくるのですが、地図等が表示されません。
最初はこれがデフォかなと思っていましたが、どうやら違ったようです。ブラウザの拡張機能「Disconnect」が原因でした。white list 化で地図等が表示されました。

早速、一番気になっていた Sentinel-1 の収録状況を確認。
2014-10-03T00:00:00 - Present となっていましたが、直近いつまで入っているのか?

Scripts tab に「Sentinel1 Composit」というDemo があったので、それを利用。クリックで center console にスクリプトが入ります。地図上で国内にマーカーを設けると、その座標が center console の一番上に入りました。で、それをスクリプト内にコピペ。で、日付を何度か調整 & Run。

var im1 = ee.Image(collectionVV.filterDate('2019-01-30', '2019-02-02').mean());

優秀!
3日前のデータが既に収録されていました!
しかも、何の苦労もなしに地図上にオーバーレイされています。優秀すぎる!

俄然やる気になり、昨年の北海道地震を見てみると・・・よくわかりません。
では、岡山の浸水を見てみると・・・これはわかりましたが、浸水直後のデータがなく、幾日か経ってのデータ。残念。Sentinel ですので仕方ないでしょう。

位相を含むデータは収録されていないようです。残念ながら InSAR 等はできません。が、国交省「災害時における衛星画像等の活用を促進~災害時の衛星画像活用のためのガイドブックを作成~」でメインの二時期カラー合成なら、誰でも、容易にできるということがわかりました。http://www.mlit.go.jp/report/press/mizukokudo03_hh_000944.html

今まで、作成にはいくつかの手数・ソフト・時間が必要でしたが、GEEだと一瞬。凄い!かなり敷居は下がったと思います。

もう少し、触ってみましょう。