第二章的再次思考

目录

一、数据的预处理
二、对于数据的思考
三、对于数据的再次思考
四、选择模型训练数据
附录

处理问题的整体思路

一、数据的预处理

导入需要使用的库

import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
import pandas as pd

运行此下代码

housing_data=pd.read_csv('housing.csv')
housing_data.info()
# 我们需要获得整体的信息

输出如下
>>

Data columns (total 10 columns):#   Column              Non-Null Count  Dtype
---  ------              --------------  -----  0   longitude           20640 non-null  float641   latitude            20640 non-null  float642   housing_median_age  20640 non-null  float643   total_rooms         20640 non-null  float644   total_bedrooms      20433 non-null  float645   population          20640 non-null  float646   households          20640 non-null  float647   median_income       20640 non-null  float648   median_house_value  20640 non-null  float649   ocean_proximity     20640 non-null  object
dtypes: float64(9), object(1)
memory usage: 1.6+ MB

我们可以看到对于total_bedrooms项是存在缺失值的,且ocean_proximity项的类型是object
我们需要在后续注意这些问题。
目前需要我们解决的问题有两个:缺失值问题、类型转化问题。我们逐一进行解决。

1.缺失值问题

我们面对缺失值主要有三个处理方法:
(1)进行缺失值的填充
(2)放弃有缺失值的测试案例
(3)放弃有缺失值的特征
这里我们选择缺失值的填充。当然这里我们缺失的数据很少,我们如果选择放弃也是没有问题的。

使用SimpleImputer来完成插值的工作

from sklearn.impute import SimpleImputer
imputer=SimpleImputer(strategy='median') # 使用中位数对数据进行填补
housing_data['total_bedrooms']=imputer.fit_transform(housing_data['total_bedrooms'].values.reshape(-1,1))
housing_data.info()

输出如下
>>

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20640 entries, 0 to 20639
Data columns (total 10 columns):#   Column              Non-Null Count  Dtype
---  ------              --------------  -----   0   longitude           20640 non-null  float64 1   latitude            20640 non-null  float64 2   housing_median_age  20640 non-null  float64 3   total_rooms         20640 non-null  float64 4   total_bedrooms      20640 non-null  float64 5   population          20640 non-null  float64 6   households          20640 non-null  float64 7   median_income       20640 non-null  float64 8   median_house_value  20640 non-null  float64 9   ocean_proximity     20640 non-null  object
dtypes: category(1), float64(9), object(1)
memory usage: 1.6+ MB

我们可以看到数据完成了填充。

2.处理object类型问题

对于数据来说我们机器更容易去处理数字的问题,同时我们观察到ocean_proximity中的数据输出是有限的,这个为我们的转化提供了条件。
我们使用OrdinalEncoder来进行处理

from sklearn.preprocessing import OrdinalEncoder
ordinal_encoder=OrdinalEncoder()
ocean_encoded=ordinal_encoder.fit_transform(housing_data['ocean_proximity'].values.reshape(-1,1))
ordinal_encoder.categories_
# 标记了类的类型

输出如下
>>

[array(['<1H OCEAN', 'INLAND', 'ISLAND', 'NEAR BAY', 'NEAR OCEAN'],dtype=object)]

这样我们就知道了转化成数字后的数字对应着什么意思。
至此我们就解决了我们看得到的数据问题。

二、对数据进行思考

1.我们直接通过直方图来看看数据分布的情况

mpl.rcParams['font.sans-serif']=['FangSong']
mpl.rcParams['axes.unicode_minus']=False # 设置字体,防止后续输入中文出错。
fig,ax=plt.subplots(3,3)
fig.set_dpi(200)for i in range(3):for j in range(3):ax[i,j].hist(housing_data.iloc[:,3*i+j],bins=np.linspace(np.min(housing_data.iloc[:,3*i+j]),np.max(housing_data.iloc[:,3*i+j]),50))ax[i,j].set_title(housing_data.columns[3*i+j],fontsize=9)plt.subplots_adjust(wspace=0.3,hspace=0.5)
plt.show()
#我们首先使用可视化的方法查看一下各个数据的分布情况。

输出如下
>>

根据图片我们就可以得到许多的信息。对于housing_median_age和median_house_value存在着一个阈值,超过阈值的都被放在一类了。
同时几乎对于每个特征都存在着极端值。
####2.使用相关矩阵来和散点图来查看可能存在的关系

# 使用相关性矩阵来查看相关性问题,不过这个就只能看出一一次的相关性,有些相关性会被埋没。
corr_matrix=housing_data.corr()
corr_matrix['median_house_value'].sort_values(ascending=False)

输出如下
>>

median_house_value,1.000000
median_income,0.688075
total_rooms,0.134153
housing_median_age,0.105623
households,0.065843
total_bedrooms,0.049686
population,-0.024650
longitude,-0.045967
latitude,-0.144160

我们发现这些数据中和median_house_value相关性较高的也只有三个,且median_income占主要的成分。
为了探索是否存在一次函数之外的关系,我们使用散点图直接查看。(当数据量过大时不宜使用)

# 数据集的大小不大,我们可以先观察各个之间是否存在相关性
from pandas.plotting import scatter_matrix
attributes=['median_house_value','median_income','total_rooms','housing_median_age']
scatter_matrix(housing_data[attributes],figsize=(12,8))
# 我们没有研究所有的变量,我们仅考察那些对房价的影响潜力较大的数据。

输出如下
>>

确实除了median_income之外其余各个数据之间的关系几乎是不存在的感觉。我们尝试其他方法进行尝试。

三、对数据再次进行处理

既然一次之间看不出关系,不妨我们看看是否和各个数据的平方和其他二次项是否存在着关系呢。
我们使用Polynomialfeatures进行实现,该类可以实现根据现有数据添加二次和高次的特征项。

# 现在来尝试来创造一些新的属性吧
from sklearn.preprocessing import PolynomialFeatures
poly=PolynomialFeatures()
housing_temporary=housing_data.drop(['latitude','longitude','ocean_proximity','income_cat','median_house_value'],axis=1)
housing_num=housing_temporary.values
housing_add=poly.fit_transform(housing_num)

接着我们用相关性矩阵来看看相关性

housing_ploy=pd.concat([housing_add,housing_data[['median_house_value','latitude','longitude']]],axis=1)
corr_matrix=housing_ploy.corr()
corr_matrix['median_house_value'].sort_values(ascending=False)
# 查看相关性的问题,我们新出现的一个数据似乎有着很好的相关性。

输出如下
>>

median_house_value,1.000000
median_income,0.688075
median_income^2,0.624514
housing_median_age median_income,0.589142
total_rooms median_income,0.376997
households median_income,0.352662
total_bedrooms median_income,0.338424
population median_income,0.276269
housing_median_age total_rooms,0.267332
housing_median_age households,0.158517
housing_median_age total_bedrooms,0.143108
total_rooms,0.134153
housing_median_age^2,0.119955
housing_median_age,0.105623
households,0.065843
total_rooms^2,0.064408
total_rooms households,0.052046
total_bedrooms,0.049457
total_rooms total_bedrooms,0.045810
households^2,0.037986
total_bedrooms households,0.034166
total_rooms population,0.028736
total_bedrooms^2,0.028708
housing_median_age population,0.021064
population households,0.010536
total_bedrooms population,0.007658
population^2,-0.010089
population,-0.024650
longitude,-0.045967
latitude,-0.144160
1,NAN

我们看到经过我们将特征扩展到二次的特征之后,我们的特征数量激增。但是同时我们也创造除了一些更加有用的特征。
(我们也可以通过两个特征做除法来进行添加特征,但是我就不再尝试了,这样也有可能获得很好的关系。)

四、选择模型处理数据

1.分割我们的数据集

对于数据集的分割我们可以使用train_test_split进行分割,代码如下。

# 下面我们分割数据集
y=housing_data['median_house_value']
X=housing_data.drop(['median_house_value'],axis=1)
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,random_state=42)
# 注意将随机数确定,保证每次都有着相同的数据集

但是对于train_test_split方法所有的抽取都是随机的。但是根据我们上面的分析发现median_income占据着影响
房价的主要方面,所以我们希望根据不同的收入区间来进行分层抽样。下面我们来实现根据房价分层抽样。
先看看median_income的分布情况。

# 我们决定将平均收入作为分层抽样的依据,那么我们再次绘制来看看
fig=plt.figure()
fig.set_dpi(150)
ax=fig.add_subplot(111)
ax.hist(housing_data.iloc[:,7],bins=np.linspace(np.min(housing_data.iloc[:,7]),np.max(housing_data.iloc[:,7]),20))
ax.set_title(housing_data.columns[7],fontsize=12)
# 在观察数据后我们为数据添加分层的标签

输出如下
>>

我们根据根据这个收入来为数据集添加一个新的新的特征,作为分层抽样的标准

# 进行数据的分层标签添加
housing_data['income_cat']=pd.cut(housing_data['median_income'],bins=[0,1.5,3.0,4,5,6.0,np.inf])
income_cat_count=housing_data['income_cat'].value_counts(sort=False)
plt.figure(dpi=150)
plt.bar(range(6),income_cat_count)
plt.xticks(range(6),income_cat_count.index)
plt.title('分层后的数据分布情况')
# 整体来说分层还是理想的,保持了正态分布的特点。

输出如下
>>

数据保持正态分布的感觉,说明我们选择的分层还不错。
根据新加入的income_cat来分层。

split=StratifiedShuffleSplit(n_splits=2,test_size=0.2,random_state=42)
start_train=[]
start_test=[]
for train_index, test_index in split.split(housing_ploy,housing_ploy['income_cat']):start_train=housing_ploy.loc[train_index]start_test=housing_ploy.loc[test_index]
# 这个分层抽样的原理就是临时添加一个train-index和test_index来实现抽样。
X_train = start_train.drop(['median_house_value','income_cat'],axis=1)
y_train = start_train['median_house_value']
X_test = start_test.drop(['median_house_value','income_cat'],axis=1)
y_test = start_test['median_house_value']

至此我们完成了数据集的分割。

2.选择模型来训练我们的数据集

先看看线性回归模型的效果

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
lin_pipeline=Pipeline([('std', StandardScaler()),('lin_reg',LinearRegression())
])
lin_pipeline.fit(X_train,y_train)

注意在采取回归模型时,一定要进行数据的归一化处理。
我们现在要考察这模型的效果,我们一般使用交叉验证的方法进行验证。

from sklearn.model_selection import cross_val_score
score=cross_val_score(lin_pipeline,X_train,y_train,scoring='neg_mean_squared_error',cv=10)
np.sqrt(-score.mean())
# 我们的训练模型效果挺一般的,可以看出会有很大的偏差了。

输出如下
>>

71134.26227024043

这个结果只能说是差强人意了。

看看随机森林的效果

# 采用随机森林进行测试
from sklearn.ensemble import RandomForestRegressor
forest_reg=RandomForestRegressor()
forest_reg.fit(X_train,y_train)
score=cross_val_score(forest_reg,X_train,y_train,scoring='neg_mean_squared_error',cv=10)
np.sqrt(-score.mean())
# 看来随机森林的效果好了不少的

输出如下
>>

51301.609169123614

我们就仅仅试验这两个方法吧,显然随机森林更加好,我们对随机森林的模型进行一些超参数的调整,看看能不能
找到一个最好值,我们采用GridSearchCV的方法实现。

# 随机森林还好一点,看看使用网格搜索是否可以得到最好值
from sklearn.model_selection import GridSearchCV
param_grid=[{'n_estimators':np.arange(250,350,15),'max_depth':np.arange(14,20),'max_features':[8,9,10,11]}
]
grid_search=GridSearchCV(forest_reg,param_grid=param_grid,cv=5,scoring='neg_mean_squared_error',return_train_score=True
)
grid_search.fit(X_train,y_train)
grid_search.best_estimator

想法很好,但是最后输出的结果还不如原来训练结果(寻找的时间也是很长的,如果拥有足够的时间,去慢慢搜索也是可以的),所以我们使用原来的结果。并且使用joblib库进行我们模型的保存,方便之后的调用等。

forest_reg=RandomForestRegressor()
forest_reg.fit(X_train,y_train)
import joblib
joblib.dump(forest_reg,'forest.pkl')

至此我们对于房价问题的研究就结束了。

附录

这篇笔记中没有提及但是也十分重要的问题:
1.关于模型的泛化问题,有些模型对于数据有着过拟合的倾向。对于这种问题我们可以通过调节模型中的超参数,或者对我们的数据进行降维减少特征量。
2.数据的特征不是越多就越好,过于多的数据特征会减慢我们的模型速度,而且不一定会得到好的效果,增加维度要谨慎的选择。
3.我们在选择模型时应当多选择几个模型来试验,我这里仅选了两个还是比较少的。
4.对于数据的思考是十分重要的,在训练之前的思考可以为我们创造很好的效果。
5.遇到问题一定要去查询官方文档,在百度上搜索经常会造成大量的时间浪费,官方文档可以解决大部分问题。
6.本文的数据、代码以及PDF版链接
链接:https://pan.baidu.com/s/1uRmh73yBDRv_MiYNT6fWjg
提取码:0k5e

对机器学习实战第二章内容的思考相关推荐

  1. 机器学习实战第二章——KNN算法(源码解析)

    机器学习实战中的内容讲的都比较清楚,一般都能看懂,这里就不再讲述了,这里主要是对代码进行解析,如果你很熟悉python,这个可以不用看. #coding=utf-8 ''' Created on 20 ...

  2. 机器学习实战-第二章代码+注释-KNN

    #-*- coding:utf-8 -*- #https://blog.csdn.net/fenfenmiao/article/details/52165472 from numpy import * ...

  3. 机器学习实战第二章K近邻算法照葫芦画瓢实践。

    分别实现了最基本的3个DEMO 1.给你若干个带有标签的二维点作为训练集,给定一系列的二维随机点,看其通过训练集,可以被分为哪一类 2.给你N个人的飞行里程数,玩游戏消耗时间百分比和每周消耗冰激凌的公 ...

  4. 基于python的界面自动化测试-基于Python语言的自动化测试实战第二章(上)

    原标题:基于Python语言的自动化测试实战第二章(上) 测试环境搭建 2.1 Windows 下的环境搭建 如果想要学习一门编程语言,对于新手来说只需到其官方网站上去下载最新版本安装即可,但对于想要 ...

  5. 认识机器学习 机器学习实战第一章

    学习目标 机器学习实战第一章 学习内容 1. 什么是机器学习? 答:简单地说,机器学习就是把无序的数据转换成有用的信息. 2. 数据来源? 从互联网上可以获取大量的人为数据,比如某用户的购物记录,刷过 ...

  6. 统计机器学习导论第二章答案

    R语言学习笔记 统计机器学习导论第二章部分习题 文章目录 R语言学习笔记 一.8题 8. This exercise relates to the College data set, which ca ...

  7. 【机器学习实战 第九章】树回归 CART算法的原理与实现 - python3

    本文来自<机器学习实战>(Peter Harrington)第九章"树回归"部分,代码使用python3.5,并在jupyter notebook环境中测试通过,推荐c ...

  8. 吴恩达机器学习(第二章)——单变量线性回归

    第二章-单变量线性回归 文章目录 第二章-单变量线性回归 模型描述 代价函数 梯度下降 梯度下降的思想 梯度下降算法的公式 梯度下降的运动方式 线性回归的梯度下降 模型描述 在监督学习中我们有一个数据 ...

  9. linux VCS+verdi运行UVM实战(第二章)中的例子

    目录 前言 介绍 建立工程 运行代码 查看波形 总结 前言 用VCS+verdi运行了下UVM实战中的例子(第二章). 介绍 在某宝上花了几十块,买了个虚拟机(已经安装好VCS+verdi).直接用U ...

  10. 云计算虚拟化技术与开发-------虚拟化技术应用第二章内容(CPU虚拟机X86要解决的问题、VT-x、VMX、vCPU、EPT、VT-d)

    目录 第二章:虚拟化实现技术架构 CPU虚拟机要解决的问题(x86处理器结构漏洞)及软硬件解决方案 intel VT-x的技术特点,VMX(非根操作)的操作模式及操作流程 vCPU的组成和基本操作 内 ...

最新文章

  1. J2EE从servlet开始
  2. 一行代码集成带负数的自定义键盘
  3. 用python绘制漂亮的图形-用Python画一些漂亮图形--Quora代码赏析
  4. Python的setuptools详解【3】打包wheel并提交给pypi
  5. DL之YoloV2:Yolo V2算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略
  6. Linux Tomcat 6.0安装配置实践总结
  7. python如何处理视频_OpenCV-Python系列之视频处理入门
  8. java paint调用,求教 如何调用这个paint
  9. 【英语学习】【English L06】U07 Jobs L5 Work overtime
  10. 微服务分布式学到这种程度,稳了!
  11. 万圣节海报设计没有思路?看看这些有趣的万圣节狂欢是如何完成的!
  12. 五款热门Android手机性能测试 Nexus S大胜
  13. 这届互联网公司月饼:阿里卡哇伊,百度酷炫风,京东乾隆审美……
  14. 怎样选择mysql的版本升级_mysql版本升级
  15. CDOJ 1157 数列(seq) 分块+线段树
  16. 弱电工程行业管理软件
  17. 格力机器人图解_你所不知道的格力机器人战略
  18. SAT考试填空习题(一)及答案
  19. 干货 | CoAP协议例析
  20. 计算机如何默认一种打字法,如何设置输入法,教您如何设置电脑的默认输入法...

热门文章

  1. Java面试题中高级,java简历技术栈怎么写
  2. 工控安全之勒索病毒篇
  3. cad打开a3样板图形_cad开始怎样设置A3纸?
  4. 服务器2008修改端口,Windows Server 2008 R2需要修改445端口
  5. 华为java安全编程规范考试答案
  6. java程序员到J2EE架构师
  7. mysql数据库更新数据库语句_MySQL数据库之UPDATE更新语句精解
  8. IIS开启了GZIP和XCACHE之后飞快
  9. Linux系统配置静态IP地址步骤
  10. 内外网同时运行路由设置