Shell

ShellはJubatusサーバとの対話型評価環境(REPL)を提供します。

JubakitスクリプトからREPLを利用する

REPLインタフェースは Service インスタンスから開始することができます。

from jubakit.classifier import Classifier, Config
service = Classifier.run(Config())
service.shell()

shell() メソッドを呼び出すと、Service インスタンスを操作するための対話シェルが起動します。対話シェルでは、RPCを対話的に呼び出すことができます。対話シェルを終了するまで、jubakitスクリプトは停止します。

対話シェルの使い方は、次のセクションで説明します。

コマンドラインからREPLを利用する

Jubakitは、Shell機能のスタンドアロンバージョンである jubash というコマンドを提供します。このツールを利用すれば、ソースコードを書かずに簡単にJubatusを利用することができます。

jubash コマンドを利用する場合(Jubakitスクリプト外から利用する場合)、Jubatusサーバを手動で起動しておく必要があります。

$ jubaclassifier -f /usr/share/jubatus/example/config/classifier/default.json &

これで jubash コマンドを使ってClassifierサーバに接続することができます。

$ jubash
[Jubatus:classifier<>@127.0.0.1:9199] #

接続に成功するとシェルプロンプトが現れます。デフォルトでは jubash コマンドは、 127.0.0.1:9199 に接続します。もちろん、接続先のサーバやポートを変更することができます:

$ jubash -H 192.168.1.2 -P 19199

その他のオプションについては Jubash Reference または jubash --help で確認してください。

シェルプロンプトからは Jubatus RPC API で定義されている全てのRPCメソッドをコマンドのように呼び出すことができます。Classifierであれば、 trainclassify コマンドをJubatusサーバに対して対話的に呼び出すことができます。

[Jubatus:classifier<>@127.0.0.1:9199] # train male height 170 weight 60
[Jubatus:classifier<>@127.0.0.1:9199] # train male height 185 weight 65
[Jubatus:classifier<>@127.0.0.1:9199] # train female height 150 weight 50
[Jubatus:classifier<>@127.0.0.1:9199] # train female height 155 weight 45
[Jubatus:classifier<>@127.0.0.1:9199] # classify height 140 weight 40
female: 1.0111604929
male: 0.0962741076946

train メソッドはラベルと Datum (key-value データ) を引数に取ります。一方、 classify メソッドは Datum だけを引数に取ります。上記の例は、以下のPythonコードとほぼ同等となります。

from jubatus.classifier.client import Classifier
from jubatus.common import Datum
from jubatus.classifier.types import LabeledDatum

client = Classifier('127.0.0.1', 9199, '', 0)

client.train([LabeledDatum('male', Datum({'height': 170, 'weight': 60}))])
client.train([LabeledDatum('male', Datum({'height': 185, 'weight': 65}))])
client.train([LabeledDatum('female', Datum({'height': 150, 'weight': 50}))])
client.train([LabeledDatum('female', Datum({'height': 155, 'weight': 45}))])

print(client.classify([Datum({'height': 140, 'weight': 40})]))

help コマンドは利用可能なコマンドの一覧を表示します。 help train のように、 help に続けてコマンド名が与えられた場合は、そのコマンドの引数についての簡単な説明を表示します。

[Jubatus:classifier<>@127.0.0.1:9199] # help

Commands:
=========
classify      do_mix      get_proxy_status  load       timeout
clear         exit        get_status        reconnect  train
connect       get_config  help              save       verbose
delete_label  get_labels  keepalive         set_label
[Jubatus:classifier<>@127.0.0.1:9199] # help train
Syntax: train label datum_key datum_value [datum_key datum_value ...]
        Trains the model with given label and datum.
        Bulk training is not supported on the command line.

コマンドライン処理との統合

jubash を利用すれば、コマンドライン処理やコマンドから取得できるデータをJubatusと簡単に統合することができます。

対話シェルで実行するコマンドを -c, --command オプションで指定すると、コマンドをバッチ実行することができます。例えば、Jubatusサーバの定期的な監視を行いたい場合には、以下のように実現することができます。

$ watch -n 1 jubash -c get_status

jubash はシェルスクリプトからも実行することができます。以下の例では、シェルスクリプトからJubatusのAPIを実行する方法を説明します。

#!/bin/bash

# Anomaly detection from number of packets on eth0
# Note: jubaanomaly must be running on localhost:9199

NIC="eth0"

rx() { ifconfig "${NIC}" | perl -n0e 'm/RX bytes:(\d+)/; print $1'; }
tx() { ifconfig "${NIC}" | perl -n0e 'm/TX bytes:(\d+)/; print $1'; }

RX2="$(rx)" TX2="$(tx)"
while :; do
  sleep 1
  RX1="${RX2}" TX1="${TX2}" RX2="$(rx)" TX2="$(tx)"
  jubash -c "add rx $((${RX2} - ${RX1})) tx $((${TX2} - ${TX1}))"
done

Jubashスクリプト

一般的なシェルプログラムと同様に、 jubash はインタプリタとして動作します。(シバン行に注目してください)

#!/usr/local/bin/jubash

# expecting jubaclassifier is already running on localhost:9199
connect 127.0.0.1 9199

get_config
get_status

train male height 170 weight 60
train male height 185 weight 65
train female height 150 weight 50
train female height 155 weight 45
classify height 140 weight 40

制限事項

jubash のコマンドは対応するAPIに似たインタフェースに設計されています。しかし、REPL表現の制約のため、いくつかの制限事項があります。

  • それぞれのデータの型は自動的にfloatまたはstringに解釈されます。つまり、厳密なデータ型が要求されるケースを想定していません。
  • バイナリ特徴量はサポートしていません。
  • Classifierの train メソッドのように、1回のRPC実行で複数のデータを登録する一括登録の仕組みはサポートしていません。