深度学习训练营 21天实战TensorFlow+Keras+scikit-learn(txt+pdf+epub+mobi电子书下载)


发布时间:2021-08-04 13:48:06

点击下载

作者:上海江初文化传播工作室

出版社:人民邮电出版社有限公司

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

深度学习训练营 21天实战TensorFlow+Keras+scikit-learn

深度学习训练营 21天实战TensorFlow+Keras+scikit-learn试读:

前言

当下我们的生活和工作已经被人工智能和深度学习的技术所包围,例如人机对话、人脸识别过闸机或付款、各种语言间的自动翻译、自动驾驶汽车、淘宝的个性化推荐等,各大科技公司都在努力发展的“千人千面”精细化产品也离不开人工智能(它背后的技术就是深度学习)。

坦白来讲,深度学习就是对深度神经网络架构的学习,基于神经网络设计出各种架构的模型,如卷积神经网络(CNN)、循环神经网络(RNN)、长短期记忆网络(LSTM)、生成对抗网络(GAN)等。每一种神经网络在不同的领域起着不同的作用,例如在图像识别领域的人脸识别一般使用CNN;语言翻译或一些需要有记忆状态的领域一般用RNN或者LSTM;需要使用神经网络模型生成各种图像和视频的领域就可以用GAN。

自从Google公司开源了TensorFlow深度学习框架后,深度学习这门技术成为广大开发者、科研人员和企业最实用的技术;之后不久,基于TensorFlow深度学习框架编写而成的Keras深度学习框架就诞生了,Keras使得编写神经网络模型更简单、更易理解、更高效,只需几行代码就可以完成一个CNN模型。Keras有着快速编写神经网络模型的原型的称号,其后端之一就是TensorFlow。对这两个框架的掌握,现在基本已成为各大公司对深度学习工程师的招聘要求的标配。

本书特色

本书内容以实践、应用为导向,以实际编写代码和运行通过为准则,无须求解方程,无须理解复杂的公式。本书以项目编码实践为主,无方程公式的理论知识,只求读者能又快又准地运行代码并看到模型最终效果,在仅配置普通CPU的计算机上也能训练模型和完成所有的项目实践。

本书介绍的21个项目选取了目前比较流行的应用案例,为读者呈现生动有趣的实践应用。当初学者掌握了一定的统计学知识后,亟需的就是神经网络模型的项目编写练习,此时学习本书再适合不过了。

本书内容分为三大类,分别是预测类、识别类和生成类,各部分内容中均有从浅入深的项目案例。每个项目的每一行代码,都是笔者实际运行通过的。有的地方代码过多,我已将之写到了Python脚本文件中,读者需要下载相关脚本文件,引入后再运行。每个神经网络模型的每一层都有激活函数和损失函数,在隐藏层时用以调节权重和误差,在输出层时用以计算概率。

本书内容及体系结构

第1章 房价预测

本章通过对波士顿和北京的房价进行分析和预测,讲解如何使用scikit-learn(sklearn)进行网格搜索来训练和预测,以及如何使用Keras构建神经网络模型来训练、评估和预测。

第2章 泰坦尼克号生还预测

本章通过对泰坦尼克号的船上乘员的人数情况进行数据清洗与分割,讲解如何使用决策树、逻辑回归、梯度提升分类器、神经网络模型来构建、训练、评估和预测模型。

第3章 共享单车使用情况预测

本章将根据Capital Bikeshare共享单车公司的用户骑行数据绘制多种图表来进行呈现、分析和总结,最终编写一个基于TensorFlow的长短期记忆网络模型来讲解如何进行预测。

第4章 福彩3D中奖预测

本章通过分析从福彩开奖的网站上获取的从2004年10月到2018年7月的3D中奖数据(读者也可以自行获取更多的数据),构建基于Keras的时间序列和多层感知器模型来讲解如何进行中奖预测。

第5章 股票走势预测

本章主要是通过从美国纳斯达克股票交易市场获取的百度和微软的股票价格走势数据,对从上市开始到2018年的股票收盘价格数据进行观察和分析,假定购买策略,构建Prophet模型来讲解如何进行预测。

第6章 垃圾邮件预测

本章通过判定给定的邮件是否是垃圾邮件来进行分析,然后构建多项式朴素贝叶斯模型和多层感知器模型来讲解如何预测邮件是否是垃圾邮件。

第7章 影评的情感分析

本章通过分析和预测给定的电影评论是正面的还是负面的,讲解如何基于TensorFlow和Keras构建长短期记忆网络模型来分析影评是正面的或者负面的。

第8章 语言翻译

本章通过从网上下载的英文和法文的平行语料库来进行机器翻译,讲解如何基于Keras的长短期记忆网络构建从法文到英文的语言神经机器翻译引擎。

第9章 MNIST手写数字识别

本章将介绍如何识别开源的MNIST手写数字数据库的图像,并基于TensorFlow和Keras构建多层感知器和卷积神经网络模型,讲解如何进行训练、评估和识别。

第10章 狗的品种识别

本章将介绍通过由120个品种的狗的图像数据库构建的数据集进行图像基本分析,然后构建Keras的卷积神经网络识别模型,再构建基于InceptionV3预训练模型的迁移学习技术来讲解如何进行训练、评估和识别。

第11章 人脸识别

本章通过提供的LFW人脸图像数据集,进行图像中的人脸对齐,然后训练模型、预测模型,还讲解了如何使用流行的开源库FaceNet和FaceRecognition来进行实时的人脸识别。

第12章 人脸面部表情识别

本章将讲解如何使用fer2013的数据集构建卷积神经网络模型来进行人脸面部表情识别。首先是对单张图片中的人脸面部表情进行识别,然后再对视频中的人脸面部表情进行识别,最后通过开启摄像头实时识别拍摄到的人脸面部表情。

第13章 人体姿态识别

本章将介绍OpenPose开源库,它是由CMU计算机感知实验室研发并开源的。我们将依据OpenPose开源库基于TensorFlow和Keras的实现版本,对单张图片、视频和摄像头拍摄到的画面进行人体姿态识别。

第14章 皮肤癌分类

本章将讲解如何通过ISIC2017:Skin Lesion Analysis提供的3种皮肤癌症的图像数据集进行构建卷积神经网络模型的分类和预测,基于TensorFlow的迁移学习技术和Keras的CNN模型进行识别。

第15章 对象检测

本章将讲解如何使用Mask R-CNN Inception COCO、Faster R-CNN Inception COCO和SSD MobileNet COCO,对COCO图像数据集里实时拍摄的画面中的对象进行识别。

第16章 看图说话

本章将讲解如何通过MSCOCO图像数据集,使每张图像都有对应的图像文本描述,使用Show and Tell模型来实现模型的构建,生成TFRecords图像格式数据,训练、评估和测试模型。

第17章 生成电视剧剧本

本章讲解如何使用The Simpsons剧本的某一个片段作为训练数据集,通过TensorFlow构建循环神经网络和Textgenrnn来实现电视剧剧本的生成。

第18章 风格迁移

本章将讲解如何通过给定的大师画作和自己提供的图片来构建TensorFlow和Keras的神经网络模型,把大师的画作风格迁移到指定的图片上。

第19章 生成人脸

本章将讲解如何使用TensorFlow构建生成对抗网络模型,先用于简单的MNIST手写数字图像识别,然后实现基于LFW人脸图像数据集的人脸生成。

第20章 图像超分辨率

本章将讲解如何使用LFW人脸图像数据集和srez开源库构建深度对抗生成网络模型,训练和生成高度清晰的图像(放大图像4倍也不模糊)。

第21章 移花接木

本章将讲解如何通过提供的3种图片数据集,基于CycleGAN技术来实现根据橘子生成苹果、根据马生成斑马,以及将男性人脸面貌和女性人脸面貌进行互换。

读者对象

◇ 统计学从业者。

◇ 人工智能研究人员。

◇ 深度学习开发者。

◇ 机器学习开发者。

◇ 人工智能工程师。

◇ 互联网行业的创业者。

阅读本书的前提

本书介绍的项目主要运行环境配置信息和安装流程分别如下。

①Linux系统的分支Ubuntu,版本16.04.5。

②虚拟环境virtualenv,版本16.0.0。

③Python脚本编程语言,版本Python3.6.6。

④试验代码运行环境Jupyter Notebook,版本5.4.0。

⑤深度学习框架TensorFlow,版本1.10.1;Keras,版本2.1.6。

各个项目不同的安装包版本信息,在各个项目开始的时候会提及。

在写这本书的时间里,各种技术框架和工具不断地更新和迭代,各自的版本也升级了,所以如果读者在本书的项目中会看到所提及的一些技术框架和工具的版本高于这里提及的版本,请以具体项目里所提及的版本为主;这么做的目的是让初学者适应和习惯持续更新的技术框架和工具。

本书对应的每一章节的资源或代码的Github仓库下载地址如下。

◇ https://github.com/21-projects-for-deep-learning/MyBook

致谢

感谢互联网时代,感恩深度学习领域的先驱者们为神经网络技术的基础架构做出的贡献,包括但不限于Geoffrey Hinton(杰弗里·希尔顿)、Yann LeCun(杨立昂)、Yoshua Bengio(约书亚·本吉奥)、Andrew Ng(吴恩达)、Francois Chollet(弗朗索瓦·肖莱)等资深专家。Google作为全球科技公司对开源做出的贡献是巨大的,让无数的开发者和研究者可以沿着Google前沿的技术一起前进,也让我们可以为此做出微薄的贡献。

还要真诚地感谢北京源智天下科技有限公司的许亚楠女士,她在知名博客网站上看到了我的博客,和我进行了详细的沟通,经过她的认可和热情的推动后,我决定编写和出版本书。也感谢王蕾编辑,因为她的重视和诚恳的建议,本书终于完美收官。

最后,由于作者水平和成书时间所限,本书难免存有疏漏和不当之处,敬请专家和读者给出批评和指正。张强2019年5月第一篇 预测类项目实战

○ 第1章 房价预测

○ 第2章 泰坦尼克号生还预测

○ 第3章 共享单车使用情况预测

○ 第4章 福彩3D中奖预测

○ 第5章 股票走势预测

○ 第6章 垃圾邮件预测

○ 第7章 影评的情感分析

○ 第8章 语言翻译第1章 房价预测

大多数编程入门教程都从“Hello,World!”开始,深度学习领域也有入门教程。在预测类项目实战篇中,我们就把房价预测作为入门教程。

房价预测是一个很现实,也很接地气的问题。也就是说,读者学完本章关于房价预测的流程和代码的用法后,可以将其用到房产公司的房屋价格统计,买房时的价格预测和定位,或者做房屋数据分析时的统计等方面。这里的分析和预测不会讲解看房买房的方方面面,但是可以给读者一个启发,通过这些代码和读者自己扩展的数据,达到解决现实问题的目的。

本章将会讲解著名的波士顿房屋价格预测(Boston Housing Prediction)和北京房屋价格预测,读者可以在前言中找到所提供的数据集并自行下载。1.1 数据准备

数据集是公开的,可以在前言所提供的链接下找到。本章使用的数据集是早期的房屋统计数据集,作为项目数据集来讲解也较为经典。波士顿的房屋数据集文件是housing.csv,北京的房屋数据集文件是bj_housing.csv。开始的时候,我们会用scikit-learn库来分析和预测,然后会用TensorFlow下的Keras的神经网络模型来预测,在预测结束后,都会使用一张对照图来直观地查看。1.1.1 环境准备

◇ numpy=1.14.6。

◇ pandas=0.22.0。

◇ sklearn=0.19.2。

◇ seaborn=0.7.1。

◇ matplotlib=2.1.2。

◇ tensorflow=1.10.0。1.1.2 预处理数据

在训练人工智能模型前,我们需要先观察和分析要训练的数据集,然后进行必要的预处理。这里我们先通过pandas的read_csv()函数加载housing.csv数据,获得489行乘以4列的数据,返回的是一个pandas的DataFrame对象(DataFrame可以简单地理解成类似Excel表格的数据对象,但它并不是Excel表格),然后查看前5行数据以观察。import pandas as pd# 加载数据集data=pd.read_csv('housing.csv')print("波士顿房屋数据有{}行x{}列。".format(data.shape[0],data.shape[1]))# 查看前5行数据data.head()

输出如下。波士顿房屋数据有489行x4列。

输出前5行数据,如图1.1所示。图1.1 波士顿房屋数据集的前5行数据

图中该数据集的4列数据的含义分别如下。

◇ RM:该地区每座房屋的平均房间数量。

◇ LSTAT:该地区的房主中低收入阶层(有工作但收入微薄)所占百分比。

◇ PTRATIO:该地区的中小学里,学生和老师的人数之比(学生数/老师数)。

◇ MEDV:该地区业主自住房屋的价格中位数。

输出结果还有其他的字段(列),此处附图中只显示了主要的字段。然后,我们通过describe()函数来观察数据的基本统计信息,代码如下。data.describe()

输出如图1.2所示。图1.2 波士顿房屋数据基本统计信息

如果我们想自己写代码统计房屋价格的信息,可以这样写。import numpy as np# 计算最低价格minimum_price=np.min(data["MEDV"])# 计算最高价格maximum_price=np.max(data["MEDV"])# 计算均值mean_price=np.mean(data["MEDV"])# 计算中间价格median_price=np.median(data["MEDV"])# 计算标准差价格std_price=np.std(data["MEDV"])# 打印输出所有计算的价格统计print("波士顿房价数据的统计:")print("最低价格:${}".format(minimum_price))print("最高价格:${}".format(maximum_price))print("均价:${}".format(mean_price))print("中间价格:${}".format(median_price))print("标准差价格:${}".format(std_price))

输出如下。波士顿房价数据的统计:最低价格:$105000.0最高价格:$1024800.0均价:$454342.9447852761中间价格:$438900.0标准差价格:$165171.13154429474

然后,我们来分割一下训练集的训练数据X和y,也就是房屋特征数据features和房屋价格prices。变量data是一个DataFrame对象,它可以通过调用drop()函数来丢弃某个列。所以我们先取出MEDV列作为训练数据y,而训练数据X就是将MEDV列丢弃后的数据。# 获取房屋价格prices=data['MEDV']# 获取房屋特征features=data.drop('MEDV',axis=1)1.1.3 数据可视化分析

我们接下来分别分析RM列、LSTAT列和PTRATIO列与MEDV列的相关性,会使用到seaborn库。seaborn库是一个用于统计数据可视化的库,它是基于Matplotlib库编写而来的,提供了更为方便、高级的封装和调用。这里就用seaborn来绘图显示。

首先,我们来分析RM列和MEDV列的相关性。先导入Matplotlib库,再导入seaborn库,最后调用regplot()函数,它会根据数据和线性回归的模型进行拟合。import matplotlib.pyplot as pltimport seaborn as sns# regplot()函数根据数据绘制线性回归(Linear Regression)模型图# 参数1:X轴,表示每座房屋的平均房间数量# 参数2:y轴,表示房屋价格# 参数3:绘图时使用的颜色,这里是红色sns.regplot(data['RM'],prices,color='red')# 显示绘图plt.show()

输出结果如图1.3所示。图1.3 RM列与MEDV列的相关性模型图

通过这个线性回归模型图,我们可以观察到,房间的数量越多,房屋价格就越高,也就是空间越大越舒适;还可以看到大部分房屋的房间数量在6个左右。

然后,我们分析LSTAT列和MEDV列的相关性。# regplot()函数根据数据绘制线性回归(Linear Regression)模型图# 参数1:X轴,表示该地区的房主中低收入阶层所占百分比# 参数2:y轴,表示房屋价格# 参数3:表示绘制的图是用什么标记绘制出来的,这里是“+”# 参数4:绘图时使用的颜色,这里是绿色sns.regplot(data['LSTAT'],prices,marker='+',color='green')# 显示绘图plt.show()

输出如图1.4所示。图1.4 LSTAT列和MEDV列的相关性模型图

通过这个线性回归模型图,我们可以看到LSTAT列的数值越高,房屋价格就越低。LSTAT列表示该地区的房主中低收入阶层所占百分比,低收入阶层所占百分比的值越高,就意味着,周边的消费水平越低,房屋价格自然也会越低。

最后,我们来分析一下PTRATIO列和MEDV列的相关性。# regplot()函数根据数据绘制线性回归(Linear Regression)模型图# 参数1:X轴,表示该地区的中小学里,学生和老师的人数之比# 参数2:y轴,表示房屋价格# 参数3:表示绘制的图是用什么标记绘制出来的,这里是“^”# 参数4:绘图时使用的颜色,这里是蓝色sns.regplot(data['PTRATIO'],prices,marker='^',color='blue')# 显示绘图plt.show()

输出如图1.5所示。图1.5 PTRATIO列和MEDV列的相关性模型图

通过这个线性回归模型图,我们得知PTRATIO列的值的增加会降低房屋价格。这是因为拥有学生和老师的人数之比较高表明该地区缺乏教学设施或资源;相反的是,学生和老师的人数之比较低的地方,教学设施或资源较好,该地区的房屋价格也就高一些。1.2 基于scikit-learn实现房价预测

本节将使用scikit-learn来实现房价预测。首先使用决定系数R2Score来做一个小测验;然后使用决策树回归器配合不同的深度值来创建和对比模型;最后使用网格搜索(grid search)来查找最佳模型,以便进行房价预测。1.2.1 衡量R2值

通过sklearn提供的r2_score()函数来计算拟合优度(Goodness of Fit),R2值越接近1表明拟合的程度越高;反之,R2值越小,则说明回归直线的拟合程度越低。# 导入r2_scorefrom sklearn.metrics import r2_score# 定义函数,计算目标值和预测值之间的分值def performance_metric(y_true,y_predict): score=r2_score(y_true,y_predict) return score

这里有一个小测验,假设有5个真实数值和5个预测数值,分别是[3,−0.5,2,7,4.2]和[2.5,0.0,2.1,7.8,5.3],然后通过r2_score()函数来看它的拟合优度的程度值。# 真实数值test_y_true=[3,-0.5,2,7,4.2]# 预测数值test_y_predict=[2.5,0.0,2.1,7.8,5.3]# 通过r2_score函数来计算score=performance_metric(test_y_true,test_y_predict)print("决定系数,R^2=:{}。".format(score))

输出如下。决定系数,R^2=:0.9228556485355649。

可以看到,R2值非常接近1,说明相关程度高。1.2.2 模型性能对比

我们将通过4个不同的深度值创建4个不同的模型,然后来对比这4个模型的性能表现,最后通过图表直观显示。现在,我们把房屋特征和价格的数据进行清洗和分割。# 从sklearn库里导入train_test_split方法from sklearn.model_selection import train_test_split# train_test_split()方法用来清洗和分割数据# 参数1:特征样本,就是房屋特征数据# 参数2:特征样本对应的目标(房屋)价格# 参数3:分配给测试集的大小为0.1,也就是10%的数据用于测试、90%的数据用于训练# 参数4:random_state表示随机数生成器的种子,如果希望第二次调用train_test_split()方法# 的结果和第一次调用的结果一致,那么就可以设置一个值,多少都可以,生产环境不要设值X_train, X_test, y_train, y_test = train_test_split(features, prices, test_size=0.1, random_state=50)print("X_train.shape={}, y_train.shape={}.".format(X_train.shape, y_train.shape))print("X_test.shape={}, y_test.shape={}.".format(X_test.shape, y_test.shape))

输出如下。X_train.shape=(440,3),y_train.shape=(440,).X_test.shape=(49,3),y_test.shape=(49,).

得到440行的数据用于训练,49行的数据用于测试。接下来,我们定义一个函数来衡量模型的性能,深度值分别是1、3、6、10,然后输出这些模型的图,便于更直观地对比。# 导入绘图库import matplotlib.pyplot as plt# 使用matplotlib在Jupyter Notebook中绘图时,需要使用这个%matplotlib inline# 导入sklearn的清洗分割、学习曲线和决策树回归器的对象和函数from sklearn.model_selection import ShuffleSplit, learning_curvefrom sklearn.tree import DecisionTreeRegressor# 定义模型的性能对比函数# 通过不同大小的深度值来创建for循环里的模型,然后以图的形式展现def ModelLearningGraphMetrics(X, y): # 清洗和分割数据对象定义 # 参数1:n_splits表示重新清洗和分割数据的迭代次数,默认值为10 # 参数2:test_size=0.2表示有0.2的数据用于测试,也就是20%的数据用于测试,80%的数据用于训练 # 参数3:random_state表示随机数生成器的种子,如果希望第二次调用ShuffleSplit()方法 # 的结果和第一次调用的结果一致,那么就可以设置一个值,多少都可以,生产环境不要设值 cv = ShuffleSplit(n_splits=10, test_size=0.2, random_state=0) # 生成训练集大小 # 函数np.rint()是计算数组各元素的四舍五入的值到最近的整数 # 函数np.linspace(start_i, stop_i, num)表示从起始值到结束值之间,以均匀的间隔返回指定个数的值。 # 那么这里就是从1开始、以X结束的总行数的80%的数据,数据间隔是9,最后将数据元素都转换成整型 train_sizes = np.rint(np.linspace(1, X.shape[0]*0.8 - 1, 9)).astype(int) # 创建一个绘图窗口,大小10×7,单位是英寸(inch) fig = plt.figure(figsize=(10, 7)) # 根据深度值创建不同的模型 # 这里的深度值就是1、3、6、10这4个 for k, depth in enumerate([1,3,6,10]): # 根据深度(max_depth)值来创建决策树回归器 regressor = DecisionTreeRegressor(max_depth=depth) # 通过学习曲线函数计算训练集和测试集的分值 # 参数1:评估器,这里就是决策树回归器 # 参数2:特征样本,房屋特征 # 参数3:目标标签,房屋价格 # 参数4:训练样本的个数,这是用来生成学习曲线的 # 参数5:交叉验证生成器,或可迭代对象 # 参数6:评分器,是一个可调用对象 sizes, train_scores, test_scores = learning_curve( regressor, X, y, train_sizes=train_sizes, cv=cv, scoring='r2') # 计算训练集分值和测试集分值的标准差 train_std = np.std(train_scores, axis=1) test_std = np.std(test_scores, axis=1) # 计算训练集分值和测试集分值的均值 train_mean = np.mean(train_scores, axis=1) test_mean = np.mean(test_scores, axis=1) # 根据学习曲线值来绘制图,四个图的位置通过k+1来控制 ax = fig.add_subplot(2, 2, k+1) # 绘制训练得分线,plot()方法 # 参数1:X轴方向的值 # 参数2:y轴方向的值 # 参数3:绘制出来的线的样式风格,比如这里的“o”表示一个圆点标记,而“-”表示实线 # 参数4:绘制的线的颜色 # 参数5:图例上的标题 ax.plot(sizes, train_mean, 'o-', color='r', label='Training Score') # 绘制测试得分线 ax.plot(sizes, test_mean, 'o-', color='g', label='Testing Score') # fill_between()方法表示为训练得分线描边 # 参数1:X轴方向的值 # 参数2:y轴方向的覆盖下限 # 参数3:y轴方向的覆盖上限 # 参数4:设置覆盖区域的透明度 # 参数5:设置覆盖区域的颜色 ax.fill_between(sizes, train_mean - train_std, train_mean + train_std, alpha=0.15, color='r') # fill_between()方法表示为测试得分线描边 ax.fill_between(sizes, test_mean - test_std, test_mean + test_std, alpha=0.15, color='g') # 在绘图的窗口上添加标题 ax.set_title('max_depth = {}'.format(depth)) # 设置X轴的标题 ax.set_xlabel('Number of Training Points') # 设置y轴的标题 ax.set_ylabel('Score') # 设置X轴方向的最小值和最大值 ax.set_xlim([0, X.shape[0]*0.8]) # 设置y轴方向的最小值和最大值 ax.set_ylim([-0.05, 1.05]) # 添加图例 ax.legend(bbox_to_anchor=(1.05, 2.05), loc='lower left', borderaxespad=0.) # 添加图形总标题 fig.suptitle('Decision Tree Regressor Learning Performances', fontsize=16, y=1.03) # 自动调整subplot符合图的区域的参数的布局。生产环境中不要使用该函数,因为这是一个实验特性函数 fig.tight_layout() # 显示绘图 fig.show()ModelLearningGraphMetrics(features, prices)

输出的图形如图1.6所示。图1.6 决策树回归器的模型性能表现

通过上面4个模型的图形对比,我们发现max_depth=3的模型表现不错;max_depth=1的模型有些欠拟合;max_depth=10的模型有些过拟合;而max_depth=6的模型训练集得分高,但是测试集得分有些低,略微过拟合。

我们还可以通过观察max_depth等于1到10的值来进行模型的性能对比,最后通过输出图形来看它们的表现。比如以后在其他场景中,读者也可以使用下述策略,会更好地找到最佳值模型。# 导入sklearn库的数据清洗与分割函数,验证曲线函数from sklearn.model_selection import ShuffleSplit, validation_curve# 定义模型在复杂度高的情况下性能表现的函数# 随着模型复杂度的增加计算它的性能表现def ModelComplexityPerformanceMetrics(X, y): # 清洗和分割数据对象定义 # 参数1:n_splits表示重新清洗和分割数据的迭代次数,默认值为10 # 参数2:test_size=0.2表示有0.2的数据用于测试,也就是20%的数据用于测试,80%的数据用于训练 # 参数3:random_state表示随机数生成器的种子,如果希望第二次调用ShuffleSplit()方法 # 的结果和第一次调用的结果一致,那么就可以设置一个值,多少都可以,生产环境不要设值 cv = ShuffleSplit(n_splits=10, test_size=0.2, random_state=0) # 定义从1到10为深度(max_depth)的参数值 max_depth = np.arange(1,11) # 通过不同的max_depth的参数值来计算训练集和测试集的分值 # 参数1:评估器,这里是决策树回归器 # 参数2:特征样本,房屋特征 # 参数3:目标标签,房屋价格 # 参数4:传入的深度参数名称 # 参数5:传入的深度参数范围值 # 参数6:交叉验证生成器,或可迭代对象 # 参数7:评分器,是一个可调用对象 train_scores, test_scores = \ validation_curve(DecisionTreeRegressor(), X, y, param_name="max_depth", param_range=max_depth, cv=cv, scoring='r2') # 计算训练集分值和测试集分值的均值 train_mean = np.mean(train_scores, axis=1) test_mean = np.mean(test_scores, axis=1) # 计算训练集分值和测试集分值的标准差 train_std = np.std(train_scores, axis=1) test_std = np.std(test_scores, axis=1) # 绘制验证分值的曲线图 # figsize表示要绘制的图形窗口大小,单位是英寸 plt.figure(figsize=(7, 5)) # 在绘制的图形窗口上添加一个标题 plt.title('Decision Tree Regressor Complexity Performance') # 绘制训练得分线,plot()方法 # 参数1:X轴方向的值 # 参数2:y轴方向的值 # 参数3:绘制出来的线的样式风格,比如这里的“o”表示一个圆点标记,而“-”表示实线 # 参数4:绘制的线的颜色 # 参数5:图例上的标题 plt.plot(max_depth, train_mean, 'o-', color='r', label='Training Score') # 绘制测试得分线 plt.plot(max_depth, test_mean, 'o-', color='g', label='Validation Score') # fill_between()方法表示为两条曲线描边,第一条是训练得分线,第二条是测试得分线 # 参数1:X轴方向的值 # 参数2:y轴方向的覆盖下限 # 参数3:y轴方向的覆盖上限 # 参数4:设置覆盖区域的透明度 # 参数5:设置覆盖区域的颜色 plt.fill_between(max_depth, train_mean - train_std, \ train_mean + train_std, alpha=0.15, color='r') plt.fill_between(max_depth, test_mean - test_std, \ test_mean + test_std, alpha=0.15, color='g') # 图上加标题注解 # 添加图例 plt.legend(loc='lower right') # 添加X轴的标题 plt.xlabel('Maximum Depth') # 添加y轴的标题 plt.ylabel('Score') # 设置y轴方向的最小值和最大值 plt.ylim([-0.05,1.05]) # 显示绘图 plt.show()ModelComplexityPerformanceMetrics(features, prices)

输出的图形如图1.7所示。图1.7 决策树回归器的模型性能表现

从结果图上看,max_depth的参数值在1到10中时,max_depth=4是最佳位置,当max_depth>4时模型表现就有些过拟合了。1.2.3 网格搜索模型

网格搜索最重要的功能就是能够自动调参,只要用户把参数传进去,它就能返回最优的结果模型和参数。它只适用于小数据集,同时还有一个缺点,那就是可能调参到局部最优,而不是全局最优。# 从sklearn库导入网格搜索VC、数据清洗与分割、决策树和分值计算对象的函数from sklearn.model_selection import GridSearchCV, ShuffleSplitfrom sklearn.tree import DecisionTreeRegressorfrom sklearn.metrics import make_scorer# 定义网格搜索最佳模型函数def gridSearchVC_fit_model(X, y): # 清洗和分割数据对象定义, # 参数1:n_splits表示重新清洗和分割数据的迭代次数,默认值为10 # 参数2:test_size=0.2表示有0.2的数据用于测试,也就是20%的数据用于测试,80%的数据用于训练 # 参数3:random_state表示随机数生成器的种子,如果希望第二次调用ShuffleSplit()方法 # 的结果和第一次调用的结果一致,那么就可以设置一个值,多少都可以,生产环境不要设值 cv = ShuffleSplit(n_splits=10, test_size=0.2, random_state=0) # 创建决策树回归器对象 regressor = DecisionTreeRegressor(random_state=0) # 创建一个字典,表示max_depth的参数值是从1到10 # 注意:如果代码运行的环境是Python 2,去掉这个list()函数调用 params = { "max_depth" : list(range(1, 10)) } # 通过make_scorer()函数将上面定义的performance_metric()函数转换成计算分值函数 scoring_fnc = make_scorer(score_func=performance_metric) # 创建网格搜索对象 # 参数1:评估器,就是回归器,这里表示的是决策树回归器 # 参数2:网格搜索参数 # 参数3:计算分值函数 # 参数4:cv(Cross-Validation)交叉验证,传入交叉验证生成器,或者可迭代对象 grid = GridSearchCV(estimator=regressor, param_grid=params, scoring=scoring_fnc, cv=cv) # 根据数据计算/训练适合网格搜索对象的最佳模型 grid = grid.fit(X, y) # 返回计算得到的最佳模型 return grid.best_estimator_# 网格搜索函数得到最佳模型reg = gridSearchVC_fit_model(X_train, y_train)print("参数max_depth={}是最佳模型。".format(reg.get_params()['max_depth']))

输出如下。参数max_depth=4是最佳模型。1.2.4 波士顿房价预测

在预测波士顿房价前,我们先做一个模拟客户数据来预测,数据如表1.1所示。表1.1 模拟房屋数据客户1# 小测验# 假设有以下3个客户的数据,分别是client_data = [[3, 30, 10], # 客户1 [7, 20, 19], # 客户2 [9, 2, 9]] # 客户3# 尝试预测for i, price in enumerate(reg.predict(client_data)): print("预测客户{}的销售价格是${:,.2f}".format(i+1, price))

输出如下。预测客户1的销售价格是$320,425.00预测客户2的销售价格是$410,658.62预测客户3的销售价格是$938,053.85

定义预测波士顿房价的函数,经过10次迭代,然后看下对比图。# 预测房价函数def PredictHousingPrice(X, y, fitter): # 迭代10次 epochs = 10 # 存储预测的价格 y_predict_test_price = None # 分割训练集和测试集数据,20%的数据用于测试,80%的数据用于训练 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) # 迭代训练 for epoch_i in range(epochs): # 根据数据训练模型,并返回最佳模型 reg = fitter(X_train, y_train) # 预测测试集数据 predicted_price = reg.predict(X_test) # 将预测到的结果存起来 y_predict_test_price = predicted_price print("迭代第{}次。".format(epoch_i+1)) return y_test, y_predict_test_pricey_true_price, y_predict_price = \PredictHousingPrice(features, prices, gridSearchVC_fit_model)

输出如下。迭代第1次。迭代第2次。迭代第3次。……迭代第9次。迭代第10次。

查看真实房价的前5行数据。我们先将y_true_price转换成Series对象,然后在调用reset_index()函数时就会把数据创建成一个新的Series,旧的索引就会被作为数据的一列,再通过drop()函数删除旧的索引那一列。pd.Series(y_true_price).reset_index().drop('index', axis=1).head()

输出如表1.2所示。表1.2 查看真实房价的前5行数据

我们再来看预测房价的前5行数据。pd.Series(y_predict_price).head()

输出如表1.3所示。表1.3 查看预测房价的前5行数据

构建真实房价和预测房价的对比图函数。# 显示真实房价和预测房价对比图def plotVersusFigure(y_true_price, y_predict_price): # 创建一个10×7的窗口 plt.figure(figsize=(10, 7)) # 绘制的图1是真实房价 X_show = np.rint(np.linspace(1, np.max(y_true_price), len(y_true_price)) ).astype(int) # 绘制图1线,plot()方法: # 参数1:X轴方向的值,真实房价从最低价到最高价 # 参数2:y轴方向的值,真实房价的值 # 参数3:绘制出来的线的样式风格,比如这里的“o”表示一个圆点标记,而“-”表示实线 # 参数4:绘制的线的颜色,这里是青色 plt.plot(X_show, y_true_price, 'o-', color='c') # 绘制的图2是预测房价,叠加在图1上 X_show_predicted = np.rint(np.linspace(1, np.max(y_predict_price), len(y_predict_price)) ).astype(int) # 绘制图2线,plot()方法: # 参数1:X轴方向的值,预测房价从最低价到最高价 # 参数2:y轴方向的值,预测房价的值 # 参数3:绘制出来的线的样式风格,比如这里的“o”表示一个圆点标记,而“-”表示实线 # 参数4:绘制的线的颜色,这里是洋红色 plt.plot(X_show_predicted, y_predict_price, 'o-', color='m') # 添加标题 plt.title('Housing Prices Prediction') # 添加图例 plt.legend(loc='lower right', labels=["True Prices", "Predicted Prices"]) # 添加X轴的标题 plt.xlabel("House's Price Tendency By Array") # 添加y轴的标题 plt.ylabel("House's Price") # 显示绘制 plt.show()

输出打印波士顿真实房价和预测房价的对比图。# 波士顿房屋价格对比图plotVersusFigure(y_true_price,y_predict_price)

输出如图1.8所示。图1.8 波士顿真实房价与预测房价对比图

通过结果可知,预测房价与真实房价之间是有一定误差的。这需要我们不断地调整参数并重新训练、预测等。1.2.5 北京房价预测

读取bj_housing.csv文件进行北京房价预测,其中一共有9999条数据。训练和预测使用的代码都在波士顿房价预测小节中详细介绍过,这里不再重复。所以本小节的代码就是读取数据,训练模型,预测和绘图显示。这里的北京房屋数据是真实的,但它的预测结果肯定受宏观环境等多种因素的影响,可能会造成预测结果不精准。读取数据代码如下。df=pd.read_csv('bj_housing.csv')df.describe()

输出如图1.9所示。图1.9 北京房价基本信息统计

数据的各列名称解释如下。

◇ Area:房屋面积,单位是平方米。

◇ Value:房屋售价,单位是万元。

◇ Room:房间数,单位是间。

◇ Living:厅数,单位是间。

◇ School:是否为学区房,0(表“否”)或1(表“是”)。

◇ Year:房屋建造年份。

◇ Floor:房屋所处楼层。

然后,将房屋特征数据集和真实价格数据集分开,代码如下。bj_prices=df['Value']bj_features=df.drop('Value',axis=1)bj_features.head()

房屋特征数据集前5行数据输出如图1.10所示。图1.10 北京房屋特征数据集前5行数据

根据数据训练和预测模型。y_true_bj_price,y_predict_bj_price=\PredictHousingPrice(bj_features,bj_prices,gridSearchVC_fit_model)

输出如下。迭代第1次。迭代第2次。迭代第3次。……迭代第9次。迭代第10次。

查看北京真实房价的前5行数据,先将y_true_bj_price转换成Series对象,然后在调用reset_index()时函数就会把数据创建成一个新的Series,旧的索引就会被作为该数据对象的一列,再通过drop()函数删除旧的索引那一列。y_true_bj_price.reset_index().drop('index',axis=1).head()

输出如表1.4所示。表1.4查看真实房价的前5行数据

我们再来看预测房价的前5行数据。pd.Series(y_predict_bj_price).head()

输出如表1.5所示。表1.5 查看预测房价的前5行数据

构建真实房价和预测房价的对比图。plotVersusFigure(y_true_bj_price,y_predict_bj_price)

绘制的结果如图1.11所示。图1.11 北京真实房价与预测房价对比图

通过对比图我们可以看到,预测房价与真实房价之间还是有一定误差的,这需要我们不断地去调整参数重新训练模型和预测等。1.3 基于Keras实现房价预测

前面我们使用scikit-learn机器学习库实现了房价预测。本节将使用神经网络模型来实现房价预测,使用的是TensorFlow下的Keras的API代码。我们将使用Keras创建模型、训练模型、预测和对比图预览。

Keras封装了一套高级的API用于构建深度学习模型,常用于快速实现原型设计和高级搜索。Keras对开发者的友好性、模块化、可组合性和易于扩展的关键特征,使其成为目前使用较为广泛的深度学习开源框架,它的后端之一就是TensorFlow。Keras在2015年12月份就将其以TensorFlow为后端的部分API融合到了TensorFlow框架中,所以目前我们可以通过tf.keras或者独立的Keras库来使用它。本书后面的章节会大量使用TensorFlow和Keras来构建深度学习模型。1.3.1 数据准备

我们通过TensorFlow提供的Keras接口下的datasets模块来加载数据集。数据集由卡内基梅隆大学维护,是波士顿近郊房价数据。读者也可以通过前言中的链接去查看后续更新的数据集。在tf.keras.datasets下加载的数据集和我们在链接中看到的数据集的格式是一样的,只是年份可能不同。加载数据集的代码如下。import tensorflow as tf# 从TensorFlow导入Keras模块from tensorflow import kerasimport numpy as np# 加载波士顿房价数据集(train_data, train_labels), (test_data, test_labels) = \keras.datasets.boston_housing.load_data()# 清洗训练集数据# np.random.random()表示返回在0.0到1.0之间指定个数的随机浮点数# np.argsort()表示返回对数组进行排序的索引order = np.argsort(np.random.random(train_labels.shape))train_data = train_data[order]train_labels = train_labels[order]# 归一化处理数据# 对不同的范围和比例进行归一化处理,并且每个元素都要减去均值后再除以标准差# 虽然模型在没有特征归一化时也可以得到收敛,但是这会让训练更加困难,# 而且会导致结果模型依赖于训练数据mean = train_data.mean(axis=0)

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载