在 scikit-learn 中进行一种热编码的可能方法?
Possible ways to do one hot encoding in scikit-learn?
我有一个包含一些分类列的 pandas 数据框。其中一些包含非整数值。
我目前想在此数据上应用多个机器学习模型。对于某些模型,有必要进行归一化以获得更好的结果。例如,将分类变量转换为 dummy/indicator 个变量。事实上,pandas 有一个名为 get_dummies 的函数用于此目的。但是,这个函数returns的结果取决于数据。因此,如果我在训练数据上调用 get_dummies,然后在测试数据上再次调用它,两种情况下获得的列可能不同,因为测试数据中的分类列可能只包含一组 sub-set/different 可能的比较值到训练数据中的可能值。
因此,我正在寻找其他方法来进行 one-hot 编码。
在 python (pandas/sklearn) 中进行一次热编码的可能方法有哪些?
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)
过去,我发现处理此问题的最简单方法是使用 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",可能的值为 "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
对于文本列,你可以试试这个
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]]
我有一个包含一些分类列的 pandas 数据框。其中一些包含非整数值。
我目前想在此数据上应用多个机器学习模型。对于某些模型,有必要进行归一化以获得更好的结果。例如,将分类变量转换为 dummy/indicator 个变量。事实上,pandas 有一个名为 get_dummies 的函数用于此目的。但是,这个函数returns的结果取决于数据。因此,如果我在训练数据上调用 get_dummies,然后在测试数据上再次调用它,两种情况下获得的列可能不同,因为测试数据中的分类列可能只包含一组 sub-set/different 可能的比较值到训练数据中的可能值。
因此,我正在寻找其他方法来进行 one-hot 编码。
在 python (pandas/sklearn) 中进行一次热编码的可能方法有哪些?
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)
过去,我发现处理此问题的最简单方法是使用 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",可能的值为 "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
对于文本列,你可以试试这个
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]]