机器学习-TensorFlow建模过程 Linear Regression线性拟合应用

TensorFlow是咱们机器学习领域非常常用的一个组件,它在数据处理,模型建立,模型验证等等关于机器学习方面的领域都有很好的表现,前面的一节我已经简单介绍了一下TensorFlow里面基础的数据结构即:Tensor和Dataset; 这里咱们开始介绍TensorFlow的建模过程以及验证模型的一些简单方法。其实无论是sklearn还是TensorFlow,他们的模型建立过程都是相似的,都是经历columns类型声明,模型定义,数据训练,validation等等几个步骤。前面的几节内容我已经简单的介绍了如何用sklearn建立tree_based模型,这里我主要是想演示TensorFlow的应用,所以我就用linear regressor来当做例子来演示TensorFlow是如何从数据加载一直到数据验证的阶段。至于线性拟合的实现的具体细节,我在下一节的内容会从数学的角度具体解释的。本节内容所使用的数据都是来自于网络中,大家可以忽略具体的数据的意思,主要的了解TensorFlow的应用过程,不必过于纠结于模型的细节部分,模型的细节我会在随后的章节解释。好了,那么咱们现在开始吧

第一步:数据准备

顾名思义,就是咱们准备数据的过程,这里包括有missing value handling, categorical data encoding,data split, data permutation等等内容,这一步咱们要将咱们将来模型训练所用到的数据都能准备好。这个准备过程无非也就是上面的这些步骤,咱们可以看下面的代码演示

cali_housing_dataset_original = pd.read_csv("https://download.mlcc.google.com/mledu-datasets/california_housing_train.csv")
cali_housing_dataset_original["median_house_value"] /= 1000.0
#create a random generator
generator = np.random.Generator(np.random.PCG64())
#permutate the data frame
cali_housing_dataset_permutation = cali_housing_dataset_original.reindex(
        generator.permutation(cali_housing_dataset_original.index)
        )
cali_housing_dataset_permutation.describe()

#select the features that we will use in the model trainning process
my_feature = cali_housing_dataset_permutation[["total_rooms"]]
#select the targets of the dataset
targets = cali_housing_dataset_permutation[["median_house_value"]]

这里我就不演示那些feature engineering的过程,那些内容太多,大家可以看我之前的博客,这里主要是想向大家演示一下permutation的过程。因为最新的numpy对于randomize的过程已经有更新了,不再使用的那些老的API了,numpy中最新的randomize的过程是通过创建2个generator来实现随机过程和随机数的生成了,这两个generator一个个是bit generator, 就如咱们上面代码中的PCG64(), 它能产生一个随机的bit stream, 根据numpy的官方文档,虽然有很多种bit generator,但是PCG64是最稳定的一种;另外一个就是Generator, 它是通过np.random.Generator()函数来实例化一个对象的,它能将bit generator产生的bit stream转化成数字。这里的数据咱们就选择一个最最简单的linear regression的方式,那就是只选择一个feature,那就是total_rooms; 咱们的target是median_house_value。

第二步:定义feature 类型 和 optimizer

既然咱们的数据都准备好了,那么之后那么得定义一下咱们数据的类型(每一个column的类型都得定义),将来在咱们定义模型的时候咱们也得将columns的信息传递给咱们的模型对象;以及用什么optimizer将来来训练咱们的模型,这个optimizer将来也得传递给咱们的模型对象。 具体optimizer是什么我下面会慢慢讲的。为了方便演示,还是先上代码给大家看

#indicates what is the data type of the feature to tensorflow
feature_columns = [tf.feature_column.numeric_column("total_rooms")]
#using stochastic gradient descent as the optimizer for our model
#to ensure the magtitute of gradient do not become too large, we apply clipping_norm to our optimizer
my_optimizer = tf.optimizers.SGD(learning_rate = 0.0000001, clipnorm=5.0)

从上面的代码可以看出,第一句是声明咱们feature_columns里面只有一个numeric_column,记住每一个column都有一个feature_column对象,这里因为咱们只选取了一个feature是total_rooms,所以咱们这里就一个tf.feature_column对象。这里的第二行代码是咱们的重点,也是以后优化模型中经常要调整的部分,这里咱们可以看出,这里的optimizer是一个SGD, SGD是stochastic gradient descent的缩写,就是每一次计算咱们的gradient descent的时候,咱们只选取一组数据进行计算,如果每一次计算gradient descent的时候咱们都用整个数据进行计算,那么咱们的计算机是负担不起的,消耗的存储空间和计算能力都太大了,因为在实际中咱们的数据集的数量经常都是以万为单位的。具体计算gradient descent的过程我会在下一节中讲述模型训练过程中演示的。咱们可以看出来,SGD中还有两个参数,分别是learning_rate和clipnorm, 咱们知道,当我们在训练我们的模型的时候,我们需要逐步的训练很多次,知道咱们的gradient descent趋于0是才停止,咱们的每一步的大小都要合理,如果learning_rate太小,咱们训练的步数就会太多,影响咱们的效率;如果learning_rate太大,则可能导致咱们训练模型的过程不能converge,就是永远找不到那个最小值,从而导致训练的模型失败;为了防止咱们咱们的gradient太大,我们这里不单单用learning_rate来限制,咱们还加了一个clipnorm来限制咱们的gradient magtitute大小,防止咱们fail to converge, 这相当于一个双重保险。

第三步:定义一个模型model

将上面的参数都定义完成后,咱们就得定义一下咱们的模型啦,TensorFlow提供了大量的模型可供使用,几乎所有主流的机器学习的模型和深度学习相关的模型,TensorFlow几乎实现全覆盖了,具体咱们可以去他的官网查询, 他的官网地址是:https://www.tensorflow.org/api_docs/python/tf  ,记住在TensorFlow中,他的模型都在tf.estimator这个模块中。因为这里是咱们讲述用TensorFlow开发机器学习应用的入门,咱们就选一个最简单的模型linear regressor模型来演示

linear_regressor = tf.estimator.LinearRegressor(
        feature_columns = feature_columns,
        optimizer = my_optimizer
        )

这里咱们可以看出是如何初始化一个LinearRegressor对象的,同样的,咱们可以看出来它初始化的时候也是需要传递feature_columns和optimizer这2个参数的,而这两个参数正是咱们第二步中所初始化的,可以说是环环相扣啊,哈哈,也可以看出咱们前面定义初始化的一个对象都是没有多余的,都是要用到的。这两个参数分别告诉了咱们的模型咱们数据columns的类型以及用什么optimizer来训练这2个信息。

第四步:数据源input_fn

既然咱们的原始数据准备好了,模型也都定义好了,如果需要训练咱们的模型,咱们还差什么呢?对了就是将咱们的原始数据(这里的例子是dataframe)转化成TensorFlow中的dataset,并将转化后的data传递给咱们的模型,让咱们之前定义的模型用这些数据去训练。这里应该也是咱们用TensorFlow来建模的一个核心部分了,咱们先看代码演示,然后我会逐个详细解释的

def my_input(features, targets, batch_size=500, shuffle=True, num_epochs=None):

    """
    epochs: while trainning, in the case of steps is larger than the length of dataset, we set the epochs to None, which means repeat forever. However,
    in trainning process, we have the steps to control the total number of iterations.  While in the case of making predictions of a given dataset, we must
    set epochs to 1 and shuffle to False. Because we only want the input function return the dataset once, otherwise the function will keep returnning the
    results forvere once and once again.

    shuffle: in the trainning process, in order to balance the dataset, we set it to True. However while in prediction process, we have to set it to False, which
    could help us to evaluate the outputs. For example, if the outputs are shuffled, we have no way to compare the outputs to our original lables.

    """

    #convert panda dataframe to a dict of Numpy array
    features = {key:tf.multiply(np.array(value),1) for key,value in dict(features).items()}
    #construct a dataset
    ds = tf.data.Dataset.from_tensor_slices((features,targets))
    ds = ds.batch(batch_size).repeat(num_epochs)

    if shuffle:
        ds = ds.shuffle(buffer_size = 10000)
    return ds

这里有几个核心的参数我需要解释一下,首先features和target两个参数很明显就是咱们第一步中获取的数据,分别是用来训练这个模型的特征变量和label;重点这里解释一下batch_size, shuffle 和 num_epochs这三个参数,这三个参数在咱们TensorFlow的整个学习过程中都得用到,绝对的重点,不容怀疑。首先咱们来看batch_size, 因为SGD每一次都只会选用一条数据来计算咱们的gradient(训练模型),而咱们的数据具有很强的随机性,那么就会导致咱们的模型最后很可能不可用,但是如果咱们每一个step都选用整个dataset来训练模型,又会导致咱们的训练过程非常漫长,那么聪明的人类就自然而然的想到了咱们可以每一次选用一定数量的数据来训练模型,一般的数据量咱们大致的范围都是在10-10000之间,这种方式就成为mini-batch SGD, 在这里咱们就是采用了这种方式,咱们每一次选用500条数据来训练咱们的模型,这是通过设置batch_size的值来实现的。对于shuffle这个参数呢,也是为了打乱咱们的数据来进行训练,最终的目的也是为了能帮助咱们训练出更加精确的模型,防止咱们的数据分布不合理导致模型有偏差,它里面的buffer_size的意思是先从ds中选中buffer_size个数据(这些数据暂时还是有序的,顺序和ds中一样),然后iterate的时候呢,就从这个buffer中随机的选择数据(这个选择数据的过程就是无序的选择了,实现了随机的目的)。最后还有这个repeat(num_epochs)的函数,首先repeat函数在training的过程中一定需要的,因为当咱们设置steps步数参数的时候,如果steps的总数要多余整个dataset的数据量的时候,那么这时候咱们一定得重复利用咱们的dataset来达到训练的目的,否则咱们的数据源的数据量不够了,会出错的,这就是为什么需要repeat的原因,至于num_epochs是来控制重复的次数的,一般在training阶段咱们将它设置成None, 意思就是无限循环,知道training中的steps全部走完位置,如果在predict阶段,咱们一般就设置成1,因为咱们验证阶段不需要重复的,同样的在predict的时候,数据源函数中的shuffle也要设置成False的,否则predict的结果都是乱序的,无法跟原来的数据进行对比了。前面几个参数在咱们模型训练过程中可以说是最重要的参数了,这里说的也比较多,所以一点得用心搞明白。

第五步:训练模型 training

既然上面咱们把模型的参数都设置好了,数据源也定义好了,那么接下来咱们的任务就是训练咱们定义的模型了,这个过程在代码中是很简单的,但它内部做的工作是很多的,它需要计算在每个维度(feature)上的gradient descent,知道它趋于0为止,它的计算细节我会在接下来的一个章节中展示出来,咱们先看代码

linear_regressor.train(
        input_fn = lambda:my_input(my_feature, targets),
        steps = 1000
        )

是不是很简单,咱们只需要将数据源函数作为参数传递给他,并且设置一个steps就可以了。这里input_fn我就不解释了,简单说一下steps,steps指的是咱们训练的步数,咱们每计算一次gradient descent,就算一步,这里指咱们最多计算1000次,即使1000的时候gradient descent不等于0咱也停止咱的训练过程,然后咱们可以重新设置optimizer中的learning_rate来重新训练。

第六步:predict和evaluate

经过前面五步后,咱们已经训练出来了一个模型,那么接下来咱们需要用这个模型来预测一下数据,并且看看它的效果,去evaluate一下这个模型。正常的情况下咱们会将数据split成training data 和 validation data,这里我为了方便,咱就直接用training data来演示如何predict还有如何evaluate咱们的模型。简单的代码如下

#create a input function for prediction
prediction_input_fn = lambda:my_input(my_feature,targets,shuffle=False,num_epochs=1)
#prediction
predictions = linear_regressor.predict(input_fn = prediction_input_fn)
predictions = np.array([item["predictions"][0] for item in predictions])

#errors MSE
mean_squared_error(targets,predictions)

在咱们做prediction的时候,咱们也是需要数据源input_fn的,在prediction的时候,shuffle=False, num_epochs=1; 然后调用这个模型linear_regressor的predict方法,将数据源函数传递给他, 它返回的结果是一个list,这个list里面的element是一个dictionary,这个dictionary的key值“predictions”, value也是一个一个list,并且只有一个元素element,此element就是咱们要的结果。最后咱们要evaluate这个模型预测的结果,咱们有很多种方式可以验证,这里只展示了一个最简单的方式,就是计算咱们的target和prediction的方差,其实有很多很多种方式,在后面的章节我会慢慢介绍。

第七步:data visualization

好了,最后咱们来看一下根据咱们的学习的模型,咱们想看看它的具体的拟合的效果,这里就需要用一点之前咱们学习的数据可视化的内容了,这里比较简单,咱们通过模型学习到的参数,画一条拟合线,然后在将数据画到画布上,坐标分别是"total_rooms"和"house_median_price",然后通过scatter plot展示出来。代码如下

sample = cali_housing_dataset_permutation.sample(n=300)
x_0 = sample["total_rooms"].min()
x_1 = sample["total_rooms"].max()
linear_regressor.get_variable_names()#retrieve the name of the variable
weights = linear_regressor.get_variable_value("linear/linear_model/total_rooms/weights")[0]#returns the value of variable given by name
bias = linear_regressor.get_variable_value("linear/linear_model/bias_weights")#retruns the value of bias
y_0 = weights*x_0+bias
y_1 = weights*x_1+bias
plt.plot([x_0,x_1],[y_0,y_1])#plot our regression line
plt.ylabel("median_house_value")#label the y Axes
plt.xlabel("total_rooms")#label the x Axes
plt.scatter(sample["total_rooms"],sample["median_house_value"])#plot a scatter plot from the sample
plt.show()

结果如下

可以看得出来,拟合的还不错。嘿嘿,关于模型训练过程的可视化,后面还有很多种,以后我慢慢说,例如:x坐标是steps, y坐标是loss, 也是非常常见的一种方式。

总结

今天完整的展示了用TensorFlow创建模型的整个过程,一直从data preparation到最后的evaluation,可以说贯穿了TensorFlow开发机器学习应用的整个过程。今天先用一个最简单的线性拟合例子展示这个过程,后面我还会展示更多的更加复杂的模型,例如:Logistic Regression, DNN, LSTM,等等等等。但是万变不离其宗,他们的基础步骤都是上面的七个步骤。最后 ,祝武汉加油!!!!!!!!

原文地址:https://www.cnblogs.com/tangxiaobo199181/p/12241170.html

时间: 2024-10-07 17:34:44

机器学习-TensorFlow建模过程 Linear Regression线性拟合应用的相关文章

从零单排入门机器学习:线性回归(linear regression)实践篇

线性回归(linear regression)实践篇 之前一段时间在coursera看了Andrew ng的机器学习的课程,感觉还不错,算是入门了. 这次打算以该课程的作业为主线,对机器学习基本知识做一下总结.小弟才学疏浅,如有错误.敬请指导. 问题原描写叙述: you will implement linear regression with one variable to predict prots for a food truck. Suppose you are the CEO of a

Coursera台大机器学习课程笔记8 -- Linear Regression for Binary classification

之前一直在讲机器为什么能够学习,从这节课开始讲一些基本的机器学习算法,也就是机器如何学习. 这节课讲的是线性回归,从使Ein最小化出发来,介绍了 Hat Matrix,要理解其中的几何意义.最后对比了linear regression 和 binary classification,并说明了linear regression 为什么可以用来做 binary classification .整节课的内容可以用下面的图来表示: 与其他课程的线性回归相比,这门课要更加理论,看完后对这门课有了更深的理解

斯坦福机器学习视频笔记 Week2 Linear Regression with Multiple Variables

相比于week1中讨论的单变量的线性回归,多元线性回归更具有一般性,应用范围也更大,更贴近实际. Multiple Features 上面就是接上次的例子,将房价预测问题进行扩充,添加多个特征(features),使问题变成多元线性回归问题. 多元线性回归将通过更多的输入特征,来预测输出.上面有新的Notation(标记)需要掌握. 相比于之前的假设: 我们将多元线性回归的假设修改为: 每一个xi代表一个特征:为了表达方便,令x0=1,可以得到假设的矩阵形式: 其中,x和theta分别表示: 所

斯坦福机器学习公开课---2. Linear regression

ufldl学习笔记与编程作业:Linear Regression(线性回归)

ufldl出了新教程,感觉比之前的好.从基础讲起.系统清晰,又有编程实践. 在deep learning高质量群里面听一些前辈说.不必深究其它机器学习的算法.能够直接来学dl. 于是近期就開始搞这个了,教程加上matlab编程,就是完美啊. 新教程的地址是:http://ufldl.stanford.edu/tutorial/ 本节学习链接:http://ufldl.stanford.edu/tutorial/supervised/LinearRegression/ 从一个最简单的线性回归,能够

使用tensorflow实现机器学习中的线性拟合

使用tensorflow实现机器学习中的线性拟合这个例子是模拟的单变量线性回归,通过提高单变量的阶数来增加特征数量,例如:4阶相当于分解为四个特征这种思想同样适用于多变量线性回归 import tensorflow as tf import numpy as np import matplotlib.pyplot as plt plt.rcParams['font.sans-serif']=['FangSong'] # 用来正常显示中文标签 plt.rcParams['axes.unicode_

机器学习经典算法具体解释及Python实现--线性回归(Linear Regression)算法

(一)认识回归 回归是统计学中最有力的工具之中的一个. 机器学习监督学习算法分为分类算法和回归算法两种,事实上就是依据类别标签分布类型为离散型.连续性而定义的. 顾名思义.分类算法用于离散型分布预測,如前面讲过的KNN.决策树.朴素贝叶斯.adaboost.SVM.Logistic回归都是分类算法.回归算法用于连续型分布预測.针对的是数值型的样本,使用回归.能够在给定输入的时候预測出一个数值.这是对分类方法的提升,由于这样能够预測连续型数据而不不过离散的类别标签. 回归的目的就是建立一个回归方程

机器学习经典算法详解及Python实现--线性回归(Linear Regression)算法

(一)认识回归 回归是统计学中最有力的工具之一.机器学习监督学习算法分为分类算法和回归算法两种,其实就是根据类别标签分布类型为离散型.连续性而定义的.顾名思义,分类算法用于离散型分布预测,如前面讲过的KNN.决策树.朴素贝叶斯.adaboost.SVM.Logistic回归都是分类算法:回归算法用于连续型分布预测,针对的是数值型的样本,使用回归,可以在给定输入的时候预测出一个数值,这是对分类方法的提升,因为这样可以预测连续型数据而不仅仅是离散的类别标签. 回归的目的就是建立一个回归方程用来预测目

机器学习之多变量线性回归(Linear Regression with multiple variables)

1. Multiple features(多维特征) 在机器学习之单变量线性回归(Linear Regression with One Variable)我们提到过的线性回归中,我们只有一个单一特征量(变量)--房屋面积x.我们希望使用这个特征量来预测房子的价格.我们的假设在下图中用蓝线划出: 不妨思考一下,如果我们不仅仅知道房屋面积(作为预测房屋价格的特征量(变量)),我们还知道卧室的数量.楼层的数量以及房屋的使用年限,那么这就给了我们更多可以用来预测房屋价格的信息. 即,支持多变量的假设为: