概要
- Apache SparkのSparseVector(疎ベクトル)とDenseVector(密ベクトル)についての整理
環境
- Apache Spark 2.4.3
- 機械学習パッケージ spark.ml
SparseVector(疎ベクトル)とは
Sparse(スパース)とは「スカスカしてる」という意味。
あるベクトルの要素に0がたくさん含まれるような場合
たとえば
[0.1,0.0,0.0,0.0,0.3]
というベクトルがあったとき、
このベクトルを表現するには
「最初の要素の値が0.1、最後の要素の値が0.3であり要素数が5である」
という情報だけで十分だよね、という考え方にもとづく。(その他の要素の値は0.0とする)
こうやって、情報量を抑えられるのでメモリも節約できるというのがご利益。
スパースベクトル的なものは、たいていの機械学習ライブラリで実装されてる。
SparkでSparceVector
さて、Sparkでスパースベクトルを作る方法は簡単。
spark.mlパッケージのorg.apache.spark.ml.linalg.SparseVectorを使う。
SparseVectorクラスはインデックスの配列(indices)と値の配列(values)を指定して初期化する
[0.1,0.0,0.0,0.0,0.3]
を作りたいときはインデクスの配列(indices)new int[] { 0, 2 }
と値の配列(values) new double[] { 0.1, 0.5 }
で初期化すればOK
// SparseVector(疎ベクトル)
int size = 3;//ベクトルの要素サイズ
int[] indices = new int[] { 0, 4 };
double[] svalues = new double[] { 0.1, 0.5 };
Vector svec = new SparseVector(size, indices, svalues);
System.out.println("SparseVector=" + Arrays.toString(svec.toArray()));
SparseVector=[0.1, 0.0, 0.0, 0.0, 0.5]
Vector#toArray
で配列化できるが、必要ない場合はもちろん消費されるメモリはindices(添え字の配列)とvalues(値の配列)のみ保持されるのでメモリが節約される。
DenseVector(密ベクトル)とは
スパースベクトルと対をなす。一般的な配列と同じようにベクトルの要素の値をすべて保持してる。
[0.1,0.0,0.0,0.0,0.3]
SparkでDenseVector
DenseVecotrは値の配列(values)を指定して初期化する
[0.1,0.0,0.0,0.0,0.3]
を作りたいときは、その要素数の配列new double[] { 0.1, 0.0, 0.0, 0.0, 0.5 }
を渡して作るのがDenseVector(密ベクトル)
// DenseVector(密ベクトル)
double[] dvalues = new double[] { 0.1, 0.0, 0.0, 0.0, 0.5 };
Vector dvec = new DenseVector(dvalues);
System.out.println("DenseVector=" + Arrays.toString(dvec.toArray()));
DenseVector=[0.1, 0.0, 0.0, 0.0, 0.5]
フルソースコード(Java)
Apache SparkをJavaから使う
package org.riversun.spark;
import java.util.Arrays;
import org.apache.spark.ml.linalg.DenseVector;
import org.apache.spark.ml.linalg.SparseVector;
import org.apache.spark.ml.linalg.Vector;
public class SparkVectorExamples {
public static void main(String[] args) {
// DenseVector(密ベクトル)
double[] dvalues = new double[] { 0.1, 0.0, 0.0, 0.0, 0.5 };
Vector dvec = new DenseVector(dvalues);
System.out.println("DenseVector=" + Arrays.toString(dvec.toArray()));
// SparseVector(疎ベクトル)
int size = 5;// ベクトルの要素サイズ
int[] indices = new int[] { 0, 4 };
double[] svalues = new double[] { 0.1, 0.5 };
Vector svec = new SparseVector(size, indices, svalues);
System.out.println("SparseVector=" + Arrays.toString(svec.toArray()));
}
}
DenseVector=[0.1, 0.0, 0.0, 0.0, 0.5]
SparseVector=[0.1, 0.0, 0.0, 0.0, 0.5]