Sklearn KBinsDiscretizer保留原始列名称

时间:2020-07-20 12:11:40

标签: python python-3.x pandas scikit-learn sklearn-pandas

我正在研究机器学习问题,并且正在使用Sklearn KBinsDiscretizer离散一些连续变量。

discretizer = KBinsDiscretizer(n_bins=8, encode='onehot')
discretizer.fit(dfDisc)

discretizer.transform(X_train)

在转换之前,我的X_train.columns返回:

["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]

X_train.columns转换后(并作为熊猫df放回去)给出:

[0, 1, 2, 3, 4, 5, ......, 66, 67, 68]

由于我正在按变量的原始名称(A,B,C,...,J)分析变量,并且必须提供有关哪些变量用于分类的反馈,因此我正在寻找一种方法来了解哪些变量变量与输出的编号关联。例如,我希望将输出X_train.columns转换为

["A_0", "A_1", "A_2", "A_3", "A_4", "B_0", "B_1", "B_2", "B_3", ... ]

我知道使用sklearn OneHotEncoder(get_feature_names)时会存在这样的命令,但是我找不到使用KBinsDiscretizer进行此操作的任何方法。

我必须解决的一个想法是为每个变量创建一个特定的离散化器,然后将相关的离散化器应用于每个列,并在合并所有内容之前手动重命名列,但这会很麻烦,因为我必须保存我的离散者...

此外,即使我指定n_bins = 8,我的10个条目中也有69个输出列,因此1个条目并不总是产生10个输出,并且我也不能使用它来设置列名。

1 个答案:

答案 0 :(得分:2)

有时KBinsDiscretizer的每个列/条目都不完全返回n_bins。例如,当我运行以下代码时:

np.random.seed(0)
df = pd.DataFrame(np.random.randint(1, 200, size=(30, 10)), 
                  columns=["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"])
df['B'] = np.random.randint(1, 4, size=30)  # Set only 3 unique values

discretizer = KBinsDiscretizer(n_bins=8, encode='onehot')
discretizer.fit(df)

我收到此警告:

特征1中宽度太小(即<= 1e-8)的框被删除。考虑减少垃圾箱的数量。

您可以使用n_bins_属性(在拟合过程中填充)查看每列的结果仓位。

>>> discretizer.n_bins_
array([8, 3, 8, 8, 8, 8, 8, 8, 8, 8])

您还可以根据需要使用该属性来命名列:

dft = pd.SparseDataFrame(
    discretizer.transform(df), 
    columns=[f'{col}_{b}' for col, bins in zip(df.columns, discretizer.n_bins_) for b in range(bins)]
)