【TensorFlow】(二)tf.feature_column.categorical_column_with_hash_bucket()函数的用法
1.作用
对于处理包含大量文字或数字类别的特征时可使用hash的方式,这能快速地建立对应的对照表,缺点则是会有哈希冲突的问题。
官方解释:代表稀疏特征,其中ID由散列设置。即:当你的稀疏特征是字符串或整数格式,并且要将输入分配到有限数量的散列桶使用此功能。
输入:
key:features是一个字典,key是特征名字,value是特征值。features[key]
或者是Tensor
或SparseTensor
。如果Tensor
,缺失值,可以表示为-1
为int和''
字符串,这将通过此功能列被删除。
hash_bucket_size:一个int> 1.桶的数量。大小一般设置为总类别数的2-5倍,该函数适用于不能确定所有类别样式的类别变量
dtype = tf.dtypes.string :该类型的特征。只有字符串和整数类型的支持。
输出:
一个HashedCategoricalColumn
。
2.例子
import tensorflow as tf
sess=tf.Session()
#特征数据
features = {
'department': ['sport', 'sport', 'drawing', 'gardening', 'travelling'],
}
#特征列
department = tf.feature_column.categorical_column_with_hash_bucket('department', 5, dtype=tf.string)
department = tf.feature_column.indicator_column(department)
#组合特征列
columns = [department]
#输入层(数据,特征列)
inputs = tf.feature_column.input_layer(features, columns)
#初始化并运行
init = tf.global_variables_initializer()
sess.run(tf.tables_initializer())
sess.run(init)
v=sess.run(inputs)
print(v)
情况一:hash_bucket_size = 5,即features[department]中的元素个数,从输出结果可以看出,是有冲突的,第三行和第五行重复,但是对应的drawing和travelling是不同的,所以存在了这样一个缺点。
输出:
[[1. 0. 0. 0. 0.]
[1. 0. 0. 0. 0.]
[0. 0. 1. 0. 0.]
[0. 0. 0. 0. 1.]
[0. 0. 1. 0. 0.]]
情况二:是不是将hash_bucket_size设置大一些,不会出现冲突现象呢?这里另hash_bucket_size=10,从下面的输出来看,还会有重复。
输出:
[[0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]
[0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]]
thinking:
hash会有冲突,为什么还会存在这个函数呢?对hash后的结果有什么影响呢?
1.该函数能将单词进行hash,相比于tf.feature_column.categorical_column_with_identity(),它不用将单词list转化为数值型的list,直接可对单词进行hash,将每一个单词作为一个类别。
2.在单词类别较少的情况下,可以通过设置较大的hash_bucket_size,来解决hash冲突问题。比如讲hash_bucket_size=15,得到下面的输出:
[[1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] #'sport'
[1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] #'sport'
[0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] #'drawing'
[0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] #'gardening'
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]] #'travelling'
hash_bucket_size的大小一般设置为总类别数的2-5倍,但hash_bucket_size可以设大也可以设小 设小了节约空间但是增大了冲突;设大了增加空间但是减少了冲突。具体情况需要试验。
当需要hash映射的量增加大到亿级别的时,增加hash_bucket_size的方法就不行了,此时需要另辟他径,需要引入外部方法,比如手写一个hash映射函数;再比如,借鉴阿里对处理亿万级别的用户id的方法。
3.hash冲突的影响:从结果上来看,使用的时候,两个不同的uuid,被映射为了一个hash,也即是这两个uuid上没有区分能力,不过很多时候tensorflow还是能够利用其他的特征列把它们区分开。所以,为了有效减少内存和计算时间,可以这么做。
参考:
1.官方文档:https://www.tensorflow.org/api_docs/python/tf/feature_column/categorical_column_with_hash_bucket
更多推荐
所有评论(0)