机器学习和 scikit-learn 介绍
监督学习介绍
机器学习中,我们通常会接触到:监督学习、无监督学习、半监督学习,强化学习等不同的应用类型。其中,监督学习(英语:Supervised learning)是最为常见,且应用最为广泛的分支之一。
监督学习的目标是从已知训练数据中学习一个预测模型,使得这个模型对于其他输入数据产生一个预测输出。其中,监督学习的「监督」是相对与「无监督」的一种表达,二者的区别在于,监督学习的训练数据经过了人工进行标注,而无监督学习则没有这个过程。
如同上面的两个简单的数据集。左边的数据集明显没有经过标注。而右边数据集则进行了颜色标注,也就是人为给数据样本打上了橙色、绿色和蓝色的标签。
监督学习的类型
监督学习中,所面对的问题大致分为两类:分类和回归。
其中,分类问题可以简单概括为:已有了一些数据样本及明确的样本分类。现在从这些样本的特征中总结规律,再用于判断新输入样本到底属于哪一类别。例如下图展示了一个分类过程,使用监督学习算法对水果进行类别区分。
分类的例子在生活中处处可见。比如这里正在讲,监督学习可以分为分类和回归一样。而面对一个新问题,判断它是属于分类还是回归,就需要根据这个问题具备的特征来判断。
其中,回归问题与分类问题的最大区别(特征)在于,输出变量的类型不同。详细来说:
分类问题,输出为有限个离散变量,布尔值或者定类变量。
回归问题,输出为连续变量,一般为实数,也就是一个确切值。
举个例子,当我们预测一个人的性别时,就是一个典型的分类问题。而预测一个人的年龄时,则应看作是回归问题。
无监督学习介绍
什么是无监督学习?笼统来讲,它和监督学习是一个相对的概念。在监督学习的过程中,我们需要对训练数据打上标签,这是必不可少的一步。而无监督学习面对的数据是没有标签的。
举个例子,比如我们现在有一堆动物的照片。在监督学习中,我们需要提前对每张照片代表的动物进行标记。这一张是狗,那一张是猫,然后再进行训练。最后,模型对于新输入的照片,就能分清楚动物的类别。
当进行无监督学习时,照片并未进行标注。我们需要将所有的训练样本照片「喂」给算法即可。注意,这个时候和监督学习有一些不同,无监督学习只能识别出训练样本里包含了几种类别的动物,而并不能直接告诉你这只是猫,那一只是狗。但是,这里的类别数量一般都不会太大,你可以手动对类别进行标记,再将数据用于其他用途。
上面这个例子中,无监督学习识别出样本包含几种类别,就是我们通常所说的「聚类」。如下图所示,演示了一个无监督的聚类过程。
https://doc.shiyanlou.com/courses/uid214893-20190522-1558510522231
当然,上面所说的聚类只是无监督学习主要面对的问题,实际上无监督学习还包括降维等更多的应用方面。机器学习中,当我们使用到的数据没有特定标签时,基本都可以被归为无监督学习问题。
scikit-learn 介绍
机器学习常用的算法有很多,例如:线性回归、支持向量机、k 近邻、决策树、朴素贝叶斯、逻辑回归等。其中的一些算法都有着比较复杂的数学过程,如果每一次都需要自己通过代码实现这些算法,那么机器学的门槛就变得很高了。
scikit-learn 是一个十分流行的开源机器学习工具,它基于 Python 的 NumPy 和 SciPy 库构建,将众多的机器学习算法封装起来,往往只需要几行代码,通过简单的方法类调用,就可以实现原本复杂的机器学习模型,在学术界和工业界广泛使用。
scikit-learn 中的数据
在 scikit-learn 中实现的大多数机器学习算法都将数据存储在二维数组或矩阵中。数组可以是 numpy 数组,在某些情况下是 scipy.sparse 矩阵。数组的大小为 (n_samples,n_features),其中:
n_samples:样本数量:每个样本都是要处理(例如分类)的项目。样本可以是文档、图片、声音、视频、数据库或CSV文件中的一行,或者可以用一组定量描述的任何东西。
n_features:特征数量,每个值定量描述样本特征。特征通常是实值,但在某些情况下可能是布尔值或离散值。特征数量必须预先确定,有些样本特征数量为零,有些维度可能非常高(例如数百万个特征)。对于特征很多的样本,scipy.sparse 矩阵会很有用,因为它们比 numpy 数组的存储效率更高。
让我们拿 scikit-learn 的内置数据集 iris data(鸢尾属植物数据集)作为一个例子,看看简单数据集的数据结构,在这个数据集中,包括了三类不同的鸢尾属植物:Iris Setosa,Iris Versicolour,Iris Virginica。每类收集了 50 个样本,因此这个数据集一共包含了 150 个样本。该数据集测量了所有 150 个样本的 4 个特征,分别是(单位都是厘米 cm):
sepal length(花萼长度)
sepal width(花萼宽度)
petal length(花瓣长度)
petal width(花瓣宽度)
from sklearn.datasets import load_iris # 导入内置数据集中的鸢尾属植物数据集
iris = load_iris()
iris.keys() # 查看数据集的所有键
查看 data 的数据:
n_samples, n_features = iris.data.shape
print(iris.data.shape)
print((n_samples, n_features))
print(iris.feature_names)
print(iris.data[0])
从上面代码运行结果来看,此数据集共有 150 个样本,每个样本有 4 个特征,特征用实数定量表示。
我们再看看 target 和 target_names 的数据:
print(iris.target.shape)
print(iris.target)
print(iris.target_names)
从结果来看,该数据集 150 个样本被分为了三类:setosa、versicolor、virginica,分别用 0、1、2 表示。
接下来将数据用图像的形式展示出来,可以对该数据集有一个直观的整体印象。利用该数据集 4 个特征中的后两个,即花瓣的长度和宽度,来展示所有的样本点。
import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('ggplot')
X = iris.data # 只包括样本的特征,150 x 4
y = iris.target # 样本的类型,[0, 1, 2]
features = iris.feature_names # 4 个特征的名称
targets = iris.target_names # 3 类鸢尾花的名称,跟 y 中的 3 个数字对应
plt.figure(figsize=(10, 4))
plt.plot(X[:, 2][y == 0], X[:, 3][y == 0],
'bs', label=targets[0]) # setosa 类绘图
plt.plot(X[:, 2][y == 1], X[:, 3][y == 1], 'kx',
label=targets[1]) # versicolor 类绘图
plt.plot(X[:, 2][y == 2], X[:, 3][y == 2], 'ro',
label=targets[2]) # virginica 类绘图
plt.xlabel(features[2]) # features[2] = pental length(cm)
plt.ylabel(features[3]) # features[3] = pental width(cm)
plt.title('Iris Data Set')
plt.legend()
plt.savefig('Iris Data Set.png', dpi=200) # 保存图片
plt.show()
scikit-learn 中的三种数据生成的方法:
Packaged Data:一些小型数据集是 scikit-learn 内置的,可以使用 sklearn.datasets.load_ * 模块生成,上面的鸢尾花植属数据集就是由这个模块导入的。
Downloadable Data:一些可供下载的较大的数据集,可用 sklearn.datasets.fetch_ * 简化下载过程,生成数据。
Generated Data:还有些数据集是根据随机数种子从模型生成的,可用 sklearn.datasets.make_ * 生成。
scikit-learn 估计器
每个算法都是通过一个 scikit-learn 的估计器(Estimator)实现的,比如调用线性回归的估计器:
from sklearn.linear_model import LinearRegression
构建相应的模型 model,并设置模型参数:
model = LinearRegression()
print(model)
代码运行结果如下:
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)
model
模型的输出参数,即是这个估计器的默认参数。当然,你可以参考 官方文档 中的说明来自定义参数。
估计器接口
scikit-learn 为所有的方法提供了一些统一的接口,用估计器构建了相应的模型 model 之后,可以使用以下方法:
在所有估计器中可用:
model.fit():拟合训练数据。对于监督学习,它接受两个参数:数据 X 和标签 y,例如 model.fit(X,y)。对于无监督学习,此方法仅接受单个参数,即数据 X(例如 model.fit(X))。
在监督学习估计器中可用:
model.predict():给定一个训练后的模型,预测新数据集的标签。此方法接受一个参数,即新数据 X_new,例如 model.predict(X_new),并返回数组中每个对象的学习后的标签。
model.predict_proba():对于分类问题,一些估计器也提供了此方法,该方法返回新数据具有每个分类标签的概率。在这种情况下,model.predict()只返回概率最高的标签。
model.score():对于分类或回归问题,此方法返回一个数值,在 0 到 1 之间,分数越高表示适合度越高。
在无监督学习估计器中可用:
model.predict():在聚类算法中预测标签。
model.transform():给定一个无监督学习模型,对数据进行处理,转化为另一种类型的数据,一般用于特征抽取和转换,通常会转换为向量,比如正则化或者归一化。
model.fit_transform():fit_transform 是 fit 和 transform 的组合,fit_transform(partData) 对部分数据先拟合 fit,找到该 part 的整体指标,如均值、方差、最大值最小值等(根据具体转换的目的),然后对该 partData 进行转换 transform,从而实现数据的标准化、归一化等。再根据之前部分 fit 拟合的整体指标,对剩余的数据(restData)使用同样的均值、方差、最大最小值等指标进行转换 transform(restData),从而保证 partData、restData 处理方式相同。