categorical_column_with_hash_bucket哈希列,对于处理包含大量文字或数字类别的特征时可使用hash的方式,这能快速地建立对应的对照表
分桶的方式,但这次分桶是根据hash的方式在有限的长度进行划分
1. 比如:
我们有120个单词,我们只希望分成100个类别,这个时候多出的20个怎么来划分?
101: 101 % 100 = 1 标记1 —> 和1一个桶
102: 102 % 100 = 2 标记2 —> 和2一个桶
…
120: 120 % 100 = 20 标记20 —> 和20一个桶
所以:
feature_id = hash(feature) % hash_buckets_size
问题也是显而易见的,哈希冲突的问题。
2. 参数
def categorical_column_with_hash_bucket(key,
hash_bucket_size,
dtype=dtypes.string):
参数 | 参数说明 |
---|---|
key | 字符串的识别输入,feature名字 |
hash_bucket_size | int类型,设置桶的个数,一般设置为总类别数的2-5倍 |
dtype | 类型的特征,只支持字符串和整数类型 |
3. 举例
import tensorflow as tf
sess = tf.Session()
# 特征数据
features = {
'animals': ['猪', '猪', '狗', '猫', '羊'],
}
# 特征列
department = tf.feature_column.categorical_column_with_hash_bucket('animals', 6, 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)
print(sess.run(inputs))
结果:
[[0. 1. 0. 0. 0. 0.] #猪
[0. 1. 0. 0. 0. 0.] #猪
[0. 1. 0. 0. 0. 0.] #狗
[0. 0. 0. 1. 0. 0.] #猫
[0. 1. 0. 0. 0. 0.]] #羊
问题: 可以看到我们把hash_bucket_size设置的6,其中特征狗和特征羊分在同一个桶里,这就是存在的hash冲突。
hash_bucket_size的设置也需要着重考虑,这是太大避免冲突,浪费空间,设置太小,又增加冲突风险
参考:
当需要hash映射的量增加大到亿级别的时,增加hash_bucket_size的方法就不行了,此时需要另辟他径,需要引入外部方法,比如手写一个hash映射函数;再比如,借鉴阿里对处理亿万级别的用户id的方法。
https://blog.csdn.net/pearl8899/article/details/107958334
有兴趣可以看我的专栏:今天你面试了吗?