Spark MLlib 之 Vector向量深入浅出
Spark MLlib里面提供了几种基本的数据类型,虽然大部分在调包的时候用不到,但是在自己写算法的时候,还是很需要了解的。MLlib支持单机版本的local vectors向量和martix矩阵,也支持集群版本的matrix矩阵。他们背后使用的都是ScalaNLP中的Breeze。
更多内容参考我的大数据学习之路
Local Vector
local vector是一种索引是0开始的整数、内容为double类型,存储在单机上的向量。MLlib支持两种矩阵,dense密集型和sparse稀疏型。一个dense类型的向量背后其实就是一个数组,而sparse向量背后则是两个并行数组——索引数组和值数组。比如向量(1.0, 0.0, 3.0)既可以用密集型向量表示为[1.0, 0.0, 3.0],也可以用稀疏型向量表示为(3, [0,2],[1.0,3.0]),其中3是数组的大小。
接口为Vector,看源码可以看到它是用sealed修饰的,在scala里面这种关键字修饰的trait在进行match的时候必须把所有的情况都列出来,不然会报错。相当于强制你考虑向量的时候,必须考虑它是dense型的,还是sparse型的。
sealed trait Vector extends Serializable {
def size: Int // 向量的大小
def toArray: Array[Double] //转换成普通的数组
override def equals(other: Any): Boolean = { // 定义比较方法——感慨,原来这么优秀的框架背后也用穷举
other match {
case v2: Vector =>
if (this.size != v2.size) return false
(this, v2) match {
case (s1: SparseVector, s2: SparseVector) =>
Vectors.equals(s1.indices, s1.values, s2.indices, s2.values)
case (s1: SparseVector, d1: DenseVector) =>
Vectors.equals(s1.indices, s1.values, 0 until d1.size, d1.values)
case (d1: DenseVector, s1: SparseVector) =>
Vectors.equals(0 until d1.size, d1.values, s1.indices, s1.values)
case (_, _) => util.Arrays.equals(this.toArray, v2.toArray)
}
case _ => false
}
}
override def hashCode(): Int = { //好好领略hashcode的魅力
var result: Int = 31 + size
var nnz = 0
this.foreachActive { (index, value) =>
if (nnz < Vectors.MAX_HASH_NNZ) {
if (value != 0) {
result = 31 * result + index
val bits = java.lang.Double.doubleToLongBits(value)
result = 31 * result + (bits ^ (bits >>> 32)).toInt
nnz += 1
}
} else {
return result
}
}
result
}
// 这里面的BV其实是breeze里面的vector,import breeze.linalg.{DenseVector => BDV, SparseVector => BSV, Vector => BV}
// 也就是说,mllib里面的vector其实就是对breeze里面的vector封装了一层而已
private[spark] def asBreeze: BV[Double]
def apply(i: Int): Double = asBreeze(i)
def copy: Vector = {
throw new NotImplementedError(s"copy is not implemented for ${this.getClass}.")
}
def foreachActive(f: (Int, Double) => Unit): Unit
def numActives: Int
def numNonzeros: Int //零的个数
def toSparse: SparseVector
def toDense: DenseVector = new DenseVector(this.toArray) //创建Dense向量还真是简单啊
def compressed: Vector = {
val nnz = numNonzeros
// A dense vector needs 8 * size + 8 bytes, while a sparse vector needs 12 * nnz + 20 bytes.
if (1.5 * (nnz + 1.0) < size) {
toSparse
} else {
toDense
}
}
def argmax: Int //返回里面的最大值
}
Vector有两种实现方式——DenseVector,和SparseVector。
import org.apache.spark.ml.linalg.{Vector,Vectors}
import org.apache.spark.sql.SparkSession
object DataTypes {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder().master("local[*]").appName("tf-idf").getOrCreate()
spark.sparkContext.setLogLevel("WARN")
// 创建dense vector
val dv: Vector = Vectors.dense(1.0, 0.0, 3.0)
// 创建sparse vector
val sv1: Vector = Vectors.sparse(3, Array(0,2), Array(1.0,3.0))
val sv2: Vector = Vectors.sparse(3, Seq((0, 1.0), (2,3.0)))
}
}
其中sparse vector有两种创建方式,第一种是传入三个参数:向量大小、索引数组、索引数组对应的值数组;第二种方式是传入两个参数:向量大小、由索引和值组成的键值对数组。
另外这个Vectors不仅仅有创建dense和sparse的方法,还有几个有用的功能,比如norm范数和sqdist距离。
val norm1Vec = Vectors.dense(1.0,-1.0,2.0)
// 第一范数,就是绝对值相加
println(Vectors.norm(norm1Vec,1)) // 4.0
// 第二番薯,就是平方和开根号
println(Vectors.norm(norm1Vec,2)) // 2.449489742783178
// 无限范数
println(Vectors.norm(norm1Vec,1000)) //2.0
val sq1 = Vectors.dense(1.0, 2.0, 3.0)
val sq2 = Vectors.dense(2.0, 4.0, 6.0)
println(Vectors.sqdist(sq1, sq2)) // (2-1)^2 + (4-2)^2 + (6-3)^2 = 14
通过上面简单的一个Vector,还是能学到不少东西的。
比如sealed关键字的使用,以及工厂方法:
object xxxFactory{
def x1: XXX
def x2: XXX
...
}
trait XXX {}
object X1 extends XXX {}
object X2 extends XXX {}
Labeled Point 有标签的向量
这种labeled point其实内部也是一个vector,可能是dense也可能是sparse,不过多了一个标签列。在ML里面,labeled point通常用于有监督算法。这个label是double类型的,这样既可以用于回归算法,也可以用于分类。在二分类中,Label不是0就是1;在多分类中label可能从0开始,1,2,3,4....
使用的时候很简单,直接new就可以了:
// Create a labeled point with a positive label and a dense feature vector.
val pos = LabeledPoint(1.0, Vectors.dense(1.0, 0.0, 3.0))
// Create a labeled point with a negative label and a sparse feature vector.
val neg = LabeledPoint(0.0, Vectors.sparse(3, Array(0, 2), Array(1.0, 3.0)))
一般在准备训练集数据的时候,数据都是稀疏型的。MMLib支持在SVM和Liner线性回归中直接读取训练数据,但是需要满足下面的格式:
label index1:value1 index2:value2 ...
比如:
val examples: RDD[LabeledPoint] = MLUtils.loadLibSVMFile(sc, "data/mllib/sample_libsvm_data.txt")
Spark MLlib 之 Vector向量深入浅出的更多相关文章
- Spark Mllib里的向量标签概念、构成(图文详解)
不多说,直接上干货! Labeled point: 向量标签 向量标签用于对Spark Mllib中机器学习算法的不同值做标记. 例如分类问题中,可以将不同的数据集分成若干份,以整数0.1.2,... ...
- Spark Mllib里的本地向量集(密集型数据集和稀疏型数据集概念、构成)(图文详解)
不多说,直接上干货! Local vector : 本地向量集 由两类构成:稀疏型数据集(spares)和密集型数据集(dense) (1).密集型数据集 例如一个向量数据(9,5,2,7),可以设 ...
- Spark MLlib Data Type
MLlib 支持存放在单机上的本地向量和矩阵,也支持通过多个RDD实现的分布式矩阵.因此MLlib的数据类型主要分为两大类:一个是本地单机向量:另一个是分布式矩阵.下面分别介绍一下这两大类都有哪些类型 ...
- 推荐系统那点事 —— 基于Spark MLlib的特征选择
在机器学习中,一般都会按照下面几个步骤:特征提取.数据预处理.特征选择.模型训练.检验优化.那么特征的选择就很关键了,一般模型最后效果的好坏往往都是跟特征的选择有关系的,因为模型本身的参数并没有太多优 ...
- Spark MLlib数据类型
MLlib支持几种数据类型:本地向量(local vectors),和存储在一个简单机器中的矩阵(matrices),以及由一个或多个RDDs组成的分布式矩阵. 1,本地向量(Local Ve ...
- Spark MLlib 机器学习
本章导读 机器学习(machine learning, ML)是一门涉及概率论.统计学.逼近论.凸分析.算法复杂度理论等多领域的交叉学科.ML专注于研究计算机模拟或实现人类的学习行为,以获取新知识.新 ...
- Spark mlib的本地向量
Spark mlib的本地向量有两种: DenseVctor :稠密向量 其创建方式 Vector.dense(数据) SparseVector :稀疏向量 其创建方式有两种: 方法一:Vector. ...
- Spark Mllib里的分布式矩阵(行矩阵、带有行索引的行矩阵、坐标矩阵和块矩阵概念、构成)(图文详解)
不多说,直接上干货! Distributed matrix : 分布式矩阵 一般能采用分布式矩阵,说明这数据存储下来,量还是有一定的.在Spark Mllib里,提供了四种分布式矩阵存储形式,均由支 ...
- spark mllib k-means算法实现
package iie.udps.example.spark.mllib; import java.util.regex.Pattern; import org.apache.spark.SparkC ...
随机推荐
- Android: SlidingDrawer(滑动式抽屉)
Android控件之SlidingDrawer(滑动式抽屉)详解与实例 一.简介 SlidingDrawer隐藏屏外的内容,并允许用户通过handle以显示隐藏内容.它可以垂直或水平滑动,它有俩个V ...
- php -- 魔术方法、魔术常量 简单介绍
魔术方法:PHP把类中所有以__(两个下划线)开头的方法当成魔术方法,一般建议用户不要将自定义的方法前面加上__作为前缀.魔术方法: 1. __construct() 类的默认构造方法,如果__con ...
- 如何从现有版本升级到element UI2.0?使用npm-check-updates
转:https://blog.csdn.net/wojiaomaxiaoqi/article/details/78428738 登录element UI官网时提示2.0已经正式发布了,Element ...
- 篮球弹起问题(for循环)
- 【转】ssh服务器启动和客户端常用操作
前言 简单的来说,SSH 是 Secure SHell protocol 的简写 (安全的壳程序协议),它可以透过数据封包加密技术,将等待传输的封包加密后再传输到网络上, 因此,数据讯息当然就比较安全 ...
- 【BZOJ2839】集合计数&&【BZOJ3622】已经没有什么好害怕的了
再谈容斥原理来两道套路几乎一致的题目[BZOJ2839]集合计数Description一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得它们的交 ...
- python小知识-属性查询优先级(如果有同名类属性、数据描述符、实例属性存在的话,实例>类>数据描述符)
https://www.cnblogs.com/Jimmy1988/p/6808237.html https://segmentfault.com/a/1190000006660339 https:/ ...
- 【Java】 剑指offer(56-2) 数组中唯一只出现一次的数字
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 在一个数组中除了一个数字只出现一次之外,其他数字都出现了三次. ...
- [OpenCV-Python] OpenCV 中的图像处理 部分 IV (二)
部分 IVOpenCV 中的图像处理 OpenCV-Python 中文教程(搬运)目录 16 图像平滑 目标 • 学习使用不同的低通滤波器对图像进行模糊 • 使用自定义的滤波器对图像进行卷积(2D 卷 ...
- 重温数据结构:树 及 Java 实现(转)
转自:http://blog.csdn.net/u011240877/article/details/53193877 读完本文你将了解到: 什么是树 树的相关术语 根节点父亲节点孩子节点叶子节点如上 ...