数据分析实战---KNN手写数字识别

KNN手写数字识别实战

大纲

1.算法背景
2.sklearn接口API
3.手写数字识别实战

算法背景
KNN(K-Nearest Neighbor):算法核心为:“近朱者赤,近墨者黑”。
工作原理:
1.计算待分类样本与训练样本的距离
2.对距离升序排序,选取距离待分类样本最近的K个邻居
3.(分类)统计K个邻居所属的类别,并将待分类样本归类到最多的类别组中
(回归)计算K个邻居的属性加权平均值,并将结果赋给待估计样本电
算法运用关键:
1.K值的选取
K值过小,待分类样本严重依赖于最近的训练样本,若训练样本中有噪声,则易过拟合;K值过大,考虑的“最近”样本数过多,可能无法准确分类,导致欠拟合。因此,K的选择可以通过设置不同的K值,看对应情况下模型性能评估的效果,择优选取K。由于一般测试样本无法得知其真实的类别数,可以利用交叉验证的方法,将训练集进一步划分为训练数据和验证数据,在训练数据上训练模型并在验证集上进行验证和模型调优。使用交叉验证的另一个好处是可以充分利用已知数据,例如使用5折交叉验证,就可以把训练数据划分为5块,随机选择用其中一块做验证集,其余四块做训练集(最后可以得到5个验证集上的得分再取平均)。
2.距离的计算
用距离来衡量样本与样本之间的相似度或差异,距离越大,两个样本的相似度越低。关于距离的计算方式,最常用的是欧氏距离(例如两点间的距离公式)、其他的还有曼哈顿距离(绝对值距离)、切比雪夫距离、余弦相似度等(举例的前三者都是闵可夫斯基距离一种的特例)。余弦相似度常用在文本分析或推荐上,计算的是两个向量的夹角,即方向上的偏差
3.凡涉及到距离的计算,都要注意对数据标准化,归一化等操作,使数据量纲统一。

算法可能存在的问题:
1.KNN需要计算测试点和样本点之间的距离,当数据量大的时候,计算量是非常庞大的,需要大量的存储空间和计算时间。
2.如果训练集中样本分类不均衡,比如银行贷款交易欺诈数据集,那么出现次数非常少的类别的分类准确率会比较低。

思考的一些解决方案
1.KNN中使用KD树减少计算距离的次数,提升搜索效率。KD树是对数据点在K维空间中划分的一种数据结构,是一种二叉树。
2.样本不均衡:过采样、下采样、在算法中设置不同类别样本的权重值,使该类在计算分类错误率时有更大的“话语权”

sklearn中提供的API:

from sklearn.neighbors import KNeighborsClassifier
from sklearn.neighbors import KNeighborsRegressor
#构建KNN分类模型
KNeighborsClassifier(n_neighbors=5,weights='uniform',algorithm='auto',leaf_size=30)
#参数解释:
#n_neighbors:K值,默认为5
#weights:邻居的权重计算,可选: uniform,distance,自定义函数
#algorithm:计算和寻找邻居的方法,可选:auto,kd_tree,ball_tree,brute
#leaf_size:构造KD树或球树时的叶子树,默认是30

手写数字识别实战

1.导入工具包

from sklearn import datasets
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCV
from sklearn import metrics

2.加载数据

data = datasets.load_digits()
data.keys()#查看该数据集有哪些字段(键值)

数据分析实战---KNN手写数字识别_第1张图片
3.数据可视化

plt.gray()
plt.imshow(data["images"][-1])
plt.show()
print("label:",data["target"][-1])

数据分析实战---KNN手写数字识别_第2张图片
··················label: 8
4.数据划分和预处理

xdata = data["data"]
ydata = data["target"]

xdata = StandardScaler().fit_transform(xdata)

x_train,x_test,y_train,y_test = train_test_split(xdata,ydata,test_size=0.33)

5.模型训练和评估

knn_model = KNeighborsClassifier()
parameters = [{'n_neighbors':range(2,11),'weights':['uniform','distance']}]
best_model = GridSearchCV(knn_model,param_grid=parameters,cv=5).fit(x_train,y_train)
print("最优参数配置:",best_model.best_params_)
print("KNN测试集上的性能评估为:",metrics.accuracy_score(best_model.predict(x_test),y_test))

结果:
最优参数配置: {‘n_neighbors’: 4, ‘weights’: ‘distance’}
KNN测试集上的性能评估为: 0.9781144781144782

补充测试一下SVM的效果

#测试一下SVM的效果
from sklearn.svm import SVC
svc_model = SVC()
parameters_svc = [{"C":[0.01,0.1,1,10],"gamma":[0.001,0.01,0.1,1]}]

svc_best_model = GridSearchCV(svc_model,param_grid=parameters_svc,cv=5).fit(x_train,y_train)
print("最优参数配置:",svc_best_model.best_params_)
print("SVC测试集上的性能评估为:",metrics.accuracy_score(svc_best_model.predict(x_test),y_test))

结果展示:
最优参数配置: {‘C’: 10, ‘gamma’: 0.01}
SVC测试集上的性能评估为: 0.9797979797979798

小结:本实验完成了《数据分析实战45讲》KNN部分的理论与实战部分,KNN实质上并没有所谓的训练过程(拟合参数),当待测样本数据输入时就直接计算该样本到各个训练样本的距离然后对距离排序,选择前K个距离范围内的所有样本(小心,不一定只有K个邻居)然后统计近邻的类别(做分类)或者计算目标值的加权平均数(做回归)。KNN算法十分简洁,主要就是距离公式的选择和设计,以及K的选择,一些可能的算法问题与处理思路也在算法背景中有所介绍。

你可能感兴趣的:(数据分析实战,python,数据挖掘,算法)