pandas 在scikit-learn中进行一个热编码的可能方法?

dluptydi  于 2023-03-21  发布在  其他
关注(0)|答案(5)|浏览(209)

我有一个pandas数据框架,其中包含一些分类列。其中一些包含非整数值。
我目前想在这些数据上应用几种机器学习模型。对于某些模型,有必要进行归一化以获得更好的结果。例如,将分类变量转换为dummy/indicator变量。事实上,pandas有一个名为get_dummies的函数用于此目的。然而,此函数返回的结果取决于数据。因此,如果我在训练数据上调用get_dummies,然后在测试数据上再次调用它,在两种情况下实现的列可能不同,因为与训练数据中的可能值相比,测试数据中的分类列可能仅包含可能值的子集/不同集合。
因此,我正在寻找其他方法来进行one-hot编码。
在python中进行一次热编码有哪些可能的方法(pandas/sklearn)?

wnavrhmk

wnavrhmk1#

Scikit-learn提供了一个编码器sklearn.preprocessing.LabelBinarizer
对于编码训练数据,您可以使用fit_transform,它将发现类别标签并创建适当的虚拟变量。

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

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

test_mat = label_binarizer.transform(test_df.Label)
voj3qocg

voj3qocg2#

在过去,我发现处理这个问题最简单的方法是使用get_dummies,然后强制test和train之间的列匹配。例如,你可以这样做:

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进行交叉验证,以便拆分包含相关的标签。

83qze16e

83qze16e3#

假设,我有一个特征“A”,其可能值为“a”,“b”,“c”,“d”。但训练数据集仅包含三个类别“a”,“b”,“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
8iwquhpp

8iwquhpp4#

对于文本列,您可以尝试这样做

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]]
omjgkv6w

omjgkv6w5#

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 函数应该可以保持标签正确匹配。

相关问题