5-2,特征列feature_column

特征列 通常用于对结构化数据实施特征工程时候使用,图像或者文本数据一般不会用到特征列。

一,特征列用法概述

使用特征列可以将类别特征转换为one-hot编码特征,将连续特征构建分桶特征,以及对多个特征生成交叉特征等等。

要创建特征列,请调用 tf.feature_column 模块的函数。该模块中常用的九个函数如下图所示,所有九个函数都会返回一个 Categorical-Column 或一个 Dense-Column 对象,但却不会返回 bucketized_column,后者继承自这两个类。

注意:所有的Catogorical Column类型最终都要通过indicator_column转换成Dense Column类型才能传入模型!

5-2,特征列feature_column - 图1

  • numeric_column 数值列,最常用。
  • bucketized_column 分桶列,由数值列生成,可以由一个数值列出多个特征,one-hot编码。
  • categorical_column_with_identity 分类标识列,one-hot编码,相当于分桶列每个桶为1个整数的情况。
  • categorical_column_with_vocabulary_list 分类词汇列,one-hot编码,由list指定词典。
  • categorical_column_with_vocabulary_file 分类词汇列,由文件file指定词典。
  • categorical_column_with_hash_bucket 哈希列,整数或词典较大时采用。
  • indicator_column 指标列,由Categorical Column生成,one-hot编码
  • embedding_column 嵌入列,由Categorical Column生成,嵌入矢量分布参数需要学习。嵌入矢量维数建议取类别数量的 4 次方根。
  • crossed_column 交叉列,可以由除categorical_column_with_hash_bucket的任意分类列构成。

二,特征列使用范例

以下是一个使用特征列解决Titanic生存问题的完整范例。

  1. import datetime
  2. import numpy as np
  3. import pandas as pd
  4. from matplotlib import pyplot as plt
  5. import tensorflow as tf
  6. from tensorflow.keras import layers,models
  7. #打印日志
  8. def printlog(info):
  9. nowtime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  10. print("\n"+"=========="*8 + "%s"%nowtime)
  11. print(info+'...\n\n')
  1. #================================================================================
  2. # 一,构建数据管道
  3. #================================================================================
  4. printlog("step1: prepare dataset...")
  5. dftrain_raw = pd.read_csv("./data/titanic/train.csv")
  6. dftest_raw = pd.read_csv("./data/titanic/test.csv")
  7. dfraw = pd.concat([dftrain_raw,dftest_raw])
  8. def prepare_dfdata(dfraw):
  9. dfdata = dfraw.copy()
  10. dfdata.columns = [x.lower() for x in dfdata.columns]
  11. dfdata = dfdata.rename(columns={'survived':'label'})
  12. dfdata = dfdata.drop(['passengerid','name'],axis = 1)
  13. for col,dtype in dict(dfdata.dtypes).items():
  14. # 判断是否包含缺失值
  15. if dfdata[col].hasnans:
  16. # 添加标识是否缺失列
  17. dfdata[col + '_nan'] = pd.isna(dfdata[col]).astype('int32')
  18. # 填充
  19. if dtype not in [np.object,np.str,np.unicode]:
  20. dfdata[col].fillna(dfdata[col].mean(),inplace = True)
  21. else:
  22. dfdata[col].fillna('',inplace = True)
  23. return(dfdata)
  24. dfdata = prepare_dfdata(dfraw)
  25. dftrain = dfdata.iloc[0:len(dftrain_raw),:]
  26. dftest = dfdata.iloc[len(dftrain_raw):,:]
  27. # 从 dataframe 导入数据
  28. def df_to_dataset(df, shuffle=True, batch_size=32):
  29. dfdata = df.copy()
  30. if 'label' not in dfdata.columns:
  31. ds = tf.data.Dataset.from_tensor_slices(dfdata.to_dict(orient = 'list'))
  32. else:
  33. labels = dfdata.pop('label')
  34. ds = tf.data.Dataset.from_tensor_slices((dfdata.to_dict(orient = 'list'), labels))
  35. if shuffle:
  36. ds = ds.shuffle(buffer_size=len(dfdata))
  37. ds = ds.batch(batch_size)
  38. return ds
  39. ds_train = df_to_dataset(dftrain)
  40. ds_test = df_to_dataset(dftest)
  1. #================================================================================
  2. # 二,定义特征列
  3. #================================================================================
  4. printlog("step2: make feature columns...")
  5. feature_columns = []
  6. # 数值列
  7. for col in ['age','fare','parch','sibsp'] + [
  8. c for c in dfdata.columns if c.endswith('_nan')]:
  9. feature_columns.append(tf.feature_column.numeric_column(col))
  10. # 分桶列
  11. age = tf.feature_column.numeric_column('age')
  12. age_buckets = tf.feature_column.bucketized_column(age,
  13. boundaries=[18, 25, 30, 35, 40, 45, 50, 55, 60, 65])
  14. feature_columns.append(age_buckets)
  15. # 类别列
  16. # 注意:所有的Catogorical Column类型最终都要通过indicator_column转换成Dense Column类型才能传入模型!!
  17. sex = tf.feature_column.indicator_column(
  18. tf.feature_column.categorical_column_with_vocabulary_list(
  19. key='sex',vocabulary_list=["male", "female"]))
  20. feature_columns.append(sex)
  21. pclass = tf.feature_column.indicator_column(
  22. tf.feature_column.categorical_column_with_vocabulary_list(
  23. key='pclass',vocabulary_list=[1,2,3]))
  24. feature_columns.append(pclass)
  25. ticket = tf.feature_column.indicator_column(
  26. tf.feature_column.categorical_column_with_hash_bucket('ticket',3))
  27. feature_columns.append(ticket)
  28. embarked = tf.feature_column.indicator_column(
  29. tf.feature_column.categorical_column_with_vocabulary_list(
  30. key='embarked',vocabulary_list=['S','C','B']))
  31. feature_columns.append(embarked)
  32. # 嵌入列
  33. cabin = tf.feature_column.embedding_column(
  34. tf.feature_column.categorical_column_with_hash_bucket('cabin',32),2)
  35. feature_columns.append(cabin)
  36. # 交叉列
  37. pclass_cate = tf.feature_column.categorical_column_with_vocabulary_list(
  38. key='pclass',vocabulary_list=[1,2,3])
  39. crossed_feature = tf.feature_column.indicator_column(
  40. tf.feature_column.crossed_column([age_buckets, pclass_cate],hash_bucket_size=15))
  41. feature_columns.append(crossed_feature)
  1. #================================================================================
  2. # 三,定义模型
  3. #================================================================================
  4. printlog("step3: define model...")
  5. tf.keras.backend.clear_session()
  6. model = tf.keras.Sequential([
  7. layers.DenseFeatures(feature_columns), #将特征列放入到tf.keras.layers.DenseFeatures中!!!
  8. layers.Dense(64, activation='relu'),
  9. layers.Dense(64, activation='relu'),
  10. layers.Dense(1, activation='sigmoid')
  11. ])
  1. #================================================================================
  2. # 四,训练模型
  3. #================================================================================
  4. printlog("step4: train model...")
  5. model.compile(optimizer='adam',
  6. loss='binary_crossentropy',
  7. metrics=['accuracy'])
  8. history = model.fit(ds_train,
  9. validation_data=ds_test,
  10. epochs=10)
  1. #================================================================================
  2. # 五,评估模型
  3. #================================================================================
  4. printlog("step5: eval model...")
  5. model.summary()
  6. %matplotlib inline
  7. %config InlineBackend.figure_format = 'svg'
  8. import matplotlib.pyplot as plt
  9. def plot_metric(history, metric):
  10. train_metrics = history.history[metric]
  11. val_metrics = history.history['val_'+metric]
  12. epochs = range(1, len(train_metrics) + 1)
  13. plt.plot(epochs, train_metrics, 'bo--')
  14. plt.plot(epochs, val_metrics, 'ro-')
  15. plt.title('Training and validation '+ metric)
  16. plt.xlabel("Epochs")
  17. plt.ylabel(metric)
  18. plt.legend(["train_"+metric, 'val_'+metric])
  19. plt.show()
  20. plot_metric(history,"accuracy")
  1. Model: "sequential"
  2. _________________________________________________________________
  3. Layer (type) Output Shape Param #
  4. =================================================================
  5. dense_features (DenseFeature multiple 64
  6. _________________________________________________________________
  7. dense (Dense) multiple 3008
  8. _________________________________________________________________
  9. dense_1 (Dense) multiple 4160
  10. _________________________________________________________________
  11. dense_2 (Dense) multiple 65
  12. =================================================================
  13. Total params: 7,297
  14. Trainable params: 7,297
  15. Non-trainable params: 0
  16. _________________________________________________________________

5-2,特征列feature_column - 图2

如果对本书内容理解上有需要进一步和作者交流的地方,欢迎在公众号”Python与算法之美”下留言。作者时间和精力有限,会酌情予以回复。

也可以在公众号后台回复关键字:加群,加入读者交流群和大家讨论。

image.png