逆变换时,MultiLabelBinarizer会混合数据

时间:2018-08-17 21:47:52

标签: python pandas machine-learning sklearn-pandas multilabel-classification

我正在使用sklearn的{​​{1}}来训练我的机器学习中用来训练模型的多列。

使用它之后,我注意到它在对数据进行逆变换时正在混合我的数据。我创建了一个随机值测试集,可以在其中拟合数据,对其进行变换并multilabelbinarizer()将数据恢复为原始数据。

我在inverse_transform笔记本中进行了一次简单的测试,以显示错误:

jupyter值中,它混淆了状态和月份的第一行。

jupyter notebook code

首先,我使用inverse_transformed的方式是否有错误?有没有其他方法可以达到相同的输出?

编辑: 感谢@Nicolas M.帮助我解决问题。我最终解决了这个问题。

原谅粗略的解释,但结果却比我原先想的要复杂。我改用multilabelbinarizer代替label_binarizer,因为它

我最终腌制了multi_label_binarizer label_binarizer,因此可以将其加载并用于我的机器学习项目的不同模块中。

可能并非不重要的一件事是我在为每列创建的数据帧中添加新的标题。它采用column_name +列号的形式。我这样做是因为我需要对数据进行逆变换。为此,我搜索了包含原始列名的列,该列名将较大的数据框分成单独的列块。

这里我使用了一些变量以及它们的含义供参考:
defaultdict-存储不同标签二进制化器的默认字典。
lb_dict-存储二进制数据的数据框。
binarize_df-标签将列中的一个标签二值化。
binarized_label-创建新的标题形式:列名+数字列。

header-存储逆转换数据的数据框。
inverse_df-查找具有原始列标记的列名称列表。
one_label_list-创建一个仅存储一列的二进制数据的新数据框。
one_label_df-二值化的数据被inverse_transform转换为一列。

此代码中的数据是我传递给函数的数据帧。

single_label

这是我编写的inverse_transform函数:

lb_dict = defaultdict(LabelBinarizer)
# create a place holder dataframe to join new binarized data to
binarize_df = pd.DataFrame(['x'] * len(data.index), columns=['place_holder'])

# loop through each column and create a binarizer and fit/transform the data
# add new data to the binarize_df dataframe
for column in data.columns.values.tolist():

    lb_dict[column].fit(data[column])
    binarized_label = lb_dict[column].transform(data[column])

    header = [column + str(i) for i in range(0, len(binarized_label[0]))]

    binarize_df = binarize_df.join(pd.DataFrame(binarized_label, columns=header))

# drop the place holder value
binarize_df.drop(labels=['place_holder'], axis=1, inplace=True)

1 个答案:

答案 0 :(得分:4)

问题来自数据(在这种情况下,该模型的使用不当)。如果您创建MultiLabelBinarizer的数据框,则将具有:

enter image description here

您可以看到所有列都按升序排序。当您要求重建时,模型将通过逐行“扫描”值来重建它。

因此,如果您选择第一行,您将拥有:

  

1000-加利福尼亚-一月

现在,如果您选择第二个,则可以:

  

750-2月-纽约

依此类推...

因此,由于排序顺序,您的月份被交换了。如果您将月份替换为“ ZFebrury”,就可以了,但仍然只能使用“运气”

您应该做的是为每个分类特征训练1个模型,并堆叠每个矩阵以得到最终矩阵。要还原它,您应该同时提取“ sub_matrix”并执行inverse_transform

要为每个功能创建1个模型,您可以在此SO question

中参考 Napitupulu Jon 的答案。

编辑1:

我尝试了SO问题中的代码,但由于列数已更改,因此它不起作用。这就是我现在拥有的(但是您仍然必须将每个功能的列都保存在某处)

import pandas as pd
import numpy as np
from sklearn.preprocessing import MultiLabelBinarizer
from collections import defaultdict

data = {
    "State" : ["California", "New York", "Alaska", "Arizona", "Alaska", "Arizona"],
    "Month" : ["January", "February", "May", "February", "January", "February" ],
    "Number" : ["1000", "750", "500", "25000", "2000", "1"]
}
df = pd.DataFrame(data)

d = defaultdict(MultiLabelBinarizer)  # dict of Features => model

list_encoded = []  # store single matrices
for column in df:
    d[column].fit(df[column])
    list_encoded.append(d[column].transform(df[column]))
merged = np.hstack(list_encoded) # matrix of 6 x 32

我希望它会有所帮助,并且解释很清楚,

尼古拉斯