我在进行一个机器学习项目,当我尝试使用交叉验证来确定需要多少邻居以在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.sstatic.net/sirSl.png <-数据集示例
接下来,这是我分配训练和测试组的第一段代码:
这就是我分配x和y的方式。通过len,我可以看到x和y都有649行,代表649名学生。
这是我进行交叉验证的第二段代码:
#CROSSVALIDATIONfrom sklearn.neighbors import KNeighborsClassifierneighbors = list (range(2,30))cv_scores=[]#print(y_train)from sklearn.model_selection import cross_val_scoreimport matplotlib.pyplot as pltfor 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中的读数是否准确。
我的问题是:
为什么我的”y中的类别”只有1个成员,len(y)明显显示y有649个实例,足以分成59组,每组11个成员?这里的”成员”是指我的数据集中的”实例”,还是y组中的列/标签?
我在进行训练/测试分割时没有使用stratify=y
,这似乎是解决这个警告的第一选择,但在我的情况下没有用。
我已经尝试了我在谷歌/Stack Overflow上看到的所有方法,但没有任何帮助,数据集似乎是问题所在,但我无法理解哪里出了问题。
回答:
我认为你的主要错误是你在使用KNeighborsClassifier,而你要预测的特征似乎是连续的(G3 – 最终成绩(数值:从0到20,输出目标)),而不是分类变量。
在这种情况下,”y”中的每个单一值都被视为不同的可能类别或标签。你得到的消息是说在你的数据集中(在”y”中),有一些值只出现了一次。例如,值3在你的数据集中只出现了一次。这不是错误,但表明模型不会正确或准确地工作。
总之,我强烈建议你使用sklearn.neighbors.KNeighborsRegressor。
这是用于”连续”变量而不是类别的Knn。使用这个模型,你应该不会再有这个问题。输出值将是你定义的最近邻居数量的平均值。
通过这些简单的更改,你的问题将得到解决。