算法 – 选择排序
- 概述
这一节主要介绍一下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啦,如下所示
剑指Offer对答如流系列 – 实现Singleton模式
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。
Linux网络文件共享服务之NFS