scikit-learn简介
- scikit-learn 是一个开源项目,可以免费使用和分发,任何人都可以轻松获取其源代码来查看其背后的原理。
- scikit-learn 项目正在不断地开发和改进中,它的用户社区非常活跃。
- scikit-learn 包含许多目前最先进的机器学习算法,每个算法都有详细的文档(http://scikit-learn.org/stable/documentation)。
- scikit-learn 是一个非常流行的工具,也是最有名的 Python 机器学习库。广泛应用于工业界和学术界。
scikit-learn安装
scikit-learn 依赖于另外两个 Python 包:NumPy 和 SciPy。
若想绘图和进行交互式开发,还应该安装 matplotlib、IPython 和 Jupyter Notebook。
那么,我们也可以使用预先打包的Python 发行版,比如Anaconda
必要的库和工具
scikit-learn 是基于 NumPy(计算基础包之一) 和 SciPy (计算科学函数集合)的。
除了 NumPy 和 SciPy,还会用到 pandas(处理和分析数据
)和 matplotlib(绘图)。
Jupyter Notebook(交互环境),一个基于浏览器的交互编程环境。比较友好
mglearn(scikit-learn专用函数库,快速美化绘图或获取一些有趣的数据)
初认识例子:鸢尾花分类
我们有已知品种的鸢尾花的测量数据,所以这是一个监督学习问题 我们要在多个选项中预测其中一个(鸢尾花的品种),所以这是一个分类问题
1. 数据
我们用scikit-learn 的 datasets 模块中 的鸢尾花(Iris)数据集,调用 load_iris 函数来加载数据
IN:from sklearn.datasets import load_irisiris_dataset = load_iris()# load_iris 返回的 iris 对象是一个 Bunch 对象,与字典非常相似,里面包含键和值
我们可以调用 iris_dataset.keys() 来查看数据集的键
Keys of iris_dataset:
dict_keys([‘target_names’, ‘feature_names’, ‘DESCR’, ‘data’, ‘target’])
- DESCR 键对应的值是数据集的简要说明
- target_names 键对应的值是一个字符串数组,里面包含我们要预测的花的品种
- feature_names 键对应的值是一个字符串列表,对每一个特征进行了说明
- 数据包含在 target 和 data 字段中。data 里面是花萼长度、花萼宽度、花瓣长度、花瓣宽
度的测量数据,格式为 NumPy 数组 target 数组包含的是测量过的每朵花的品种,也是一个 NumPy 数组
2. 训练数据与测试数据
用于构建机器学习模型的数据,叫作训练数据(training data)或训练集(training set)。
用来评估模型性能的数据,叫作测试数据(test data)、测试集(test set)或留出集(hold-out set)。
scikit-learn 中的 train_test_split 函数可以打乱数据集并进行拆分。
scikit-learn 中的数据通常用大写的 X 表示,而标签用小写的 y 表示。这是受到了数学标准公式 f(x)=y 的启发,其中 x 是函数的输入,y 是输出。用大写的 X 是因为数据是一个二维数组(矩阵),用小写的 y 是因为目标是一个一维数组(向量)。
IN:from sklearn.model_selection import train_test_split# 划分训练数据与测试数据X_train, X_test, y_train, y_test = train_test_split(iris_dataset['data'], iris_dataset['target'], random_state=0)
3. 观察数据
检查数据的最佳方法之一就是将其可视化。
一种可视化方法是绘制散点图(scatter plot)。数据散点图将一个特征作为 x 轴,另一个特征作为 y 轴,将每一个数据点绘制为图上的一个点。不幸的是,计算机屏幕只有两个维度,所以我们一次只能绘制两个特征(也可能是3 个)。用这种方法难以对多于 3 个特征的数据集作图。解决这个问题的一种方法是绘制散点图矩阵(pair plot),从而可以两两查看所有的特征。如果特征数不多的话,比如我们这里有 4 个,这种方法是很合理的。但是你应该记住,散点图矩阵无法同时显示所有特征之间的关系,所以这种可视化方法可能无法展示数据的某些有趣内容。
IN:# 利用X_train中的数据创建DataFrame# 利用iris_dataset.feature_names中的字符串对数据列进行标记iris_dataframe = pd.DataFrame(X_train, columns=iris_dataset.feature_names)# 利用DataFrame创建散点图矩阵,按y_train着色grr = pd.scatter_matrix(iris_dataframe, c=y_train, figsize=(15, 15), marker='o',hist_kwds={'bins': 20}, s=60, alpha=.8, cmap=mglearn.cm3)
4. 构建模型:K近邻算法
k 近邻算法中 k 的含义是,我们可以考虑训练集中与新数据点最近的任意 k 个邻居(比如说,距离最近的 3 个或 5 个邻居),而不是只考虑最近的那一个。然后,我们可以用这些邻居中数量最多的类别做出预测。
k 近邻分类算法是在 neighbors 模块的 KNeighborsClassifier 类中实现的。我们需要将这个类实例化为一个对象,然后才能使用这个模型。这时我们需要设置模型的参数。KNeighborsClassifier 最重要的参数就是邻居的数目。
from sklearn.neighbors import KNeighborsClassifierknn = KNeighborsClassifier(n_neighbors=1) # 近邻值设置为1
knn 对象对算法进行了封装,既包括用训练数据构建模型的算法,也包括对新数据点进行预测的算法。它还包括算法从训练数据中提取的信息。对于 KNeighborsClassifier 来说,里面只保存了训练集。 想要基于训练集来构建模型,需要调用 knn 对象的 fit 方法,输入参数为 X_train 和 y_train,二者都是 NumPy 数组,前者包含训练数据,后者包含相应的训练标签
IN:knn.fit(X_train, y_train)OUT:KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',metric_params=None, n_jobs=1, n_neighbors=1, p=2,weights='uniform')
构建模型时用到的参数。几乎所有参数都是默认值,还有一些像 n_neighbors=1,这是我们传入的参数。scikit-learn 中的大多数模型都有很多参数,但多用于速度优化或非常特殊的用途。一般无需关注这个字符串表示中的其他参数。
5. 做出预测
有一朵鸢尾花,花萼长 5cm 宽 2.9cm,花瓣长 1cm 宽 0.2cm。接下来我们预测一下这朵鸢尾花属于哪个品种?
IN:X_new = np.array([[5, 2.9, 1, 0.2]])print("X_new.shape: {}".format(X_new.shape))OUT:X_new.shape: (1, 4)
注意,我们将这朵花的测量数据转换为二维 NumPy 数组的一行,这是因为 scikit-learn的输入数据必须是二维数组。
我们调用 knn 对象的 predict 方法来进行预测:
IN:prediction = knn.predict(X_new)print("Prediction: {}".format(prediction))print("Predicted target name: {}".format(iris_dataset['target_names'][prediction]))OUT:Prediction: [0]Predicted target name: ['setosa']
根据我们模型的预测,这朵新的鸢尾花属于类别 0,也就是说它属于 setosa 品种。
6. 评估模型
我们需要用到之前创建的测试集。这些数据没有用于构建模型,但我们知道测试集中每朵鸢尾花的实际品种。
因此,我们可以对测试数据中的每朵鸢尾花进行预测,并将预测结果与标签(已知的品种)进行对比。通过计算精度(accuracy)来衡量模型的优劣,精度就是品种预测正确的花所占的比例。
IN:y_pred = knn.predict(X_test)print("Test set predictions:\n {}".format(y_pred))OUT:Test set predictions:[2 1 0 2 0 2 0 1 1 1 2 1 1 1 1 0 1 1 0 0 2 1 0 0 2 0 0 1 1 0 2 1 0 2 2 1 0 2]IN:print("Test set score: {:.2f}".format(np.mean(y_pred == y_test)))OUT:Test set score: 0.97
对于这个模型来说,测试集的精度约为 0.97。根据一些数学假设,对于新的鸢尾花,可以认为我们的模型预测结果有 97% 都是正确的。
7. 汇总
如今机器学习的门槛并不是很高,思维是我个人觉得比较重要的,比如上面看似复杂的思路,一个模型的训练、构建、评估其实就几行代码就能解决:
IN:X_train, X_test, y_train, y_test = train_test_split(iris_dataset['data'], iris_dataset['target'], random_state=0)knn = KNeighborsClassifier(n_neighbors=1)knn.fit(X_train, y_train)print("Test set score: {:.2f}".format(knn.score(X_test, y_test)))OUT:Test set score: 0.97
