在tensorflow2.0 环境下的tfrecord读写及tf.io.parse_example和tf.io.parse_single_example的区别中已经讲到了从tfrecord 中读取数据需要提供一个dict,里面包含了特征名称和特征的类型,如果我们特征很少,只需要手写这个dict就可以。但是当特征非常多的时候,就需要更方便的工具来生成这个dict。这个工具的就是tf.feature_column,同时tf.feature_column也是一个特征工程的工具,可以用来自动one-hot处理,还有hash分桶等处理。

tf.feature_column中的函数主要包括以下的的函数,下面会分别进行讲解

数值类型tf.feature_column.numeric_column

tf.feature_column.numeric_column(key, shape=(1,), default_value=None, dtype=tf.dtypes.float32, normalizer_fn=None
)

tf.feature_column.numeric_column用于抽取数值类型的特征,即dense特征,在tensorflow2.0 环境下的tfrecord读写及tf.io.parse_example和tf.io.parse_single_example的区别 中,7日内的消费和7日内打开淘宝的天数都用该函数定义:

pay = tf.feature_column.numeric_column('pay',shape=(1,), default_value=None, dtype=tf.dtypes.float32, normalizer_fn=None)
use_day = tf.feature_column.numeric_column("use_day",shape=(1,), default_value=None, dtype=tf.dtypes.int64, normalizer_fn=None)

应该注意的是key必须和tfrecord 中的key对应。shape必须与tfrecord中的shape对应,如果我们还有一个特征,是用户连续几天的消费金额[99.9, 249, 33] ,那么shape就要被定义成(3, )

类别特征系列

解析类别特征的方法最常用的有

方法 生成的子类
categorical_column_with_identity CategoricalColumn
categorical_column_with_vocabulary_list CategoricalColumn,存有vocabulary_list
categorical_column_with_vocabulary_file CategoricalColumn,存有vocabulary_file
categorical_column_with_hash_bucket HashedCategoricalColumn

categorical_column_with_vocabulary_list

根据sparse特征列表定义特征

city = tf.feature_column.categorical_column_with_vocabulary_list("city",["shanghai","beijing","guangzhou","tianjin","shenzhen"])

这种方法的缺点是只能用于数量较少的种类,比如性别,省份等。种类非常多的catogery,例如店铺id,就非常不适合这种方法了。

categorical_column_with_identity

这个方法用于已经编码的sparse特征,例如,店铺id虽然数量非常大,但是已经把每个店铺id都从0开始编码,那么就可以用

poi = tf.feature_column.categorical_column_with_identity("poi", num_buckets=10, default_value=0)

其中,num_bucket是最大编号

tf.feature_column.categorical_column_with_vocabulary_file

前面已经说了,当sparse特征的种类数量非常巨大的时候,就不能用用categorical_column_with_vocabulary_list了,用categorical_column_with_identity 又需要事先对sparse特征编码,这时候可以用tf.feature_column.categorical_column_with_vocabulary_file命令,读取sparse特征的所有可能取值。当然这种方法的效率也是比较低的,在要求低延迟的线上是不太划算的。

tf.feature_column.categorical_column_with_vocabulary_file(key, vocabulary_file, vocabulary_size=None, dtype=tf.dtypes.string,default_value=None, num_oov_buckets=0
)

categorical_column_with_hash_bucket

如果sparse特征非常庞大,例如上面的poi可以写成

poi = tf.feature_column.categorical_column_with_hash_bucket("poi", hash_bucket_size=10, dtype=tf.dtypes.int64)

但是应该注意的是,hash_bucket_size的大小应该留有充分的冗余量,否则非常容易出现hash冲突,在这个例子中,一共有3个店铺,把hash_bucket_size设定为10,仍然得到了hash冲突的结果,这样poi的信息就被丢失了一些信息

tf.feature_column.indicator column

tf.feature_column.indicator column  是一个onehot工具,用于把sparse特征进行onehot 变换,用于把categorical_column_with_*工具生成的特征变成onehot 编码

tf.feature_column.indicator column 的入参非只有一个,就是categorical_column_with_*的结果。

poi = tf.feature_column.categorical_column_with_hash_bucket("poi", hash_bucket_size=15, dtype=tf.dtypes.int64)
poi_idc = tf.feature_column.indicator_column(poi)

这里还有一个有趣的细节,在tensorflow2.0 环境下的tfrecord读写及tf.io.parse_example和tf.io.parse_single_example的区别中我们已经提到了tf.io.parse_example和tf.io.parse_single_example的区别。在这里他们还有另一个区别

poi = tf.feature_column.categorical_column_with_hash_bucket("poi", hash_bucket_size=15, dtype=tf.dtypes.int64)   #创建poi特征
poi_idc = tf.feature_column.indicator_column(poi)  #onehot处理
feature_column = [poi_idc]
feature = tf.feature_column.make_parse_example_spec(feature_column)  #生成poi的featuredict
path = "./tfrecord"
data = tf.data.TFRecordDataset(path)  #读取tfrecord
#分别用tf.io.parse_example 和 tf.io.parse_single_example 解析数据
data2 = data.map(lambda x : tf.io.parse_example(tf.reshape(x,[1]), features = feature))
data3 = data.map(lambda x : tf.io.parse_single_example(x, features = feature))

tf.io.parse_example得到的poi是一个形状为[1 3]的张量,而tf.io.parse_single_example得到的是一个形状为[3]的张量,这个区别就直接决定了

for batch in data2:tensor = tf.compat.v1.feature_column.input_layer(batch,feature_column)  #可以执行
for batch2 in data3:tensor2 = tf.compat.v1.feature_column.input_layer(batch2,feature_column)  #报错

如果看不懂也没关系,只需要记住tf.io.parse_example的结果,在用tf.compat.v1.feature_column.input_layer生成输入时,可以把所有的特征一起生成

而记住tf.io.parse_single_example的结果,只能对sparse特征逐个生成,然后合并成起来。

tf.feature_column.embedding_column

用于生成embedding后的张量

tf.feature_column.embedding_column(categorical_column, dimension, combiner='mean', initializer=None,ckpt_to_load_from=None, tensor_name_in_ckpt=None, max_norm=None, trainable=True,use_safe_embedding_lookup=True
)

他的几个入参意义分别是

categorical_column: categorical_column_with_* 工具的结果

dimension:embedding后的维度

combiner:对于多种类的sparse特征怎么组合,Currently 'mean', 'sqrtn' and 'sum' are supported

其他配置全部用默认就好了,绝大部分情况都不会有什么影响

应该注意的是,与indicator的一样,用tf.io.parse_single_example会生成一个embedding后的举证,而tf.io.parse_example会得到一个向量。例如

poi = tf.feature_column.categorical_column_with_hash_bucket("poi", hash_bucket_size=15, dtype=tf.dtypes.int64)
poi_ebd = tf.feature_column.embedding_column(poi,dimension = 3,combiner = "mean")
feature_column = [poi_ebd]
feature = tf.feature_column.make_parse_example_spec(feature_column)
path = "./tfrecord"
data = tf.data.TFRecordDataset(path)
data2 = data.map(lambda x : tf.io.parse_example(tf.reshape(x,[1]), features = feature))
data3 = data.map(lambda x : tf.io.parse_single_example(x, features = feature))
for batch in data2:tensor = tf.compat.v1.feature_column.input_layer(batch,feature_column)
for batch2 in data3:tensor2 = tf.compat.v1.feature_column.input_layer(batch2,feature_column)
print(tensor)
print(tensor2)result:
tf.Tensor([[0.00952441 0.01638425 0.29906932]], shape=(1, 3), dtype=float32)
tf.Tensor(
[[-0.59089464 -0.52776134  0.3303768 ][ 0.74979115  0.11539479  0.3902657 ][ 0.08098221  0.21678661 -0.11189163]], shape=(3, 3), dtype=float32)

tf.feature_column.make_parse_example_spec

tf.io.parse_example和tf.io.parse_single_example需要一个dict,定义特征名称和特征类型(fixedlenfeature还是varlenfeature)

tf.feature_column.make_parse_example_spec用于生成这个dict,他的入参必须是个可迭代对象,一般都是一个list,list的元素是上面讲过的所有函数的result。

这里应该非常注意的是,tf.feature_column.indicator column 和tf.feature_column.embedding_column 并不影响tf.feature_column.make_parse_example_spec,也就是说,一个特征是否经过了tf.feature_column.indicator column 和tf.feature_column.embedding_column 后tf.feature_column.make_parse_example_spec的结果是一样的,tf.io.parse_example和tf.io.parse_single_example的结果也是一样的。

例子:

poi = tf.feature_column.categorical_column_with_hash_bucket("poi", hash_bucket_size=15, dtype=tf.dtypes.int64)  #定义poi特征
poi_ebd = tf.feature_column.embedding_column(poi,dimension = 3,combiner = "mean") #poi做embedding
poi_idc = tf.feature_column.indicator_column(poi)  #poi做indicatorfeature_column = [poi]
feature_column2 = [poi_ebd]
feature_column3 = [poi_idc]feature = tf.feature_column.make_parse_example_spec(feature_column)
feature2 = tf.feature_column.make_parse_example_spec(feature_column2)
feature3 = tf.feature_column.make_parse_example_spec(feature_column3)print(feature)
print(feature2)
print(feature3)===============================================================result:
{'poi': VarLenFeature(dtype=tf.int64)}
{'poi': VarLenFeature(dtype=tf.int64)}
{'poi': VarLenFeature(dtype=tf.int64)}===============================================================path = "./tfrecord"
data = tf.data.TFRecordDataset(path)
data2 = data.map(lambda x : tf.io.parse_example(tf.reshape(x,[1]), features = feature))
data3 = data.map(lambda x : tf.io.parse_example(tf.reshape(x,[1]), features = feature2))
data4 = data.map(lambda x : tf.io.parse_example(tf.reshape(x,[1]), features = feature3))for batch in data2:tensor = tf.compat.v1.feature_column.input_layer(batch,feature_column)print(tf.sparse.to_dense(batch["poi"]))
for batch2 in data3:tensor2 = tf.compat.v1.feature_column.input_layer(batch2,feature_column)print(tf.sparse.to_dense(batch2["poi"]))
for batch3 in data4:tensor3 = tf.compat.v1.feature_column.input_layer(batch3,feature_column)print(tf.sparse.to_dense(batch2["poi"]))result:
tf.Tensor([[1 3 2]], shape=(1, 3), dtype=int64)
tf.Tensor([[1 3 2]], shape=(1, 3), dtype=int64)
tf.Tensor([[1 3 2]], shape=(1, 3), dtype=int64)

特征工程

可以看到tf.feature_column.make_parse_example_spec和tf.io.parse_example和tf.io.parse_single_example 仅仅是从tfrecord 中读取数据,并不会对数据做任何的特征工程的处理。

那么特征工程在哪个环节进行呢?

poi = tf.feature_column.categorical_column_with_hash_bucket("poi", hash_bucket_size=15, dtype=tf.dtypes.int64)  #定义poi特征
poi_ebd = tf.feature_column.embedding_column(poi,dimension = 3,combiner = "mean") #poi做embeddingfeature_column2 = [poi_ebd]feature2 = tf.feature_column.make_parse_example_spec(feature_column2)print(feature2)===============================================================result:
{'poi': VarLenFeature(dtype=tf.int64)}===============================================================path = "./tfrecord"
data = tf.data.TFRecordDataset(path)data2 = data.map(lambda x : tf.io.parse_example(tf.reshape(x,[1]), features = feature2))for batch in data2:tensor = tf.compat.v1.feature_column.input_layer(batch,feature_column2)print(tf.sparse.to_dense(batch["poi"]))result:
tf.Tensor([[1 1 1]], shape=(1, 3), dtype=int64)

从上面的代码可以看到categorical_column_with_identity、categorical_column_with_vocabulary_list、categorical_column_with_vocabulary_file、categorical_column_with_hash_bucket 保存了数值化方式,

embedding_column, bucketized_column, indicator_column,保存了特征工程方式,

最后通过调用feature_column.input_layer,实现了特征工程的处理

tf.feature_column详解相关推荐

  1. tf.feature_column详解及避坑攻略

    在使用tensorflow搭建模型时会有特征工程的工作,今天介绍一下tensorflow做特征工程的api:tf.feature_column. feature_column 输入输出类型 1.深度模 ...

  2. 深度学习 - 26.TF TF2.x tf.feature_column 详解

    一.引言 上一篇文章 Tensorflow - TF1.x VS TF2.x tf.feature_column 介绍了 feature_column 在 TF1.x 与 TF 2.x 在使用上的区别 ...

  3. tf.unstack() 详解 —》理解为主

    tensorflow中的tf.unstack(): 解释:这是一个对矩阵进行分解的函数,以下为关键参数解释: value:代表需要分解的矩阵变量(其实就是一个多维数组,一般为二维): axis:指明对 ...

  4. tf.cancat() 详解 —》理解为主

    tensorflow 中用来拼接张量的函数tf.concat(),用法: tf.concat([tensor1, tensor2,...], axis) 代码详解-维度变化理解: # 参考:https ...

  5. tensorflow feature_column详解

    关于 feature_column官网说的 还比较少,其它说明 大多数 都是 直接 翻译 官网解释,很明显,达不到效果,现在 对feature_column进行说明,更详细的说明,可以参照github ...

  6. tf.concat()详解

    tensorflow中用来拼接张量的函数tf.concat(),用法: tf.concat([tensor1, tensor2, tensor3,...], axis) 先给出tf源代码中的解释: t ...

  7. Tensorflow中tf.ConfigProto()详解

    参考Tensorflow Machine Leanrning Cookbook tf.ConfigProto()主要的作用是配置tf.Session的运算方式,比如gpu运算或者cpu运算 具体代码如 ...

  8. tf.where() 详解

    tf.where(tensor) :tensor 为一个bool 型张量,where函数将返回其中为true的元素的索引. tf.where(tensor,a,b):a,b为和tensor相同维度的t ...

  9. tf.ConfigProto()详解

    tf.ConfigProto()主要的作用是配置tf.Session的运算方式,比如gpu运算或者cpu运算 tf.ConfigProto一般用在创建session的时候,用来对session进行参数 ...

最新文章

  1. 【转】Python机器学习库
  2. 经典语录【摘自网路】
  3. Exploring the 7 Different Types of Data Stories
  4. leetcode868
  5. JVM 的 工作原理,层次结构 以及 GC工作原理
  6. Multi-Temporal SAR Data Large-Scale Crop Mapping Based on U-Net Model(利用U-net对多时相SAR影像获得作物图)...
  7. proxool java_Java应用中使用Proxool
  8. 我为什么要写FansUnion个人官网-BriefCMS-电子商务malling等系统
  9. python36中文手册_python36中文手册_python_36_文件操作4
  10. 加州大学欧文分校 计算机专业,加州大学欧文分校计算机科学排名第36(2020年TFE美国排名)...
  11. 【电路】LM293D电机驱动芯片
  12. 使用expect编写脚本
  13. ArcIMS9.2新增地图服务时check your map file's layers and data source connections解决
  14. 豪华版飞机大战系列(三)
  15. 【ZOJ4110】Strings in the Pocket (马拉车算法+分析)
  16. iMeta | ggClusterNet微生物网络分析和可视化保姆级教程
  17. laravel seeder factory填充数据
  18. 科学网肖波:海外博后申请的一点经验与看法
  19. 三维建模初学者学习方法及资料
  20. DB-Engines 2017年9月数据库排名发布

热门文章

  1. 备案新规:个人网站有行业内容必须转为企业备案,草根站长该如何应对?
  2. 锐捷日志服务器系统,CCIE的梦-锐捷交换机日志过滤
  3. 【Android学习之路】新手入门Kotlin语言
  4. “用好”北斗,还看芯片——新一代旗舰芯片HD8120
  5. windows认证原理kerberos协议详解
  6. 还经营着一家汽车销售公司
  7. 树莓派 (为学生计算机编程教育设计的一种卡片式电脑)
  8. FusionCharts基本属性
  9. 红队攻防知识分享-红日安全团队靶场1
  10. 单身程序员如何找对象?#罗志祥时间管理