这是我的第一个 KNN 实现。我应该使用(最初不缩放数据)线性回归和 KNN 模型来预测贷款状态(Y/N)给定一系列参数,如收入、教育状况等。
我设法建立了 LR 模型,它运行得相当好。对于KNN模型,我选择了最基本的求k值的方法:将k初始化为3,然后遍历(1,40)中k的各种值,绘制出错误率与k的关系图。最终应根据图表选择最小化误差的 k 值,以获得预测。
代码的 KNN 部分:
from sklearn.neighbors import KNeighborsClassifier
# initialize k as 3
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(x_train,y_train.ravel())#.ravel() converts the column vector into a row vector (1d array). warning without this.
#Predict the values using test dataset, for k=3
pred = knn.predict(x_test)
#Print the classification report and confusion matrix(checking accuracy for k=3 value)
from sklearn.metrics import classification_report,confusion_matrix
print(confusion_matrix(y_test,pred))
print(classification_report(y_test,pred))
#now, we vary k from 1 to 40 and see which value minimizes the error rate
error_rate = []
for i in range(1,40): #also,k value should be odd
knn = KNeighborsClassifier(n_neighbors=i)
knn.fit(x_train,y_train.ravel()) #.ravel() converts the column vector into a row vector (1d array). warning without this and takes a lot of time.
pred_i = knn.predict(x_test)
error_rate.append(np.mean(pred_i != y_test))
plt.figure(figsize=(10,6))
plt.plot(range(1,40),error_rate,color='blue', linestyle='dashed', marker='o',
markerfacecolor='red', markersize=10)
plt.title('Error Rate vs. K Value')
plt.xlabel('K')
plt.ylabel('Error Rate')
plt.show()
#k value which minimizes the error rate: 39
knn = KNeighborsClassifier(n_neighbors=39)
knn.fit(x_train,y_train.ravel())
pred=knn.predict(x_test)
from sklearn.metrics import classification_report, confusion_matrix
print(confusion_matrix(y_test,pred))
print(classification_report(y_test,pred))
from sklearn.metrics import r2_score
from sklearn.metrics import mean_squared_error
r2score_knn= r2_score(y_test,pred)
MSE_knn= mean_squared_error(y_test,pred)
print("r2 score,non normalized knn: ", r2score_knn)
print("MSE , non normalised knn: ", MSE_knn)
然而,输出是相当令人费解的。k=39(0.65) 的准确度得分比 k=3(0.74) 差,尽管图表显示 k=3 的错误率远高于 39 的错误率。
[[14 21]
[ 4 57]]
precision recall f1-score support
0 0.78 0.40 0.53 35
1 0.73 0.93 0.82 61
accuracy 0.74 96
macro avg 0.75 0.67 0.67 96
weighted avg 0.75 0.74 0.71 96
[[ 1 34]
[ 0 61]]
precision recall f1-score support
0 1.00 0.03 0.06 35
1 0.64 1.00 0.78 61
accuracy 0.65 96
macro avg 0.82 0.51 0.42 96
weighted avg 0.77 0.65 0.52 96
r2 score,non normalized knn: -0.5288056206088991
MSE, non normalised knn: 0.3541666666666667
这可能是什么原因?那么我究竟如何推导出最佳k值呢?
查看图表,我假设这可能与 k=3 是局部最小值(某种程度)这一事实有关,而 k=39 不是……我尝试了 k=25 的模型(其他局部最小值),并且准确度得分确实增加了(0.70),但仍然小于 k=3。
但是,唯一相关的信息应该只是错误率......那么这里到底发生了什么?