【问题标题】:sklearn FeatureHasher output has lots of collisions and unused columns [duplicate]sklearn FeatureHasher 输出有很多冲突和未使用的列[重复]
【发布时间】:2021-07-23 23:33:45
【问题描述】:

我正在使用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 进行编码的任务,有没有更好的方法呢?

【问题讨论】:

  • 是的,谢谢!

标签: python scikit-learn hash data-science


【解决方案1】:

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

Feature Hashing of zip codes with Scikit in machine learning

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

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

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

谢谢!

【讨论】:

    猜你喜欢
    • 2017-04-05
    • 1970-01-01
    • 1970-01-01
    • 2021-07-20
    • 2014-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多