1.导入数据
import numpy as np
import matplotlib.pyplot as plt
from sklearn import neighbors,datasets,cross_validation #交叉验证
#定义一个加载数据集函数
def load_classification_data():
digits = datasets.load_digits() #手写数字
print('数据集说明,大小:',digits.data.shape ) #data中的图片数据是一行64列
print('一张图片的数据:',digits.data[0]) #图片数据
print('数据集中的键:',digits.keys())
print( 'target:',digits.target[0:50])
print( 'images:',digits.images[0:1]) #image中是多个二维数组成 每个二维数组就是一个数据
x_train = digits.data
y_train = digits.target
# cross_validation.train_test_split() 数据集与测试集的拆分 random_state=0 随机
return cross_validation.train_test_split( x_train,y_train,test_size=0.25,random_state=0,stratify=y_train) #stratify分层采样
#加载训练数据以及测试数据
x_train,x_test,y_train,y_test=load_classification_data()
得到以上输出结果,如下图:
2.数据分析
digits手写数据集其实是1797组8*8的手写数字图像的像素点集合。有10个分类,代表了“0,1,2,…,9”这是个数字。特征维度为64,对应了每组数据的8 * 8个像素点。
通过分析,我们可以查看一下具体数据
print( y_train[0:20]) #输出前二十个数据
print( x_train[0:1]) #输出第一组数据
print(y_train[0:1]) #输出y_train第一个数据
#多分类问题 数据集中是图片数据 8*8矩阵
3.显示图片
通过上述介绍,我们已经了解到了这是一个手写的数据集,通过每一组数据可以得到某些数据,那么下面我们来具体看一下:
#显示一下图片
digits = datasets.load_digits() #加载数据
import matplotlib.pyplot as plt
%matplotlib inline
print( x_train[0:1] )
plt.figure(figsize=(8,8))
plt.imshow( digits.images[1])
print( '标准结果:',digits.target[1])
上面的图片就是得到的手写的**‘1’**
4.测试KNeighborsClassifier的用法
def test_KNeighborsClassifier(*data): # *代表自动解包 *data->列表参数
'''
测试KNeighborsClassifier的用法
:param data 可变参数 是一个元组 要求其元素为:训练样本集、测试样本集、训练样本的标记、测试样本的标记
:return: None
'''
X_train,X_test,y_train,y_test = data
clf = neighbors.KNeighborsClassifier()
clf.fit(X_train,y_train)
print( "模型在训练集中的评分:%f" % clf.score(X_train,y_train))
print("模型在测试集中的评分:%f" % clf.score(X_test,y_test))
test_KNeighborsClassifier(x_train,x_test,y_train,y_test)
5.做交叉验证
def test_KNeighborsClassifier_k_w(*data):
'''
测试 KNeighborsClassifier 中 n_neighbors 和 weights 参数(投票策略) 的影响
:param data:可变参数。它是一个元组,这里要求其元素依次为:训练样本集、测试样本集、训练样本的标记、测试样本的标记
:return: None
'''
X_train,X_test,y_train,y_test=data
#k的取值 从1到 数据集的大小( train: 1749*0.75 =1190)
# linspace:在指定的间隔内返回均匀间隔的数字
# num:#生成100个数 endpoint:是否包括最后一个数值 1 1189
Ks= np.linspace(1,y_train.size,num = 100, endpoint=False,dtype='int')
print( len(Ks) ) #100
print( Ks )
weights = ['uniform','distance'] #uniform权重相等 distance距离权重
fig = plt.figure( figsize=(10,10))
ax = fig.add_subplot(1,1,1) #子图 ax 画布的轴
#绘制不同 weights 下,预测随机得分随 n_neighbors 的曲线
for weight in weights:
training_scores=[]
testing_scores = []
for K in Ks:
clf = neighbors.KNeighborsClassifier(weights=weight,n_neighbors = K )
clf.fit(X_train,y_train)
testing_scores.append( clf.score(X_test,y_test))
training_scores.append(clf.score(X_train,y_train))
#k值为x,评分为y
ax.plot(Ks,testing_scores,label="testing score:weight=%s"%weight)
ax.plot(Ks,training_scores,label="training score:weight=%s"%weight)
ax.legend(loc='best')
ax.set_xlabel("K")
ax.set_ylabel("score")
ax.set_ylim(0,1.05) #y刻度的极限
ax.set_title("KNeighborsClassifier")
plt.show()
test_KNeighborsClassifier_k_w(x_train,x_test,y_train,y_test)
6.超参数搜索/网格搜索
此处具体参数设置请参照官网 :GridSearchCV
from sklearn.model_selection import GridSearchCV
ps = [1,2,10] #指定 距离度量算法
ks = [4,5,6,7,8,9,10] #指定k的数量
ws = ['uniform','distance'] #指定权重算法
param_grid = {'p':ps,'n_neighbors':ks,'weights':ws}
clf = GridSearchCV(neighbors.KNeighborsClassifier(),param_grid,cv = 5)
clf.fit( x_train,y_train)
输出最优参数组合
print('最佳结果:%0.3f' % clf.best_score_ )
print('最优参数组合:')
best_parameters = clf.best_estimator_.get_params()
for param_name in sorted(param_grid.keys() ):
print( '\t%s:%r' %(param_name,best_parameters[param_name]))
使用最优参数重新测试
digits=datasets.load_digits()
clf=neighbors.KNeighborsClassifier(p=2,n_neighbors=4,weights='uniform')
clf.fit(x_train,y_train)
y_predict = clf.predict(x_test)
print('KNN Classifier 准确率为:' ,clf.score(x_test,y_test))