scalaNLP是用于机器学习和数值计算的一个scala工具库,大数据分析工具spark就集成了它。
它包含Breeze和Epic两个工具,前者适用于机器学习和数值计算,后者则可以用于统计分析预测。
今天花了点时间初步了解了下breeze这个工具。
创建向量和矩阵
现在的计算机数学离不开向量和矩阵,特别是机器学习,所以对于这类工具,要创造一个矩阵和向量,并对其的一些四则运算提供很方便的方法是最重要的。
像matlab那样,直接字面量就可以构造,也有简单的方式创建一些特殊的矩阵,像numpy也可以使用一些简单的方式去构造,比如np.arange(0, 30, 2),当然breeze限于scala语言的特性,也充分的利用了scala语言的特性,提供了一些简单的方式去创建向量。
下面有个跟numpy的对比
Operation | Breeze | Numpy |
---|---|---|
Zeroed matrix | DenseMatrix.zeros[Double](n,m) |
zeros((n,m)) |
Zeroed vector | DenseVector.zeros[Double](n) |
zeros(n) |
Vector of ones | DenseVector.ones[Double](n) |
ones(n) |
Vector of particular number | DenseVector.fill(n){5.0} |
ones(n) * 5 |
n element range | linspace(start,stop,numvals) |
|
Identity matrix | DenseMatrix.eye[Double](n) |
eye(n) |
Diagonal matrix | diag(DenseVector(1.0,2.0,3.0)) |
diag((1,2,3)) |
Matrix inline creation | DenseMatrix((1.0,2.0), (3.0,4.0)) |
array([ [1,2], [3,4] ]) |
Column vector inline creation | DenseVector(1,2,3,4) |
array([1,2,3,4]) |
Row vector inline creation | DenseVector(1,2,3,4).t |
array([1,2,3]).reshape(-1,1) |
Vector from function | DenseVector.tabulate(3){i => 2*i} |
|
Matrix from function | DenseMatrix.tabulate(3, 2){case (i, j) => i+j} |
|
Vector creation from array | new DenseVector(Array(1, 2, 3, 4)) |
|
Matrix creation from array | new DenseMatrix(2, 3, Array(11, 12, 13, 21, 22, 23)) |
|
Vector of random elements from 0 to 1 | DenseVector.rand(4) |
|
Matrix of random elements from 0 to 1 | DenseMatrix.rand(2, 3) |
numpy我其实没用过的,从图中对比,其实两者的创建都很方便,其实如果import breeze.linalg.DenseVector._ 可以省略掉DenseVector。(但请注意别跟其他的方法冲突了)
简单使用案例
import breeze.linalg._
import breeze.stats.distributions.{Binomial, Poisson}
val x = DenseVector.zeros[Double](5) // 创建长度为5的0向量
x(0)
x(1) = 2 // 将向量的第二个值改为2
x(1)
x(3 to 4) := 0.5 //将向量的第四个和第五个值改为0.5
x
x(1)
val m = DenseMatrix.zeros[Int](5,5) // 创建一个5*5的0矩阵
(m.rows, m.cols)
val p = Poisson(3.0) // 创建一个λ为3.0的泊松分布
p.sample(10) // 获取泊松分布一个大小为10的样本
val b = Binomial(10, 0.5) // 创建一个n为10,成功概率为0.5的二项分布
b.sample(3) // 获取二项分布的三个样本
使用起来很简单的。
矩阵向量的一些基本运算
这里同样的先给出一些比较
Operation | Breeze | Matlab | Numpy |
---|---|---|---|
Elementwise addition | a + b |
a + b |
a + b |
Elementwise multiplication | a :* b |
a .* b |
a * b |
Elementwise comparison | a :< b |
a < b (gives matrix of 1/0 instead of true/false) |
a < b |
Inplace addition | a :+= 1.0 |
a += 1 |
a += 1 |
Inplace elementwise multiplication | a :*= 2.0 |
a *= 2 |
a *= 2 |
Vector dot product | a dot b ,a.t * b † |
dot(a,b) |
dot(a,b) |
Elementwise sum | sum(a) |
sum(sum(a)) |
a.sum() |
Elementwise max | a.max |
max(a) |
a.max() |
Elementwise argmax | argmax(a) |
argmax(a) |
a.argmax() |
Ceiling | ceil(a) |
ceil(a) |
ceil(a) |
Floor | floor(a) |
floor(a) |
floor(a) |
其实如果这里没有大家想要的运算,或者大家对这些不熟的话,breeze的矩阵和向量也提供了map、reduce等操作。
一些例子:
import breeze.linalg._
val a = DenseVector(1,2,4,5,6)
val b = DenseVector(4,5,6,7,8)
val c = a + b
val res = a dot b
val m = max(c)
val d = c *:* 2
val su = sum(a)
上述结果
iimport breeze.linalg._
a: breeze.linalg.DenseVector[Int] = DenseVector(1, 2, 4, 5, 6)
b: breeze.linalg.DenseVector[Int] = DenseVector(4, 5, 6, 7, 8)
c: breeze.linalg.DenseVector[Int] = DenseVector(5, 7, 10, 12, 14)
res: Int = 121
m: Int = 14
d: breeze.linalg.DenseVector[Int] = DenseVector(10, 14, 20, 24, 28)
su: Int = 18
res0: Int = 4
Broadcasting
有的时候我们想把矩阵中的每一行或者每一列作为一个单元去做运算,比如下面的例子:
import breeze.stats.mean
val x = DenseMatrix((1,2,3),(4,5,6))
x(::, *) + DenseVector(1,2)
mean(x(*, ::))
结果
import breeze.stats.mean
x: breeze.linalg.DenseMatrix[Double] = 1.0 2.0 3.0
4.0 5.0 6.0
res1: breeze.linalg.DenseMatrix[Double] = 2.0 3.0 4.0
6.0 7.0 8.0
res2: breeze.linalg.DenseVector[Double] = DenseVector(2.0, 5.0)
概率分布
breeze内置了很多概率分布,如泊松分布、正态分布等。
import breeze.stats.distributions._
import breeze.stats._
val p = Poisson(3.0)
val samp = p.sample(10)
val posi = samp.map(p.probabilityOf)
val doublePoi = for(x <- p) yield x.toDouble
meanAndVariance(doublePoi.samples.take(1000))
p.mean
p.variance
结果
import breeze.stats.distributions._
import breeze.stats._
p: breeze.stats.distributions.Poisson = Poisson(3.0)
samp: IndexedSeq[Int] = Vector(1, 2, 3, 3, 0, 2, 4, 4, 2, 4)
posi: IndexedSeq[Double] = Vector(0.14936120510359185, 0.22404180765538775, 0.22404180765538775, 0.22404180765538775, 0.049787068367863944, 0.22404180765538775, 0.16803135574154085, 0.16803135574154085, 0.22404180765538775, 0.16803135574154085)
doublePoi: breeze.stats.distributions.Rand[Double] = MappedRand(Poisson(3.0),lew.bing.nlp.A$A28$A$A28$$Lambda$1368/249549676@28b8a031)
res0: breeze.stats.MeanAndVariance = MeanAndVariance(3.0000000000000018,3.141141141141139,1000)
res1: Double = 3.0
res2: Double = 3.0
结语
breeze还有很多的功能,本人的一些高等数学知识都交还给了老师了,对这些功能没有太过深究,限于时间,也不想去写案例了,大家可以去看官方的文档,文档写的很简洁,入门很容易,感兴趣的可以去看看。