1.作用

对于处理包含大量文字或数字类别的特征时可使用hash的方式,这能快速地建立对应的对照表,缺点则是会有哈希冲突的问题。

官方解释:代表稀疏特征,其中ID由散列设置。即:当你的稀疏特征是字符串或整数格式,并且要将输入分配到有限数量的散列桶使用此功能。

输入:

key:features是一个字典,key是特征名字,value是特征值。features[key]或者是TensorSparseTensor 。如果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

2.例子的来源:https://zhuanlan.zhihu.com/p/73701872

GitHub 加速计划 / te / tensorflow
184.55 K
74.12 K
下载
一个面向所有人的开源机器学习框架
最近提交(Master分支:2 个月前 )
a49e66f2 PiperOrigin-RevId: 663726708 3 个月前
91dac11a This test overrides disabled_backends, dropping the default value in the process. PiperOrigin-RevId: 663711155 3 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐