数据说明:本程序中的所有使用数据都是datasets包与Counter包里的数据,如需要改成自己的数据读取自己的数据即可
库函数调用版
1.导入依赖包
# 用来导入一个样本数据
from sklearn import datasets
# 用来做数据集的分割,把数据分成训练集和测试集,这样做的目的是为了评估模型。
from sklearn.model_selection import train_test_split
# 导入了KNN的模块,是sklearn提供的现成的算法。
from sklearn.neighbors import KNeighborsClassifier
import numpy as np
2.导入数据及数据说明
# 导入数据集,iris数据集为开源的数据集,数据包含了3个类别
iris=datasets.load_iris()
# X存储的是数据的特征,y存储的每一个样本的标签或者分类
X=iris.data
y=iris.target
# X拥有四个特征,并且标签y拥有0,1,2三种不同的值。
print(X,y)
结果:
3.把数据分为训练数据集和测试数据集
# 使用 train_test_split来把数据分成了训练集和测试集。
# 主要的目的是为了在训练过程中也可以验证模型的效果。如果没有办法验证,则无法知道模型训练的好坏。
X_train,X_test,y_train,y_test=train_test_split(X,y,random_state=2003)
4.直接调用库函数里的KNN,选择K值
# 定义了一个KNN object,它带有一个参数叫做n_neighbors=3, 意思就是说我们选择的K值是3.
clf=KNeighborsClassifier(n_neighbors=3)
clf.fit(X_train,y_train)
# 做预测以及计算准确率,计算准确率的逻辑也很简单,就是判断预测和实际值有多少是相等的。如果相等则算预测正确,否则预测失败。
correct=np.count_nonzero((clf.predict(X_test)==y_test)==True)
print("正确率:%.3f"%(correct/len(X_test)))
结果:
手动版KNN算法解决分类问题
<1>欧式距离函数定义
"""
计算两个样本instance1和instance2之间的欧式距离
instance1: 第一个样本, array型
instance2: 第二个样本, array型
"""
def euc_dis(instance1,instance2):
dist = np.sqrt(sum((instance1 - instance2)**2))
return dist
<2>投票数据集导入与KNN函数
from collections import Counter # 为了做投票
"""
给定一个测试数据testInstance, 通过KNN算法来预测它的标签。
X: 训练数据的特征
y: 训练数据的标签
testInstance: 测试数据,这里假定一个测试数据 array型
k: 选择多少个neighbors?
"""
def knn_classify(X, y, testInstance, k):
# TODO 返回testInstance的预测标签 = {0,1,2}
#计算每个训练数据样例到测试数据样例的距离
#distances为列表
distances = [euc_dis(x, testInstance) for x in X]
#对distances进行排序,选择前k个样本
kneighbors = np.argsort(distances)[:k]
#统计这k个样本中标签最多
count = Counter(y[kneighbors])
return count.most_common()[0][0]
<3>函数调用
# 预测结果。 predictions = [knn_classify(X_train, y_train, data, 3) for data in X_test] # 被预测正确的样本数 correct = np.count_nonzero((predictions==y_test)==True) print ("Accuracy is: %.3f" %(correct/len(X_test)))
<4>结果