如何使用 LabelBinarizer 对正确的训练和测试进行一次热编码

     2023-03-12     213

关键词:

【中文标题】如何使用 LabelBinarizer 对正确的训练和测试进行一次热编码【英文标题】:How to use LabelBinarizer to one hot encode both train and test correctly 【发布时间】:2020-04-28 12:03:16 【问题描述】:

假设我有这样的火车:

Name   | day
------------
First  |  0
Second |  1
Third  |  1
Forth  |  2

还有一个不包含所有这些名称或日期的测试集。像这样:

Name   | day
------------
First  |  2
Second |  1
Forth  |  0

我有以下代码来转换编码特征中的这些列:

features_to_encode = ['Name', 'day']
label_final = pd.DataFrame()

for feature in features_to_encode:
    label_campaign = LabelBinarizer()
    label_results = label_campaign.fit_transform(df[feature])
    label_results = pd.DataFrame(label_results, columns=label_campaign.classes_)
    label_final = pd.concat([label_final, label_results], axis=1)

df_encoded = label_final.join(df)

在火车上产生以下输出(效果很好):

First  | Second  | Third  | Forth | 0 | 1 | 2 | 
-----------------------------------------------
  1    |    0    |   0    |   0   | 1 | 0 | 0 |
  0    |    1    |   0    |   0   | 0 | 1 | 0 |
  0    |    0    |   1    |   0   | 0 | 1 | 0 |
  0    |    0    |   0    |   1   | 0 | 0 | 1 |

但是,当我在测试数据(新数据)上运行此程序时,如果测试数据不包含与训练数据完全相同的名称和日期,我会得到不匹配的特征。所以如果我在这个测试样本上运行类似的代码,我会得到:

First  | Second  | Forth | 0 | 1 | 2 | 
--------------------------------------
  1    |    0    |   0   | 0 | 0 | 1 |
  0    |    1    |   0   | 0 | 1 | 0 |
  0    |    0    |   1   | 1 | 0 | 0 |

我可以做些什么来保留来自训练数据的相同转换并将其正确应用于测试数据,从而产生这个所需的输出

First  | Second  | Third  | Forth | 0 | 1 | 2 | 
-----------------------------------------------
  1    |    0    |   0    |   0   | 0 | 0 | 1 |
  0    |    1    |   0    |   0   | 0 | 1 | 0 |
  0    |    0    |   0    |   1   | 1 | 0 | 0 |

我已经尝试添加一个 dict 来捕获 fit_transform 结果,但我不确定这是否有效或之后如何处理:

features_to_encode = ['Name', 'day']
label_final = pd.DataFrame()

labels = --------------------------------------------------------------------> TRIED THIS
for feature in features_to_encode:
    label_campaign = LabelBinarizer()
    label_results = label_campaign.fit_transform(df[feature])
    labels[feature] = label_results--------------------------------------------> WITH THIS
    label_results = pd.DataFrame(label_results, columns=label_campaign.classes_)
    label_final = pd.concat([label_final, label_results], axis=1)

df_encoded = label_final.join(df)

感谢任何帮助。谢谢=)

【问题讨论】:

训练和测试数据是在不同时间产生的吗?在这种情况下,您可以在拆分之前创建这些列。无论如何,在更真实的场景中,我通常会创建一个名为 normalize_X 的函数,在其中检查测试集中缺失的列并将它们添加为 0,并删除训练集中不存在的列。 是的,这应该在生产环境中运行,其中测试数据从不同的来源收集并以完全相同的原始格式出现。预处理应该是相同的,因为我训练了 XGBoost,并且必须在类似的数据集上进行预测。 【参考方案1】:

这样的事情应该可以工作。我通常使用数据框直到最后一次,因为它们更容易使用。 X 应该是您预测之前的测试数据框。 original_cols 应该是您的训练集列的列表。让我知道它是否适合您。

def normalize_X(X, original_cols):


    missing_cols= set(original_cols) - set(X.columns)
    extra_cols= set(X.columns) - set(original_cols)
    if len(missing_cols)>0:

        print(f'missing columns: ", ".join(missing_cols)')
        for col in (missing_cols):

            X[col] = 0
    if len(extra_cols)>0:

        print(f'Columns to drop: ", ".join(extra_cols) ',)
        X = X.drop(columns = extra_cols)
    X = X[original_cols]
    return X

【讨论】:

【参考方案2】:

pd.CategoricalDtypepd.get_dummies

names_cat = pd.CategoricalDtype(['First', 'Second', 'Third', 'Forth'])
days_cat = pd.CategoricalDtype([0, 1, 2, 3, 4])

dumb_names = pd.get_dummies(df.Name.astype(names_cat))
dumb_names.columns = dumb_names.columns.to_numpy()

dumb_days = pd.get_dummies(df.day.astype(days_cat))
dumb_days.columns = dumb_days.columns.to_numpy()

   First  Second  Third  Forth  0  1  2  3  4
0      1       0      0      0  0  0  1  0  0
1      0       1      0      0  0  1  0  0  0
2      0       0      0      1  1  0  0  0  0

LabelBinarizer.classes_

from sklearn.preprocessing import LabelBinarizer

lb_0 = LabelBinarizer()
lb_1 = LabelBinarizer()

lb_0.classes_ = ['First', 'Second', 'Third', 'Forth']
lb_1.classes_ = [0, 1, 2, 3, 4]

a = lb_0.transform(df.Name)
b = lb_1.transform(df.day)

data = np.column_stack([a, b])
idx = df.index
col = np.concatenate([lb_0.classes_, lb_1.classes_])

result = pd.DataFrame(data, idx, col)
result

   First  Second  Third  Forth  0  1  2  3  4
0      1       0      0      0  0  0  1  0  0
1      0       1      0      0  0  1  0  0  0
2      0       0      0      1  1  0  0  0  0

reindex

cols = ['First', 'Second', 'Third', 'Forth', 0, 1, 2]
result = pd.concat(map(pd.get_dummies, map(df.get, df)), axis=1)
result.reindex(columns=cols, fill_value=0)

   First  Second  Third  Forth  0  1  2
0      1       0      0      0  0  0  1
1      0       1      0      0  0  1  0
2      0       0      0      1  1  0  0

【讨论】:

LabelBinarizer.classes_解决方案暗示我已经在训练集上使用了fit_transform? 没有。 fit 方法是识别唯一标签的探索过程。这绕过了它并预先设置了标签。这确实假设您预先知道唯一标签。 可能是我不知道训练集的标签,但测试集始终是训练的一个子集。所以我可以做类似 df_train[feature].unique() 的事情来总是得到所有可能类的列表。对吗? 是的,你可以。如果您始终只想保留 train 拥有的列,您可以通过多种方式做到这一点。 test.reindex(columns=train.columns, fill_value=0) 可能是最简单的。 你也可以test.align(train, join='right', axis=1, fill_value=0)[0]【参考方案3】:

另一种方法,可能更适合您在不同变量之间具有共同值的情况,并且如果您计划为多个列自动编码以进行编码:

df_train = pd.DataFrame('Name': ['First', 'Second', 'Third', 'Fourth'], 'Day': [2,1,1,2])
df_test = pd.DataFrame('Name': ['First', 'Second', 'Fourth'], 'Day': [2,1,0])
categories = []

cols_to_encode = ['Name', 'Day']
# Union of all values in both training and testing datasets:
for col in cols_to_encode:
    categories.append(list(set(df_train[col].unique().tolist() + df_test[col].unique().tolist())))

# Sorts the class names under each variable    
for cat in categories:
    cat.sort()

for col_name, cat in zip(cols_to_encode, categories):
    df_test[col_name] =  pd.Categorical(df_test[col_name], categories=cat)
df_test = pd.get_dummies(df_test, columns=cols_to_encode)

df_test

>>

    Name_First  Name_Second Name_Third  Name_Fourth Day_0   Day_1   Day_2   Day_3   Day_4
0   1           0           0           0           0       0       1       0    0 
1   0           1           0           0           0       1       0       0    0
2   0           0           0           1           1       0       0       0    0

【讨论】:

如何在 Scikit-Learn 中重用 LabelBinarizer 进行输入预测

】如何在Scikit-Learn中重用LabelBinarizer进行输入预测【英文标题】:Howtore-useLabelBinarizerforinputpredictioninScikit-Learn【发布时间】:2018-03-2105:54:36【问题描述】:我使用Scikit-Learn训练了一个分类器。我正在加载输入以从CSV训练我的分类... 查看详情

LabelEncoder 和 LabelBinarizer 的区别? [复制]

】LabelEncoder和LabelBinarizer的区别?[复制]【英文标题】:DifferencebetweenLabelEncoderandLabelBinarizer?[duplicate]【发布时间】:2019-05-2603:55:30【问题描述】:fromsklearn.preprocessingimportLabelBinarizer对fromsklearn.preprocessingimportLabelEncod 查看详情

LabelBinarizer() 需要永远

】LabelBinarizer()需要永远【英文标题】:LabelBinarizer()Takesforever【发布时间】:2013-12-0803:29:50【问题描述】:尝试为庞大的数据集进行多标签分类。我有大约4000个独特的标签,所以当我尝试使用LabelBinarizer().fit(yTuple)/transform时,它... 查看详情

sklearn.preprocessing.labelbinarizer

sklearn.preprocessing.LabelBinarizer  查看详情

更改数据表示“LabelBinarizer”后尺寸不匹配

】更改数据表示“LabelBinarizer”后尺寸不匹配【英文标题】:Dimensionsdon\'tmatchafterchangindatarepresentation"LabelBinarizer"【发布时间】:2017-08-2922:13:53【问题描述】:我有66类字符。l训练了一个多层感知器,给它输入图像,每个... 查看详情

如何正确保留对 ActionSheet 委托使用的对象的引用?

】如何正确保留对ActionSheet委托使用的对象的引用?【英文标题】:HowtoproperlykeepreferencetoanobjectusedbyanActionSheetdelegate?【发布时间】:2013-04-1609:35:36【问题描述】:我经常遇到引用对象的情况。我必须用UIActionSheet询问用户如何处... 查看详情

如何正确使用 Muenchian 按元素对非常重复的标签进行分组?

】如何正确使用Muenchian按元素对非常重复的标签进行分组?【英文标题】:HowtoproperlyusetheMuenchianforgroupingaveryrepetitivetagbyanelement?【发布时间】:2017-12-2103:21:09【问题描述】:我在使用Muenchian时遇到问题。我有一个非常大的xml可以... 查看详情

如何正确使用存储库模式?

】如何正确使用存储库模式?【英文标题】:Howtousetherepositorypatterncorrectly?【发布时间】:2010-12-0212:08:48【问题描述】:我想知道我应该如何对我的存储库进行分组?就像我在asp.netmvc和我的书中看到的示例一样,它们基本上每个... 查看详情

如何仅使用客户端 JavaScript 正确签署对 Amazon 的 ItemLookup 的 GET 请求?

】如何仅使用客户端JavaScript正确签署对Amazon的ItemLookup的GET请求?【英文标题】:HowtoproperlysignaGETrequesttoAmazon\'sItemLookupusingclient-sideJavaScriptonly?【发布时间】:2014-04-3012:32:43【问题描述】:这是我目前所拥有的:functionsha256(stringTo... 查看详情

如何正确使用 express-gateway 对 Web 应用程序进行身份验证?

】如何正确使用express-gateway对Web应用程序进行身份验证?【英文标题】:Howtoproperlyuseexpress-gatewayforauthenticationofawebapp?【发布时间】:2019-01-0511:31:51【问题描述】:总的来说,我对微服务和API网关的概念相当陌生。我试图了解api... 查看详情

如何使用 Keycloak 正确进行委派用户自我管理

】如何使用Keycloak正确进行委派用户自我管理【英文标题】:Howtoproperlydodelegateduserself-administrationwithKeycloak【发布时间】:2018-01-1603:15:04【问题描述】:我对如何使用Keycloak正确执行委派用户自我管理有疑问。一些背景资料:我们... 查看详情

如何正确映射与@IdClass 的多对一关系?

】如何正确映射与@IdClass的多对一关系?【英文标题】:Howtomapproperlyamany-to-onerelationshipwith@IdClass?【发布时间】:2018-09-1716:00:40【问题描述】:我想在Hibernate中使用组合主键创建一个表。主键的一部分是自动生成的值,另一部分... 查看详情

使用 PowerTransformer 时如何正确使用 inverse_transform 方法?

】使用PowerTransformer时如何正确使用inverse_transform方法?【英文标题】:HowdoIcorrectlyusetheinverse_transformmethodwhenusingPowerTransformer?【发布时间】:2019-11-1801:53:06【问题描述】:在对各种数组执行连续变换后,我在使用inverse_transform方法... 查看详情

Pandas groupby:如何在使用两列创建 groupby 时以正确的顺序对工作日进行排序?

】Pandasgroupby:如何在使用两列创建groupby时以正确的顺序对工作日进行排序?【英文标题】:Pandasgroupby:Howtosortweekdaysinthecorrectorderwhencreatinggroupbywithtwocolumns?【发布时间】:2019-05-0316:20:22【问题描述】:以下数据框包含一年中每个... 查看详情

如何正确强制正确使用类方法?

】如何正确强制正确使用类方法?【英文标题】:HowtoProperlyEnforceCorrectUsageofaClassMethod?【发布时间】:2009-10-1916:26:45【问题描述】:我们当前的ORM解决方案使用数据映射器来表示数据库中的表/视图,然后返回一个Collection对象,... 查看详情

将 HQL 与 MySQL 一起使用,如何在 group by 之前对结果集进行排序,以便选择正确的记录?

】将HQL与MySQL一起使用,如何在groupby之前对结果集进行排序,以便选择正确的记录?【英文标题】:UsingHQLwithMySQLhowcanIordertheresultsetbeforethegroupbysotherightrecordispicked?【发布时间】:2011-11-2514:05:35【问题描述】:有没有办法在单个... 查看详情

如何使用 SQL/T-SQL 正确地对扩展字符集进行 Base64 编码

】如何使用SQL/T-SQL正确地对扩展字符集进行Base64编码【英文标题】:HowtoBase64encodeextendedcharactersetsproperlyusingSQL/T-SQL【发布时间】:2019-12-0706:38:36【问题描述】:我无法以解码的方式获取以下值以进行base64编码。我有base64编码为以... 查看详情

如何正确使用 django 静态文件

】如何正确使用django静态文件【英文标题】:Howtoworkproperlywithdjangostaticfiles【发布时间】:2012-11-1004:25:17【问题描述】:我在处理django静态文件时遇到问题。我对如何使用MEDIA_ROOT、STATIC_ROOT、MEDIA_URL和STATIC_URL感到困惑我有这样的... 查看详情