推荐阅读时间:10min~12min 文章内容: 使用sklearn入门机器学习
sklearn(scikit-learn)是一个非常优秀的Python库,它封装了机器学习中常用的算法,包括监督学习、非监督学习等。它有以下几个特点:
sklearn中常用的模块有分类、回归、聚类、降维、模型选择、预处理。
分类:识别某个对象属于哪个类别,常用的算法有:SVM(支持向量机)、nearest neighbors(最近邻)、random forest(随机森林),常见的应用有:垃圾邮件识别、图像识别。
回归:预测与对象相关联的连续值属性,常见的算法有:SVR(支持向量机)、 ridge regression(岭回归)、Lasso,常见的应用有:药物反应,预测股价。
聚类:将相似对象自动分组,常用的算法有:k-Means、 spectral clustering、mean-shift,常见的应用有:客户细分,分组实验结果。
降维:减少要考虑的随机变量的数量,常见的算法有:PCA(主成分分析)、feature selection(特征选择)、non-negative matrix factorization(非负矩阵分解),常见的应用有:可视化,提高效率。
模型选择:比较,验证,选择参数和模型,常用的模块有:grid search(网格搜索)、cross validation(交叉验证)、 metrics(度量)。它的目标是通过参数调整提高精度。
预处理:特征提取和归一化,常用的模块有:preprocessing,feature extraction,常见的应用有:把输入数据(如文本)转换为机器学习算法可用的数据。
sklearn 实现了很多算法,面对这么多的算法,如何去选择呢?其实选择的主要考虑的就是需要解决的问题以及数据量的大小。sklearn官方提供了一个选择算法的引导图。
鸢尾花识别是一个经典的机器学习分类问题,它的数据样本中包括了4个特征变量,1个类别变量,样本总数为150。
它的目标是为了根据花萼长度(sepal length)、花萼宽度(sepal width)、花瓣长度(petal length)、花瓣宽度(petal width)这四个特征来识别出鸢尾花属于山鸢尾(iris-setosa)、变色鸢尾(iris-versicolor)和维吉尼亚鸢尾(iris-virginica)中的哪一种。
加载数据
from sklearn import datasets
# 加载鸢尾花数据
iris = datasets.load_iris()
# 查看特征名称
print("feature_names: {0}".format(iris.feature_names))
# 查看目标标签名称
print("target_names: {0}".format(iris.target_names))
# 查看元数据(特征矩阵)形状
print("data shape: {0}".format(iris.data.shape))
# 查看元数据(特征矩阵)前五条
print("data top 5:\n {0}".format(iris.data[: 5]))
# 查看目标标签的类别标识
print("target unique: {0}".format(np.unique(iris.target)))
print("target top 5:\n {0}".format(iris.target[: 5]))
输出:
feature_names: ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
target_names: ['setosa' 'versicolor' 'virginica']
data shape: (150, 4)
data top 5:
[[ 5.1 3.5 1.4 0.2]
[ 4.9 3. 1.4 0.2]
[ 4.7 3.2 1.3 0.2]
[ 4.6 3.1 1.5 0.2]
[ 5. 3.6 1.4 0.2]]
target unique: [0 1 2]
target top 5:
[0 0 0 0 0]
很明显,元数据(特征矩阵)的形状是(n_samples, n_features),即(150, 4),从target top5可以看出,前五个样本的数据都属于目标0,即都属于 setosa 。
结合 data 和 target 中第一条数据来看,说明了当一个鸢尾花满足以下特征:
花萼长度(sepal length)为5.1 cm
花萼宽度(sepal width )为3.5 cm
花瓣长度(petal length )为1.4 cm
花瓣宽度(petal width)为 0.2 cm
则该鸢尾花属于目标类别0,即山鸢尾(setosa )。
数据可视化
简单分析下不同花萼长度和宽度的情况下,对应的不同的鸢尾花的情况。
import matplotlib.pyplot as plt
sepal_length_list = iris.data[:, 0] # 花萼长度
sepal_width_list = iris.data[:, 1] # 花萼宽度
# 构建 setosa、versicolor、virginica 索引数组
setosa_index_list = iris.target == 0 # setosa 索引数组
versicolor_index_list = iris.target == 1 # versicolor 索引数组
virginica_index_list = iris.target == 2 # virginica 索引数组
plt.scatter(sepal_length_list[setosa_index_list],
sepal_width_list[setosa_index_list], color="red", marker='o', label="setosa")
plt.scatter(sepal_length_list[versicolor_index_list],
sepal_width_list[versicolor_index_list], color="blue", marker="x", label="versicolor")
plt.scatter(sepal_length_list[virginica_index_list],
sepal_width_list[virginica_index_list],color="green", marker="+", label="virginica")
# 设置 legend
plt.legend(loc="best", title="iris type")
# 设定横坐标名称
plt.xlabel("sepal_length (cm)")
# 设定纵坐标名称
from sklearn import linear_model
# 指定训练数据 X
X = iris.data
# 指定训练目标 y
y = iris.target
# 创建一个逻辑回归分类器
clf = linear_model.LogisticRegression()
# 使用样本数据训练(喂养)分类器
clf.fit(X, y)
# 待预测样本
wait_predict_sample = X[np.newaxis, 0]
print("wait_predict_sample: {0}".format(wait_predict_sample))
# 预测所属目标类别
print("predict: {0}".format(clf.predict(wait_predict_sample)))
# 预测所属不同目标类别的概率
print("predict_proba: {0}".format(clf.predict_proba(wait_predict_sample)))
输出:
wait_predict_sample: [[ 5.1 3.5 1.4 0.2]]
predict: [0]
predict_proba: [[ 8.79681649e-01 1.20307538e-01 1.08131372e-05]]
上面的代码说明,经过训练后的分类器模型,如果一个鸢尾花满足以下特征:
花萼长度(sepal length)为5.1 cm
花萼宽度(sepal width )为3.5 cm
花瓣长度(petal length )为1.4 cm
花瓣宽度(petal width)为 0.2 cm。
则模型认为它属于目标类别0,即山鸢尾(setosa )。
上面已经能够使用模型完成对某个样本进行预测,如果想要直观的查看模型的预测结果的话,可以使用可视化的技术来表现出来。
# 只考虑前两个特征,即花萼长度(sepal length)、花萼宽度(sepal width)
X = iris.data[:, 0:2]
y = iris.target
# 创建一个逻辑回归的模型,并用它训练(拟合,fit)数据
logreg = linear_model.LogisticRegression(C=1e5)
logreg.fit(X, y)
# 网格大小
h = .02
# 将 X 的第一列(花萼长度)作为 x 轴,并求出 x 轴的最大值与最小值
x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
# 将 X 的第二列(花萼宽度)作为 y 轴,并求出 y 轴的最大值与最小值
y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
# 使用 x 轴的最小值、最大值、步长生成数组,y 轴的最小值、最大值、步长生成数组
# 然后使用 meshgrid 函数生成一个网格矩阵 xx 和 yy(xx 和 yy 的形状都一样)
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
# 调用 ravel() 函数将 xx 和 yy 平铺,然后使用 np.c_ 将平铺后的列表拼接
# 生成需要预测的特征矩阵,每一行的表示一个样本,每一列表示每个特征的取值
pre_data = np.c_[xx.ravel(), yy.ravel()]
Z = logreg.predict(pre_data)
# Put the result into a color plot
# 将预测结果 Z 的形状转为与 xx(或 yy)一样
Z = Z.reshape(xx.shape)
plt.figure(1, figsize=(8, 6))
# 使用 pcolormesh 函数来填充颜色,对 xx,yy的位置来填充颜色,填充方案为 Z
# cmap 表示使用的主题
plt.pcolormesh(xx, yy, Z, cmap=plt.cm.Paired)
# 将训练数据所表示的样本点填充上颜色
plt.scatter(X[:, 0], X[:, 1], c=y, edgecolors='k', cmap=plt.cm.Paired)
# 设置坐标轴label
plt.xlabel("sepal length")
plt.ylabel("sepal width")
# 设置坐标轴范围
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
# 设置坐标轴刻度
plt.xticks(np.arange(x_min, x_max, h * 10))
plt.yticks(np.arange(y_min, y_max, h * 10))
plt.show()
作者:无邪,个人博客:脑洞大开,专注于机器学习研究。