takeshi kiura のすべての投稿

Spotfireと飲酒。ヨガと仏教と宇宙論を嗜んで生きています。

StreamBaseとH2O連携

StreamBaseとH2O連携

前回の記事でH2Oで作成したモデルをPOJOというJavaファイルに保存し、アプリケーション化する方法をご紹介しました。

今回はTIBCO製品であるTIBCO StreamBaseとH2Oの連携についてご紹介します。

TIBCO Software StreamBaseとは

StreamBaseはリアルタイム処理が行える製品です。
様々なストリーミングデータを元に高速処理が行えるのが特徴で
元は金融のアルゴリズム取引などに使用されていました。

処理の流れはGUIから設定できますのでコードをゴリゴリ書く必要はありません。

残念ながら有償ソフトとなりますが、30日のトライアルはこちらから可能です

StreamBaseにはH2Oアダプタがありますので、
これを使用して簡単に連携ができます。

モデルをビルドして、POJOファイルを入手した段階が前提です。
今回も同様に複数のパラメータを従属変数とし、品質を目的変数としました。

H2Oアダプタへのモデル実装

H2Oアダプタへは従属変数を入力パラメータとして与えると、予測品質がアウトプットとして出力されます。
モデルの実装はとても簡単で、POJOファイルをアダプタのプロパティに設定するだけです。

今回はサンプルのファイルから1秒間に10レコードずつ流して仮想のストリームを作っています。

StreamBaseを使うとWeb上からリアルタイムに結果も見えるので、短期間でH2Oを使用したリアルタイム可視化ができます。


画面キャプチャーが小さくてすいませんが、徐々に不良が発生して、アラートが表示されます。
このWeb画面も自由に設計可能です。今回は円グラフと棒グラフ、ある不良が予測された場合のアラートだけ追加してみました。創作時間10分程度です。

ご興味のある方は是非TIBCO社までお問合せください。

H2OモデルのJavaによる実装

Javaによる予測モデルの実装

H2Oを使えばWeb上から簡単にモデリングできる事をご紹介しましたが、
更に作成したモデルをPOJO(Plain Old Java Object)としてエクスポートすることができます。
これにより作成したモデルをJava上で動作させることができますので、予測モデルをバッチ処理などに組み込みたい場合は非常に便利です。

実装の手順としてPOJOファイルを使用したサンプルを作成しました。

POJOファイルの作成

H2O Flowで作成したモデルですがWEB UI上からダウンロードする事ができます。
Model作成後の画面で「Download POJO」をクリックするとjavaファイルとしてダウンロードできますので、任意のディレクトリに保存してください。

今回はDeepLearning_model_TIBCO_1489641113699_1.javaという名前で保存しています。

h2o-genmodel.jarの入手

http://localhost:54321/3/h2o-genmodel.jar
からダウンロードできますのでこれも先ほどダウンロードしたPOJOファイルと同じディレクトリに保存します。

main.javaの作成

同じディレクトリにmain.javaとして下記コードを記載したファイルを作成します。

import java.io.*;
import hex.genmodel.easy.RowData;
import hex.genmodel.easy.EasyPredictModelWrapper;
import hex.genmodel.easy.prediction.*;
import hex.genmodel.MojoModel;

public class main {
  // モデルの指定
  private static String modelClassName = "DeepLearning_model_TIBCO_1489641113699_1";

  public static void main(String[] args) throws Exception {
    hex.genmodel.GenModel rawModel;
    rawModel = (hex.genmodel.GenModel) Class.forName(modelClassName).newInstance();
    EasyPredictModelWrapper model = new EasyPredictModelWrapper(rawModel);

    // 予測に使うデータ(Setosaに近いデータです)
    RowData row = new RowData();
    row.put("C1", "5.0");
    row.put("C2", "3.4");
    row.put("C3", "1.5");
    row.put("C4", "0.2");

    model = new EasyPredictModelWrapper(rawModel);

    // 予測
    MultinomialModelPrediction p = model.predictMultinomial(row);

    // 結果出力
    System.out.println("Species will be " + p.label);
    System.out.print("Class probabilities: \n");
    for (int i = 0; i < p.classProbabilities.length; i++) {
      if (i > 0) {
        System.out.print("\n");
      }
      System.out.print(p.classProbabilities[i]);
    }
    System.out.println("");
  }
}

これで準備はOKです。

コンパイル

javac -cp h2o-genmodel.jar -J-Xmx2g -J-XX:MaxPermSize=128m DeepLearning_model_TIBCO_1489641113699_1.java main.java

実行

java -cp .;h2o-genmodel.jar main

Species will be Iris-setosa
Class probabilities:
0.9999219016198672
7.809838013280072E-5
1.1767060238448459E-33

予測元データはSetosaのイメージでしたが、予測もSetosaでした。
確率は99.99パーセントという事ですのでかなり自信を持った予測でしたね。

POJOファイルとh2o-genmodel.jarを使用する事で割と簡単に実装できることが分かりました。

TERR(R)によるH2O操作

TERRによるH2Oの実行

H2OをWEBで操作してディープラーニングを走らせてみましたが、
ある程度カラムが増えてくると操作が遅くなってきますし、スクリプトベースで手順を記載した方が再実行性が高いので、学習をバッチ処理で実行して見ます。

H2OはRやPythonのパッケージも配布しているので、それらの言語を使用してスクリプト化する事ができます。
Rによる実装は至る所で紹介されているので、どうせなら自社製品のTERRで動作させます。

TERRとはTIBCO社が開発しているR言語のコンパチエンジンです。
TIBCO社は元々S-PlusというS言語エンジンを開発していたのですが、
R言語が世の中の主流になってきたので、R言語の実装系として再開発しました。
再開発しただけあり、パフォーマンスはRの10倍以上と謳っています。

使用したTERRのバージョンは4.3です。4.2ではinstall.packagesに失敗しました。
また、事前にjava -jar h2o.jarでH2Oのエンジンを起動しておく必要があります。

# パッケージのインストール
install.packages("h2o" , dependencies = TRUE )

# ライブラリ呼び出し
library ( h2o ) 

h2o.init()

少しエラーが出ていますが、動作します。

# H2O ライブラリ内にあるirisデータのファイルパスを取得
irisPath = system.file("extdata", "iris.csv", package = "h2o")

# ファイルをhexにインポート
iris.hex = h2o.importFile( path = irisPath)

# モデルを構築
iris.model=  h2o.deeplearning(x = 1:4, y = "C5", training_frame = iris.hex)

結果のiris.modelを見てみます。


今回はやたら精度が悪いですね。

POJOファイルのダウンロード

# POJOファイルのダウンロード
h2o.download_pojo( iris.model , getwd()  )

既定ではユーザーディレクトリにjavaファイルが作成されます。

H2Oでお試しディープラーニング

ディープラーニングとは?

以前の記事で重回帰を用いたモデル化の紹介をしました。

この時は、目的とするパラメータに対して関連の高い(と思われる)パラメータを自分で選択してモデルを構築。モデルが正しくなければ試行錯誤を繰り返す必要がありました。

これは非常に属人性の高い業務で、慣れている人であれば単なる「作業」ですが、
この「作業」をできるようになるまでには長い修練が必要となることが多いです。

ところが近年、この分野で革命が起きています。
「ディープラーニング」という技術のおかげでコンピューターが自動でデータから特徴を抽出してくれるようになりました。

ディープラーニングとはニューラルネットワークを進化させた機械学習の手法の一種で、
下記のような特徴があります。

  • 他の機械学習技術では達成できないレベルの精度を実現できる。
  • 特徴量(パラメータ)の抽出は自動化されて人がルールを記述する必要がない。

一言でいうと、データを用意すれば高い精度で予測モデルが自動で作成されるという事。
暴力的に言うと高い精度のモデルができなければ「データが悪い」という事になります。

ディープラーニングを試したい

ディープラーニングは2012年から始まったまだ新しい技術ですが、
既にGoogleやFacebookなどの多くの企業で実運用され、いくつかのパッケージも存在しています。

ただし、どのパッケージでもPythonなどのプログラミング言語でコーディングが必要になることが多いです。
この記事では「とりあえずディープラーニングを試してみたい」という方向けにH2Oというパッケージをご紹介します。

H2Oとは?

インメモリプラットフォームとしてHadoop上やSpark上でも動作可能な機械学習フレームワークであり、オープンソースかつ、商用可能なアパッチライセンスで配布されています。
特徴的なのはWeb-UI上で解析が可能なので、ノンコーディングで動作確認できます。

H2Oの入手

H2Oパッケージはこちらからダウンロード可能です。

スクロールして左下にある
「Download H2O Latest Stable Release」をクリックしてください。

「DOWNLOAD H2O」をクリック
ここでユーザー情報などを入力する画面が表示されますが、
特に入力しなくてもダウンロードが始まります。

ダウンロードが完了したら
任意の場所で解凍します。
私はCドライブ直下に置きました。

このh2o.jarが本体です。

H2Oの起動

解凍が終わったらH2Oを起動します。
Windowsのコマンドプロンプトを起動して
cd C:\h2o-3.10.3.5
java -jar h2o.jar

のように実行します。

javaが必要になるので無い方は事前にインストールが必要です。

これでH2Oが起動しました。
お手持ちのブラウザから
http://localhost:54321
へアクセスしてみてください。

H2O Flow画面が表示できているはずです。

モデリング

こちらから実際のモデリングに取り掛かってみます。
皆さんが自分のデータで実行したい場合は下記のようなデータをご用意ください。

一つの「目的変数」と多数の「従属変数」からなるデータです。
ディープラーニングは既存のデータを学習して、予測モデルを作成してくれます。
目的変数は最終的な目的にしたいカラム。
例えば製造業でしたら不良だった/そうでなかったのか
小売りでしたら、顧客が買った/買わなかった
などです。
対して従属変数は、目的変数に関連するであろうパラメータ群です。

不良に関するパラメータだと、製造時の温度や材質などが考えられます。
従属変数は多い方が良いです。

注意事項

ここでアドバイスがあります

  • Null値(空白)は除いておいてください。
  • 日本語はカラムもデータも避けてください。

日本語は対策があるのかもしれませんが、文字化けしますし(内部的にはちゃんと保持している)割とエラーが出ますので、事前に英数字などに置換しておくのをお勧めします。

とりあえず動作だけ試したいという方は
Irisのデータを使ってください。

アヤメの萼(がく)片と花弁のサイズ、種のデータになります。
このデータにはカラム名が無いため
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
を一行目に追加してください。

種が目的変数でそれ以外は従属変数です。
こちらをiris.csvという名前で保存します。

データのインポート

H2O FlowのDataから「Import Files」を選択します。

Searchにc:\tmp\h2o\iris.csvのように手入力すると
候補が表示されますので+をクリックします。

ファイルが選択されたので、Importを押します。

パースの確認が表示されます。
区切り文字やデータの型、ヘッダーなどの設定と最初の数行を確認できます。
問題なければParseボタンを押します。

JOBが完了しiris.hexという名前でデータが内部的に保存されます。
Viewを押すと内容を確認できます。

データの統計値が確認できます。
ここからモデルを作成したいので
「Build Model」をクリックします。

モデル構築のアルゴリズムを選択することができます。

Deep Learningを選択して下さい。

H2Oはディープラーニング以外にも複数のアルゴリズムをサポートしています。

教師あり学習
  • Generalized Linear Modeling (GLM)
  • Gradient Boosting Machine (GBM)
  • Deep Learning
  • Distributed Random Forest
  • Naive Bayes
  • Stacked Ensembles
教師なし学習
  • Generalized Low Rank Models (GLRM)
  • K-Means Clustering
  • Principal Components Analysis (PCA)

モデル構築

モデルを選択すると下記画面が表示されます。
最低限選択しなければならないのは
validation_frameとresponse_columnです。

validation_frame

H2Oはモデル構築後にモデル構築に使用したデータ以外の同一フォーマットデータを使用して検証を行います。
Aというデータを元にモデルを作成したは良いが、Aに特化したモデルを作成してしまうと、別の日のBというデータに対して当てはめた時に結果が悪くなります(これを過学習といいます)。
過学習が起きた場合は、activationで設定されている活性化関数をDropoutありの物に変更するなどパラメータを調整する必要があります。

今回は元データと同じiris.hexを指定しておきます。

respose_column

目的変数です。モデルを構築する目的となるカラムを選択します。
既定ではこちらで選択されている以外のカラムは全て従属変数として扱われます。
必要ないカラムがある場合はignored_columnsでチェックを入れてください。

irisでは種である「Species」を選択します。

設定が終わったら左下の「Build Model」を押します。
データが大きい場合はかなりの時間がかかります。

JOBが終了すると結果が表示されます。

Viewを押して結果を確認しましょう。

結果確認

重要なのは下に表示されているクロス集計です。
2つの表があり、上の表は学習時の結果、下の表は検証時の結果です。
上下で結果に大きな隔たりがあれば過学習を疑ってよいでしょう。
今回は同じデータを使っているので同じ結果です。

縦が実際の値で横が予測された値です。
黄色のセルが正解で、それ以外は予測が外れたものです。
最終的な結果は右下のError 0.0267 , 4 / 150を見ます。
今回のモデルでは150のデータの内4つは実際の種を当てることはできませんでしたが、
97パーセント以上の確率で適合するモデルとなっています。

言い換えるとアヤメの萼片と花弁のサイズがわかれば、97パーセントの確率で種が推定できるという事です。

ディープラーニングはランダムに与えられる初期値が割と重要で、
いつも同じ結果が出るとは限りませんので実行する毎に異なる正解率が出ます。
この辺りも機械っぽくなくて好感が持てます。

今回はとりあえずディープラーニングを試してみたいという方向けに一番簡単な方法で試してみました。
実際のデータで試してみようと思う場合、データ収集に苦労されるケースが多いと思いますし、
大きなデータでは学習もかなり時間がかかるとは思いますが、まずはディープラーニングがどのような物で、何が革命なのか、少しでも分かっていただければと思います。

パッケージインストール方法

パッケージインストール方法

TERRに関して

Spotfireに標準搭載されているTERR(TIBCO Runtime for R)はTIBCOが独自で開発したR言語の実行エンジンです。

TIBCOは元々S-Plusと言う統計解析ソフトの開発元です。
S-PlusはS言語というR言語の元になった言語なので長い開発実績があります。
しかしS-Plus自体かなりデザインが古くなったり、世間的にはR言語の方がメジャーになってきているので、
TERRとして刷新してSpotfire上に実装しています。

動作は高速なのでRのパフォーマンスに不満がある方は使ってみるといいと思います。

splus
※S-Plusの画面

TERRはTIBCO独自の開発ですが、Rと同じようにCRANからパッケージを追加して使うことができます。
勿論全てのパッケージに完全対応している訳ではありませんが、メジャーなものは大体使う事ができます。

動作確認リストはこちらから取得できます。
(一番下にあるWindows、Linux、Macなど書いてあるリンクから)

パッケージの追加方法

7.0以降であれば「ツール」の中に「TERRツール」というメニューがあるのでそちらから実行します。
3

TERRツールの「パッケージ管理」タブからインストール済みのパッケージ一覧が確認できますし、
足りないものは利用可能なパッケージから選択して「インストール」する事ができます。

4

RのパッケージもCRANに登録してあるものだけでなく、
個人で配布しているようなパッケージを使用したい場合は
ローカルファイルからインストールする必要があります。

その場合はコンソールから実行します。

5

今回は普通にinstall.packagesコマンドでインストールしてみました。
7

Spotfireのバージョンが7以前の場合はTERRツールメニューがないので
直接TERRのエンジンを実行してinstall.packagesコマンドを使います。

エンジンの場所はデスクトップ版であれば

C:\Users\ユーザー名\AppData\Local\TIBCO\Spotfire Desktop\XXX\Modules\TIBCO Enterprise Runtime for R_XXXX\engine\bin

Analyst版であれば

C:\Program Files (x86)\TIBCO\Spotfire\XXXX\Modules\TIBCO Enterprise Runtime for R_XXXX\engine\bin

内にあります。Modulesディレクトリが隠しディレクトリになっているので表示する設定にするか、DOSプロンプトから直接移動する必要があります。
8

TERR.exeを実行すると、コンソールが立ち上がるので、コマンドからパッケージをインストールしてください。
6

選択データのみ縦変換

時系列項目がカラムとしてまとめられているのをよく見ます。

1

縦軸に識別子、横軸が時系列のサマリーとして表現されているので、
人間が読むには非常にわかりやすいのですが、コンピュータに制御させる場合は色々問題があります。

このデータをラインチャートでName別に表示しようとすると
横軸に(カラム名)縦軸に時間のパラメータをすべて入力し、
色の基準でNameにすると表現できます。
2

ただし、横軸の並びはアスキー順になるのでカスタムの並び替えにしなければならなかったり、そもそも文字列扱いされているので、時間として扱う事ができません。

データの縦変換

このような場合にデータを縦変換すると便利です。

以前データ変換でピボットの解除の方法をご紹介したのですが、
ピボットの解除は横データを縦型に変換するため、時間もかかりデータのボリュームも膨れ上がります。
今回のデータも横に18パラメータあるので、100行あった場合は1800行になります。

しかもピボットの解除はデータテーブルを一括変換する事しかできないので
元データが数万行あった場合は時間もリソースも無駄に消費します。

必要なデータだけ縦変換する方法として、TERRを使用する方法を紹介します。

TERRスクリプト

3

「ツール」→「データ関数を登録」を選択
名前は任意でOKですが、reshape2パッケージを使用しますので
パッケージの欄に”reshape2″と入力してください。

※reshape2は標準パッケージではないので初回使用時にはダウンロードして追加する必要があります。
こちらを参考にパッケージを追加してください。

スクリプトに下記スクリプトを記入してください。

outdata <- melt ( indata , id = c("Name" , na.rm=TRUE ) 

idの項目はキーとして保持するカラム名のリストを設定してください。

4

ここではindataを入力として縦変換(melt)したデータをoutdataとして受け取ります。
indataとoutdataの定義もしていきます。

パラメータの入力

入力パラメーターとしてindataを定義します。
「追加」から「入力パラメータ」indata
「タイプ」は「テーブル」
「使用可能なデータ型」は「すべて」を選択して下さい。
5

出力パラメータ

出力用にoutdataを定義します。
「追加」から「結果パラメータ」outdata
「タイプ」は「テーブル」を選択してください。
6

準備が完了したので実行してみます。

実行

右上にある実行ボタンを押してスクリプトを実行します。
7

実行時のパラメータとデータの割り当てを設定します。
入力パラメータは、マークした範囲のデータを変換したいので
indataは「カラム」で検索式’*’にしておきます。これでカラムが可変になった場合でも対応できます。
「制限の基準」で「マークされたロー」のチェックを忘れないでください。
今回のキモです。これを設定しないと全データが一度に渡されるので元も子もないです。
8

出力の設定です。
outdataをSpotfire側で扱う方法を選択します。
データテーブルで「新しいデータテーブルの作成」を選択します。
9
「OK」を押すと実行されます。

動作確認

元データ(一行)を選択するとoutdataには18行作成されることが分かります。
10

Bを選択するとoutdataが更新されます。
11

ちなみにvariableカラムが文字列型なのでminutesカラムを計算カラムとして追加しました。
式は下記のとおりです。

integer ( left ([variable]  , find ( "分" ,[variable]  ) -1 )  ) 

(勿論R言語側で処理してもいいのですが、忘れました。。。。)

このように複数行を選択した場合でも適時データが更新されます。
大量データを扱っていて、必要な箇所だけ縦変換する事ができました。
12
横軸を時間で取り、色別に回帰を取りました。

パッケージがない場合

reshape2は標準パッケージではないので初回使用時にはダウンロードして追加する必要があります。
こちらを参考にパッケージを追加してください。

パッケージがない場合、左下のステータス表示にエラーが表示されます。
1

2

詳細な地図を表示する

詳細な地図を表示したい

Spotfireのマップチャートを使うと地図上にデータをプロットする事ができます。
この機能はOpenStreetMapというフリーの地図情報データをベースに
拡張したGeo AnalyticsというTIBCO社が運営するサービスを元に動作します。

ただ、このGeo Analyticsですが元のOpenStreetMapと比較すると
地図の情報量が少なく、詳細な情報を確認したい場合は少し不便です。

TMSレイヤ

Spotfire 7.6からTMSを使用したレイヤを追加する事ができるようになりました。
TMSとはWebを通して地図情報を配信する方式ですが、OpenStreetMapをこちらの機能に対応していますので、レイヤとして追加する事ができます。

追加方法

マップチャートのプロパティから
「レイヤ」‐>「追加」を選択し、
「マップレイヤ」から「TMSレイヤ」を選択します。
1

TMSレイヤのURLを入力する画面が表示されるので

http://a.tile.openstreetmap.org/{z}/{x}/{y}.png

と入力し「更新」ボタンを押してください。
2

これでレイヤが追加されました。
3

OpenStreetMapとの比較

比較してみましょう。

こちらが OpenStreetMapで表示した秋葉原周辺の地図(と人の集まり)です。

4

こちらが元のマップです。だいぶスカスカですね。

5

OpenStreetMapを初期設定にしたい

いちいちマップチャートを開くたびに設定をするのは面倒なので、
初期設定をOpenStreetMapにする方法をご紹介します。

「ツール」→「オプション」を選択します。
6

オプション画面が開きますので、「マップチャート」から「デフォルトのレイヤ」を設定します。
「追加」から「マップレイヤ」で「TMSレイヤ」を選択し、

7

後は先ほどと同じです。

著作権テキストもライセンス表記に合わせて追加しておきましょう。
10

時間列が文字列で取り込まれた場合

時間列が文字列になってしまった場合

Spotfireでは時間はdatetimeという型で扱われ、
トレンドだけでなく、曜日や時間帯という見方で扱うこともできるので非常に便利です。

ただ、このdatetimeという型、取り込みの際に型指定する必要があるのですが、
型チェックが割と厳格なので、気が付いたら文字列になっていたり、Null扱いになっていたりします。

構文的には”YYYY/MM/DD HH:MM:SS”の形になっている必要があり
“/”や日付けと時刻の区切りの” “などが無いと文字列扱いにされてしまいます。
1

そのため取り込み後、日付型として使う必要があります。
その場合は計算カラムを使います。

2
↑のように日付に”/”がなかったり、日付と時刻が別のカラムになっている場合
文字列関数で正しい構文に変換し、datetime関数で日付に変換。

計算カラム

「挿入」から「計算カラム」を選択します。
3

4

datetimeという型

手順としては画一的ではないのですがright,left,midなどの文字列関数を使用したり”&”で結合して、
“YYYY/MM/DD HH:MM:SS”の文字列を作成後、datetime関数を使用します。

少しめんどくさいですが、これでどのような形式でもとりあえず取り込んだ後に
日付型として扱う事ができます。

16進数から10進数へ変換

16進数から10進数への変換

装置などから出力されるデータの中に16進数の文字列が含まれていることがあります。

Spotfireで扱える型は文字列型、数値型などがありますが、
16進数文字列はあくまで文字列としてしか扱えないため、一度10進数に変換する必要があります。
ただ、Spotfireの関数では16進→10進の変換関数はありません。

1
↑16進だと文字列扱いになるので10進変換しないと計算ができない。

このような時にはデータ関数の登録機能で関数を追加すると便利です。

データ関数の登録

データ関数の登録機能を使うと、R言語を使用して独自の関数を定義できます。

「編集」→「データ関数の登録」を選択し、
2

新規ボタンをクリック
3

式の関数画面が開くので
名前と説明、登録する関数のカテゴリと戻り型を定義します。
4
スクリプトは下記のように記載します。

output <- as.integer(as.hexmode( input1 ))

式の関数の場合は
入力カラムはinput1、出力カラムはoutputと記載する約束事になります。

これで登録は完了です。

計算カラムで確認

「挿入」→「計算カラム」で確認してみましょう。
5
計算の関数の中に確かに登録したhextodecが追加されています。
これで通常の関数と同じように使う事ができます。

6

勿論計算カラムだけでなくカスタム演算式内でも使用できます。