在scikit学习中进行一次热编码的可能方法



我有一个带有一些分类列的panda数据框架。其中一些包含非整数值。

我目前想在这些数据上应用几个机器学习模型。对于某些模型,有必要进行归一化以获得更好的结果。例如,将分类变量转换为伪/指标变量。实际上,panda有一个名为get_dummies的函数用于此目的。但是,此函数会根据数据返回结果。因此,如果我对训练数据调用get_dummies,然后对测试数据再次调用它,在两种情况下实现的列可能不同,因为与训练数据中的可能值相比,测试数据中的分类列可能只包含一个子集/不同的可能值集。

因此,我正在寻找其他方法来做一个热编码。

有哪些可能的方法可以在python中进行一次热编码(pandas/sklearn)?

Scikit learn提供了一个编码器sklearn.preprocessing.LabelBinarizer

对于编码训练数据,您可以使用fit_transform,它将发现类别标签并创建适当的伪变量。

label_binarizer = sklearn.preprocessing.LabelBinarizer()
training_mat = label_binarizer.fit_transform(df.Label)

对于测试数据,您可以使用transform使用相同的类别集。

test_mat = label_binarizer.transform(test_df.Label)

在过去,我发现处理这个问题的最简单方法是使用get_dummies,然后强制测试和训练之间的列匹配。例如,您可以执行以下操作:

import pandas as pd
train = pd.get_dummies(train_df)
test = pd.get_dummies(test_df)
# get the columns in train that are not in test
col_to_add = np.setdiff1d(train.columns, test.columns)
# add these columns to test, setting them equal to zero
for c in col_to_add:
    test[c] = 0
# select and reorder the test columns using the train columns
test = test[train.columns]

这将丢弃您在训练集中没有看到的标签信息,但将增强一致性。如果您使用这些拆分进行交叉验证,我建议您做两件事。首先,在整个数据集上执行get_dummies以获得所有列(而不是像上面的代码中那样仅在训练集上)。其次,使用StratifiedKFold进行交叉验证,以便您的拆分包含相关标签。

比方说,我有一个可能值为"a"、"b"、"c"、"d"的特性"a"。但训练数据集仅包含三个类别"a"、"b"one_answers"c"作为值。如果在此阶段使用get_dummies,则生成的特征将是三个(A_A、A_b、A_c)。但理想情况下,应该还有另一个全为零的特征A_ d。这可以通过以下方式实现:

import pandas as pd
data = pd.DataFrame({"A" : ["a", "b", "c"]})
data["A"] = data["A"].astype("category", categories=["a", "b", "c", "d"])
mod_data = pd.get_dummies(data[["A"]])
print(mod_data)

输出为

   A_a  A_b  A_c  A_d
0  1.0  0.0  0.0  0.0
1  0.0  1.0  0.0  0.0
2  0.0  0.0  1.0  0.0

对于文本列,您可以尝试此

from sklearn.feature_extraction.text import CountVectorizer
data = ['he is good','he is bad','he is strong']
vectorizer = CountVectorizer()
vectors = vectorizer.fit_transform(data)

输出:

for i in range(len(data)):
    print(vectors[i, :].toarray())

输出:

[[0 1 1 1 0]]
[[1 0 1 1 0]]
[[0 0 1 1 1]]

Sklearn实际上有一个OneHotEndcoder,它工作得非常好。

from sklearn.preprocessing import OneHotEncoder
one_hot_encoder = OneHotEncoder(sparse=False)
train_labels_one_hot = one_hot_encoder.fit_transform(train_df["target"].to_numpy().reshape(-1, 1))
val_labels_one_hot = one_hot_encoder.transform(val_df["target"].to_numpy().reshape(-1, 1))
test_labels_one_hot = one_hot_encoder.transform(test_df["target"].to_numpy().reshape(-1, 1))

在第一次使用如上所述的fit_transform函数之后,仅使用transform功能应该可以保持标签的正确匹配。

相关内容

  • 没有找到相关文章

最新更新