机器学习-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,我会简单说一下它们之间的优缺点以及应用场景。git

  • 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啦,以下所示spa

 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的整个过程。code

补充:在这里我们在补充一个小知识点,那就是既然我们实例化了一个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())

我们直接调用上面的函数就能打印出我们想要的值了,以下blog

[[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的方式。element

  • 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。

相关文章
相关标签/搜索