KNN 模型的准确度得分(IRIS 数据)

Posted

技术标签:

【中文标题】KNN 模型的准确度得分(IRIS 数据)【英文标题】:Accuracy score for a KNN model (IRIS data) 【发布时间】:2019-11-15 15:20:44 【问题描述】:

在 IRIS 数据上增加或稳定这个基本 KNN 模型的准确度得分不会显着变化)可能是哪些关键因素?

尝试

from sklearn import neighbors, datasets, preprocessing
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix

iris = datasets.load_iris() 
X, y = iris.data[:, :], iris.target

Xtrain, Xtest, y_train, y_test = train_test_split(X, y)
scaler = preprocessing.StandardScaler().fit(Xtrain)
Xtrain = scaler.transform(Xtrain)
Xtest = scaler.transform(Xtest)

knn = neighbors.KNeighborsClassifier(n_neighbors=4)
knn.fit(Xtrain, y_train)
y_pred = knn.predict(Xtest)

print(accuracy_score(y_test, y_pred))
print(classification_report(y_test, y_pred))
print(confusion_matrix(y_test, y_pred))

样本准确度得分

0.9736842105263158
0.9473684210526315
1.0
0.9210526315789473

分类报告

              precision    recall  f1-score   support

           0       1.00      1.00      1.00        12
           1       0.79      1.00      0.88        11
           2       1.00      0.80      0.89        15

    accuracy                           0.92        38
   macro avg       0.93      0.93      0.92        38
weighted avg       0.94      0.92      0.92        38

样本混淆矩阵

[[12  0  0]
 [ 0 11  0]
 [ 0  3 12]]

【问题讨论】:

稳定精度是什么意思?你想为这个问题找到一个好的“k”值吗? 你的意思是跨越多次运行?如果是,那你为什么要这样做? What is "random-state" in sklearn.model_selection.train_test_split example?的可能重复 【参考方案1】:

在 iris 数据集中只有 3 个类可用,Iris-Setosa、Iris-Virginica 和 Iris-Versicolor。

使用此代码。这给了我97.78% 准确度

from sklearn import neighbors, datasets, preprocessing
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix

iris = datasets.load_iris() 
X, y = iris.data[:, :], iris.target
Xtrain, Xtest, y_train, y_test = train_test_split(X, y, stratify = y, random_state = 0, train_size = 0.7)

scaler = preprocessing.StandardScaler().fit(Xtrain)
Xtrain = scaler.transform(Xtrain)
Xtest = scaler.transform(Xtest)

knn = neighbors.KNeighborsClassifier(n_neighbors=3)
knn.fit(Xtrain, y_train)
y_pred = knn.predict(Xtest)

print(accuracy_score(y_test, y_pred))
print(classification_report(y_test, y_pred))
print(confusion_matrix(y_test, y_pred))

【讨论】:

检查新答案,如果有效,请将其标记为正确。 将 train_size = 0.7 更改为 97.78% 的准确率。 如何确保模型不会过拟合?【参考方案2】:

我建议调整 k-NN 的 k 值。由于 iris 是一个小数据集并且非常平衡,我将执行以下操作:

对于 [2 到 10] 范围内的每个 `k` 值(例如) 执行 n 次 k 折交叉验证(例如 n=20 和 k=4) 存储准确度值(或任何其他指标)

根据平均值和方差绘制分数,并选择具有最佳 k 值的 k 值。交叉验证的主要目标是估计测试误差,并在此基础上选择最终模型。会有一些差异,但应该小于 0.03 或类似的值。这取决于数据集和您采取的折叠次数。一个好的过程是,为k 的每个值制作所有 20x4 精度值的箱线图。选择下分位数与上分位数相交的k 的值,或者简单地说,在精度(或其他度量值)没有太大变化的情况下。

一旦基于此选择k 的值,目标就是使用该值来构建使用整个训练数据集的最终模型。接下来,这可用于预测新数据。

另一方面,对于更大的数据集。创建一个单独的测试分区(就像您在此处所做的那样),然后仅在训练集上调整 k 值(使用交叉验证,忘记测试集)。选择合适的k 训练算法后,仅使用训练集进行训练。接下来,使用测试集报告最终值。永远不要根据测试集做出任何决定。

另一种方法是训练、验证、测试分区。使用训练集进行训练,使用k 的不同值训练模型,然后使用验证分区进行预测并列出分数。根据此验证分区选择最佳分数。接下来使用训练集或训练+验证集使用基于验证集选择的k 的值训练最终模型。最后取出测试集,上报最终成绩。同样,切勿在其他任何地方使用测试集。

这些是适用于任何机器学习或统计学习方法的通用方法。

执行分区(训练、测试或交叉验证)时需要注意的重要事项,请使用stratified sampling,以便在每个分区中类比率保持不变。

阅读有关crossvalidation 的更多信息。在 scikitlearn 中很容易做到。如果使用 R,则可以使用 caret。

要记住的主要内容是,目标是训练一个泛化新数据的函数,或者在新数据上表现良好,而不是仅仅在现有数据上表现良好。

【讨论】:

嗨 phoxis,他为什么要使用多个 k 值,因为 k =3 已经固定。这是分类器而不是聚类问题。 @RheateyBash 但在这种情况下,差异并不重要。如果值 4 的方差很大,那么值 4 可能不是这个问题的好值。 假设有三类 iris 数据集,如果我选择 k 不是 3,你将如何证明正确的分类。实际上它会变成聚类问题而不是分类问题。永远无法达到预期的结果。 我不明白你是如何将班级数量和邻居数量联系起来的?根据问题,任务是构建基于 kNN 的分类器模型。类的数量不应该与邻居的数量有任何关系。 知道了。谢谢。

以上是关于KNN 模型的准确度得分(IRIS 数据)的主要内容,如果未能解决你的问题,请参考以下文章

比较模型之间的 AUC、对数损失和准确度得分

OpenCV-Python实战(番外篇)——利用 KNN 算法识别手写数字

机器学习:kNN的超参数

测试准确度较低但 AUC 得分较高的可能原因

机器学习系列 - 3. 数据预处理

如何使用 Matlab 实现 KNN 并计算百分比准确度