首页 > sklearn 阅读数:26

scikit-learn选择模型

 在 sklearn 机器学习中,当准备好数据集后,接着就是根据机器学习问题选择相应的模型。例如,Iris 数据集属于机器学习中的分类问题,因此,应选择分类模型。

1. 选择模型的流程

在 sklearn 官网(http://scikit-learn.org/stable/tutorial/machine_learning_map/index.html)提供了一个选择模型的流程图,如图 1 所示。

选择模型流程图
图 1:选择模型流程图

在流程图中有分类、回归、聚类、降维四类算法,其中分类和回归是监督式学习,即每个数据对应一个 label(标签),聚类是非监督式学习,没有 label(标签),还有一类是降维。降维就是当数据集有很多属性的时候,可以通过降维算法把属性归纳起来。

例如数据集中有 20 个属性,将其变成 2 个属性。应注意的是,降维不是挑选出 2 个属性,而是压缩成 2 个属性,这 2 个属性要集合了原 20 个属性的所有特征,相当于提取出重要的信息,不重要的信息丢弃。

从 START 开始,首先看数据的样本是否大于 50。如果样本小于 50 则需要收集更多的样本数据。如果样本大于 50 就先判断预测的是否是一个分类,如果预测的是一个分类,就判断预测的数据是否有标签,如果预测的数据有标签就选择分类模型,否则就选择聚类模型。

如果预测不是一个分类,而是数量,就选择回归模型。当然还要考虑数据大小,例如 100×103 就是一个阈值。另外,在流程图中,单击任何一个绿色方框就可以查看相应模型的 API 文档。

2. 应用模型

sklearn 有许多种类的数据集,数据集种类及导入方法如下。
  • 自带的小数据集(Packaged Dataset):sklearn.datasets.load_<name>。
  • 可在线下载的数据集(Downloaded Dataset):sklearn.datasets.fetch_<name>。
  • 计算机生成的数据集(Generated Dataset):sklearn.datasets.make_<name>。
  • svmlight/libsvm 格式的数据集:sklearn.datasets.load_svmlight_file(...)。

其中 sklearn 自带的小数据集导入方法为:sklearn.datasets.load_<name>,自带的小数据集名称(name)如下。
  • 鸢尾花数据集 iris()。
  • 手写数字数据集 digits()。
  • 乳腺癌数据集 breast_cancer()。
  • 糖尿病数据集 diabetes()。
  • 波士顿房价数据集 boston()。
  • 体能训练数据集 linnerud()。

用户可以选择 sklearn 自带的数据集,也可以选择自行数据处理后的数据集进行练习。

【例 1】以 sklearn 自带的鸢尾花数据集 iris() 和数据清洗后保存的数据 iris-clean.csv 为例,使用 KNN 分类器模型进行训练和预测。

1) KNN 分类器

KNN 分类器是最简单最初级的分类器,它将全部的训练数据所对应的类别都记录下来,当测试对象的属性和某个训练对象的属性完全匹配时,便可以对其进行分类。

KNN 分类器是依据 K 近邻 (K-nearest Neighbors,KNN) 算法进行分类的。KNN 算法的核心思想是如果一个样本在特征空间中 k 个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。

KNN 方法在类别决策时,只与极少量的相邻样本有关。由于 KNN 方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN 方法较其他方法更为适合。

在 scikit-learn 中,与近邻法这一大类相关的类库都在 sklearn.neighbors 包中。KNN 分类树的类是 KNeighborsClassifier,KNN 回归树的类是 KNeighborsRegressor,KNN 分类和回归的类参数完全一样。

2) 使用 KNN 分类器模型的步骤

① 导入 KNN 模块:from sklearn.neighbors import KNeighborsClassifier。

② 导入 sklearn 自带的鸢尾花数据集 iris(),其代码如下。
from sklearn import datasets
iris = datasets.load_iris()

③ 将整个数据集分为训练集和测试集,包括特征矩阵和目标数组。

④ 建立模型:clf=KNeighborsClassifier()。

⑤ 用 .fit() 训练模型:clf.fit(X_train, y_train)。

⑥ 用 .predict() 进行预测:clf.predict(X_test)。

⑦ 用 .score() 计算准确率:clf.score(X_test, y_test,sample_weight=None)。

⑧ 保存模型:当模型训练好后,可以保存模型,以便下次可直接调用。保存模型需要导入 pickle 库,保存模型的代码如下。
with open('d:/data/knn_model.pkl', 'wb') as f:
    pickle.dump(knn_model, f)

⑨ 读取保存模型:代码如下。
with open('d:/data/knn_model.pkl', 'rb') as f:
    model = pickle.load(f)

⑩ 绘制 distplot 图形,判断模型的表现与训练集选择的关系。

示例代码 test1.py 如下。
# -*- coding: utf-8 -*-
import pandas as pd
from sklearn import datasets
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.neighbors import KNeighborsClassifier
import seaborn as sns
import matplotlib.pyplot as plt
import pickle
#创建自定义函数
def knn_function(X,y):
    #划分训练集和测试集,其中test_size=0.3,即测试集占总数据的30%
    X_train, X_test, y_train, y_test = \
        train_test_split(X, y, test_size=0.3)
    clf = KNeighborsClassifier()# 建立模型
    clf.fit(X_train, y_train)  # 用.fit()训练模型
    #用.predict()进行预测,输出模型预测的值
    predict_test = clf.predict(X_test)
    print('预测的值','\n',predict_test)
    print('真实的值','\n',y_test)  # 输出真实的值,与预测的值对比
    #计算准确率
    score = clf.score(X_test, y_test, sample_weight=None)
    print('准确率','\n',score)
    return clf

#导入自带的数据集
iris = datasets.load_iris()
#查看数据集
print(iris.data)
print(iris.data.shape)
print(iris.target_names)
print(iris.target)
#获取特征矩阵和目标数组(标签)
iris_X = iris.data
iris_y = iris.target
#调用函数
knn_function(iris_X,iris_y)

#导入iris-clean.csv数据集
iris= pd.read_csv('d:\data\iris-clean.csv')
#获取特征矩阵和目标数组(标签)
iris_X = iris.loc[0:,'sepal_length':'petal_width']
iris_y = iris['class']
#调用函数
knn_model = knn_function(iris_X,iris_y)

# 保存模型
with open('d:/data/knn_model.pkl', 'wb') as f:
    pickle.dump(knn_model, f)

# 读取保存模型
with open('d:/data/knn_model.pkl', 'rb') as f:
    model = pickle.load(f)

#绘制distplot图形
model_accuracies = []
for repetition in range(1000):
    X_train, X_test, y_train, y_test = \
        train_test_split(iris_X, iris_y, test_size=0.3)
    # 通过读取保存模型knn_model.pkl代码,建立模型model
    score = model.score(X_test, y_test, sample_weight=None)
    model_accuracies.append(score)
sns.distplot(model_accuracies)
plt.show()

观察运算结果可知,准确率为 0.9777。通过绘制 distplot(直方图与核密度估计图)图形,可以观察到模型的表现与训练集的选择有很大关系,这种现象被称为“过度拟合”。即模型针对训练集的分类表现太好,而对那些没有见过的数据则表现很差。distplot 图形如图 2 所示。

直方图与核密度估计图
图 2:直方图与核密度估计图