sklearn交叉验证:y中人口最少的class只有1个成员,小于n_splits=10

sklearn cross validation : The least populated class in y has only 1 members, which is less than n_splits=10

我在一个机器学习项目中工作,当我尝试使用交叉验证来了解我需要多少邻居才能在 knn 中达到最佳准确度时,我遇到了这个警告;这是警告:

The least populated class in y has only 1 members, which is less than n_splits=10.

我使用的数据集是https://archive.ics.uci.edu/ml/datasets/Student+Performance

在这个数据集中,我们有几个属性,但我们将只使用“G1”、“G2”、“G3”、“studytime”、“freetime”、“health”、“famrel”。这些列中的所有实例都是整数。 https://i.stack.imgur.com/sirSl.png <-数据集示例

接下来,这是我分配训练组和测试组的第一段代码:

import pandas as pd
import numpy as np
from google.colab import drive
drive.mount('/gdrive')
import sklearn

data=pd.read_excel("/gdrive/MyDrive/Colab Notebooks/student-por.xls")

#print(data.head())
data = data[["G1", "G2", "G3", "studytime","freetime","health","famrel"]]  
print(data)
predict = "G3"


x = np.array(data.drop([predict], axis=1))  
y = np.array(data[predict])  
print(y)
x_train, x_test, y_train, y_test = sklearn.model_selection.train_test_split(x, y, test_size=0.3, random_state=42)
print(len(y))
print(len(x))

这就是我分配 x 和 y 的方式。使用 len,我可以看到 x 和 y 都有 649 行,代表 649 名学生。

这是我执行 cross_val:

时的第二段代码
#CROSSVALIDATION
from sklearn.neighbors import KNeighborsClassifier
neighbors = list (range(2,30))
cv_scores=[]
#print(y_train)

from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt

for k in neighbors:
    knn = KNeighborsClassifier(n_neighbors=k)
    scores = cross_val_score(knn,x_train,y_train,cv=11,scoring='accuracy')
    cv_scores.append(scores.mean())
plt.plot(cv_scores)
plt.show()```

如您所见,代码非常自明

警告:

The least populated class in y has only 1 members, which is less than n_splits=10.

发生在 for 循环的每次迭代中

虽然这个警告每次都会发生,plt.show() 仍然能够绘制一个图表,说明哪些邻居数量最能达到良好的准确性,我不知道这个图表或读数是否在cv_scores 是准确的。

我的问题是:

怎么我的“class in y”只有1个成员,len(y)明明说y有649个实例,绰绰有余分成 59 组,每组 11 名成员?,成员指的是我数据集中的“实例”,还是 y 组中的 colums/labels?

当我进行 train/test 拆分时,我没有使用 stratify=y,它似乎是此警告的 1# 解决方案,但对我来说没用。

我已经尝试了我在 google/stack overflow 上看到的所有内容,但没有任何帮助,数据集似乎是问题所在,但我不明白哪里出了问题。

我认为您的主要错误是您使用的是 KNeighborsClassifier,并且您要预测的特征似乎是 连续G3 - 最终成绩(数字:从 0 到 20,输出目标))而不是分类。

在这种情况下,“y”的每个值都被视为不同的可能 class 或标签。您获得的消息是说在您的数据集中(在“y”上),有些值只出现一次。例如,值 3 在您的数据集中只出现一次。这不是错误,但表明该模型无法正确或准确地工作。

毕竟我强烈推荐你使用sklearn.neighbors.KNeighborsRegressor.

这是用于“连续”变量的 Knn,而不是 classes。使用这个模型,你应该不会再有这个问题了。输出值将是您定义的最近邻居数之间的平均值。

通过这个简单的更改,您的问题将得到解决。