FeatureHasher使用方法详解
Posted ybdesire
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FeatureHasher使用方法详解相关的知识,希望对你有一定的参考价值。
1. 引入
当我们的原始数据,是字符串,字符串列表,整数列表,pair列表时,都可以使用FeatureHasher转换为特征向量,这又是特征工程中的一个利器。
具体到PE文件分析领域,导入导出表(string list),各种section的size list(int list),都可以使用FeatureHasher来提取特征。
2. FeatureHasher原理简介
从FeatureHasher的出处(参考1),可以知道FeatureHasher是使用Murmurhash3来对输入数据计算hash值。
Murmurhash是一种非加密哈希,所以相似的内容计算出来的hash值(特征向量)也是相似的,所以Murmurhash可以被用于做相似性搜索。
Murmurhash3是Murmurhash家族的一种具体算法,详见参考2。Murmurhash的名字由来,是从参考3中看到,(multiply and rotate) and (multiply and rotate) Hash,乘法和旋转的hash 算法。
3. FeatureHasher用法
从参考1中可知,FeatureHasher输入不同类型的数据,需要配置的就是input_type这个参数,它有三种选择
Choose a string from ‘dict’, ‘pair’, ‘string’. Either “dict” (the default) to accept dictionaries over (feature_name, value); “pair” to accept pairs of (feature_name, value); or “string” to accept single strings. feature_name should be a string, while value should be a number.
3.1 FeatureHasher输入dict
这是参考1中给定的FeatureHasher的默认用法,具体示例如下
from sklearn.feature_extraction import FeatureHasher
h = FeatureHasher(n_features=10)
# 2 sample as 2 dict
D = ['dog': 1, 'cat':2, 'elephant':4,'dog': 2, 'run': 5]
f = h.transform(D).toarray()
print(f)
'''[[ 0. 0. -4. -1. 0. 0. 0. 0. 0. 2.]
[ 0. 0. 0. -2. -5. 0. 0. 0. 0. 0.]]'''
这里输入两个样本特征,并设置特征向量维度为10,所以最终得到的结果是2x10的array。
3.2 FeatureHasher输入string
输入一个字符串(这里假设输入是’hello’),计算其特征向量的代码如下:
from sklearn.feature_extraction import FeatureHasher
h = FeatureHasher(n_features=10, input_type="string")
D = ['hello']# input one string
f = h.transform(D).toarray()
print(f)# output [[ 0. 0. 2. 1. 0. -1. 0. 0. 0. 1.]]
3.3 FeatureHasher输入string list
如下为输入一个字符串列表,计算得到一个特征向量。
from sklearn.feature_extraction import FeatureHasher
h = FeatureHasher(n_features=10, input_type="string")
D = [['hello','this','is','my code']]
f = h.transform(D).toarray()
print(f)# output [[0. 0. 1. 0. 0. 0. 0. 1. 0. 0.]]
如下为输入多个(两个)字符串列表,计算得到多个(两个)特征向量。
from sklearn.feature_extraction import FeatureHasher
h = FeatureHasher(n_features=10, input_type="string")
# input 2 samples as 2 list of strings
D = [['hello','this','is','my code'],['hello','this','is','my co']]
f = h.transform(D).toarray()
print(f)
#[[0. 0. 1. 0. 0. 0. 0. 1. 0. 0.]
#[0. 1. 1. 0. 0. 0. 1. 1. 0. 0.]]
3.4 FeatureHasher输入int
FeatureHasher输入int数据,用法如下:
from sklearn.feature_extraction import FeatureHasher
h = FeatureHasher(n_features=10, input_type="pair")
D = [[('aaa',777)]]
f = h.transform(D).toarray()
print(f)# [[ 0. 0. 0. 0. 0. 777. 0. 0. 0. 0.]]
FeatureHasher本身是不接受int值作为输入的,所以必须转换为tuple,而且tuple第一个数据还必须是字符串,所以还得为这个int值额外插入一个字符串。
这就是参考1中提到的pair输入的要求
- “pair” to accept pairs of (feature_name, value); or “string” to accept single strings. feature_name should be a string, while value should be a number.
- tuple的第一个数据,feature_name必须是字符串类型
- tuple的第二个数据,value必须是int类型
3.5 FeatureHasher输入int list
从上一小节可知,输入为int list时,input_type=“pair”,而且要为每个int值增加feature_name后组成tuple,具体写法如下:
from sklearn.feature_extraction import FeatureHasher
h = FeatureHasher(n_features=10, input_type="pair")
x_list = [4,1,2,7,5]
D = [[('feature_name0'.format(i), x_list[i]) for i in range(len(x_list))]]
f = h.transform(D).toarray()
print(f)# [[ 0. 0. 0. 0. 0. 777. 0. 0. 0. 0.]]
print(D)# [[('feature_name0', 4), ('feature_name1', 1), ('feature_name2', 2), ('feature_name3', 7), ('feature_name4', 5)]]
4. FeatureHasher输入特征向量的相似性
用下面两个例子来说明,对于 FeatureHasher,如果输入的内容相似,则最终生成的特征向量也相似。
- 输入string list
from sklearn.feature_extraction import FeatureHasher
h = FeatureHasher(n_features=10, input_type="string")
D1 = [['hello','this','is','my code']]
f1 = h.transform(D1).toarray()# [[0. 0. 1. 0. 0. 0. 0. 1. 0. 0.]]
D2 = [['is','this','my code','hello']]
f2 = h.transform(D2).toarray()# [[0. 0. 1. 0. 0. 0. 0. 1. 0. 0.]]
D3 = [['is','this','my cOde','hello']]
f3 = h.transform(D3).toarray()# [[ 0. 1. 1. 0. 0. 0. 0. 1. -1. 0.]]
从结果中可以看到
- D2和D1内容相似:D2是D1的元素顺序调换,不改变内容,只改变元素顺序,最终结果f2和f1的结果是完全相同的
- D3和D2内容相似:D3是D2基础上改动了一个字符,最终结果f3也和f2是相似的
- 输入int list
from sklearn.feature_extraction import FeatureHasher
h = FeatureHasher(n_features=10, input_type="pair")
x_list1 = [4,1,2,7,5]
D1 = [[('feature_name0'.format(x_list1[i]), x_list1[i]) for i in range(len(x_list1))]]
f1 = h.transform(D1).toarray()
x_list2 = [1,7,4,2,5]
D2 = [[('feature_name0'.format(x_list2[i]), x_list2[i]) for i in range(len(x_list2))]]
f2 = h.transform(D2).toarray()
x_list3 = [4,1,2,7,9]
D3 = [[('feature_name0'.format(x_list3[i]), x_list3[i]) for i in range(len(x_list3))]]
f3 = h.transform(D3).toarray()
print(f1)#[[ 0. -7. -4. 0. -5. 3. 0. 0. 0. 0.]]
print(f2)#[[ 0. -7. -4. 0. -5. 3. 0. 0. 0. 0.]]
print(f3)#[[ 0. -7. -4. 0. -9. 3. 0. 0. 0. 0.]]
可见,list中int值的顺序调换,或者数值有细微的变化,最终生成的特征向量值都是相等/相似的。当然int值比较特殊,这里需要feature_name也相似或不变。
5. 总结
使用FeatureHasher为整数列表,或者字符串列表计算特征向量,是一个比较轻量级(相比于深度学习或者NLP的wordembedding)的特征工程方案。
参考
- https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.FeatureHasher.html
- https://en.wikipedia.org/wiki/MurmurHash
- https://blog.csdn.net/yjgithub/article/details/120447399
以上是关于FeatureHasher使用方法详解的主要内容,如果未能解决你的问题,请参考以下文章
sklearn使用FeatureHasher处理字符串特征: AttributeError: ‘str‘ object has no attribute ‘items‘