Python 模型预测类不在目标中(零数组)

Python 模型预测类不在目标中(零数组),python,machine-learning,scikit-learn,Python,Machine Learning,Scikit Learn,我已经使用多重LabelBinarizer对目标变量进行了编码。然后,我用这种方式根据转换的结果创建了一个新的数据帧 y_trans = pd.DataFrame(MultiLabelBinarizer().fit_transform(y)) 这是head() 我使用 X_train, X_test, y_train, y_test = train_test_split(X_trans, y_trans, random_state=0) 在拟合randomfreest或KNN后,预测X_检验

我已经使用多重LabelBinarizer对目标变量进行了编码。然后,我用这种方式根据转换的结果创建了一个新的数据帧

y_trans = pd.DataFrame(MultiLabelBinarizer().fit_transform(y))
这是
head()

我使用

X_train, X_test, y_train, y_test = train_test_split(X_trans, y_trans, random_state=0)
在拟合
randomfreest
KNN
后,预测
X_检验
变量将返回一个数组,其中一些预测如下

array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])
由于

len(y_trans.where(y_trans == [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]).dropna())
实际上是0

我不明白为什么会这样。

复制我的问题 我提供要下载的文件。它们已被腌制成二进制格式。 从这里开始,重现我的错误的步骤非常简单

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
import pickle

X_trans = pickle.load(open('features.pkl', 'rb'))
y_trans = pickle.load(open('target.pkl', 'rb'))

X_train, X_test, y_train, y_test = train_test_split(X_trans, y_trans, random_state=0)

rfc = RandomForestClassifier(random_state=0)
rfc.fit(X_train, y_train)
print(rfc.predict(X_test)[1])
打印预测中的第二个值将返回
[0 0 0 0 0 0 0 0 0]

我的分类目标 我的目标是创建一个分类器,它可以预测至少一个“正确的类”,由条目中的1表示。 例如,y的第一个条目是
[0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0]
。 我会考虑正确的

  • [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
  • [0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0]
但这是一个评估问题,一旦预测正确就会发生。正如我所说,不可能有“空洞”的预测。共有18个类和127个唯一组合,其中没有一个是
[0 0 0 0 0 0 0 0 0 0]

我也有同样的“问题” 在这一点上,这个输出必须有意义。但我想不出来。 注意:在这个例子中,使用的分类器是
KNN
,我显示了
randomfreest
,但是如果我使用
KNN
,我会得到同样的问题

from sklearn.datasets import make_multilabel_classification
from sklearn.multioutput import MultiOutputClassifier
from sklearn.neighbors import KNeighborsClassifier

X, y = make_multilabel_classification(n_classes=18, random_state=0)
clf = MultiOutputClassifier(KNeighborsClassifier()).fit(X, y)
clf.predict(X)[3]

>>> array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
当拆分为列车和测试集时,同样适用

from sklearn.datasets import make_multilabel_classification
from sklearn.multioutput import MultiOutputClassifier
from sklearn.neighbors import KNeighborsClassifier

X, y = make_multilabel_classification(n_classes=18, random_state=0)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0, test_size=0.2)
clf = MultiOutputClassifier(KNeighborsClassifier()).fit(X_train, y_train)
clf.predict(X_test)[8]

>>> array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

首先,谢谢你提出的问题

我认为这里有几点需要解释:

  • 您的分类目标:您需要定义自己的度量标准来衡量您所描述的内容。(见附件)。这是第一步,因为如果不能衡量改进是什么,就无法改进模型
  • 接下来,在训练模型时,需要调整模型参数(称为“超参数”)以优化分数。为了快速解释,您可以选择一组参数,训练您的模型,并检查测试集上的分数。您可以通过修改参数来迭代以优化测试分数。一个简单的方法就是使用
  • 现在,回答你的问题:你的模型是为你的18个班级中的每一个独立预测一个样本是否在这个班级。这就是为什么在某些情况下,您可以得到一个似乎不属于任何类的示例
你能做些什么

  • 首先,您需要检查您的模型是否适合,并调整超参数以提高分数。目前,它的拟合度很差(训练分数远高于考试分数)。您可能会发现数据中没有足够的信号使其正常工作
  • 也许另一个模型可以帮助您获得更好的结果,具体取决于数据的拓扑结构(您需要试试看)
  • 您还可以使用rfc获得每个类别的预测概率。predict_proba:这将允许您设置不同于默认值0.5的阈值,甚至选择更高的阈值

谢谢您的回答。我知道我必须定义自己的评分函数,但因为我不能做出好的(有意义的)预测,我不能继续。我试过KNN、RF和SVC,但没有一个效果好。还有GridSearch,让它运行30分钟,但没有大的改进。我被卡住了,sklearn示例似乎也没有帮助。选择一个模型并优化改进结果,但最好的改进来自更好的输入数据(更好的特性,意味着添加特性,改进编码,等等)。一个好的分数是90%的数据,10%的模型优化。我的建议是:首先定义你的分数,第二步像你一样实现一个基本的随机森林模型,第三步获得更好的特性来提高分数。但有时你只是没有足够的信号来获得显著的结果。你能用你的输入特征手动分类吗?如果没有,您可能无法使用ML完成此操作
from sklearn.datasets import make_multilabel_classification
from sklearn.multioutput import MultiOutputClassifier
from sklearn.neighbors import KNeighborsClassifier

X, y = make_multilabel_classification(n_classes=18, random_state=0)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0, test_size=0.2)
clf = MultiOutputClassifier(KNeighborsClassifier()).fit(X_train, y_train)
clf.predict(X_test)[8]

>>> array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])