python数据分析处理笔记(房价预测01)
一. 数据预处理
-
导入相关库以及数据
# 数据处理,数据分析 import numpy as np import pandas as pd import missingno as msn # 统计计算 from scipy import stats from scipy.optimize import minimize from scipy.stats import norm # 绘图 import seaborn as sns import matplotlib.pyplot as plt %matplotlib inline # 不显示警告 import warnings warnings.filterwarnings('ignore')
# 读写数据文件 import io train = pd.read_csv('train.csv')
-
对数据缺失值情况进行查看
-
通过missingno库对缺失值进行查看
主要通过以下函数对缺失值进行可视化处理,参考http://t.csdn.cn/m2LtI
# 缺失值条形图 msn.bar(train) # 缺失值矩阵的数据密集显示 msn.matrix(train) # 缺失值相关性热图 msn.heatmap(train)
缺失值条形图
缺失值矩阵的数据密度显示
缺失值相关性热图
通过条形图和数据密度显示,可以发现“lot_size”和“lot_size_units”列数据存在缺失。再通过相关性热图可以发现,两列数据为关联数据
-
通过pandas库对缺失值进行查看
# 计算所有特征缺失值占比 train_na = (train.isnull().sum() / len(train)) * 100 # 去掉不包含缺失值的属性,并对剩下的属性按照缺失值比例降序排序,存下排名前10的属性 train_na = train_na.drop(train_na[train_na == 0].index).sort_values(ascending=False)[:10] # 转换成DataFrame的格式 missing_data = pd.DataFrame({'缺失值占比' :train_na})
通过pandas库可以更直观地看出,“lot_size”和”lot_size_units”列数据存在缺失,缺失程度为17.2%
-
-
填充缺失值并做单位统一
-
填充缺失值
通过pandas库中的fillna()函数将缺失值(NaN)填充为(None)
注意:None能够直接被导入数据库作为空值处理, 包含NaN的数据导入时会报错。
train['lot_size'] = train['lot_size'].fillna('None') train['lot_size_units'] = train['lot_size_units'].fillna('None')
观察填充之后的数据可以发现,“lot_size_units”列存在两种单位“sqft”于“acre”,为方便后续处理,这里做单位统一
-
单位统一
在缺失值分析时有提到,“lot_size_units”和“lot_size”为关联数据,因此一起处理
for i in range(train.shape[0]): if train['lot_size_units'][i] == 'acre': train['lot_size_units'][i] = 'sqft' train['lot_size'][i] = train['lot_size'][i]*43560
处理后的数据如上,观察分析后,主要考虑计算属性“beds”“baths””size””lot_size”对“price”的影响,因此,这里删去”size_units”“lot_size_units”“zip_code”列
train = train.drop(['size_units','lot_size_units','zip_code'], axis=1)
处理后结果如上
-
-
检查数据异常值
-
先作居住面积(size)与房价(price)的散点图,观察数据分布
plt.figure(figsize=(16, 8),dpi=600) fig = sns.scatterplot(data=train, x='size', y='price')
可以观察到左上角存在离群点
-
删去离群点
train = train.drop(train[(train['size']<2000) & (train['price']>20000000)].index)
-
再作散点图,观察分布
plt.figure(figsize=(16, 8),dpi=600) fig = sns.scatterplot(data=train, x='size', y='price')
-
二. 对房价进行正态分布化处理
-
在原数据的柱状图上添加正态分布概率密度曲线和核密度估计曲线
(mu, sigma) = norm.fit(train['price'])#计算变换前的均值和方差 print("\n mu = %.2f and sigma = %.2f\n" %(mu,sigma))#打印均值和方差 #画出变换前房价的核密度估计曲线,拟合出的生态分布密度概率曲线 plt.figure(figsize=(16, 8),dpi=600)#设置图片大小,分辨率 sns.set_style("darkgrid") #第一个参数为房价数据,fit=norm代表绘制生态分布密度概率曲线(黑色曲线),kde=True代表绘制核密度估计曲线(蓝色曲线) #fit_kws,kde_kws,hist_kws分别可以设置黑色曲线,蓝色曲线和直方图的图例标签。 sns.distplot(train['price'] ,fit=norm,kde=True,fit_kws={'label':'Normal distribution probability density curve'}, kde_kws={'label':'Kernel Density Estimation Curve'},hist_kws={'label':'price frequency'}) plt.ylabel('Probability Density')#设置纵轴标签 plt.title('Price Distribution', fontsize=20)#设置图片标题 plt.legend(prop = {'size':15})#设置图例
plt.figure(figsize=(16, 8),dpi=600)#设置图片大小 sns.set_style("darkgrid") res = stats.probplot(train['price'], plot=plt)#计算概率图的分位数,plt是绘图对象,plot=plt显示该图
第一张图中的蓝色直方图代表对应区间房价的频数,蓝色曲线为和核密度估计曲线,黑色的曲线代表以房价的均值和方差拟合出的正态分布概率密度曲线。可以看出,观测数据的分布与正态分布有一定差距,故应对观测数据进行正态分布化处理
蓝色的作图方法:
- 找出标准正态分布的所有分位点作为X轴刻度值;
- 找出与X轴上所有分位点对应的样本分位点,以标准正态分布分位点为横坐标,样本分位点为纵坐标,可以做出Q-Q图中蓝色的点;
红色线的作图方法:
- 以样本的均值和方差生成一组正态分布样本(对应第一张图中黑色曲线);
- 找出与X轴上所有分位点对应的正态分布样本的分位点,以标准正态分布分位点为横坐标,正态分布分位点为纵坐标,可以做出Q-Q图红色直线。
结论:蓝色的点越贴近直线,越说明观测数据的分布贴近正态分布
对房价进行正态分布化处理,计算变换后的均值和方差,作频数直方图、拟合后的正态分布概率密度曲线、Q-Q图。
-
对房价进行正态分布化处理
train['price'] = np.log1p(train['price'])#对数变换ln(1+x) (mu, sigma) = norm.fit(train['price'])#计算变换后的均值和方差 print("\n mu = %.2f and sigma = %.2f\n" %(mu,sigma))#打印均值和方差 #画出变换前房价的核密度估计曲线,拟合出的生态分布密度概率曲线 plt.figure(figsize=(16, 8),dpi=600)#设置图片大小,分辨率 sns.set_style("darkgrid") #第一个参数为房价数据,fit=norm代表绘制生态分布密度概率曲线(黑色曲线),kde=True代表绘制核密度估计曲线(蓝色曲线) #fit_kws,kde_kws,hist_kws分别可以设置黑色曲线,蓝色曲线和直方图的图例标签。 sns.distplot(train['price'] ,fit=norm,kde=True,fit_kws={'label':'Normal distribution probability density curve'}, kde_kws={'label':'Kernel Density Estimation Curve'},hist_kws={'label':'price frequency'})#绘图 plt.ylabel('Probability Density')#设置纵轴标签 plt.title('Price Distribution', fontsize=20)#设置图片标题 plt.legend(prop = {'size':15})#设置图例
plt.figure(figsize=(16, 8),dpi=600)#设置图片大小 sns.set_style("darkgrid") res = stats.probplot(train['price'], plot=plt)#计算概率图的分位数,plt是绘图对象,plot=plt显示该图
上述结果解释:
正态分布化处理后,核密度估计曲线与拟合出的正态分布概率密度曲线更加贴近,Q-Q图中蓝色的点相比处理前更加贴近直线。因此可以认为经过对数变换后的房价数据近似服从正态分布,可以用于接下来的回归任务。