1 什么是机器学习?

给定一组(x(i), y(i)),给定一个模型,将x(i)输入模型后得到y(i)^
计算y(i)和y(i)^的差距,差距越小,模型越优。
通过不断地优化模型,使得差距越来越小,这就是机器学习

2 分类与回归

在上述例子中,y的值有可能是连续的,也有可能离散的。
离散的指的是y值之间没有大小关系。如打分1,2,3,4,5,虽然是数学意义上的离散,但是因为有大小关系,因此不是离散。
如果y的值是连续的,则是回归问题;如果y的值是离散的,则是分类问题。

3 过拟合与欠拟合


过拟合与欠拟合在图形上可以很容易看出来,图中1阶为欠拟合,8阶为过拟合,
而在数学表现上,可以看到图像上的参数如下:

1阶,系数为: [-12.12113792 3.05477422]
2阶,系数为: [-3.23812184 -3.36390661 0.90493645]
3阶,系数为: [-3.90207326 -2.61163034 0.66422328 0.02290431]
4阶,系数为: [-8.20599769 4.20778207 -2.85304163 0.73902338 -0.05008557]
5阶,系数为: [ 21.59733285 -54.12232017 38.43116219 -12.68651476 1.98134176 -0.11572371]
6阶,系数为: [ 14.73304785 -37.87317494 23.67462342 -6.07037979 0.42536833 0.06803132 -0.00859246]
7阶,系数为: [ 314.30344622 -827.89446924 857.33293186 -465.46543638 144.21883851 -25.67294678 2.44658612 -0.09675941]
8阶,系数为: [-1189.50149198 3643.69109456 -4647.92941149 3217.22814712 -1325.87384337 334.32869072 -50.57119119 4.21251817 -0.148521 ]

可以看到,1 - 4阶的参数比较正常,而后面几阶的参数绝对值非常大,参数绝对值大,那么x的值稍微有一点变化,则结果变化会非常大,也就是过拟合。

4 使用线性回归分析波士顿房价

4.1 导入数据

波士顿房价的数据集网上有,这里用的是.data格式的,大概形式如下:

我们可以看到这里的数据不是csv或Excel格式,并且分隔不是用的’,’,而是用的tab(空格),并且每个数据间的空格数量不同。我们尝试使用之前的pd.read_csv读取数据,并用空格分隔数据:

import pandas as pdif __name__ == '__main__':data = pd.read_csv('housing.data', sep=' ')print(data)

可以看到报错如下:


原因是分隔使用的空格,数量不相等,pandas无法使用空格将数据分开。
一个比较简单粗暴的修改方式是,使用替换功能,将数据中的所有连续两个空格替换成一个空格,重复多次后,数据的分隔就全部变成一个空格了。这种方式不太好,因为我们改变了原数据。
而另一个解决方式是使用正则表达式,
将第四行改成

    data = pd.read_csv('housing.data', sep='\s+', header=None)

这里的'\s+'就是使用的正则表达式,后面的header=None的意思是告诉pandas我们的数据没有数据头。
运行就可以得到我们的数据:

前面的0-12列就是我们的x,13列是y。
使用以下代码给x和y赋值:

    x,y = data.loc[:, :12], data.loc[:, 13] # loc的slice首尾都包括# x, y = data[np.arange(13)], data[13]

这样我们就把housing.data文件里的数据成功赋值给x和y了。

4.2 模型计算

使用from sklearn.linear_model import LinearRegression进行线性模型引入(未安装的话需要在cmd命令行输入pip install scikit-learn安装)。
输入如下代码:

    model = LinearRegression()  # 调用构造函数print(model)model.fit(x, y)print('系数:', model.coef_)print('截距:', model.intercept_)y_pred = model.predict(x)

代码第一行调用了LinearRegression中的构造函数,这里只是构造了,还没有给model喂数据,所以第二行打印的输出为LinearRegression()
第三行将刚才获取到的x和y喂给模型,然后我们就可以得到模型的系数和截距。
最后一行的y_pred 就是我们通过模型得到的y的预测值。
我们可以使用print(np.mean((y-y_pred)**2))计算MSE
也可以通过导入包from sklearn.metrics import mean_squared_error, mean_absolute_error,使用系统提供的方法直接计算相关值。
使用如下代码:

    # print(np.mean((y - y_pred) ** 2))mse = mean_squared_error(y, y_pred)rmse = math.sqrt(mse)mae = mean_absolute_error(y, y_pred)print('MES = %.3f, RMSE = %.3f, MAE = %.3f' % (mse, rmse, mae))

这里有一个rmse,计算这个值的意义在于,我们计算的mse实际上是一个平方值,比如说我们的数据中y的单位为千元每平方,那么mse的单位就是(千元每平方)的平方,这样不直观也不好理解,因此我们这里对mse开方。

以上内容完整代码如下:

import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, mean_absolute_errorif __name__ == '__main__':data = pd.read_csv('housing.data', sep='\s+', header=None)print(data)x,y = data.loc[:, :12], data.loc[:, 13] # loc的slice首尾都包括# x, y = data[np.arange(13)], data[13]print('X = ', x)print('Y = ', y)model = LinearRegression()  # 调用构造函数print(model)model.fit(x, y)print('系数:', model.coef_)print('截距:', model.intercept_)y_pred = model.predict(x)# print(np.mean((y - y_pred) ** 2))mse = mean_squared_error(y, y_pred)rmse = math.sqrt(mse)mae = mean_absolute_error(y, y_pred)print('MES = %.3f, RMSE = %.3f, MAE = %.3f' % (mse, rmse, mae))

4.3 划分训练集与测试集

在之前的例子中,我们把全部的506组数据都作为训练集对波士顿房价进行了学习,而在实际过程中,我们需要一部分数据作为训练集,一部分内容作为测试集。
我们采用的做法是,首先打乱数据集的顺序,然后选取前20%作为测试集,后80%作为训练集,代码如下:

    m, _ = data.shape   # 获取data的行数index = np.arange(m)print(index)np.random.shuffle(index)print(index)test_size = int(m*0.2)test_data = data.loc[index[:test_size], :]print(test_data)train_data = data.loc[index[test_size:], :]print(train_data)

这段代码首先获取了数据的行数,然后使用index作为每行数据的索引,使用np.random.shuffle(index)打乱index的顺序后,再选取index指向的数据中的前20%作为测试集,后80%作为训练集。

当然,sklearn包中也提供了直接供我们调用的方式来对数据集进行划分,导入包from sklearn.model_selection import train_test_split后,使用如下代码:

 x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)

这句话的意思是将x按照测试集占总数据20%的比例进行划分,其中两部分的名称分别为x_train,x_test,y同。
这里要注意,使用train_test_split时,划分的结果的第一个是训练集,第二个是测试集。

划分好后,我们仍然用4.2提到的方式,将训练集喂给模型,之后用训练好的模型来预测测试集的结果,并进行比对。完整代码如下:

import math
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, mean_absolute_error
from sklearn.model_selection import train_test_splitif __name__ == '__main__':np.set_printoptions(suppress=True)   # 强制输出格式为浮点数data = pd.read_csv('housing.data', sep='\s+', header=None)print(data)x,y = data.loc[:, :12], data.loc[:, 13] # loc的slice收尾都包括x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)print(x_test, x_train)model = LinearRegression()  # 调用构造函数print(model)model.fit(x_train, y_train)print('训练集系数:', model.coef_)print('训练集截距:', model.intercept_)y_train_pred = model.predict(x_train)mse_train = mean_squared_error(y_train, y_train_pred)rmse_train = math.sqrt(mse_train)mae_train = mean_absolute_error(y_train, y_train_pred)print('训练集MSE = %.3f, RMSE = %.3f, MAE = %.3f' % (mse_train, rmse_train, mae_train))y_test_pred = model.predict(x_test)mse_test = mean_squared_error(y_test, y_test_pred)rmse_test = math.sqrt(mse_test)mae_test = mean_absolute_error(y_test, y_test_pred)print('测试集MSE = %.3f, RMSE = %.3f, MAE = %.3f' % (mse_test, rmse_test, mae_test))

在以上代码中,第19行使用了训练集对模型进行训练。
22行使用模型对训练集进行了预测;并在28行计算了训练集的MSE等值进行了输出。
30行使用模型对测试集的数据进行了预测,并在36行对使用该模型预测的结果与实际值进行了对比。

我的运行结果如下:

4.4 数据结果显示

在机器学习的过程中,我们不仅要看模型的学习结果,另一个我们想了解的内容还包括了模型最终的系数分别对应的值,以及这些值中,哪些更重要,对结果的影响更大。
因此我们在刚才的代码中,在一开始的读取data的部分,可以添加一些代码来将每个属性的名称显示出来。
将开头读取数据的代码做如下更改:

    np.set_printoptions(suppress=True)pd.set_option('display.width', 1000)pd.set_option('display.max_columns', 30)col_names = ['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV']data = pd.read_csv('housing.data', sep='\s+', header=None, names = col_names)print(data)

打印结果如图:

修改后,刚才关于x和y值的选取也需要做相应修改:

    x,y = data[col_names[:-1]], data['MEDV']

这句话的意思是x的取值为data中除了最后一列以外所有的列,而y的取值为data中名为’MEDV’的一列。

在我们将训练集喂给模型后,我们会得到训练集的系数,也就是各个属性值的权重,我们加入如下代码:

    t = pd.DataFrame(data=model.coef_, index=list(x.columns), columns=['权重'])t['权重绝对值'] = np.abs(t['权重'])t.sort_values(by='权重绝对值', ascending=False, inplace=True)print(t['权重'])

以上代码的第一行是给我们训练集的系数添加了一个列名“权重”,然后添加了一列“权重绝对值”,之后根据权重绝对值对系数进行一个降序的排序,我的输出结果如下:

从这个结果中可以看到,NOX这个值可能对房价的影响最大,并且与房价呈一个负相关的关系,而AGE这个值可能对房价的影响最小。

4.5 模型优化

之前我们得到了13个属性的一次幂对结果的权重,那么有没有可能这些属性值的二次幂对结果的影响更大呢?这里我们可以对代码稍作修改,添加以下代码:

    for col in col_names[:-1]:data[col+'2'] = data[col]**2# x,y = data[col_names[:-1]], data['MEDV']x = data.drop(labels='MEDV', axis=1)y = data['MEDV']

通过for循环,将data中的各项属性值的平方放到data后面,列名称为col_names中各项后面加“2”;第5行代码,将data中除了名称为MEDV以外的列全部加入x,drop后面的axis,为0表示按行删除,1表示按列删除,默认是0;第6行将data中的MEDV列加入y。
运行结果如下:

可以看到运行结果要优于4.3中的结果。

在python的sklearn中,可以使用Pipeline实现以上的过程(Pipeline的具体使用方式后面的文章会讲),需要引入以下包:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures

初始化模型时,用以下语句:

    model = Pipeline([('poly', PolynomialFeatures(degree=2)),('LinearRegression', LinearRegression())])

在获取权重和截距时,使用以下语句:

    print("权重:", model.get_params()['LinearRegression'].coef_)print("截距:", model.get_params()['LinearRegression'].intercept_)

运行结果如下:

可以看到,截距非常大,权重的第一个值也非常大,这个结果显然是过拟合的。

继续优化,可以使用sklearn中的MinMaxScaler,使用数据归一化的方式优化我们的数据,关于数据归一化的内容具体可以看这篇博文。添加以下包:

from sklearn.preprocessing import PolynomialFeatures, MinMaxScaler

修改模型:

    model = Pipeline([('mms', MinMaxScaler()),('poly', PolynomialFeatures(degree=2)),('LinearRegression', LinearRegression())])

运行结果有的时候会很好,有的时候很差,跟我们的随机选取的训练集有关,较好的结果如下:

差的结果如下:

也可以不用LinearRegression,而使用Ridge或者Lasso来回归,加入包:

from sklearn.linear_model import LinearRegression, Ridge, Lasso

初始化模型改为:

    model = Pipeline([('mms', MinMaxScaler()),('poly', PolynomialFeatures(degree=2)),# ('LinearRegression', LinearRegression())('ridge', Ridge(alpha=1.0))])

输出改为:

    print("权重:", model.get_params()['ridge'].coef_)print("截距:", model.get_params()['ridge'].intercept_)

运行结果如下:

本节最终代码如下:

import math
import numpy as np
import pandas as pd
import sklearn
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.metrics import mean_squared_error, mean_absolute_error
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures, MinMaxScalerif __name__ == '__main__':np.set_printoptions(suppress=True)pd.set_option('display.width', 1000)pd.set_option('display.max_columns', 30)np.set_printoptions(suppress=True, linewidth=150)col_names = ['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV']data = pd.read_csv('housing.data', sep='\s+', header=None, names = col_names)print(data)# m, _ = data.shape   # 获取data的行数# index = np.arange(m)# print(index)# np.random.shuffle(index)# print(index)# test_size = int(m*0.2)# test_data = data.loc[index[:test_size], :]# print(test_data)# train_data = data.loc[index[test_size:], :]# print(train_data)model = Pipeline([('mms', MinMaxScaler()),('poly', PolynomialFeatures(degree=2)),# ('LinearRegression', LinearRegression())('ridge', Ridge(alpha=1.0))])# x,y = data.loc[:, :12], data.loc[:, 13] # loc的slice收尾都包括# x, y = data[np.arange(13)], data[13]# for col in col_names[:-1]:#     data[col+'2'] = data[col]**2# x,y = data[col_names[:-1]], data['MEDV']x = data.drop(labels='MEDV', axis=1)y = data['MEDV']x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)# print(x_test, x_train)# model = LinearRegression()  # 调用构造函数# print(model)model.fit(x_train, y_train)# print('训练集系数:', model.coef_)# print('训练集截距:', model.intercept_)print("权重:", model.get_params()['ridge'].coef_)print("截距:", model.get_params()['ridge'].intercept_)# t = pd.DataFrame(data=model.coef_, index=list(x.columns), columns=['权重'])# t['权重绝对值'] = np.abs(t['权重'])# t.sort_values(by='权重绝对值', ascending=False, inplace=True)# print(t['权重'])y_train_pred = model.predict(x_train)# print(np.mean((y - y_pred) ** 2))mse_train = mean_squared_error(y_train, y_train_pred)rmse_train = math.sqrt(mse_train)mae_train = mean_absolute_error(y_train, y_train_pred)print('训练集MSE = %.3f, RMSE = %.3f, MAE = %.3f' % (mse_train, rmse_train, mae_train))y_test_pred = model.predict(x_test)mse_test = mean_squared_error(y_test, y_test_pred)rmse_test = math.sqrt(mse_test)mae_test = mean_absolute_error(y_test, y_test_pred)print('测试集MSE = %.3f, RMSE = %.3f, MAE = %.3f' % (mse_test, rmse_test, mae_test))

同样也可以使用lasso来进行回归。

python学习笔记 4 - 线性回归、波士顿房价数据分析相关推荐

  1. 【Python学习笔记—保姆版】第四章—关于Pandas、数据准备、数据处理、数据分析、数据可视化

    第四章 欢迎访问我搞事情的[知乎账号]:Coffee 以及我的[B站漫威剪辑账号]:VideosMan 若我的笔记对你有帮助,请用小小的手指,点一个大大的赞哦. #编译器使用的是sypder,其中&q ...

  2. MOOC网深度学习应用开发1——Tensorflow基础、多元线性回归:波士顿房价预测问题Tensorflow实战、MNIST手写数字识别:分类应用入门、泰坦尼克生存预测

    Tensorflow基础 tensor基础 当数据类型不同时,程序做相加等运算会报错,可以通过隐式转换的方式避免此类报错. 单变量线性回归 监督式机器学习的基本术语 线性回归的Tensorflow实战 ...

  3. 深度学习经典入门项目—波士顿房价预测

    目录 房价预测--线性回归 数据处理 数据形状变换 数据集划分 数据归一化处理 housing.data数据格式 模型设计 线性回归模型设计 训练配置 训练过程 保存并测试模型 保存模型 测试模型 房 ...

  4. python学习笔记目录

    人生苦短,我学python学习笔记目录: week1 python入门week2 python基础week3 python进阶week4 python模块week5 python高阶week6 数据结 ...

  5. python基本语法语句-python学习笔记:基本语法

    原标题:python学习笔记:基本语法 缩进:必须使用4个空格来表示每级缩进,支持Tab字符 if语句,经常与else, elif(相当于else if) 配合使用. for语句,迭代器,依次处理迭代 ...

  6. Python学习笔记之类型判断,异常处理,终止程序操作小结

    Python学习笔记之类型判断,异常处理,终止程序操作小结 运行结果: 这里有我自己整理了一套最新的python系统学习教程,包括从基础的python脚本到web开发. 爬虫.数据分析.数据可视化.机 ...

  7. 数据挖掘学习笔记 5 线性回归知识及预测糖尿病实例

    #2018-03-21 16:45:01 March Wednesday the 12 week, the 080 day SZ SSMR http://blog.csdn.net/eastmount ...

  8. Python学习笔记六——画小猪佩奇

    目录 Python学习笔记六--画小猪佩奇 画布 画笔 属性设置 操纵命令 运动命令 画笔控制命令 全局控制命令 其他命令 Python学习笔记六--画小猪佩奇 使用Python的turtle库可以绘 ...

  9. OpenCV之Python学习笔记

    RSS订阅 登陆 注册 原文链接地址:http://www.itozi.net/19477.html OpenCV之Python学习笔记 ITOZI 发布于 2015-08-06 分类:OpenSta ...

最新文章

  1. 对人工神经网络“开刀”,利用神经科学消融法检测人工神经网络
  2. python的类型 变量 数值和字符串
  3. Python遍历目录的4种方法
  4. VTK修炼之道2_VTK体系结构1
  5. lnmp一键包502 Bad Gateway解决方法
  6. 转 .NET 2.0 SqlDependency快速上手指南
  7. nagios mysql 监控_nagios监控mysql
  8. asp.net 2.0 防止密码框被清空的解决方案
  9. libevent的线程优雅的退出方式
  10. Android自定义View—刮刮卡效果
  11. 【bzoj4987】Tree【树形dp】
  12. MATLAB的图像显示函数imshow()详解
  13. 面试官:Java的重写和重载有什么区别?
  14. wow.js动画插件
  15. 2021年最新3d材质贴图素材大合集来咯
  16. error和exception区别,throw和throws
  17. 银行业务中台这么搞,新产品上线提速60%
  18. Error response from daemon: conflict: unable to delete a9ac6b268134 (must be forced) - image is bein
  19. Java版Word开发工具Aspose.Words功能解析:查找和替换Word文档中的文本
  20. Ubuntu18.04 安装QQ、Tim、微信与win无差异

热门文章

  1. 手牵手,使用uni-app从零开发一款视频小程序 (系列上 准备工作篇)
  2. 分子对接教程 | (4) 蛋白受体文件的预处理
  3. 函数内部的this指向/call()方法
  4. thinkphp使用phpoffice读取Excel并写入数据库
  5. 【Python简明教程二十八】PIP
  6. Windows server 2008、2012、2016、2019搭建sftp服务(超级简单)
  7. 电子书——人类进步的电梯
  8. 大二在读,身为女生我该选择读研还是直接工作?
  9. SpringMVC——文件上传下载,异步请求和SSM整合
  10. 微信小程序进行加减法运算的小技巧