機器學習-TensorFlow應用之 binned features, Cross features和optimizer


  • 概述

這一節主要介紹一下TensorFlow在應用的過程中的幾個小的知識點,第一個是關於features的處理的,例如Bucketized (Binned) Features 和 Feature scalling。第二個是簡單的介紹一下常用的幾個Optimizer之間的區別,例如SGD, Adagrad, Adam等等。這里主要是對前面一節的內容的一個小補充。其實關於feature的處理,我在前面已經用了很長一段時間在講了,但是基本都是基於sklearn的框架來處理的,雖然前面咱們說了很多很多,但是總有漏網之魚嘛,那就是Binned features,咱們這里就用TensorFlow來解釋並且應用。還有一個部分就是optimizer,咱們前面說了一個SGD的應用,這一節我准備簡單講述一下另外兩個常用的optimizer,他們分別是Adagrad, Adam,我會簡單說一下它們之間的優缺點以及應用場景。

  • Bucketized (Binned) Features

  Features engineering咱們在前面講述了很多很多,並且都用sklearn演示了他們的應用和實現過程。這里補充一下Binned features的知識點,具體什么是Binned features呢?它其實很簡單就是將咱們的數據按大小順序分成n 個bins, 或者這里可以理解成n個quantiles, 然后咱們將每一個bin的boundary記錄下來放到一個list里面,最后將咱們的數據在應用到這個bin里面,看看咱們的每一個數據屬於哪一個bin,咱的的結果是按照bin的大小從小到大一次是0,1,2,................這樣。咱們可以看一個簡單的實例

boundaries = [0, 10, 100]
input tensor = [[-5, 10000]
                [150,   10]
                [5,    100]]

output如下

output = [[0, 3]
          [3, 2]
          [1, 3]]

從上面的一個簡單的實例咱們看出,咱們的原始數據的范圍非常大,咱們可以根據boundaries這個list來將他們分成4個bins, 最后再來看咱們的原始數據屬於哪一個bin。上面的是一個簡單的例子,那么接下來咱們來看看具體的代碼實現過程。如果咱們需要將一個seriesbucketized,那么整個bucketized的過程其實分成三個部分,即分別是創建boundary,將series轉成numerical_column,和最后的bucketized三個部分;咱們看下面

def get_quantile_based_boundaries(series,num_bucket):
    quantiles = np.arange(1.0,num_bucket)/num_bucket
    boundaries = series.quantile(quantiles)#the index are the quantiles
    return [boundaries[key] for key in boundaries.keys()]

上面的這個函數的目的就是根據quantile來找到每一個bin的boundary;然后咱們需要將咱們的series轉成一個numerical_column,如下所示

house_median_age_numeric_column = tf.feature_column.numeric_column("housing_median_age")

其實這一個就是聲明咱們的這一個column的類型,既然是按照大小來分配到不同的bin, 那么咱們這一列的數據肯定得是數字型的。既然咱們有了boundary, 也有了numeric_column, 那么接下來就是bucketized啦,如下所示

 bucketized_house_median_age = tf.feature_column.bucketized_column(source_column=house_median_age_numeric_column,
                                                                   boundaries = get_quantile_based_boundaries(series=cali_housing_dataset_permutation["housing_median_age"],num_bucket=10)
                                        )

這里咱們就聲明並且完成了一個column的bucketized的過程,然后咱們就是可以將這個bucketized_column傳遞給模型的feature_column參數。咱們就完成了一個column的bucketized的整個過程。

補充:在這里咱們在補充一個小知識點,那就是既然咱們實例化了一個bucketized feature_column對象,並且告訴了咱們的模型,那么咱們如何獲取咱們的這個bucketized后的feature_column的值呢??簡單點就是,咱們怎么知道bucketized_house_median_age這個轉化后的值呢?其實很簡單,我直接上代碼,大家可以直接拿出來用哈

def demo(feature_column):
  feature_layer = tf.keras.layers.DenseFeatures(feature_column)
  print(feature_layer(dict(cali_housing_dataset_permutation)).numpy())

咱們直接調用上面的函數就能打印出咱們想要的值了,如下

[[0. 0. 0. ... 0. 1. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 1. 0. 0.]
 ...
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 1. ... 0. 0. 0.]
 [0. 0. 0. ... 1. 0. 0.]]

這里咱們也可以看出來bucketized過后,咱們的feature會轉成one-hot encoding的方式。

  • Cross_features

在咱們的sklearn中的feature generation中已經介紹了cross_features的相關信息,在sklearn中咱們可以直接將categorical data或者numerical data進行cross操作並且生成一個新的feature, 並且將它進行一個新的feature進行一些feature engineering中的相應的操作。其實在TensorFlow中咱們也有相應的方法進行操作,TensorFlow中有專門的cross_feature來進行操作,並且將返回的cross_feature告訴咱們的模型,這是一個cross feature;在這里咱們也可以看出來TensorFlow的牛逼之處,那就是他只需要告訴咱們的模型咱們的如何操作每一列的數據,而不像在sklearn中的那樣,需要咱們自己去label encoding 等一些列復雜的feature engineering的操作。但是凡事都是有好有壞的,TensorFlow中隱藏了很多feature engineering中的很多細節部分也導致咱們不能理解一些操作的底層原理,不利於咱們優化咱們的feature engineering的過程。其實總結起來就是說TensorFlow在cross_feature方面只需要咱們聲明一下某幾個features需要cross並且告訴一下模型就可以了,而不需要咱們真的去一步步的cross咱們的數據生成一個新的feature從而改變了咱們的原始的dataframe。具體在咱們的TensorFlow中,feature cross有多簡單呢,咱們看下面的就可以了

    lon_x_lat = tf.feature_column.crossed_column(keys=[bucketized_longitude, bucketized_latitude],
                                                 hash_bucket_size = 1000)

注意上面的keys是一個list,這個list里面的元素只可以是string或者是categorical feature type的feature_column, 這里的element如果是string的話,我們就會用這些string相對應的feature來cross(同樣的,這些feature的data type也必須要是string);如果是categorical feature type的話,咱們就會直接用這些數據進行cross。這里有個小細節哈就是feature type和data type的區別,初學者經常會混淆,feature type只有2中categorical和numerical, 而data type則有可能是int float string等等,當data type是int 或者 float的時候,那么它的feature type則不一定是numerical,也有可能是categorical,例如咱們上面的bucketized columns雖然data type是int,但是它還是categorical data type。

  • Optimizer

在咱們訓練模型的過程中,經常會碰到選擇optimizer的情況,實際中這一塊沒有最好只有更好。一般情況下每一種optimizer都有自己的優缺點,適合不同的應用場景。我今天主要講一下三個常用的optimizer,分別是SGD, Adagrad和Adam。首先SDG是咱們最傳統的一種計算梯度下降的算法, 它除了消耗的資源有點大外,沒啥大毛病,幾乎適用於所有的convex 的場景;Adagrad是一種改進的算法,它的learning rate並不是固定的,它的learning rate能夠根據咱們數據的大小來改變的,它在convex problem中的表現非常好,但是在non-convex的場景中,表現的不好;Adam常用於non-convex的場景,它在non-convex中的表現要好於SGD和Adagrad。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM