本篇主要借鉴了Kaggle基础问题——房价预测的两篇教程Comprehensive data exploration with Python和House Prices EDA并进行总结。
基于上一篇数据探索,我们可以对整个数据集的基本特征进行大致了解,并同时学习到了Pandas
和Seaborn
的一些操作技巧。接下来,我们以此为基础,进行数据的预处理
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler, OneHotEncoder
import seaborn as sns
from scipy import stats
%matplotlib inline
缺失值处理
缺失值处理有两种方案,一种是分析含缺失值的特征对任务有没有用,没用的特征直接删除,有用的特征依据缺失量,少则删除样本,多则用mean,median或mod补全;另一种方案是分析这些缺失值缺失的原因,并用一定方法将其转换为一类数据(成为类型变量的一个类型)。
1.缺失值含义分析与删除
依然是先导入数据:
df_train = pd.read_csv(r'E:\kaggle\house_price_regression\train.csv')
进行数据分析,我们首先要对缺失值进行处理,因此,首先要看一下缺失值具体出现在那些特征中,缺失信息是否对整个特征有较大影响,缺失信息是否有其他特殊意义? 先进行缺失值的缺失情况统计:
na_count = df_train.isnull().sum().sort_values(ascending=False)
na_rate = na_count / len(df_train)
na_data = pd.concat([na_count,na_rate],axis=1,keys=['count','ratio'])
na_data.head(20)
count | ratio | |
---|---|---|
PoolQC | 1453 | 0.995205 |
MiscFeature | 1406 | 0.963014 |
Alley | 1369 | 0.937671 |
Fence | 1179 | 0.807534 |
FireplaceQu | 690 | 0.472603 |
LotFrontage | 259 | 0.177397 |
GarageCond | 81 | 0.055479 |
GarageType | 81 | 0.055479 |
GarageYrBlt | 81 | 0.055479 |
GarageFinish | 81 | 0.055479 |
GarageQual | 81 | 0.055479 |
BsmtExposure | 38 | 0.026027 |
BsmtFinType2 | 38 | 0.026027 |
BsmtFinType1 | 37 | 0.025342 |
BsmtCond | 37 | 0.025342 |
BsmtQual | 37 | 0.025342 |
MasVnrArea | 8 | 0.005479 |
MasVnrType | 8 | 0.005479 |
Electrical | 1 | 0.000685 |
Utilities | 0 | 0.000000 |
统计发现,整个数据集中有19个特征存在不同程度的信息缺失,让我们逐一分析:
首先,如果某一特征的数据缺失量达到15%以上,那这项特征应该予以删除并认为数据集中不存在这样的特征(也就是说我们并不会设法去填补这些特征的缺失值,因为假定它是不存在的),因此删除数据的’PoolQC’, ‘MiscFeature’, ‘Alley’这几列(这应该不会导致数据的有效信息量下降,因为这些特征的字面含义似乎根本与房价无关,难怪会有这么多缺失值XD,而且这些特征的有效数据具有各种离群值)。
然后,在剩下的含缺失值变量中,以Garage
开头的5个GarageX
特征具有相同数量的缺失值,据此推测他们可能代表的是同一组观测值,而关于Garage的信息,’GarageCars’已经能够很好地表征了,因此删除这几个特征,对BsmtX
也可以进行同样的操作。
对于MasVnrArea
和MasVnrType
,根据其字面意思我们认为它们并不重要,而且它们与YearBuilt
和OverallQual
有较强的相关性。因此,我们删除这两个特征也不会丢失任何信息。
总的来看,除了Electrical
,其他含缺失值的变量我们都已经删除了,Electrical
这个变量下只有一个样本带有缺失值,因此我们不妨删除带有这个缺失值的那各样本。
df_train = df_train.drop(na_data[na_data['count']>1].index, axis=1) # 删除上述前18个特征
df_train = df_train.drop(df_train.loc[df_train['Electrical'].isnull()].index) # 删除 Electrical 取值丢失的样本
df_train.shape # 缺失值处理后的数据大小:1459个样本,63个特征
(1459, 63)
2.缺失值补全与变换
依然先导入数据,然后进行变量类型的处理
df_tr = pd.read_csv(r'E:\kaggle\house_price_regression\train.csv').drop('Id',axis=1)
df_X = df_tr.drop('SalePrice',axis=1)
df_y = df_tr['SalePrice']
quantity = [attr for attr in df_X.columns if df_X.dtypes[attr] != 'object'] # 数值变量集合
quality = [attr for attr in df_X.columns if df_X.dtypes[attr]