Scikit Learn OneHotEncoded Features 导致分类器出错

数据挖掘 Python scikit-学习 预测建模 分类数据 数据框
2022-02-16 14:26:41

我正在尝试为决策树和多项朴素贝叶斯分类器的输入准备数据。

这就是我的数据的样子(熊猫数据框):

Label  Feat1  Feat2  Feat3  Feat4

0        1     3       2      1
1        0     1       1      2
2        2     2       1      1
3        3     3       2      3

我已将数据拆分为 dataLabel 和 dataFeatures。使用准备好的dataLabeldataLabel.ravel()

我需要离散化特征,以便分类器将它们视为分类而不是数字。

我正在尝试使用OneHotEncoder

enc = OneHotEncoder()

enc.fit(dataFeatures)
chk = enc.transform(dataFeatures)
from sklearn.naive_bayes import MultinomialNB

mnb = MultinomialNB()

from sklearn import metrics
from sklearn.cross_validation import cross_val_score
scores = cross_val_score(mnb, Y, chk, cv=10, scoring='accuracy')

我收到此错误:bad input shape (64, 16)

这是标签和输入的形状:

dataLabel.shape = 72 chk.shape = 72,16

为什么分类器不接受 onehotencoded 特征?

编辑:添加我如何获得 dataFeatures

dataFeatures = data[['Accpred', 'Gyrpred', 'Barpred', 'altpred']]

Y = dataLabel.ravel()

1个回答
scores = cross_val_score(mnb, Y, chk, cv=10, scoring='accuracy')

你有你的Ychk切换的。就是这样。:)

的签名cross_val_scoresklearn.cross_validation.cross_val_score(estimator, X, y)

X是一个矩阵,y是一个带有类标签的一维向量。

与 R 不同,大多数(或全部?)sklearn 模型不支持分类变量。大多数时候,将特征矩阵编码X为所谓的 one-hot 编码就足够了。

请注意,在某些模型中,这种 hack 与真正的原生分类支持不同,模型的性能会更差。

反转 One-Hot 编码

Sklearn 似乎没有一种简单的方法来反转 one-hot 编码。

如何做到这一点并非易事。我发现了这个建议

def inverse(enc, out, shape):
    return np.array([enc.active_features_[col] for col in out.sorted_indices().indices]).reshape(shape) - enc.feature_indices_[:-1]

例子:

import numpy as np
from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder()
X = np.array([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]]))
Z = enc.fit_transform(X)
print(inverse(enc, Z, X.shape))
# [[0 0 3]
#  [1 1 0]
#  [0 2 1]
#  [1 0 2]]
print(X)
# [[0 0 3]
#  [1 1 0]
#  [0 2 1]
#  [1 0 2]]

注意:

  • 这仅在HotOneEncoding(sparse=True)(默认)时有效,因为它使用 scipy 稀疏矩阵方法(这可以通过使代码仅使用 numpy 方法来更改),但这可能是您想要的,因为使用密集矩阵无论如何都会杀死您的记忆
  • 我认为这仅在您的变量在 [0,something] 范围内时才有效,因为您在转换中丢失了该信息(除了您使用DictVectorizer 之类的东西之外没有解决方法,它可以让您更好地控制转换。