本地向量
本地向量(Local vector)是由整型索引和双精度浮点型数值组成的数据结构,本地向量的使用,方便了MLlib对数据的描述和操作。本地向量分为密集型向量(DenseVector)和稀疏型向量(SparseVector )。
本地向量的基类是Vector,有两种实现:DenseVector和SparseVector.推荐使用在Vectors中实现的工厂方法创建本地向量。
密集向量通过一个浮点数组来表示
稀疏向量通过索引和值两个并列的数组来表示
package MLlib.localvector
import org.apache.spark.mllib.linalg.{Vector,Vectors}
object LocalVector {
def main(args: Array[String]): Unit = {
// 创建一个密集向量
val dv:Vector = Vectors.dense(1.0,2.0,3.0)
// 打印密集向量的第2个值
println(dv(1)) // 2.0
// 创建稀疏向量方式1
// 向量长度+索引数组+值数组
val sv1:Vector = Vectors.sparse(3,Array(0,2),Array(1.0,3.0))
// 打印稀疏向量的第3个值
println(sv1(2)) // 3.0
// 创建稀疏向量方式2
// 向量长度+索引数组+值数组
val sv2:Vector = Vectors.sparse(3,Seq((0,1.0),(2,3.0)))
// 打印稀疏向量的第2个值
println(sv2(2)) // 3.0
}
}
标签点
- 标签点有一个本地向量(密集或稀疏)和一个类标签组成。
- 在机器学习中,标签点用于监督学习算法。
- 用双精度浮点型来存储标签,因此可以在回归和分类中使用标签点
- 在二元分类中(binary classification),标签或为0(负标记)或为1(正标记)
- 在多元分类中,标签从0开始索引,如0,1,2,…
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.regression.LabeledPoint
object LP {
def main(args: Array[String]): Unit = {
// 使用正标记和密集向量来创建标签点
val pos = LabeledPoint(1.0,Vectors.dense(1.0,2.0,3.0))
// 打印标签标记的数据
println(pos.features)
// 打印标签
println(pos.label)
// 使用负标记和稀疏向量来创建标签点
val neg = LabeledPoint(1.0,Vectors.sparse(3,Array(0,2),Array(1.0,3.0)))
}
}
实际运用中,稀疏数据是很常见的,在MLlib可以读取以libSVM格式存储的训练实例。其中libSVM格式是LIBSVM和LIBLINEAR的默认格式,每行代表一个含类标签的稀疏特征向量,格式如下:
label index1:value1 index2:value2 …
索引从1开始并且递增,加载完成后,索引被转换为从0开始,代码如下:
import org.apache.spark.mllib.regression.LabeledPoint
import org.apache.spark.mllib.util.MLUtils
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
object LP {
def main(args: Array[String]): Unit = {
val conf = new SparkConf()
.setAppName("Labeled Point")
.setMaster("local")
val sc = new SparkContext(conf)
val example:RDD[LabeledPoint] = MLUtils.loadLibSVMFile(sc,"D:/bigdata/project_all/spark-scala/sample_libsvm_data")
example.foreach(println)
}
}
//输出:
(1.0,(5,[0,1,2],[2.0,3.0,4.0]))
(2.0,(5,[1,2,3],[3.0,4.0,5.0]))
(3.0,(5,[2,3,4],[4.0,5.0,6.0]))
本地矩阵
MLlib中的矩阵其实就是向量型的RDD,分为本地矩阵和分布式矩阵。
本地矩阵由整型行列索引数据和双精度浮点型值数据组成并存储。MLlib支持密集矩阵,实体值以列优先的方式存储在一个双精度浮点型数组中。MLlib也支持稀疏矩阵,非0实体值以列优先的Compressed Sparse Column (CSC) 格式存储。
import org.apache.spark.mllib.linalg.{Matrices, Matrix}
object LM {
def main(args: Array[String]): Unit = {
val dm:Matrix = Matrices.dense(3,2,Array(1.0,3.0,5.0,2.0,4.0,6.0))
println(dm)
//输出:
1.0 2.0
3.0 4.0
5.0 6.0
// 三行两列
// 第一个数组:Array从0开始,数字1代表第0列元素个数,数字3代表第0列元素个数+第1列元素个数
// 第二个数组:非0元素所在的行
// 第三个数组:非零元素
val sm: Matrix = Matrices.sparse(3, 2, Array(0, 1, 3), Array(0, 2, 1), Array(9, 6, 8))
println(sm)
//输出:
3 x 2 CSCMatrix
(0,0) 9.0
(2,1) 6.0
(1,1) 8.0
}
}
分布式矩阵
行矩阵
行矩阵是一个面向行的分布式矩阵,行索引没有具体含义
package mllib.datatype
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.linalg.distributed.RowMatrix
import org.apache.spark.{SparkConf, SparkContext}
object RM {
def main(args: Array[String]): Unit = {
// 定义一个本地向量的RDD
val conf = new SparkConf()
.setAppName("RowMatrix")
.setMaster("local")
val sc = new SparkContext(conf)
val rdd = sc.textFile("D:/bigdata/project_all/spark-scala/sample_libsvm_data")
.map(_.split(" ") //按“ ”分割
.map(_.toDouble)) //转成Double类型
.map(line => Vectors.dense(line)) //转成Vector格式
val rm = new RowMatrix(rdd) //读入行矩阵
println(rm.numRows()) //打印列数
println(rm.numCols())
}
}
//数据:
1 2 3
4 5 6