一、思想
- 物以类聚,人以群分。
- 给定训练集,对于给定的测试集,计算它与训练集集中每个对象的距离。圈定距离最近的k个训练对象,作为测试对象的近邻。根据k个近邻的主要类别,确定测试对象的分类。
(一)k(划分的类数)的确定
- k小:训练误差小,泛化误差大,对噪声敏感,模型复杂,容易发生过拟合
过拟合:参数多,样本少,过度训练 - k大:训练误差大,泛化误差小,模型简单,容易发生欠拟合
欠拟合:参数少,训练不到位 - try [3,20]
(二)距离的度量
(三)类别的判定
- 简单投票法:少数服从多数,近邻中哪个类别的点最多就分为该类
- 加权投票法:根据距离的远近,对近邻的投票进行加权,距离越近则权重越大(权重为距离平方的倒数)
二、存在问题
1.样本不平衡
改善:加权投票法
2.计算量大,效率低,计算复杂度和空间复杂度双高
改善: (1)样本剪辑,删除对分类作用不大的训练样本 (2)设置参数:algorithm=‘kd_tree’/‘ball_tree’
三、Python实现
import sklearn
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import cross_val_score
from sklearn.metrics import accuracy_score
#构造训练集和测试集
x=truck_data[['speed', 'acceleration', 'throttle']]
y=truck_data['if_full']
# 确定k
k_error = []
for k in range(2,21):
knn = KNeighborsClassifier(n_neighbors=k)
#cv参数决定数据集划分比例,这里是按照5:1划分训练集和测试集
scores = cross_val_score(knn, x, y, cv=6, scoring='accuracy')
k_error.append(1 - scores.mean())
#画图,x轴为k值,y值为误差值
plt.plot(range(2,21), k_error)
plt.xlabel('Value of K for KNN')
plt.ylabel('Error')
plt.xticks(np.arange(0,21,1)) # 设置x轴刻度
plt.show()
acc_knn_list=[]
for i in range(100):
x_train, x_test, y_train, y_test = train_test_split(x,y,test_size=0.3)
knn_2 = KNeighborsClassifier(n_neighbors=2)
knn_2.fit(x_train,y_train)
knn_2_y_test=knn_2.predict(x_test)
acc_2=accuracy_score(y_test,knn_2_y_test)
acc_knn_list.append(acc_2)
sns.distplot(acc_knn_list)
|