Sklearn KBinsDiscretizer 保留原始列名

Sklearn KBinsDiscretizer keep origin column names

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

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

discretizer.transform(X_train)

改造前,我的X_train.columnsreturns:

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

转换后(并放回 pandas df),X_train.columns 给出:

[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 个输出,我也不能使用它设置列名。

有时 KBinsDiscretizer 并不 return 完全 n_bins 每个 column/entry。比如当我运行下面的代码:

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)

我收到这个警告:

Bins whose width are too small (i.e., <= 1e-8) in feature 1 are removed. Consider decreasing the number of bins.

您可以使用 n_bins_ 属性(在拟合期间填充)查看每列生成的 bin。

>>> 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)]
)