tensorflow2.x学习笔记二十:特征列feature_column

特征列feature_column

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

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

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

  • 注意:所有的Catogorical Column类型最终都要通过indicator_column转换成Dense Column类型才能传入模型!
    在这里插入图片描述

  • 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生存问题的完整范例。

import datetime
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
import tensorflow as tf
from tensorflow.keras import layers,models


#打印日志
def printlog(info):
    nowtime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    print("\n"+"=========="*8 + "%s"%nowtime)
    print(info+'...\n\n')

一,构建数据管道

'''
#==================================================================
# 一,构建数据管道
#==================================================================
'''
printlog("step1: prepare dataset...")


dftrain_raw = pd.read_csv("./data/titanic/train.csv")
dftest_raw = pd.read_csv("./data/titanic/test.csv")

dfraw = pd.concat([dftrain_raw,dftest_raw],axis=0)

def prepare_dfdata(dfraw):
    dfdata = dfraw.copy()
    dfdata.columns = [x.lower() for x in dfdata.columns]
    dfdata = dfdata.rename(columns={'survived':'label'})
    dfdata = dfdata.drop(['passengerid','name'],axis = 1)
    for col,dtype in dict(dfdata.dtypes).items():
        # 判断是否包含缺失值
        if dfdata[col].hasnans:
            # 添加标识是否缺失列
            dfdata[col + '_nan'] = pd.isna(dfdata[col]).astype('int32')
            # 填充,如果是数字,那么就添加这一列的平均值,否则空着
            if dtype not in [np.object,np.str,np.unicode]:
                dfdata[col].fillna(dfdata[col].mean(),inplace = True)
            else:
                dfdata[col].fillna('',inplace = True)
    return(dfdata)

dfdata = prepare_dfdata(dfraw)
dftrain = dfdata.iloc[0:len(dftrain_raw),:]
dftest = dfdata.iloc[len(dftrain_raw):,:]



# 从 dataframe 导入数据 
def df_to_dataset(df, shuffle=True, batch_size=4):
    dfdata = df.copy()
    if 'label' not in dfdata.columns:
        ds = tf.data.Dataset.from_tensor_slices(dfdata.to_dict(orient = 'list'))
    else: 
        labels = dfdata.pop('label')
        ds = tf.data.Dataset.from_tensor_slices((dfdata.to_dict(orient = 'list'), labels))  
    if shuffle:
        ds = ds.shuffle(buffer_size=len(dfdata))
    ds = ds.batch(batch_size)
    return ds

ds_train = df_to_dataset(dftrain)
ds_test = df_to_dataset(dftest)
print(dfdata.shape)
#dfdata.head().to_dict(orient = 'list')
dfdata.head()

输出:

(891, 13)
在这里插入图片描述

二,定义特征列

'''
#==================================================================
# 二,定义特征列
#==================================================================
'''
printlog("step2: make feature columns...")

feature_columns = []

'''
********************************数值列***************************
'''
for col in ['age','fare','parch','sibsp'] + [
    c for c in dfdata.columns if c.endswith('_nan')]:
    feature_columns.append(tf.feature_column.numeric_column(col))

'''
********************************分桶列******************************
意思就是我们设置一些分界点,假如是3个分界点,那么这些分界点将数据分成3+1=4类,并且表示为one-hot编码形式
'''
age = tf.feature_column.numeric_column('age')
age_buckets = tf.feature_column.bucketized_column(age, 
             boundaries=[18, 25, 30, 35, 40, 45, 50, 55, 60, 65])
feature_columns.append(age_buckets)
'''
*******************************类别列******************************
              注意:所有的Catogorical Column类型最终都要通过
            indicator_column转换成Dense Column类型才能传入模型!!
'''

sex = tf.feature_column.indicator_column(
      tf.feature_column.categorical_column_with_vocabulary_list(
      key='sex',vocabulary_list=["male", "female"]))
feature_columns.append(sex)

pclass = tf.feature_column.indicator_column(
      tf.feature_column.categorical_column_with_vocabulary_list(
      key='pclass',vocabulary_list=[1,2,3]))
feature_columns.append(pclass)

embarked = tf.feature_column.indicator_column(
      tf.feature_column.categorical_column_with_vocabulary_list(
      key='embarked',vocabulary_list=['S','C','B']))
feature_columns.append(embarked)

'''
********************************哈希列****************************
当类别很多或者我们不知道有多少类的时候,我们不能一个一个的列出来,这时候就可以使用hash_bucket,
第二个参数是我们想把这些数据分成多少类,这个类别数和真实的类别数不一定是一样的,我们自己设置划分为多少类即可
'''
ticket = tf.feature_column.indicator_column(
     tf.feature_column.categorical_column_with_hash_bucket('ticket',3))
feature_columns.append(ticket)

'''
*******************************嵌入列******************************
'''
cabin = tf.feature_column.embedding_column(
    tf.feature_column.categorical_column_with_hash_bucket('cabin',32),2)
feature_columns.append(cabin)
'''
******************************交叉列*******************************
'''
pclass_cate = tf.feature_column.categorical_column_with_vocabulary_list(
          key='pclass',vocabulary_list=[1,2,3])

crossed_feature = tf.feature_column.indicator_column(
    tf.feature_column.crossed_column([age_buckets, pclass_cate],hash_bucket_size=15))

feature_columns.append(crossed_feature)

三,定义模型

'''
#==================================================================
# 三,定义模型
#==================================================================
'''
printlog("step3: define model...")

tf.keras.backend.clear_session()
model = tf.keras.Sequential([
  layers.DenseFeatures(feature_columns), #将特征列放入到tf.keras.layers.DenseFeatures中!!!
  layers.Dense(64, activation='relu'),
  layers.Dense(64, activation='relu'),
  layers.Dense(1, activation='sigmoid')
])

四,训练模型

'''
#==================================================================
# 四,训练模型
#==================================================================
'''
printlog("step4: train model...")

model.compile(optimizer='adam',
              loss='binary_crossentropy',
              metrics=['accuracy'])

history = model.fit(ds_train,
          validation_data=ds_test,
          epochs=10)

五,评估模型

'''
#==================================================================
# 五,评估模型
#==================================================================
'''
printlog("step5: eval model...")

model.summary()


%matplotlib inline
%config InlineBackend.figure_format = 'svg'

import matplotlib.pyplot as plt

def plot_metric(history, metric):
    train_metrics = history.history[metric]
    val_metrics = history.history['val_'+metric]
    epochs = range(1, len(train_metrics) + 1)
    plt.plot(epochs, train_metrics, 'bo--')
    plt.plot(epochs, val_metrics, 'ro-')
    plt.title('Training and validation '+ metric)
    plt.xlabel("Epochs")
    plt.ylabel(metric)
    plt.legend(["train_"+metric, 'val_'+metric])
    plt.show()

plot_metric(history,"accuracy")

在这里插入图片描述在这里插入图片描述

参考文章eat_tensorflow2_in_30_days

关于各种特征列更详细的讲解可以参考https://blog.csdn.net/u014061630/article/details/82937333

猜你喜欢

转载自blog.csdn.net/qq_39507748/article/details/105523022
今日推荐