目录
1 项目背景
项目链接:House Prices - Advanced Regression Techniques | Kaggle
这是kaggle的一个经典Data Science项目,作为数据分析的新手,房价预测是一个很好的入门练习项目。
数据集分为训练集‘train.csv’和测试集‘test.csv’,要求根据房子的质量、面积、街区、壁炉个数等79个特征,预测相应的房价。
评价指标是回归问题中常用的均方误差(RMSE):
2 初始数据分析
首先导入所需的库:
import warnings
warnings.filterwarnings("ignore") # 忽略警告信息
import numpy as np
import pandas as pd
from scipy.stats import norm, skew #获取统计信息
from scipy import stats # 离散统计分布以及连续统计分布
import seaborn as sns # 绘图包
color = sns.color_palette()
sns.set_style('darkgrid')
import matplotlib
import matplotlib.pyplot as plt
pd.set_option('display.float_format', lambda x: '{:.3f}'.format(x)) # 限制浮点输出到小数点后3位
import os
读取训练集和测试集,检查数据集大小,并查看前5行数据:
# 加载数据
train = pd.read_csv('kagglehouse/train.csv')
test = pd.read_csv('kagglehouse/test.csv')
# 检查样本和特征的数量
print("训练集初始大小: {} ".format(train.shape))
print("测试集初始大小: {} ".format(test.shape))
训练集初始大小: (1460, 81)
测试集初始大小: (1459, 80)
#查看前5行数据
print(train.head())
print(test.head())
训练集初始大小为1460行81列,测试集初始大小为1459行80列,训练集比测试集多出最后一列价格列,这也是我们测试集的预测目标。
其中第一列Id列没有用,直接删掉:
# 删除原数据集的Id列
train.drop("Id", axis=1, inplace=True)
test.drop("Id", axis=1, inplace=True)
目标值分析
目标值就是房屋价格,我们先看一看它的分布情况:
#绘制目标值分布
sns.distplot(train['SalePrice'])
plt.show()
是明显的右偏分布,和正态分布有较大差距,我们再看一下这个分布曲线的峰度和偏度:
# 计算房价的峰度和偏度
SP_skew = train['SalePrice'].skew()
SP_kurt = train['SalePrice'].kurt()
print('峰度:',SP_skew)
print('偏度:',SP_kurt)
峰度: 1.8828757597682129
偏度: 6.536281860064529
峰度(Kurtosis)是描述总体中所有取值分布形态陡缓程度的统计量,是与正态分布作比较的。
峰度为0表示该总体数据分布与正态分布的陡缓程度相同;峰度大于0表示该总体数据分布与正态分布相比较为陡峭,为尖顶峰;峰度小于0表示该总体数据分布与正态分布相比较为平坦,为平顶峰。
偏度(Skewness)描述的是某总体取值分布的对称性,同样与正态分布相比较。
偏度为0表示其数据分布形态与正态分布的偏斜程度相同;偏度大于0表示其数据分布形态与正态分布相比为正偏或右偏,即有一条长尾巴拖在右边,数据右端有较多的极端值;偏度小于0表示其数据分布形态与正态分布相比为负偏或左偏。
根据图可知,数据目标值峰度大于0,为尖顶峰,偏度较大,整体呈右偏分布,后期需要我们做一些处理,使其向正态分布靠拢,因为回归模型在正态分布的数据集上表现更好。
查看目标值统计信息:
#查看目标值统计信息
print(train['SalePrice'].describe())
count 1460.000
mean 180921.196
std 79442.503
min 34900.000
25% 129975.000
50% 163000.000
75% 214000.000
max 755000.000
Name: SalePrice, dtype: float64
最大值太大了,与75%的取值都差很多,推断最大值附近应该有异常值存在。
特征与目标值相关性
下面看一下各个特征与目标值之间的关系,这里要先分开类别特征和数字特征:
num_features = []
cate_features = []
for col in test.columns:
if test[col].dtype == 'object':
cate_features.append(col)
else:
num_features.append(col)
print('数值型特征:', len(num_features))
print('类别型特征:', len(cate_features))
数值型特征: 36
类别型特征: 43
先查看各数值型特征与目标值之间的关系,采用散点图:
#数值特征与目标值画散点图
plt.figure(figsize=(20, 30))
plt.subplots_adjust(left=0.1, bottom=0.1,wspace=0.6,hspace=0.6)
for i, feature in enumerate(num_features):
plt.subplot(6,6, i+1)
sns.scatterplot(x=feature, y='SalePrice', data=train, alpha=0.5)
plt.xlabel(feature)
plt.ylabel('SalePrice')
plt.show()
通过散点图发现&