python - LeaveOneOut 确定 knn 中的 k

标签 python machine-learning scikit-learn cross-validation knn

我想知道 k 最近邻的最佳 k。我正在使用 LeaveOneOut 将数据划分为训练集和测试集。在下面的代码中,我有 150 个数据条目,因此我得到 150 个不同的训练集和测试集。 K 应介于 1 到 40 之间。

我想将交叉验证平均分类误差绘制为 k 的函数,也看看哪个 k 最适合 KNN。

这是我的代码:

import scipy.io as sio
import seaborn as sn
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import LeaveOneOut    
error = []
array = np.array(range(1,41))

dataset = pd.read_excel('Data/iris.xls')
X = dataset.iloc[:, :-1].values  
y = dataset.iloc[:, 4].values

loo = LeaveOneOut()
loo.get_n_splits(X)
for train_index, test_index in loo.split(X):
    #print("TRAIN:", train_index, "TEST:", test_index)
    X_train, X_test = X[train_index], X[test_index]
    y_train, y_test = y[train_index], y[test_index]
    #print(X_train, X_test, y_train, y_test)

    for i in range(1, 41):  
        classifier = KNeighborsClassifier(n_neighbors=i)  
        classifier.fit(X_train, y_train)
        y_pred = classifier.predict(X_test)
        error.append(np.mean(y_pred != y_test))

plt.figure(figsize=(12, 6))  
plt.plot(range(1, 41), error, color='red', linestyle='dashed', marker='o', markerfacecolor='blue', markersize=10)
plt.title('Error Rate K Value')  
plt.xlabel('K Value')  
plt.ylabel('Mean Error')

最佳答案

您正在计算每次预测的误差,这就是为什么您的 error 数组中有 6000 个点。您需要收集给定 'n_neighbors' 折叠中所有点的预测,然后计算该值的误差。

你可以这样做:

# Loop over possible values of "n_neighbors"
for i in range(1, 41):  

    # Collect the actual and predicted values for all splits for a single "n_neighbors"
    actual = []
    predicted = []


    for train_index, test_index in loo.split(X):
        #print("TRAIN:", train_index, "TEST:", test_index)
        X_train, X_test = X[train_index], X[test_index]
        y_train, y_test = y[train_index], y[test_index]

        classifier = KNeighborsClassifier(n_neighbors=i)  
        classifier.fit(X_train, y_train)
        y_pred = classifier.predict(X_test)

        # Append the single predictions and actual values here.
        actual.append(y_test[0])
        predicted.append(y_pred[0])

    # Outside the loop, calculate the error.
    error.append(np.mean(np.array(predicted) != np.array(actual))) 

其余代码没问题。

如果您使用cross_val_predict,则可以通过更紧凑的方式来执行此操作。

from sklearn.model_selection import cross_val_predict

for i in range(1, 41):  

    classifier = KNeighborsClassifier(n_neighbors=i)  
    y_pred = cross_val_predict(classifier, X, y, cv=loo)
    error.append(np.mean(y_pred != y))

关于python - LeaveOneOut 确定 knn 中的 k,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53804854/

相关文章:

python - 将参数传递给自定义异常

c++ - 开始物理模拟

machine-learning - 即使训练和测试数据相同,分类器每次训练都会给出不同的结果

python - Pytorch:如何创建不是来自衍生品的更新规则?

python - scikit-learn 转换器根据用户提供的切点对数据进行分类

python - python中是否有用于均方根误差(RMSE)的库函数?

python 3 : How can I align the the format of this data when it prints

machine-learning - 如何处理对数据集中的多列应用 One Hot Encoding 后产生的大量恐惧?

python - 属性错误 : 'GridSearchCV' object has no attribute 'best_estimator_'

python - 如何从文件路径中提取文件名?