14. DataFrameでのスカラ整数を扱うプログラム
▪ 全てSparkが生成したコードを実行する
▪ int型の足し算を実行する、きれいなJavaコードが生成される
– DataframeがSpark内でvalueがint型であることを知っている
– Project Tungstenで高速化のために導入した列の独自データ構造表現から、整
数を読み出し、intを使ったJavaコードを生成する
14
while (itr.hasNext()) { // execute a row
// get a value from a row in DF
int value =((Row)itr.next()).getInt(0);
// compute a new value
int mapValue = value + 1;
// store a new value to a row in DF
outRow.write(0, mapValue);
append(outRow);
}
// df: DataFrame for int …
df.selectExpr(“value + 1”)
コード
生成
DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
Catalystで
Javaコードを
生成
列の独自データ構造(Row)
row.getInt(0)
outRow.write(0, …)
15. Datasetでのスカラ整数を扱うプログラム@Spark 2.0
▪ ラムダ式はScalacのコードを、それ以外はSparkが生成したコードを実行
▪ 4つのデータ型変換(intとIntegerオブジェクト)を含む、複雑なJavaコー
ドが生成される
– Scalaのラムダ式の標準インタフェース apply(Object) を使うため、Integerオブ
ジェクトを使う必要がある
15
コード
生成
DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
Catalystで
Javaコードを
生成
// ds: Dataset[Int] …
ds.map(value => value + 1)
while (itr.hasNext()) {
int value = ((Row)itr.next()).getInt(0);
Object objValue = new Integer(value);
int mapValue = ((Integer)
mapFunc.apply(objVal)).toValue();
outRow.write(0, mapValue);
append(outRow);
}
Object apply(Object obj) {
int value = Integer(obj).toValue();
return new Integer(apply$II(value));
}
int apply$II(int value) { return value + 1; }
Scalacがラムダ式から
生成したコード
16. Spark 2.2でどのように改善したか?
▪ DataFrameと同様に、 int型の足し算を実行する、きれいなJavaコードを
生成する(SPARK-19008)
– Scalacが apply$II(int) というコードを出すことを知って、Sparkが生成した
コードからをObjectを使わず、apply$II(int)を直呼びするコードを生成する
16
コード
生成
DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
Catalystで
Javaコードを
生成
// ds: Dataset[Int] …
ds.map(value => value + 1)
while (itr.hasNext()) {
int value = ((Row)itr.next()).getInt(0);
int mapValue = mapFunc.apply$II(value);
outRow.write(0, mapValue);
append(outRow);
}
int apply$II(int value) { return value + 1; }
Scalacがラムダ式から
生成したコード
36. DatasetはSpark ML pipelineの中でどう使われている?
▪ ML Pipelineを構築するために、Datasetは使われている
▪ 個々のMLアルゴリズムを見ると、実は内部ではRDDに変換して処理を
行っている
– 主に記述力(ループ、その他)の問題?
– RDDとDatasetの変換は実行時オーバヘッドを発生する
36 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
val trainingDS: Dataset = ...
val tokenizer = new Tokenizer()
val hashingTF = new HashingTF()
val lr = new LogisticRegression()
val pipeline = new Pipeline().setStages(
Array(tokenizer, hashingTF, lr))
val model = pipeline.fit(trainingDS)
def fit(ds: Dataset[_]) = {
...
train(ds)
}
def train(ds:Dataset[_]):LogisticRegressionModel = {
val instances: RDD[Instance] =
ds.select(...).rdd.map { // convert DS to RDD
case Row(...) => ...
}
instances.persist(...)
instances.treeAggregate(...)
}
ML pipeline Machine learning algorithm (LogisticRegression)
37. もし、DatasetをMLアルゴリズムの記述に使ったら
▪ ML Pipelineを構築するために、Datasetを使う
▪ MLアルゴリズムもDataset上のデータに対して処理を行う
– データ変換オーバヘッドが無くなる
– Catalystによる最適化が適用される(もしSPARK-14083がマージされたら)
37 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
val trainingDataset: Dataset = ...
val tokenizer = new Tokenizer()
val hashingTF = new HashingTF()
val lr = new LogisticRegression()
val pipeline = new Pipeline().setStages(
Array(tokenizer, hashingTF, lr))
val model = pipeline.fit(trainingDataset)
def train(ds:Dataset[_]):LogisticRegressionModel = {
val instances: Dataset[Instance] =
ds.select(...).rdd.map {
case Row(...) => ...
}
instances.persist(...)
instances.treeAggregate(...)
}
ML pipeline
Machine learning algorithm (LogisticRegression)