大年初四了,哈哈,年快过完了,这套DC学院的《数据分析》课程也快要KO了( ̄︶ ̄)↗
一、探索型数据分析
1. 导入数据
import pandas as pd
import numpy as np
%matplotlib notebook
housing_df = pd.read_csv('housing.csv')#具体路径为housing.csv文件保存的绝对路径
housing_df.head(5)
Id | MSSubClass | MSZoning | LotFrontage | LotArea | Street | Alley | LotShape | LandContour | Utilities | ... | PoolArea | PoolQC | Fence | MiscFeature | MiscVal | MoSold | YrSold | SaleType | SaleCondition | SalePrice | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 60 | RL | 65.0 | 8450 | Pave | NaN | Reg | Lvl | AllPub | ... | 0 | NaN | NaN | NaN | 0 | 2 | 2008 | WD | Normal | 208500 |
1 | 2 | 20 | RL | 80.0 | 9600 | Pave | NaN | Reg | Lvl | AllPub | ... | 0 | NaN | NaN | NaN | 0 | 5 | 2007 | WD | Normal | 181500 |
2 | 3 | 60 | RL | 68.0 | 11250 | Pave | NaN | IR1 | Lvl | AllPub | ... | 0 | NaN | NaN | NaN | 0 | 9 | 2008 | WD | Normal | 223500 |
3 | 4 | 70 | RL | 60.0 | 9550 | Pave | NaN | IR1 | Lvl | AllPub | ... | 0 | NaN | NaN | NaN | 0 | 2 | 2006 | WD | Abnorml | 140000 |
4 | 5 | 60 | RL | 84.0 | 14260 | Pave | NaN | IR1 | Lvl | AllPub | ... | 0 | NaN | NaN | NaN | 0 | 12 | 2008 | WD | Normal | 250000 |
5 rows × 81 columns
注意:
- 这里使用%matpoltlib notebook将绘制的图片内嵌在交互窗口,并且可以方便进一步操作和保存(新绘制另一张图形的时候需要首先点击关闭上一张图形)
- 数据集下载链接: https://pan.baidu.com/s/1htSLy2g 密码: kdkh
2. 查看数据的属性
print(housing_df.columns)
Index(['Id', 'MSSubClass', 'MSZoning', 'LotFrontage', 'LotArea', 'Street',
'Alley', 'LotShape', 'LandContour', 'Utilities', 'LotConfig',
'LandSlope', 'Neighborhood', 'Condition1', 'Condition2', 'BldgType',
'HouseStyle', 'OverallQual', 'OverallCond', 'YearBuilt', 'YearRemodAdd',
'RoofStyle', 'RoofMatl', 'Exterior1st', 'Exterior2nd', 'MasVnrType',
'MasVnrArea', 'ExterQual', 'ExterCond', 'Foundation', 'BsmtQual',
'BsmtCond', 'BsmtExposure', 'BsmtFinType1', 'BsmtFinSF1',
'BsmtFinType2', 'BsmtFinSF2', 'BsmtUnfSF', 'TotalBsmtSF', 'Heating',
'HeatingQC', 'CentralAir', 'Electrical', '1stFlrSF', '2ndFlrSF',
'LowQualFinSF', 'GrLivArea', 'BsmtFullBath', 'BsmtHalfBath', 'FullBath',
'HalfBath', 'BedroomAbvGr', 'KitchenAbvGr', 'KitchenQual',
'TotRmsAbvGrd', 'Functional', 'Fireplaces', 'FireplaceQu', 'GarageType',
'GarageYrBlt', 'GarageFinish', 'GarageCars', 'GarageArea', 'GarageQual',
'GarageCond', 'PavedDrive', 'WoodDeckSF', 'OpenPorchSF',
'EnclosedPorch', '3SsnPorch', 'ScreenPorch', 'PoolArea', 'PoolQC',
'Fence', 'MiscFeature', 'MiscVal', 'MoSold', 'YrSold', 'SaleType',
'SaleCondition', 'SalePrice'],
dtype='object')
属性的详细说明在文件中了,这里省略。
3. 绘制房屋价格分布图
import seaborn as sns
sns.distplot(housing_df['SalePrice'])
<IPython.core.display.Javascript object>
<matplotlib.axes._subplots.AxesSubplot at 0x223691f3e48>
- 房屋价格对应的属性是’SalePrice’
- 可以从图中看到,SalePrice的分布图大致服从右偏态分布,平均数大于中位数
- 大部分房屋价格在100000到300000之间
- 有少量的房屋价格大于500000
4. 绘制居住面积分布图
sns.distplot(housing_df['GrLivArea'])
<IPython.core.display.Javascript object>
<matplotlib.axes._subplots.AxesSubplot at 0x22369b44cc0>
- 居住面积对应的属性是’GrLivArea’
- 大部分房屋的居住面积在800到2000之间
- 有少量的房屋居住面积大于4000
5. 地下室面积分布图
sns.distplot(housing_df['TotalBsmtSF'])
<IPython.core.display.Javascript object>
<matplotlib.axes._subplots.AxesSubplot at 0x2236a7b4828>
- 地下室面积对应的属性是’TotalBsmtSF’
- 有一部分的房屋地下室面积为0,也就是没有地下室
6. 探索连续型变量之间的相关性
可以使用seaborn的regplot方法,探索探索两个连续型变量之间的相关性。
#连续变量之间的相关性
sns.regplot(x='GrLivArea', y='SalePrice', data=housing_df)
sns.regplot(x='TotalBsmtSF', y='SalePrice', data=housing_df)
<IPython.core.display.Javascript object>
<matplotlib.axes._subplots.AxesSubplot at 0x2236a207c50>
- 从代码生成的图中可以看到,GrLivArea和SalePrice呈现明显的正相关关系
- 从代码生成的图中可以看到,TotalBsmtSF和SalePrice呈现明显的正相关关系
7. 探索离散型变量和连续型变量之间的相关性
可以使用seaborn的boxplot方法,探索离散型变量和连续型变量之间的相关性。
使用regplot绘制OverallQual和SalePrice之间的关系,比较跟boxplot的区别
#离散变量和连续变量之间的相关性
sns.regplot(x='OverallQual', y='SalePrice', data=housing_df)
<IPython.core.display.Javascript object>
<matplotlib.axes._subplots.AxesSubplot at 0x2236bce10b8>
#使用boxplot绘制OverallQual和SalePrice之间的关系
sns.boxplot(x='OverallQual', y='SalePrice', data=housing_df)
#使用boxplot绘制CentralAir和SalePrice之间的关系
##sns.boxplot(x='CentralAir', y='SalePrice', data=housing_df)
#使用boxplot绘制Neighborhood和SalePrice之间的关系
##sns.boxplot(x='Neighborhood', y='SalePrice', data=housing_df)
<IPython.core.display.Javascript object>
<matplotlib.axes._subplots.AxesSubplot at 0x2236c2f3c18>
8. 绘制相关系数矩阵热力图
从housing_df数据框中挑选出SalePrice,GrLivArea,TotalBsmtSF,GarageArea,YearBuilt,OverallQual等属性,计算这些属性之间的相关系数矩阵,并使用seaborn的heatmap方法绘制相关系数矩阵热力图,可以快速并且直观地探索出与SalePrice相关的属性。
#挑选属性
info = ['SalePrice','GrLivArea','TotalBsmtSF','GarageArea','YearBuilt','OverallQual']
#把图形中的字体设置为原来的0.7倍
sns.set(font_scale = 0.7)
#首先使用.corr()方法计算属性之间的相关系数矩阵,再使用heatmap绘制热力图
#annot=True的作用是把相关系数在图中注释出来
sns.heatmap(housing_df[info].corr(), annot = True, vmin = 0, vmax = 1)
<IPython.core.display.Javascript object>
<matplotlib.axes._subplots.AxesSubplot at 0x2236c313978>
从代码生成的热力图可以看出,SalePrice跟OverallQual的相关性最高,相关系数为0.79,SalePrice跟YearBuilt的相关性最低,相关系数为0.52
二、预测型数据分析
1. 预测型数据分析的注意事项
- 首先使用探索型数据分析方法,探索出跟预测目标相关的特征
- 对相关的特征进行数据处理使其更加符合数据建模的要求
- 特征挑选应该同时注重模型的准确率和可解释性
2. 使用线性回归和逻辑森林回归建立预测模型
import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import cross_val_score
housing_df = data = pd.read_csv('housing.csv')
features = ['GrLivArea','TotalBsmtSF','GarageArea','YearBuilt','OverallQual']
target = 'SalePrice'
lr = LinearRegression()
rf = RandomForestRegressor(100)#可以改变括号里的值(也就是子树的个数)来得到更优的回归效果
models = [lr, rf]
for model in models:
scores = cross_val_score(model, housing_df[features], housing_df[target], cv = 5, scoring = 'neg_mean_absolute_error')
print(type(model).__name__, np.mean(scores))
LinearRegression -24462.4780632
RandomForestRegressor -20710.1090994
可以看到,随机森林还是效果好一些的。
3. 创建新的特征
可以根据数据集原来的特征,创建新的对于预测目标有帮助的新特征,用于得到更好的效果。
比如创建“有没有地下室”这个新的属性(因为之前在探索性数据分析看到地下室面积为零也占很大比例,且房价也有很大的波动)
housing_df['HasBsmt'] = 0
#创建有没有地下室
housing_df.at[housing_df['TotalBsmtSF'] > 0, 'HasBsmt'] = 1
housing_df['LogArea'] = np.log(housing_df['GrLivArea'])
new_features = ['GrLivArea','TotalBsmtSF','GarageArea','YearBuilt','OverallQual','HasBsmt']
lr = LinearRegression()
rf = RandomForestRegressor(100)
models = [lr, rf]
for model in models:
scores = cross_val_score(model, housing_df[new_features], housing_df[target],cv = 5, scoring = 'neg_mean_absolute_error')
print(type(model).__name__, np.mean(scores))
LinearRegression -24357.2382512
RandomForestRegressor -20442.399757
ok!对比一下,两个模型的预测精度都有所提高!
- 根据特征’TotalBsmtSF’创建一个新特征’HasBsmt’,也就是房屋是否有地下室。当’TotalBsmtSF’为0时’HasBsmt’为0,当’TotalBsmtSF’大于0时’HasBsmt’为1
- 根据特征’GrLivArea’创建一个新特征’LogArea’,也就是取特征’GrLivArea’的对数,缩小特征’GrLivArea’之间的差异
- 可以看到新特征对预测的效果有一定的帮助,其效果跟不同模型的内在机制存在一定的关系