[Spark ML] 第五章:Spark构建分类模型(5.2-5.3节)

5.2 从数据中抽取合适的特征

回顾第三章,可以发现大部分机器学习模型以特征向量的形式处理数值数据。另外,对于分类和回归等监督学习方法,需要将目标变量(或者多类别情况下的变量)和特征向量放在一起。

MLlib中的分类模型通过LabeledPoint对象操作,其中封装了目标变量(标签)和特征向量:

 

虽然在使用分类模型的很多样例中会碰到向量格式的数据集,但在实际工作中,通常还需要从原始数据中抽取特征。正如前几章介绍的,这包括封装数值特征、归一化或正则化特征,以及使用1-of-K编码表示类属特征。

从Kaggle/StumbleUpon evergreen分类数据集中抽取特征

考虑到推荐模型中的MovieLens数据集和分类问题无关,本章使用另外一个数据集。这个数据集源自Kaggle比赛,由StumbleUpon提供。比赛的问题中涉及网页中的推荐页面是短暂的(短暂存在,很快就不流行了)还是长久的(长时间流行)。

下载数据集的链接:http://www.kaggle.com/c/stumbleupon/data。下载训练数据(train.tsv)之前,需要点击同意条款。关于更多有关比赛的信息,可以看这里:http://www.kaggle.com/c/stumbleupon

开始之前,为了让Spark更好的操作数据,我们需要删除文件第一行的列头名称。进入数据的目录(这里用PATH表示),然后输入如下命令删除第一行并且通过管道保存到以train_noheader.tsv命名的文件中:

 

现在,启动spark-shell:

 

和前面几章类似,我们可以将训练数据读入到RDD并且进行检查:

 

可以查看上面的数据集页面中的简介得知可用的字段。开始四列分别包含URL,页面的ID,原始的文本内容和分配给页面的类别。接下来22列包含各种各样的数值和类属特征。最后一列为目标值,-1为长久,0为短暂。

我们将用简单的方法直接对数值特征做处理。因为每个类属变量是二元的,对这些变量已有一个用1-of-k编码的特征,于是不需要额外提出特征。

由于数据格式的问题,我们做一些数据清洗工作,在处理过程中把额外的(“)去掉。数据集中还有一些用”?“代替的缺失数据,本例中,我们直接使用0替换那些缺失的数据:

 

在清理和处理缺失数据后,我们提取最后一列的标记变量以及第5列到第25列的特征矩阵。将标签变量转换为Int值特征向量转换为Double数组。最后,我们将标签和特征向量转换为LabeledPoint实例,从而将特征向量存储到MLlib的vector中。

我们也对数据进行缓存并且统计数据样本的数目:

 

在对数据集做进一步处理之前,我们发现数值数据中包含负的特征值。我们知道,朴素贝叶斯模型要求特征值非负,否则碰到负的特征值程序为抛出错误。因此,需要为朴素贝叶斯模型构建一份输入特征向量的数据,将负特征值设为0

 

5.3 训练分类模型

大幅度