理论原理部分可以看这一篇:http://www.cnblogs.com/charlesblc/p/6109551.html
这里是实战部分。参考了 http://www.cnblogs.com/shishanyuan/p/4747778.html
采用了三个案例,分别对应聚类、回归和协同过滤的算法。
我觉得很好,需要每一个都在实际系统中试一下。
更多api介绍可以参考 http://spark.apache.org/docs/2.0.1/ml-guide.html
1.1 聚类实例
1.1.1 算法说明
聚类(Cluster analysis)有时也被翻译为簇类,其核心任务是:将一组目标object划分为若干个簇,每个簇之间的object尽可能相似,簇与簇之间的object尽可能相异。聚类算法是机器学习(或者说是数据挖掘更合适)中重要的一部分,除了最为简单的K-Means聚类算法外,比较常见的还有层次法(CURE、CHAMELEON等)、网格算法(STING、WaveCluster等),等等。
较权威的聚类问题定义:所谓聚类问题,就是给定一个元素集合D,其中每个元素具有n个可观察属性,使用某种算法将D划分成k个子集,要求每个子集内部的元素之间相异度尽可能低,而不同子集的元素相异度尽可能高。其中每个子集叫做一个簇。
K-means聚类属于无监督学习,以往的回归、朴素贝叶斯、SVM等都是有类别标签y的,也就是说样例中已经给出了样例的分类。而聚类的样本中却没有给定y,只有特征x,比如假设宇宙中的星星可以表示成三维空间中的点集(a,b,c)。聚类的目的是找到每个样本x潜在的类别y,并将同类别y的样本x放在一起。比如上面的星星,聚类后结果是一个个星团,星团里面的点相互距离比较近,星团间的星星距离就比较远了。
监督学习与无监督学习的内容可以看这里:
https://www.zhihu.com/question/23194489
这个问题可以回答得很简单:是否有监督(supervised),就看输入数据是否有标签(label)。输入数据有标签,则为有监督学习,没标签则为无监督学习。(我理解,特征是input, 标签是output)
在上述的分类过程中,如果所有训练数据都有标签,则为有监督学习(supervised learning)。如果数据没有标签,显然就是无监督学习(unsupervised learning)了,也即聚类(clustering)。(注:也可以理解为,聚类是没有标签输入的分类) 但有监督学习并非全是分类,还有回归(regression)。
这时各位可能要问,既然分类如此之好,聚类如此之不靠谱(分类<( ̄︶ ̄)/,聚类└(T_T;)┘),那为何我们还可以容忍聚类的存在?因为在实际应用中,标签的获取常常需要极大的人工工作量,有时甚至非常困难。例如在自然语言处理(NLP)中,Penn Chinese Treebank在2年里只完成了4000句话的标签……
这时有人可能会想,难道有监督学习和无监督学习就是非黑即白的关系吗?有没有灰呢?Good idea。灰是存在的。二者的中间带就是半监督学习(semi-supervised learning)。
对于半监督学习,其训练数据的一部分是有标签的,另一部分没有标签,而没标签数据的数量常常极大于有标签数据数量(这也是符合现实情况的)。隐藏在半监督学习下的基本规律在于:数据的分布必然不是完全随机的,通过一些有标签数据的局部特征,以及更多没标签数据的整体分布,就可以得到可以接受甚至是非常好的分类结果。(此处大量忽略细节( ̄ε ̄;))
有监督学习(分类,回归)
↕
半监督学习(分类,回归),transductive learning(不懂怎么翻译,直推式学习?)(分类,回归)
↕
半监督聚类(有标签数据的标签不是确定的,类似于:肯定不是xxx,很可能是yyy)
↕
无监督学习(聚类)
另外,还有如下回答也不错:
机器(计算机)学习分为有监督和无监督两个类,基本上可以从他们会不会得到一个特定的标签(label)输出来区分。
有监督学习(Supervised Learning):
先来问题化地解释一下有监督学习:你有一些问题和他们的答案,你要做的有监督学习就是学习这些已经存在的问题和他们的答案。然后你就具备了经验了,这就是学习过成果。然后在你接受到一个新的不知道答案的问题的时候,你可以根据学习的结果,得出答案。
我们有一个样本数据集,如果对于每一个单一的数据根据它的特征向量我们要去判断它的标签(算法的输出值),那么就是有监督学习。通俗的说,有监督学习就是比无监督学习多了一个可以表达这个数据特质的标签。
我们再来看有监督学习,分为两个大类:
1.回归分析(Regression Analysis):回归分析,其数据集是给定一个函数和它的一些坐标点,然后通过回归分析的算法,来估计原函数的模型,求出一个最符合这些已知数据集的函数解析式。然后它就可以用来预估其它未知输出的数据了,你输入一个自变量它就会根据这个模型解析式输出一个因变量,这些自变量就是特征向量,因变量就是标签。 而且标签的值是建立在连续范围的。
2.分类(Classification):其数据集,由特征向量和它们的标签组成,当你学习了这些数据之后,给你一个只知道特征向量不知道标签的数据,让你求它的标签是哪一个?其和回归的主要区别就是输出结果是离散的还是连续的。
无监督学习(Unsupervised Learning):
“Because we don't give it the answer, it's unsupervised learning”。
还是先来问题化地解释一下无监督学习:我们有一些问题,但是不知道答案,我们要做的无监督学习就是按照他们的性质把他们自动地分成很多组,每组的问题是具有类似性质的(比如数学问题会聚集在一组,英语问题会聚集在一组,物理........)。
所有数据只有特征向量没有标签,但是可以发现这些数据呈现出聚群的结构,本质是一个相似的类型的会聚集在一起。把这些没有标签的数据分成一个一个组合,就是聚类(Clustering)。比如Google新闻,每天会搜集大量的新闻,然后把它们全部聚类,就会自动分成几十个不同的组(比如娱乐,科技,政治......),每个组内新闻都具有相似的内容结构。
无监督学习还有一个典型的例子就是鸡尾酒会问题(声音的分离),在这个酒会上有两种声音,被两个不同的麦克风在不同的地方接收到,而可以利用无监督学习来分离这两种不同的声音。注意到这里是无监督学习的原因是,事先并不知道这些声音中有哪些种类(这里的种类就是标签的意思)。
上面可以看出,回归分析的标准答案是连续的,分类的答案是离散的。
回归(regression)与分类(classification)的区别也可以参考这篇文章:
https://my.oschina.net/zzw922cn/blog/544221?p=1
1.回归问题的应用场景
回归问题通常是用来预测一个值,如预测房价、未来的天气情况等等,例如一个产品的实际价格为500元,通过回归分析预测值为499元,我们认为这是一个比较好的回归分析。一个比较常见的回归算法是线性回归算法(LR)。另外,回归分析用在神经网络上,其最上层是不需要加上softmax函数的,而是直接对前一层累加即可。回归是对真实值的一种逼近预测。
2.分类问题的应用场景
分类问题是用于将事物打上一个标签,通常结果为离散值。例如判断一幅图片上的动物是一只猫还是一只狗,分类通常是建立在回归之上,分类的最后一层通常要使用softmax函数进行判断其所属类别。分类并没有逼近的概念,最终正确结果只有一个,错误的就是错误的,不会有相近的概念。最常见的分类方法是逻辑回归,或者叫逻辑分类。
注:Softmax可以看这里:
http://blog.csdn.net/acdreamers/article/details/44663305
广义线性模型的一个重要例子,它可以看成是Logistic回归的扩展,即softmax回归。 我们知道Logistic回归只能进行二分类,因为它的随机变量的取值只能是0或者1,那么如果我们面对多分类问题怎么
办?比如要将一封新收到的邮件分为垃圾邮件,个人邮件,还是工作邮件;根据病人的病情预测病人属于哪种病;对于
诸如MNIST手写数字分类(MNIST是一个手写数字识别库,相见:http://yann.lecun.com/exdb/mnist/)。诸
如此类问题都涉及到多分类,那么今天要讲的softmax回归能解决这类问题。
3.如何选择模型
下面一幅图可以告诉实际应用中我们如何选择合适的模型。
再回到本文的主题,机器学习实战
回到参考这篇文章: http://www.cnblogs.com/shishanyuan/p/4747778.html
与分类不同,分类是示例式学习,要求分类前明确各个类别,并断言每个元素映射到一个类别。
而聚类是观察式学习,在聚类前可以不知道类别甚至不给定类别数量,是无监督学习的一种。目前聚类广泛应用于统计学、生物学、数据库技术和市场营销等领域,相应的算法也非常多。
1.1.2 实例介绍
在该实例中将介绍K-Means算法,K-Means属于基于平方误差的迭代重分配聚类算法,其核心思想十分简单:
l随机选择K个中心点;
l计算所有点到这K个中心点的距离,选择距离最近的中心点为其所在的簇;
l简单地采用算术平均数(mean)来重新计算K个簇的中心;
l重复步骤2和3,直至簇类不再发生变化或者达到最大迭代值;
l输出结果。
注,我的理解:就是先选K个点,然后把点都分到K个簇里面;然后对相同的簇的点,重新计算这个簇里面的中心点;然后再对所有的点,用这个中心点进行计算。
K-Means算法的结果好坏依赖于对初始聚类中心的选择,容易陷入局部最优解,对K值的选择没有准则可依循,对异常数据较为敏感,只能处理数值属性的数据,聚类结构可能不平衡。
来一个实例吧。按照注释,可以看出步骤。
package com.spark.my import org.apache.log4j.{Level, Logger}
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.mllib.clustering.KMeans
import org.apache.spark.mllib.linalg.Vectors /**
* Created by baidu on 16/11/28.
*/
object Kmeans {
def main(args: Array[String]) { //Logger.getLogger("org.apache.spark").setLevel(Level.WARN)
val conf = new SparkConf()
val sc = new SparkContext(conf) println("Begin text")
// 装载数据集
val text = sc.textFile("hdfs://master.Hadoop:8390/kmeans/kmeans_data.txt")
val parsedData = text.map(s=>Vectors.dense(s.split(' ').map(_.toDouble))) println("Begin kmeans")
// 聚类,2个类,20次迭代
val numCluster = 2
val numIterations = 20
val model = KMeans.train(parsedData, numCluster, numIterations) println("Print kmeans centers:")
// 打印中心点
for (c <- model.clusterCenters) {
println(" " + c.toString)
} // 用误差平方之和来评估
val cost = model.computeCost(parsedData)
println("Within Set Sum of Squared Errors = " + cost) // 使用模型测试单点数据
println("Vectors 0.2 0.2 0.2 is belongs to cluster:" + model.predict(Vectors.dense("0.2 0.2 0.2".split(' ').map(_.toDouble))))
println("Vectors 0.25 0.25 0.25 is belongs to cluster:" + model.predict(Vectors.dense("0.25 0.25 0.25".split(' ').map(_.toDouble))))
println("Vectors 8 8 8 is belongs to cluster:" + model.predict(Vectors.dense("8 8 8".split(' ').map(_.toDouble)))) // 交叉评估 Cross Validation
// 因为聚类是无监督学习,是不是交叉验证不好弄?
val testdata = text.map(s=>Vectors.dense(s.split(' ').map(_.toDouble)))
val result1 = model.predict(testdata)
result1.saveAsTextFile("hdfs://master.Hadoop:8390/kmeans-result1") // 交叉评估2, 返回数据集和结果
val result2 = text.map {
line=>
val oldline = Vectors.dense(line.split(' ').map(_.toDouble))
val predict = model.predict(oldline)
line + " " + predict
}.saveAsTextFile("hdfs://master.Hadoop:8390/kmeans-result2") sc.stop()
println("All elements done") }
}
然后在m42n05机器上面建一个文件 kmeans_data.txt,内容:
0.0 0.0 0.0
0.1 0.1 0.1
0.2 0.2 0.2
9.0 9.0 9.0
9.1 9.1 9.1
9.2 9.2 9.2
放到hadoop上:
$ hadoop fs -mkdir /kmeans
注意,要加 / $ hadoop fs -put kmeans_data.txt /kmeans
运行命令:
./bin/spark-submit --class com.spark.my.Kmeans --master spark://10.117.146.12:7077 myjars/scala-demo.jar 运行成功。发现打了好多日志呀。看来是要把日志级别调成WARNING。
其中有一些日志如下: Print kmeans centers:
[0.1,0.1,0.1]
[9.099999999999998,9.099999999999998,9.099999999999998] Within Set Sum of Squared Errors = 0.11999999999994547
Vectors 0.2 0.2 0.2 is belongs to cluster:0
Vectors 0.25 0.25 0.25 is belongs to cluster:0
Vectors 8 8 8 is belongs to cluster:1
然后用hadoop命令看输出文件:
$ hadoop fs -ls /kmeans-result1
Found 3 items
-rw-r--r-- 3 work supergroup 0 2016-12-12 00:26 /kmeans-result1/_SUCCESS
-rw-r--r-- 3 work supergroup 8 2016-12-12 00:26 /kmeans-result1/part-00000
-rw-r--r-- 3 work supergroup 4 2016-12-12 00:26 /kmeans-result1/part-00001 $ hadoop fs -cat /kmeans-result1/part-00000
0
0
0
1 $ hadoop fs -cat /kmeans-result1/part-00001
1
1
再看kmeans-result2:
$ hadoop fs -cat /kmeans-result2/part-00000
0.0 0.0 0.0 0
0.1 0.1 0.1 0
0.2 0.2 0.2 0
9.0 9.0 9.0 1 $ hadoop fs -cat /kmeans-result2/part-00001
9.1 9.1 9.1 1
9.2 9.2 9.2 1
可以merge一下的:
$ hdfs dfs -getmerge hdfs://master.Hadoop:8390/kmeans-result2 /home/work/data/kmeans-result2 $ cat /home/work/data/kmeans-result2
0.0 0.0 0.0 0
0.1 0.1 0.1 0
0.2 0.2 0.2 0
9.0 9.0 9.0 1
9.1 9.1 9.1 1
9.2 9.2 9.2 1
好了,这样基本的聚类算法就实战完成了。
回归算法实例
1.2.1 算法说明
线性回归是利用称为线性回归方程的函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析方法,只有一个自变量的情况称为简单回归,大于一个自变量情况的叫做多元回归,在实际情况中大多数都是多元回归。
线性回归(Linear Regression)问题属于监督学习(Supervised Learning)范畴,又称分类(Classification)或归纳学习(Inductive Learning)。
这类分析中训练数据集中给出的数据类型是确定的。机器学习的目标是,对于给定的一个训练数据集,通过不断的分析和学习产生一个联系属性集合和类标集合的分类函数(Classification Function)或预测函数)Prediction Function),这个函数称为分类模型(Classification Model——或预测模型(Prediction Model)。通过学习得到的模型可以是一个决策树、规格集、贝叶斯模型或一个超平面。通过这个模型可以对输入对象的特征向量预测或对对象的类标进行分类。
回归问题中通常使用最小二乘(Least Squares)法来迭代最优的特征中每个属性的比重,通过损失函数(Loss Function)或错误函数(Error Function)定义来设置收敛状态,即作为梯度下降算法的逼近参数因子。
最小二乘法可见:http://www.cnblogs.com/iamccme/archive/2013/05/15/3080737.html
我们以最简单的一元线性模型来解释最小二乘法。什么是一元线性模型呢? 监督学习中,如果预测的变量是离散的,我们称其为分类(如决策树,支持向量机等),如果预测的变量是连续的,我们称其为回归。回归分析中,如果只包括一个自变量和一个因变量,且二者的关系可用一条直线近似表示,这种回归分析称为一元线性回归分析。如果回归分析中包括两个或两个以上的自变量,且因变量和自变量之间是线性关系,则称为多元线性回归分析。对于二维空间线性是一条直线;对于三维空间线性是一个平面,对于多维空间线性是一个超平面...
对于一元线性回归模型, 假设从总体中获取了n组观察值(X1,Y1),(X2,Y2), …,(Xn,Yn)。对于平面中的这n个点,可以使用无数条曲线来拟合。要求样本回归函数尽可能好地拟合这组值。综合起来看,这条直线处于样本数据的中心位置最合理。 选择最佳拟合曲线的标准可以确定为:使总的拟合误差(即总残差)达到最小。有以下三个标准可以选择: (1)用“残差和最小”确定直线位置是一个途径。但很快发现计算“残差和”存在相互抵消的问题。
(2)用“残差绝对值和最小”确定直线位置也是一个途径。但绝对值的计算比较麻烦。
(3)最小二乘法的原则是以“残差平方和最小”确定直线位置。用最小二乘法除了计算比较方便外,得到的估计量还具有优良特性。这种方法对异常值非常敏感。
最小二乘法与梯度下降法
最小二乘法跟梯度下降法都是通过求导来求损失函数的最小值,那它们有什么区别呢。
相同
1.本质相同:两种方法都是在给定已知数据(independent & dependent variables)的前提下对dependent variables算出出一个一般性的估值函数。然后对给定新数据的dependent variables进行估算。
2.目标相同:都是在已知数据的框架内,使得估算值与实际值的总平方差尽量更小(事实上未必一定要使用平方),估算值与实际值的总平方差的公式为:
不同
1.实现方法和结果不同:最小二乘法是直接对求导找出全局最小,是非迭代法。
而梯度下降法是一种迭代法,先给定一个,然后向下降最快的方向调整,在若干次迭代之后找到局部最小。梯度下降法的缺点是到最小点的时候收敛速度变慢,并且对初始点的选择极为敏感,其改进大多是在这两方面下功夫。
上面这个还是讲的不太好,更好的对比是看:https://www.zhihu.com/question/20822481
最小二乘法的目标:求误差的最小平方和,对应有两种:线性和非线性。线性最小二乘的解是closed-form即
而非线性最小二乘没有closed-form,通常用迭代法求解。
这下懂了,非线性压根没有除了迭代法之外的最小二乘法。(或者有下面的高斯-牛顿法)
梯度下降是迭代法的一种,可以用于求解最小二乘问题(线性和非线性都可以)。高斯-牛顿法是另一种经常用于求解非线性最小二乘的迭代法(一定程度上可视为标准非线性最小二乘求解方法)。
还有一种叫做Levenberg-Marquardt的迭代法用于求解非线性最小二乘问题,就结合了梯度下降和高斯-牛顿法。
所以如果把最小二乘看做是优化问题的话,那么梯度下降是求解方法的一种,上面的公式是求解线性最小二乘的一种,高斯-牛顿法和Levenberg-Marquardt则能用于求解非线性最小二乘。
1.2.2 实例介绍
该例子给出了如何导入训练集数据,将其解析为带标签点的RDD,然后使用了LinearRegressionWithSGD 算法来建立一个简单的线性模型来预测标签的值,最后计算了均方差来评估预测值与实际值的吻合度。
线性回归分析的整个过程可以简单描述为如下三个步骤:
(1)寻找合适的预测函数,即上文中的 h(x) ,用来预测输入数据的判断结果。这个过程是非常关键的,需要对数据有一定的了解或分析,知道或者猜测预测函数的“大概”形式,比如是线性函数还是非线性函数,若是非线性的则无法用线性回归来得出高质量的结果。
(2)构造一个Loss函数(损失函数),该函数表示预测的输出(h)与训练数据标签之间的偏差,可以是二者之间的差(h-y)或者是其他的形式(如平方差开方)。综合考虑所有训练数据的“损失”,将Loss求和或者求平均,记为 J(θ) 函数,表示所有训练数据预测值与实际类别的偏差。
(3)显然, J(θ) 函数的值越小表示预测函数越准确(即h函数越准确),所以这一步需要做的是找到 J(θ) 函数的最小值。找函数的最小值有不同的方法,Spark中采用的是梯度下降法(stochastic gradient descent,SGD)。
关于梯度下降法,可以参考:http://www.cnblogs.com/maybe2030/p/5089753.html?utm_source=tuicool&utm_medium=referral
SGD实际是随机梯度下降法。
1.2.3程序代码
注意,写的过程中发现,LinearRegressionWithSGD is deprecated,而推荐使用 ml库。看了ml库和mllib库的区别,在于ml面向的dataset,mllib面向的是RDD,dataset是比RDD更高层级的抽象。后面再看,这次还是用mllib。
package com.spark.my import org.apache.log4j.{Level, Logger}
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.mllib.regression.{LabeledPoint, LinearRegressionWithSGD}
import org.apache.spark.mllib.linalg.Vectors /**
* Created by baidu on 16/11/28.
*/
object MyRegression {
def main(args: Array[String]) { Logger.getLogger("org.apache.spark").setLevel(Level.WARN)
val conf = new SparkConf()
val sc = new SparkContext(conf) println("Begin text")
// 装载数据集
val text = sc.textFile("hdfs://master.Hadoop:8390/regression/lpsa.data")
val parsedData = text.map{
line =>
val parts = line.split(',')
LabeledPoint(parts(0).toDouble, Vectors.dense(parts(1).split(' ').map(_.toDouble)))
} println("Begin regression")
// Building the model
val numIterations = 100
val model = LinearRegressionWithSGD.train(parsedData, numIterations) println("Evaluating the model and compute training error")
// 用误差平方之和来评估
val valueAndPreds = parsedData.map{
point =>
val pred = model.predict(point.features)
(point.label, pred)
} val MSE = valueAndPreds.map{
case(v, p) =>
math.pow((v-p), 2)
}.reduce(_+_) / valueAndPreds.count()
println("Training Mean Squared Error = " + MSE) sc.stop()
println("All elements done") }
}
数据示例如下:
-0.4307829,-1.63735562648104 -2.00621178480549 -1.86242597251066 -1.02470580167082 -0.522940888712441 -0.863171185425945 -1.04215728919298 -0.864466507337306
-0.1625189,-1.98898046126935 -0.722008756122123 -0.787896192088153 -1.02470580167082 -0.522940888712441 -0.863171185425945 -1.04215728919298 -0.864466507337306
-0.1625189,-1.57881887548545 -2.1887840293994 1.36116336875686 -1.02470580167082 -0.522940888712441 -0.863171185425945 0.342627053981254 -0.155348103855541
-0.1625189,-2.16691708463163 -0.807993896938655 -0.787896192088153 -1.02470580167082 -0.522940888712441 -0.863171185425945 -1.04215728919298 -0.864466507337306
0.3715636,-0.507874475300631 -0.458834049396776 -0.250631301876899 -1.02470580167082 -0.522940888712441 -0.863171185425945 -1.04215728919298 -0.864466507337306
0.7654678,-2.03612849966376 -0.933954647105133 -1.86242597251066 -1.02470580167082 -0.522940888712441 -0.863171185425945 -1.04215728919298 -0.864466507337306
0.8544153,-0.557312518810673 -0.208756571683607 -0.787896192088153 0.990146852537193 -0.522940888712441 -0.863171185425945 -1.04215728919298 -0.864466507337306
可以看出,第一列是结果数据lable,和后面的用逗号分隔;后面的用空格分隔。
把数据传到Hadoop上:
$ hadoop fs -mkdir /regression
$ hadoop fs -put lpsa.data /regression
$ hadoop fs -ls /regression
Found 1 items
-rw-r--r-- 3 work supergroup 10395 2016-12-12 15:52 /regression/lpsa.data
准备好jar包后,运行命令:
./bin/spark-submit --class com.spark.my.MyRegression --master spark://10.117.146.12:7077 myjars/scala-demo.jar
这次精简日志后,方便查看多了。全部日志如下:
$ ./bin/spark-submit --class com.spark.my.MyRegression --master spark://10.117.146.12:7077 myjars/scala-demo.jar
16/12/12 15:55:02 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
16/12/12 15:55:03 INFO util.log: Logging initialized @1665ms
16/12/12 15:55:03 INFO server.Server: jetty-9.2.z-SNAPSHOT
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@34a75079{/jobs,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@346a361{/jobs/json,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@107ed6fc{/jobs/job,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@1643d68f{/jobs/job/json,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@186978a6{/stages,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@2e029d61{/stages/json,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@482d776b{/stages/stage,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@4052274f{/stages/stage/json,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@132ddbab{/stages/pool,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@297ea53a{/stages/pool/json,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@acb0951{/storage,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@5bf22f18{/storage/json,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@267f474e{/storage/rdd,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@7a7471ce{/storage/rdd/json,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@28276e50{/environment,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@62e70ea3{/environment/json,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@3efe7086{/executors,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@675d8c96{/executors/json,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@741b3bc3{/executors/threadDump,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@2ed3b1f5{/executors/threadDump/json,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@63648ee9{/static,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@68d6972f{/,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@45be7cd5{/api,null,AVAILABLE}
16/12/12 15:55:03 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@7651218e{/stages/stage/kill,null,AVAILABLE}
16/12/12 15:55:03 INFO server.ServerConnector: Started ServerConnector@4f5ebbd{HTTP/1.1}{0.0.0.0:4040}
16/12/12 15:55:03 INFO server.Server: Started @1790ms
16/12/12 15:55:04 INFO handler.ContextHandler: Started o.s.j.s.ServletContextHandler@77e2a6e2{/metrics/json,null,AVAILABLE}
Begin text
Begin regression
16/12/12 15:55:05 INFO mapred.FileInputFormat: Total input paths to process : 1
16/12/12 15:55:07 WARN regression.LinearRegressionWithSGD: The input data is not directly cached, which may hurt performance if its parent RDDs are also uncached.
16/12/12 15:55:07 WARN netlib.BLAS: Failed to load implementation from: com.github.fommil.netlib.NativeSystemBLAS
16/12/12 15:55:07 WARN netlib.BLAS: Failed to load implementation from: com.github.fommil.netlib.NativeRefBLAS
16/12/12 15:55:10 WARN regression.LinearRegressionWithSGD: The input data was not directly cached, which may hurt performance if its parent RDDs are also uncached.
Evaluating the model and compute training error
Training Mean Squared Error = 6.207597210613578
16/12/12 15:55:10 INFO server.ServerConnector: Stopped ServerConnector@4f5ebbd{HTTP/1.1}{0.0.0.0:4040}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@7651218e{/stages/stage/kill,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@45be7cd5{/api,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@68d6972f{/,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@63648ee9{/static,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@2ed3b1f5{/executors/threadDump/json,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@741b3bc3{/executors/threadDump,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@675d8c96{/executors/json,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@3efe7086{/executors,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@62e70ea3{/environment/json,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@28276e50{/environment,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@7a7471ce{/storage/rdd/json,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@267f474e{/storage/rdd,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@5bf22f18{/storage/json,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@acb0951{/storage,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@297ea53a{/stages/pool/json,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@132ddbab{/stages/pool,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@4052274f{/stages/stage/json,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@482d776b{/stages/stage,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@2e029d61{/stages/json,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@186978a6{/stages,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@1643d68f{/jobs/job/json,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@107ed6fc{/jobs/job,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@346a361{/jobs/json,null,UNAVAILABLE}
16/12/12 15:55:10 INFO handler.ContextHandler: Stopped o.s.j.s.ServletContextHandler@34a75079{/jobs,null,UNAVAILABLE}
All elements done
而原示例的误差也是6.2左右。
1.3 协同过滤实例
因为协同过滤内容比较多,就新开一篇文章啦: http://www.cnblogs.com/charlesblc/p/6165201.html
可以移步上面的页面。
(完)