缺少类别的单热编码
One-hot-encoding with missing categories
我有一个包含类别列的数据集。为了使用线性回归,我对这一列进行了 1-hot 编码。
我的集合有 10 列,包括类别列。删除该列并附加 1-hot 编码矩阵后,我最终得到 14 列 (10 - 1 + 5)。
所以我用形状为 (n, 14) 的矩阵训练(拟合)我的 LinearRegression 模型。
训练完成后,我想在训练集的一个子集上测试它,所以我先只取 5 个,然后将它们放在同一个管道中。但是这 5 个 first 只包含其中的 3 个类别。因此,在通过管道后,我只剩下形状为 (n, 13) 的矩阵,因为它缺少 2 个类别。
如何强制 1-hot 编码器使用 5 个类别?
我正在使用 sklearn 中的 LabelBinarizer。
我已经 运行 解决了这个问题,但我无法通过 scikit-learn
找到解决方案。
我正在使用 pandas .get_dummies()
来做类似于 OneHotEncoder
的事情。
下面是我为处理这个确切问题而创建的函数,请随意使用并改进它(如果您发现任何错误请告诉我,实际上我只是从我的代码库中有更具体的功能):
import numpy as np
import pandas as pd
def one_hot_encoding_fixed_columns(pandas_series, fixed_columns):
# Creates complete fixed columns list (with nan and 'other')
fixed_columns = list(fixed_columns)
fixed_columns.extend([np.nan, 'other'])
# Get dummies dataset
ohe_df = pd.get_dummies(pandas_series, dummy_na=True)
# Create blank 'other' column
ohe_df['other'] = 0
# Check if columns created by get_dummies() are in 'fixed_columns' list.
for column in ohe_df.columns:
if column not in fixed_columns:
# If not in 'fixed_columns', transforms exceeding column into 'other'.
ohe_df['other'] = ohe_df['other'] + ohe_df[column]
ohe_df.drop(columns=[column])
# Check if elements in 'fixed_columns' are in the df generated by get_dummies()
for column in fixed_columns:
if column not in ohe_df.columns:
# If the element is not present, create a new column with all values set to 0.
ohe_df['column'] = 0
# Reorders columns according to fixed columns
ohe_df = ohe_df[fixed_columns]
return ohe_df
基本上,您创建一个包含将始终使用的列的列表。如果 test
样本不包含给定类别的任何元素,则会创建具有 values = 0
的对应列。如果 test
有一个不在 train
样本中的新值,它将被归类为 other
.
我已经注释掉了代码,希望它是可以理解的,如果您有任何问题,请告诉我,我会澄清的。
此函数的输入是 pandas_series = df['column_name']
,您可以在训练集上执行类似 fixed_columns = df[selected_column].str[0].value_counts().index.values
的操作以生成也将在测试集上使用的值。
错误是"put the test data through the same pipeline"。基本上我在做:
data_prepared = full_pipeline.fit_transform(train_set)
lin_reg = LinearRegression()
lin_reg.fit(data_prepared, labels)
some_data = train_set.iloc[:5]
some_data_prepared = full_pipeline.fit_transform(some_data)
lin_reg.predict(some_data_prepared)
# => error because mismatching shapes
有问题的行是:
some_data_prepared = full_pipeline.fit_transform(some_data)
通过 fit_transform
,我会将 LabelBinarizer 适合仅包含 3 个标签的集合。相反,我应该这样做:
some_data_prepared = full_pipeline.transform(some_data)
这样我使用的是全套(train_set
)拟合的管道,并以同样的方式对其进行转换。
基本上,首先我们需要对基础数据应用 fit_transform,然后对样本数据应用转换,因此样本数据也将获得准确的 no.of 列 w.r.t 基础数据.
我有一个包含类别列的数据集。为了使用线性回归,我对这一列进行了 1-hot 编码。
我的集合有 10 列,包括类别列。删除该列并附加 1-hot 编码矩阵后,我最终得到 14 列 (10 - 1 + 5)。
所以我用形状为 (n, 14) 的矩阵训练(拟合)我的 LinearRegression 模型。
训练完成后,我想在训练集的一个子集上测试它,所以我先只取 5 个,然后将它们放在同一个管道中。但是这 5 个 first 只包含其中的 3 个类别。因此,在通过管道后,我只剩下形状为 (n, 13) 的矩阵,因为它缺少 2 个类别。
如何强制 1-hot 编码器使用 5 个类别?
我正在使用 sklearn 中的 LabelBinarizer。
我已经 运行 解决了这个问题,但我无法通过 scikit-learn
找到解决方案。
我正在使用 pandas .get_dummies()
来做类似于 OneHotEncoder
的事情。
下面是我为处理这个确切问题而创建的函数,请随意使用并改进它(如果您发现任何错误请告诉我,实际上我只是从我的代码库中有更具体的功能):
import numpy as np
import pandas as pd
def one_hot_encoding_fixed_columns(pandas_series, fixed_columns):
# Creates complete fixed columns list (with nan and 'other')
fixed_columns = list(fixed_columns)
fixed_columns.extend([np.nan, 'other'])
# Get dummies dataset
ohe_df = pd.get_dummies(pandas_series, dummy_na=True)
# Create blank 'other' column
ohe_df['other'] = 0
# Check if columns created by get_dummies() are in 'fixed_columns' list.
for column in ohe_df.columns:
if column not in fixed_columns:
# If not in 'fixed_columns', transforms exceeding column into 'other'.
ohe_df['other'] = ohe_df['other'] + ohe_df[column]
ohe_df.drop(columns=[column])
# Check if elements in 'fixed_columns' are in the df generated by get_dummies()
for column in fixed_columns:
if column not in ohe_df.columns:
# If the element is not present, create a new column with all values set to 0.
ohe_df['column'] = 0
# Reorders columns according to fixed columns
ohe_df = ohe_df[fixed_columns]
return ohe_df
基本上,您创建一个包含将始终使用的列的列表。如果 test
样本不包含给定类别的任何元素,则会创建具有 values = 0
的对应列。如果 test
有一个不在 train
样本中的新值,它将被归类为 other
.
我已经注释掉了代码,希望它是可以理解的,如果您有任何问题,请告诉我,我会澄清的。
此函数的输入是 pandas_series = df['column_name']
,您可以在训练集上执行类似 fixed_columns = df[selected_column].str[0].value_counts().index.values
的操作以生成也将在测试集上使用的值。
错误是"put the test data through the same pipeline"。基本上我在做:
data_prepared = full_pipeline.fit_transform(train_set)
lin_reg = LinearRegression()
lin_reg.fit(data_prepared, labels)
some_data = train_set.iloc[:5]
some_data_prepared = full_pipeline.fit_transform(some_data)
lin_reg.predict(some_data_prepared)
# => error because mismatching shapes
有问题的行是:
some_data_prepared = full_pipeline.fit_transform(some_data)
通过 fit_transform
,我会将 LabelBinarizer 适合仅包含 3 个标签的集合。相反,我应该这样做:
some_data_prepared = full_pipeline.transform(some_data)
这样我使用的是全套(train_set
)拟合的管道,并以同样的方式对其进行转换。
基本上,首先我们需要对基础数据应用 fit_transform,然后对样本数据应用转换,因此样本数据也将获得准确的 no.of 列 w.r.t 基础数据.