sklearn FeatureHasher 中的哈希技巧

Hash trick in sklearn FeatureHasher

想了解"the hashing trick"我写了如下测试代码:

import pandas as pd
from sklearn.feature_extraction import FeatureHasher
test = pd.DataFrame({'type': ['a', 'b', 'c', 'd', 'e','f','g','h']})
h = FeatureHasher(n_features=4, input_type='string')
f = h.transform(test.type)
print(f.toarray())

在上面的示例中,我将 8 个类别映射到 4 列,输出为:

[[ 0.  0.  1.  0.]<-a
 [ 0. -1.  0.  0.]<-b
 [ 0. -1.  0.  0.]<-c
 [ 0.  0.  0.  1.]<-d
 [ 0.  0.  0.  1.]<-e
 [ 0.  0.  0.  1.]<-f
 [ 0.  0. -1.  0.]<-g
 [ 0. -1.  0.  0.]]<-g

在生成的矩阵中,我可以看到重复项,并且某些类别的表示方式相同。这是为什么?如果我使用二进制表示,8 个类别可以映射到 4 列。

有人可以解释一下这种技术的输出结果并详细说明一下吗?

如果将

设置为如此低的值,FeatureHasher 将导致不希望的结果。这样做的原因是它将类别映射到列索引的方式。

例如,与 CountVectorizer 相反,每个类别都被分配了一个唯一的整数索引,该索引对应于仅按出现顺序排列的列,FeatureHasher 将应用 哈希function 到features 来确定每个类别的列索引。因此,它的主要优点是 提高了速度 。然而,通过将 n_features 限制为如此低的值,散列给定类别的结果可能会导致索引 比集合 n_features 更高,因此,您将得到一个 截断的 特征向量。


我们实际上可以通过重现散列是如何完成的来检查这一点 _hashing_fast which uses murmurhash3_bytes_s32 生成哈希:

from sklearn.utils.murmurhash import murmurhash3_bytes_s32

raw_X = test['type']
raw_X = iter(raw_X)
raw_X = (((f, 1) for f in x) for x in raw_X)

for x in raw_X:
    for f, v in x:
        f = f'{f}={v}'
        fb = (f).encode("utf-8")
        h = murmurhash3_bytes_s32(fb, seed=0)
        print(f'{f[0]} -> {h}')

如您所见,它会为 ef 精确地生成较大的哈希值,这些哈希值被截断为对应于 d:

的较低哈希值
a -> -424864564
b -> -992685778
c -> -1984769100
d -> 728527081
e -> 2077529484
f -> 2074045163
g -> -1877798433
h -> -51608576