sklearn FeatureHasher 输出有很多冲突和未使用的列

sklearn FeatureHasher output has lots of collisions and unused columns

我正在使用 sklearn.feature_extraction.FeatureHasher 为机器学习编码分类变量。我的分类变量是数字 ID,例如 1、2、3、6、18、19、20,...。我总共有 18,000 个唯一 ID,最高 ID 是 28,000。

我想对它们进行哈希处理以将它们编码为类别,因为 One-hot 编码不在画面中,因为它会创建 18,000 列,而我的数据集已经有 4,000,000 行,这会很痛苦。

我无法显示我的数据框,所以我在示例数据框上进行了说明。

from sklearn.feature_extraction import FeatureHasher
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
tmpdf = pd.DataFrame(np.arange(10000), columns=["test"])

生产

      test
0        0
1        1
2        2
3        3
4        4
...    ...
9995  9995
9996  9996
9997  9997
9998  9998
9999  9999

[10000 rows x 1 columns]

现在如果我用字典散列:

H = FeatureHasher(n_features=50, input_type="dict")

cdict = [{str(i) : 1} for i in range(10000)]
arr = H.transform(cdict)

plt.matshow(arr.toarray()[::100], cmap="tab10", vmin=-5, vmax=4)
plt.colorbar(shrink=0.4)
plt.show()

这会产生:

如果我用字符串散列:

H = FeatureHasher(n_features=50, input_type="string")

arr = H.transform(tmpdf["test"].astype(str))

plt.matshow(arr.toarray()[::100], cmap="tab10", vmin=-5, vmax=4)
plt.colorbar(shrink=0.4)
plt.show()

我得到:

问题:

为什么基于字符串的散列的输出看起来很奇怪?看起来很多冲突正在发生,因为 很多列仍然完全未使用 ... 我用错了吗?对于我对用户 ID 进行编码的任务,是否有更好的方法来完成?

正如 Ben Reiniger 评论的那样,问题在于给出字符串列表会使哈希器迭代字符串,例如字符串“12345”没有按原样进行哈希处理,而是对子字符串“1”、“2”、“3”、“4”、“5”进行了哈希处理。鉴于我只有数字,我只有 10 个唯一的字符串(数字“0”到“9”),因此会导致很多冲突

一个可能的解决方案是将字符串放入列表中,这样 Hasher 就不会遍历字符串本身,而是遍历列表,然后对整个字符串进行哈希处理。

obj = tmpdf["test"].astype(str).to_numpy()
obj = obj.reshape(*obj.shape, 1)

结果

array([['0'],
       ['1'],
       ['2'],
       ...,
       ['9997'],
       ['9998'],
       ['9999']], dtype=object)

哈希时:

H = FeatureHasher(n_features=50, input_type="string")

arr = H.transform(obj)

plt.matshow(arr.toarray()[::100], cmap="tab10", vmin=-5, vmax=4)
plt.colorbar(shrink=0.4)
plt.show()

生成的输出更符合我的喜好。

谢谢!