“曲则全,枉则直;洼则盈,弊则新;少则得,多则惑,是以圣人抱一为天下式。
不自见,故明;不自是,故彰;不自伐,故有功;不自矜,故长。
夫唯不争,故天下莫能与之争。
古之所谓“曲则全”者,岂虚言哉?
诚全而归之。” [1]
本篇文章记录了用scikit-learn框架下以KNN对数据集进行分类预测时的一个完整步骤。
下文涉及下面内容:
- 实例介绍
- 数据准备
- 选择模型
- 训练模型
- 测试模型
- 保存模型
- 用模型进行预测
实例介绍
建议在开始之前扫一眼 Scikit-learn鸟瞰
本文从sklearn自带的dataset iris,对鸢尾花数据集进行分类。Iris数据中data存储花瓣长宽(column0,1)和花萼长宽(column2,3),target存储花的分类,Iris-setosa , Iris-versicolor , and Iris-virginica ,分别存储为数字 0,1,2
数据准备
打开sklearn官网api,sklearn.datasets
里有两大模块:
-
loaders
提供非常丰富的用于实践分类、回归、聚类的采集数据,你完全可以这些数据进行各种算法的训练。本文使用的数据就是iris。
-
Samples generator
当你不想用sklearn自提供的采集数据,你可以用数据生成器根据场景为您生成个性的模拟数据进行算法训练。
可视化数据
我们首先看看iris数据长什么样子?
from sklearn import datasets
import numpy as np
iris = datasets.load_iris()
X = iris.data
y = iris.target
X[:10] # 显示前10条记录
y # 类别分类
输出:
array([[ 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],
[ 5.4, 3.9, 1.7, 0.4],
[ 4.6, 3.4, 1.4, 0.3],
[ 5. , 3.4, 1.5, 0.2],
[ 4.4, 2.9, 1.4, 0.2],
[ 4.9, 3.1, 1.5, 0.1]])
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]) # 可见共有三个分类
首先要对数据集进行随机划分,分为训练集和测试集
from sklearn.model_selection import train_test_split
'''
train_data:所要划分的样本特征集
train_target:所要划分的样本结果
test_size:样本占比,如果是整数的话就是样本的数量
random_state:是随机数的种子。
随机数种子:其实就是该组随机数的编号,在需要重复试验的时候,保证得到一组一样的随机数。
比如你每次都填1,其他参数一样的情况下你得到的随机数组是一样的。但填0或不填,每次都会不一样。
'''
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=0)
选择模型
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=7) # K最近邻(k-Nearest Neighbor,KNN)
训练模型
knn.fit(X_train, y_train)
print(knn.score(X_test, y_test)) # 对模型进行验证
输出结果:
0.966666666667
通常在训练模型的时候,采用交叉验证会大大提高模型的准确性:
from sklearn.model_selection import cross_val_score
scores = cross_val_score(knn, X, y, cv=5, scoring='accuracy')
print(scores) # 对模型进行交叉验证后结果
print(scores.mean()) # 求平均值
输出结果:
[ 0.96666667 1. 0.96666667 0.96666667 1. ]
0.98 # 很明显结果比没有进行交叉验证的准确性有了显著提高
保存和使用模型
from sklearn.externals import joblib
joblib.dump(knn, "/Users/song/work/ai/sklearn_practice/model/knn_test_001.pkl") # 保存
knn3 = joblib.load("/Users/song/work/ai/sklearn_practice/model/knn_test_001.pkl") # 使用
print(knn3.score(X_test, y_test))
保存模型还有另一种方式:(建议使用上一种方式)
import pickle
# 保存
with open('/Users/song/work/ai/sklearn_practice/model/knn_test_001.pickle', 'wb') as f:
pickle.dump(knn, f)
# 使用
with open('/Users/song/work/ai/sklearn_practice/model/knn_test_001.pickle', 'rb') as f:
knn3 = pickle.load(f)
print(knn3.score(X_test, y_test))
-
老子《道德经》第二十二章,老子故里,中国鹿邑。 ↩