方式1:序号编码
根据特征在整个特征集合中的index进行编码。
在Spark里的编码逻辑:
1.把样本集合的特征map{feature:value}放到一个Set集合里,然后取集合的index作为一个特征feature:value的编号,map{map{feature:value}:index}。
2.然后将每条样本转成index表示的fea_ids。
2.最后将每条样本表示成SparseVector(feature_zise,fea_ids,1)。
方式2:Hash Bucket
根据特征值的hash值进行编码
output_id = Hash(input_feature_string) % bucket_size
比如在tesorflow中对商品id进行编码:
hashed_feature_column =
tf.feature_column.categorical_column_with_hash_bucket(
key = "item_id",
hash_buckets_size = 10000000) # The number of categories
此时,您可能会认为:“这太疯狂了!”,这种想法很正常。毕竟,我们是将不同的输入值强制划分成更少数量的类别。这意味着,两个可能不相关的输入会被映射到同一个类别,这样一来,神经网络也会面临同样的结果。下图显示了这一困境,即厨具和运动用品都被分配到类别(哈希分桶)12:
与机器学习中的很多反直觉现象一样,事实证明哈希技术经常非常有用。这是因为哈希类别为模型提供了一些分隔方式。模型可以使用其他特征进一步将厨具与运动用品分隔开来。
方式3:Feature Hashing
方式4:Embedding
用户、商品等id类特征维度合计高达几千万维, 假设在输入层后直接连接 100 个输出神经元的全连接层,那么这个模 型的参数规模将达到上亿规模。
直接接入全连接层将导致以下几个问题:
1. 各个域都存在冷门的特征,这些冷门的特征将会被热门的特征淹没,基本不起作用, 跟全连接层的连接边权值会趋向于 0,冷门的商品只会更冷门。
2. 模型的大小 将会非常庞大,超过G,在训练以及预测中都会出现很多工程上的问题。
We can use an embedding column to overcome this limitation. Instead of representing the data as a one-hot vector of many dimensions, an embedding column represents that data as a lower-dimensional, ordinary vector in which each cell can contain any number, not just 0 or 1. By permitting a richer palette of numbers for every cell, an embedding column contains far fewer cells than an indicator column.
对大规模特征的Embedding需要一些特殊的Trick,目前探索的方法如下:
https://stackoverflow.com/questions/43288147/how-do-i-use-a-very-large-2m-word-embedding-in-tensorflow
https://stackoverflow.com/questions/44863493/could-word2vec-algorithm-be-distributed-on-multi-computers-using-tensorflow
https://stackoverflow.com/questions/43130893/seq2seq-embedding-size-is-too-large-for-distributed-training
https://stackoverflow.com/questions/38427471/why-does-tf-nn-embedding-lookup-use-a-list-of-embeddings
https://stackoverflow.com/questions/47523374/feature-columns-embedding-lookup
https://stackoverflow.com/questions/34870614/what-does-tf-nn-embedding-lookup-function-do
参考:https://www.tensorflow.org/versions/master/get_started/feature_columns