Spark中常见的三种分类模型:线性模型、决策树和朴素贝叶斯模型。
线性模型,简单而且相对容易扩展到非常大的数据集;线性模型又可以分成:1.逻辑回归;2.线性支持向量机
决策树是一个强大的非线性技术,训练过程计算量大并且较难扩展(幸运的是,MLlib会替我们考虑扩展性的问题),但是在很多情况下性能很好;
朴素贝叶斯模型简单、易训练,并且具有高效和并行的优点(实际中,模型训练只需要遍历所有数据集一次)。当采用合适的特征工程,这些模型在很多应用中都能达到不错的性能。而且,朴素贝叶斯模型可以作为一个很好的模型测试基准,用于比较其他模型的性能。
现在我们采用的数据集是stumbleupon,这个数据集是主要是一些网页的分类数据。
内容样例:String = “http://www.bloomberg.com/news/2010-12-23/ibm-predicts-holographic-calls-air-breathing-batteries-by-2015.html" ”4042” ”{“”title””:””IBM Sees Holographic Calls Air Breathing Batteries ibm sees holographic calls, air-breathing batteries””,””body””:””A sign stands outside the International Business Machines Corp IBM Almaden Research Center campus in San Jose California Photographer Tony Avelar Bloomberg Buildings stand at the International Business Machines Corp IBM Almaden Research Center campus in the Santa Teresa Hills of San Jose California Photographer Tony Avelar Bloomberg By 2015 your mobile phone will project a 3 D image of anyone who calls and your laptop will be powered by kinetic energy At least that s what International Business Machines Corp sees in its crystal …
开始四列分别包含 URL 、页面的 ID 、原始的文本内容和分配给页面的类别。接下来 22 列包含各种各样的数值或者类属特征。最后一列为目标值, -1 为长久, 0 为短暂。
1 | val rawData = sc.textFile("/user/common/stumbleupon/train_noheader.tsv") |
由于数据格式的问题,我们做一些数据清理的工作,在处理过程中把额外的( “ )去掉。数据集中还有一些用 “?” 代替的缺失数据,本例中,我们直接用 0 替换那些缺失数据 。
在清理和处理缺失数据后,我们提取最后一列的标记变量以及第 5 列到第 25 列的特征矩阵。将标签变量转换为 Int 值,特征向量转换为 Double 数组。
最后,我们将标签和和特征向量转换为 LabeledPoint 实例,从而将特征向量存储到 MLlib 的 Vector 中。
1 | import org.apache.spark.mllib.regression.LabeledPoint |
(朴素贝叶斯特殊的数据处理)在对数据集做进一步处理之前,我们发现数值数据中包含负的特征值。我们知道,朴素贝叶斯模型要求特征值非负,否则碰到负的特征值程序会抛出错误。因此,需要为朴素贝叶斯模型构建一份输入特征向量的数据,将负特征值设为 0
1 | val nbData = records.map { r => |
分别训练逻辑回归、SVM、朴素贝叶斯模型和决策树
1 | import org.apache.spark.mllib.classification.LogisticRegressionWithSGD |
训练逻辑回归模型
1 | val lrModel = LogisticRegressionWithSGD.train(data, numIterations) |
训练SVM模型
1 | val svmModel = SVMWithSGD.train(data, numIterations) |
训练**朴素贝叶斯模型 **
1 | val nbModel = NaiveBayes.train(nbData) |
训练决策树模型
1 | val dtModel = DecisionTree.train(data, Algo.Classification, Entropy, maxTreeDepth) |
验证预测结果的正确性,以逻辑回归为例子,说明预测的结果是错误的
1 | val dataPoint = data.first |
评估分类模型的性能
1.逻辑回归模型
1 | val lrTotalCorrect = data.map { point => |
1 | lrAccuracy: Double = 0.5146720757268425 |
2.SVM模型
1 | val svmTotalCorrect = data.map { point => |
1 | svmAccuracy: Double = 0.5146720757268425 |
3.贝叶斯模型
1 | val nbTotalCorrect = nbData.map { point => |
1 | nbAccuracy: Double = 0.5803921568627451 |
4.决策树模型
1 | val dtTotalCorrect = data.map { point => |
1 | dtAccuracy: Double = 0.6482758620689655 |
准确率和召回率
改进模型性能以及参数调优
1.特征标准化
研究特征是如何分布的,先将特征向量用 RowMatrix 类表示成 MLlib 中的分布矩阵。 RowMatrix 是一个由向量组成的 RDD ,其中每个向量是分布矩阵的一行。
RowMatrix 类中有一些方便操作矩阵的方法,其中一个方法可以计算矩阵每列的统计特性:
1 | import org.apache.spark.mllib.linalg.distributed.RowMatrix |
1 | println(matrixSummary.mean) #输出矩阵每列的均值 |
对特征矩阵进行归一化
1 | import org.apache.spark.mllib.feature.StandardScaler |
1 | import org.apache.spark.mllib.evaluation.BinaryClassificationMetrics |
可以看出,特征标准化提升了逻辑回归模型的准确率和AUC
1 | LogisticRegressionModel |