目次


IBM Analytics Engine を利用して Apache Spark シェル内で Apache SystemML を使用する

Apache SystemML を使用して機械学習とビッグデータのニーズのすべてに対応する

Comments

using-systemML-in-spark-with-IAE手軽に Apache Spark クラスターを起動してハイレベルな計算を処理する?信じようが信じまいと、そのとおりなのです!ここで紹介する手順に従えば、皆さんが考えるより遥かに簡単に Spark クラスターを使用できます。このチュートリアルでは、Apache SystemML を使用して機械学習とビッグデータのニーズのすべてに対処する簡単な方法を紹介します。チュートリアルの手順に従えば、IAE を利用して、Spark シェル内でさっそうと SystemML をセットアップして実行できます。

学習の目的

全体的に見て、SystemML はデータ・サイエンス・プロジェクトの機械学習と計算の部分に使用するものです。Spark シェルにログインして、シェル内に SystemML をロードした上でデータをロードすると、通常の Spark シェル構文を使用して作成する場合よりも遥かに簡潔なコードで線形代数や統計式、行列などを作成できます。SystemML は数学上の調査や機械学習アルゴリズムに役立つだけではありません。Spark 上で SystemML を使用すれば、ローカル・コンピューター上では扱いきれない規模のビッグデータを使って前述のすべてのタスクをこなすことができます。

前提条件

IBM Analytics Engine を利用すると、Web ユーザー・インターフェースを使ってわずか数分で Spark クラスターを起動できます。

このチュートリアルで IBM Analytics Engine と Spark の 2 つをツールとして使用して説明するのは、SystemML の前提条件のすべてに対応するようコンピューターをセットアップする方法、IAE と Spark クラスターをセットアップする方法、SSH を使用してコンピューター上の Spartk に接続する方法、Spark シェルを起動する方法、SystemML をインポートする方法、そしてデータをロードして Scala のサンプルを実行する方法です。かなりの数のタスクですが、すべてこなせることをお約束します。

早速、学習を始めましょう!

所要時間

このチュートリアルの所要時間は約 30 分です。

手順

IBM Analytics Engine サービス・インスタンスを作成する

  1. IBM Cloud にログインし、IBM Analytics Engine サービスを見つけます。または、https://console.bluemix.net/catalog/services/ibm-analytics-engine でこのサービスに直接アクセスすることもできます。
  2. サービスのインスタンスを作成し (このチュートリアルについては、すべてデフォルト設定を受け入れるので構いません)、ページの下部にある「Create (作成)」をクリックします。サービス・インスタンスが作成されるまでに数分かかる場合があります。 IBM Analytics Engine サービス・インスタンスを作成する画面のスクリーンショット
    IBM Analytics Engine サービス・インスタンスを作成する画面のスクリーンショット
  3. クラスターが作成されたら、「Manage (管理)」セクションが表示されていることを確認します。それでなければ、このセクションまでナビゲートしてください!ここには多くの情報が表示されていますが、そのうち、ユーザー名、パスワード、SSH (「Connection Details (接続の詳細)」の下) を後のステップで使えるようにメモしておいてください。 IBM Analytics Engine サービスの「Manage (管理)」セクションのスクリーンショット
    IBM Analytics Engine サービスの「Manage (管理)」セクションのスクリーンショット
  4. まず、SSH が示されている行をコピーします。
  5. ターミナル内に、コピーした SSH の行を貼り付けて Enter キーを押します。
  6. パスワードを求めるプロンプトが出されます。「Manage (管理)」コンソール上に表示されていたパスワードを入力します。

注: このリンク先の IBM Analytics Engine ページは、IBM Analytics Engine の詳細を学ぶのに絶好の資料となります。

ログインしていますか?そうだとしたら、さっそうと SystemML を使い始めることができます!

Spark シェルから SystemML にアクセスする

Fまず、(ターミナルから) SystemML をダウンロードします。

wget https://sparktc.ibmcloud.com/repo/latest/SystemML.jar

次のコードを入力して、SystemML がロードされた Spark シェルにアクセスします。

spark-shell --executor-memory 4G --driver-memory 4G --jars SystemML.jar

Spark シェル (Scala) を使用して MLContext をインポートし、SystemML を起動します。

    import org.apache.sysml.api.mlcontext._
    import org.apache.sysml.api.mlcontext.ScriptFactory._
    val ml = new MLContext(sc)
IAE の Spark クラスター上で起動された ApacheSystemML を示す画面のスクリーンショット
IAE の Spark クラスター上で起動された ApacheSystemML を示す画面のスクリーンショット

おめでとうございます! ご覧のように、Apache SystemML 内ではなく Spark シェル上で SystemML にアクセスしています!

今後は、最後の 2 つの手順を行うだけで Spark シェル上で SystemML にアクセスできます。また、ローカルの Spark シェル上で最後の 2 つの手順を繰り返すこともできます。

Spark シェル上の SystemML を使用してワークロードを実行する

スクリプトをロードして実行する方法を見ていきましょう。その後、データをロードしてサンプルを実行します。こうすることで、Spark シェルと SystemML を十分に理解できるようになります。

この例では、URL から読み込んだスクリプトを使用します。以下に示されている s1 は、URL アドレスから Univar-Stats.dml を読み込んで作成されたものです。

val uniUrl = "https://raw.githubusercontent.com/apache/incubator-systemml/master/scripts/algorithms/Univar-Stats.dml"
val s1 = ScriptFactory.dmlFromUrl(uniUrl)

次のステップでは、情報を並列処理し、2 つの行列を RDD として読み込み、最初の RDD の合計と 2 つ目の RDD の合計を算出してから、メッセージを出力します。

val data1 = sc.parallelize(Array("1.0,2.0", "3.0,4.0"))
val data2 = sc.parallelize(Array("5.0,6.0", "7.0,8.0"))
val s = """
  | s1 = sum(m1);
  | s2 = sum(m2);
  | if (s1 > s2) {
  |  message = "s1 is greater"
  | } else if (s2 > s1) {
  |  message = "s2 is greater"
  | } else {
  |  message = "s1 and s2 are equal"
  | }
  | """

val script = dml(s).in("m1",data1).in("m2", data2).out("s1","s2", "message")

上記のコードを実行すると、以下の結果が出力されるはずです。

script: org.apache.sysml.api.mlcontext.Script =
Inputs:
[1] (RDD) m1: ParallelCollectionRDD[0] at parallelize at <console>:33
[2] (RDD) m2: ParallelCollectionRDD[1] at parallelize at <console>:33

Outputs:
[1] s1
[2] s2
[3] message

スクリプトの情報を出力します。

println(script.info)

以下の結果が出力されるはずです。

Script Type: DML

Inputs:
[1] (RDD) m1: ParallelCollectionRDD[0] at parallelize at <console>:33
[2] (RDD) m2: ParallelCollectionRDD[1] at parallelize at <console>:33

Outputs:
[1] s1
[2] s2
[3] message

Input Parameters:
None

Input Variables:
[1] m1
[2] m2

Output Variables:
[1] s1
[2] s2
[3] message

Symbol Table:
[1] (Matrix) m1: Matrix: null, [-1 x -1, nnz=-1, blocks (1 x 1)], csv, not-dirty
[2] (Matrix) m2: Matrix: null, [-1 x -1, nnz=-1, blocks (1 x 1)], csv, not-dirty

Script String:

s1 = sum(m1);
s2 = sum(m2);
if (s1 > s2) {
message = "s1 is greater"
} else if (s2 > s1) {
message = "s2 is greater"
} else {
message = "s1 and s2 are equal"
}

Script Execution String:
m1 = read('');
m2 = read('');

s1 = sum(m1);
s2 = sum(m2);
if (s1 > s2) {
  message = "s1 is greater"
} else if (s2 > s1) {
message = "s2 is greater"
} else {
  message = "s1 and s2 are equal"
}
write(s1, '');
write(s2, '');
write(message, '');

スクリプトを実行して、結果を取得します。

val results = ml.execute(script)

以下の結果が出力されるはずです。

results: org.apache.sysml.api.mlcontext.MLResults =
[1] (Double) s1: 10.0
[2] (Double) s2: 26.0
[3] (String) message: s2 is greater

一例として、値を x に設定すると、結果を Double 型で取得できます。

val x = results.getDouble("s1")

以下の結果が出力されるはずです。

x: Double = 10.0

値を y に設定します。

val y = results.getDouble("s2")

以下の結果が出力されるはずです。

y: Double = 26.0

以下は、両方を合計する単純な例です。

x + y

以下の結果が出力されるはずです。

res1: Double = 36.0

以下に、上記の例の別のバージョンを示します。この API は Scala で簡単に扱えるように設計されているため、結果を Scala タプルとして取得できます。

val (firstSum, secondSum, sumMessage) = results.getTuple[Double, Double, String]("s1", "s2", "message")

以下の結果が出力されるはずです。

firstSum: Double = 10.0
secondSum: Double = 26.0
sumMessage: String = s2 is greater

この API には他にも実に便利なところがあります。もう 1 つの例として、データをロードして短いコードを入力し、各特徴の標準的な統計値を取り込んだテーブル全体を取得することもできます。

それにはまず、データを Spark に取り込んで SystemML スクリプトを実行します。

val habermanUrl = "http://archive.ics.uci.edu/ml/machine-learning-databases/haberman/haberman.data"
val habermanList = scala.io.Source.fromURL(habermanUrl).mkString.split("\n")
val habermanRDD = sc.parallelize(habermanList)
val habermanMetadata = new MatrixMetadata(306, 4)
val typesRDD = sc.parallelize(Array("1.0,1.0,1.0,2.0"))
val typesMetadata = new MatrixMetadata(1, 4)
val scriptUrl = "https://raw.githubusercontent.com/apache/systemml/master/scripts/algorithms/Univar-Stats.dml"
val script = dmlFromUrl(scriptUrl).in("A", habermanRDD, habermanMetadata).in("K", typesRDD, typesMetadata).in("$CONSOLE_OUTPUT", true).out("baseStats")

val results = ml.execute(script)

以下の結果が出力されるはずです。

    Feature [1]: Scale
     (01) Minimum             | 30.0
     (02) Maximum             | 83.0
     (03) Range               | 53.0
     (04) Mean                | 52.45751633986928
     (05) Variance            | 116.71458266366658
     (06) Std deviation       | 10.803452349303281
     (07) Std err of mean     | 0.6175922641866753
     (08) Coeff of variation  | 0.20594669940735139
     (09) Skewness            | 0.1450718616532357
     (10) Kurtosis            | -0.6150152487211726
     (11) Std err of skewness | 0.13934809593495995
     (12) Std err of kurtosis | 0.277810485320835
     (13) Median              | 52.0
     (14) Interquartile mean  | 52.16013071895425
-------------------------------------------------
    Feature [2]: Scale
     (01) Minimum             | 58.0
     (02) Maximum             | 69.0
     (03) Range               | 11.0
     (04) Mean                | 62.85294117647059
     (05) Variance            | 10.558630665380907
     (06) Std deviation       | 3.2494046632238507
     (07) Std err of mean     | 0.18575610076612029
     (08) Coeff of variation  | 0.051698529971741194
     (09) Skewness            | 0.07798443581479181
     (10) Kurtosis            | -1.1324380182967442
     (11) Std err of skewness | 0.13934809593495995
     (12) Std err of kurtosis | 0.277810485320835
     (13) Median              | 63.0
     (14) Interquartile mean  | 62.80392156862745
-------------------------------------------------
    Feature [3]: Scale
     (01) Minimum             | 0.0
     (02) Maximum             | 52.0
     (03) Range               | 52.0
     (04) Mean                | 4.026143790849673
     (05) Variance            | 51.691117539912135
     (06) Std deviation       | 7.189653506248555
     (07) Std err of mean     | 0.41100513466216837
     (08) Coeff of variation  | 1.7857418611299172
     (09) Skewness            | 2.954633471088322
     (10) Kurtosis            | 11.425776549251449
     (11) Std err of skewness | 0.13934809593495995
     (12) Std err of kurtosis | 0.277810485320835
     (13) Median              | 1.0
     (14) Interquartile mean  | 1.2483660130718954
-------------------------------------------------
    Feature [4]: Categorical (Nominal)
     (15) Num of categories   | 2
     (16) Mode                | 1
     (17) Num of modes        | 1
    results: org.apache.sysml.api.mlcontext.MLResults =
    [1] (Matrix) baseStats: Matrix: scratch_space/_p5250_9.31.116.229/parfor/2_resultmerge1, [17 x 4, nnz=44, blocks (1000 x 1000)], binaryblock, dirty

基本的な統計を SystemML 行列として取得することもできます。

val baseStats = results.getMatrix("baseStats")

以下の結果が出力されるはずです。

baseStats: org.apache.sysml.api.mlcontext.Matrix = org.apache.sysml.api.mlcontext.Matrix@237cd4e5

このような行列であれば、さまざまな形に変換できます!

baseStats.
asDataFrame          asDoubleMatrix       asInstanceOf         asJavaRDDStringCSV   asJavaRDDStringIJV   asMLMatrix           asMatrixObject       asRDDStringCSV
asRDDStringIJV       isInstanceOf         toString

例えば、基本的な統計を RDD として取得できます。注: 数値以外の値は IJV では除外され、CSV では含められます。以下に、この両方の例を示します。

baseStats.toRDDString

次の選択肢が表示されます。

toRDDStringCSV   toRDDStringIJV

CSV で試してみます。

baseStats.toRDDStringCSV.collect

以下の結果が出力されるはずです。

res4: Array[String] = Array(30.0,58.0,0.0,0.0, 83.0,69.0,52.0,0.0, 53.0,11.0,52....1.0)

IJV で試してみます。

baseStats.toRDDStringIJV.collect

以下の結果が出力されるはずです。

res5: Array[String] = Array(1 1 30.0, 1 2 58.0, 1 3 0.0, 1 4 0.0, 2 1 83.0, 2 2 69.0, 2 3 52.0, 2 4 0.0, ... 1...

IBM Analytics Engine 上の Spark シェルで SystemML を使う上で、絶好のスタートを切りました!作業が完了したら、quit を実行して終了できます。

:quit

まとめ

おめでとうございます! チュートリアルに従って見事、IBM Analytics Engine (IAE) 上で SystemML と Spark を実行するようにコンピューターをセットアップし、Spark シェルをロードしてスクリプトを実行し、データをロードしてサンプルを実行しました。新しく身に付けた素晴らしいスキルを活用して世界を救ってください。


ダウンロード可能なリソース


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=ビジネス・アナリティクス
ArticleID=1065890
ArticleTitle=IBM Analytics Engine を利用して Apache Spark シェル内で Apache SystemML を使用する
publish-date=05302019