1. 程式人生 > >機器學習-TensorFlow應用之 binned features, Cross features和optimizer

機器學習-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和Adagra