《机器学习系统设计:Python语言实现》一2.8 Scikit-learn-阿里云开发者社区

开发者社区> 华章出版社> 正文

《机器学习系统设计:Python语言实现》一2.8 Scikit-learn

简介:

.本节书摘来自华章出版社《机器学习系统设计:Python语言实现》一书中的第2章,第2.8节,作者 [美] 戴维·朱利安(David Julian),更多章节内容可以访问云栖社区“华章计算机”公众号查看

2.8 Scikit-learn

Scikit-learn包含了最常见的机器学习任务的算法,例如,分类、回归、聚类、降维、模型选择和预处理。
Scikit-learn中有一些用于练习的真实世界的数据集。我们来看看其中之一,Iris数据集:

image

该数据集包含了三种iris类型(Setosa、Versicolor和Virginica)的150个样本,每个样本具有四个特征。我们可以获取数据集的描述:
image

我们可以看到四个属性或特征分别是,萼片宽度、萼片长度、花瓣长度和花瓣宽度,单位为厘米。每个样本属于三种类型之一。Setosa、Versicolor和Virginica分别由0、1和2表示。
让我们使用这一数据来观察一个简单的分类问题。我们期望根据萼片和花瓣的长度和宽度特征来预测iris的类型。通常,scikit-learn使用估计来实现fit(X, y)和predict(X)方法,其中fix(X, y)用于训练分类器,predict(X)根据给定的无标签观察值X返回预测的标签y。fit()和predict()方法通常需要一个二维数组对象作为参数。
这里我们将使用K近邻(K-NN)算法来解决此分类问题。K-NN的原理比较简单,即通过近邻数据的类别来对无标签样本进行分类。对每个数据点的分类,首先找到少量的与其最为相邻的k个数据点,然后根据k个数据点中占多数的类型来确定其类型。K-NN是一种基于实例的学习,其分类不是取决于其内在的模型,而是对有标签测试集进行参考。K-NN只是简单地记住所有训练数据,并与每个新样本进行比较,因此它是一种非归纳方法。尽管K-NN显得简单,也许正是因为简单,所以这是一种使用非常广泛的技术,用于解决各种分类和回归问题。
在Scikit-learn中有两种不同的K-NN分类器。KNeighborsClassifier需要用户来指定k,即近邻数据的数量。RadiusNeighborsClassifier则不同,它对每个训练数据点指定固定的半径r,根据半径r内的近邻数量进行学习。KNeighborsClassifier更为常用。k值的优化取决于数据,通常,噪声数据较多时使用较大的k值,而这样也牺牲了一些分类边界的明确性。如果数据不是均匀采样的,则RadiusNeighborsClassifier可能是更好的选择。因为近邻的数量取决于半径,所以每个点的k值会不同,稀疏区域的k值要小于样本密度高的区域:
image
image
image

以下是上面代码的输出如下图所示:
image

现在,我们再来看看Scikit-learn如何解决回归问题。最简单的方案是最小化误差平方和。对此可以使用LinearRegression对象。该对象的fit()方法需要两个向量参数:X是特征向量,y是目标向量。
image

LinearRegression对象有四个可选的参数:
fit_intercept:布尔值,如果设为false,则假设数据是居中的,模型在计算时不会使用截距。默认值是true。
normalize:如果为true,X将在回归前以0为均值,1为方差进行归一化。因为归一化后能够比较明确地解释回归系数,所以有时会有用。默认值是false。
copy_X:默认值为true。如果设为false,将会覆盖X。
n_jobs:计算时所用作业的数量,默认值为1。在多CPU的情况下,对于大型问题可以用来加速计算。
其输出有如下属性:
coef_:线性回归问题的估计系数数组。如果y是多维的,即有多个目标变量,则coef_是以(n_targets, n_features)为形式的二维数组。如果只传入一个目标变量,则coef_将是长度为n_features的一维数组。
intercept_:线性模型中的截距或独立项数组。
对于普通最小二乘法(Ordinary Least Squares),我们假设特征是独立的。当特征之间具有相关性时,则X矩阵会接近奇异性。这意味着估计将对输入数据的微小变化高度敏感。这被称为多重共线性(multicollinearity),它会导致大的方差和最终不确定性。后续会深入讨论这一问题,但现在来看一个某种程度上可以解决该问题的算法。
岭回归不仅可以解决多重共线性问题,还可以用于输入变量远远超出样本数量的情形。linear_model.Ridge()对象使用了L2正则化。直观地讲,我们可以将其理解为对权重向量的极值加以惩罚。这样会使平均权重更小,因此有时也称为收缩(shrinkage)。因为其减小了对极值的敏感度,所以会使模型更为稳定。
Scikit-learn的linear_model.ridge对象增加了一个正则化参数alpha。通常,赋予alpha一个小的正值会提高模型的稳定性。alpha也可以是浮点数或数组。如果是数组,则假设数组对应于目标变量,因此,其大小与目标变量相同。我们可以尝试下面的简单函数:
image
image

接下来我们再看看scikit-learn中用于降维的算法。降维对于机器学习十分重要,因为这样可以减少模型需要考虑的输入变量或特征的数量。这样会使模型更有效率,并且使结果更容易解释。同时,这样还能减少过度拟合而提高模型的普遍性。
当然,避免丢弃影响模型准确性的信息也很重要。降维算法的主要工作就是确定哪些是冗余或无关的数据。通常有两种方法:特征提取和特征选择。特征选择是试图在原始特征变量中找到子集。特征提取则不同,是指结合那些具有相关性的变量,在此之上创建新的特征变量。
让我们先看看可能是最常用的特征提取算法,即主成分分析(PCA)。PCA使用正交变换将一组相关变量转换为一组不相关变量。其中的重要信息,如向量长度和向量之间的角度,保持不变。这些信息由内积定义,并在正交变化中保持不变。PCA构造特征向量的方式是,第一成分尽可能多地表示数据中的可变性,后续成分所表示的可变性则依次减少。这意味着,对于大多数模型,我们可以只选择少量的主要成分,只要它们所表示的数据可变性能够满足实验规格所要求的即可。
径向基函数(RBF)大概是最为通用的、在大多数情况下都能给出良好结果的核函数。径向基核函数采用参数gamma,可以粗略地理解为每个样本的径向作用范围的逆。gamma值小则意味着对于模型所选择的样本,每个样本的作用范围半径大。KernalPCA的fit_transform方法接受一个训练向量,对模型进行拟合,并变换为主成分。例如:
image

image

正如我们所见,有监督学习算法成功的主要障碍是,由训练数据到测试数据的转化。有标签训练集可能具有独特的特点,而新的无标签数据并没有。我们可以看到,对于训练数据,训练的模型可以十分精确,然而这种精确性可能无法转化到无标签测试数据上。过度拟合是有监督学习的一个重要问题,而我们有很多技术可以用来最小化这一问题。一种方式是使用交叉验证来对模型在训练集上的估计性能进行评价。让我们使用支持向量机在iris数据上对此进行尝试。首先,我们需要将数据分割为训练集和测试集。train_test_split方法接受两个数据结构:数据本身和分割结果。这两个结构可以是NumPy数组、Pandas的DataFrames列表,或SciPy矩阵。正如我们所期望的,分割结果的长度应该和数据一样。test_size参数可以是0和1之间的浮点数,表示分割数据的比例,也可以是整数,表示测试样本的数量。这里,我们对test_size赋值为0.3,表示我们将40%的数据用于测试。
在本例中,我们使用svm.SVC类和.scores的方法来返回测试数据在标签预测中的平均精度:
image

我们可以观察到如下输出:
image

支持向量机有个penalty参数需要手工设置,我们很可能要调整这一参数并多次运行SVC,直到获得最优拟合。然而即使完成这一步,由于从训练集到测试集存在信息泄漏,我们可能还是存在过度拟合的问题。对于任何存在手工设置参数的估计都会有这个问题,我们将在第4章中进行探索。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:

华章出版社

官方博客
官网链接