做者:xiaoyupython
微信公众号:Python数据科学segmentfault
知乎:python数据分析师微信
目的:本篇给你们介绍一个数据分析的初级项目,目的是经过项目了解如何使用Python进行简单的数据分析。数据源:博主经过爬虫采集的链家全网北京二手房数据(公众号后台回复 二手房数据 即可获取)。网络
下面是第二篇建模篇
,看完这篇可继续研究这篇。机器学习
首先导入要使用的科学计算包numpy
,pandas
,可视化matplotlib
,seaborn
,以及机器学习包sklearn
。性能
import pandas as pd import numpy as np import seaborn as sns import matplotlib as mpl import matplotlib.pyplot as plt from IPython.display import display plt.style.use("fivethirtyeight") sns.set_style({'font.sans-serif':['simhei','Arial']}) %matplotlib inline # 检查Python版本 from sys import version_info if version_info.major != 3: raise Exception('请使用Python 3 来完成此项目')
而后导入数据,并进行初步的观察,这些观察包括了解数据特征的缺失值,异常值,以及大概的描述性统计。学习
# 导入链家二手房数据 lianjia_df = pd.read_csv('lianjia.csv') display(lianjia_df.head(n=2))
初步观察到一共有11
个特征变量,Price
在这里是咱们的目标变量,而后咱们继续深刻观察一下。spa
# 检查缺失值状况 lianjia_df.info()
发现了数据集一共有23677
条数据,其中Elevator
特征有明显的缺失值。3d
lianjia_df.describe()
上面结果给出了特征值是数值的一些统计值,包括平均数,标准差,中位数,最小值,最大值,25%分位数,75%分位数。这些统计结果简单直接,对于初始了解一个特征好坏很是有用,好比咱们观察到 Size 特征
的最大值为1019平米,最小值为2平米,那么咱们就要思考这个在实际中是否是存在的,若是不存在没有意义,那么这个数据就是一个异常值,会严重影响模型的性能。code
固然,这只是初步观察,后续咱们会用数据可视化来清晰的展现,并证明咱们的猜想。
# 添加新特征房屋均价 df = lianjia_df.copy() df['PerPrice'] = lianjia_df['Price']/lianjia_df['Size'] # 从新摆放列位置 columns = ['Region', 'District', 'Garden', 'Layout', 'Floor', 'Year', 'Size', 'Elevator', 'Direction', 'Renovation', 'PerPrice', 'Price'] df = pd.DataFrame(df, columns = columns) # 从新审视数据集 display(df.head(n=2))
咱们发现 Id
特征其实没有什么实际意义,因此将其移除。因为房屋单价分析起来比较方便,简单的使用总价/面积就可获得,因此增长一个新的特征 PerPrice
(只用于分析,不是预测特征)。另外,特征的顺序也被调整了一下,看起来比较舒服。
对于区域特征,咱们能够分析不一样区域房价和数量的对比。
# 对二手房区域分组对比二手房数量和每平米房价 df_house_count = df.groupby('Region')['Price'].count().sort_values(ascending=False).to_frame().reset_index() df_house_mean = df.groupby('Region')['PerPrice'].mean().sort_values(ascending=False).to_frame().reset_index() f, [ax1,ax2,ax3] = plt.subplots(3,1,figsize=(20,15)) sns.barplot(x='Region', y='PerPrice', palette="Blues_d", data=df_house_mean, ax=ax1) ax1.set_title('北京各大区二手房每平米单价对比',fontsize=15) ax1.set_xlabel('区域') ax1.set_ylabel('每平米单价') sns.barplot(x='Region', y='Price', palette="Greens_d", data=df_house_count, ax=ax2) ax2.set_title('北京各大区二手房数量对比',fontsize=15) ax2.set_xlabel('区域') ax2.set_ylabel('数量') sns.boxplot(x='Region', y='Price', data=df, ax=ax3) ax3.set_title('北京各大区二手房房屋总价',fontsize=15) ax3.set_xlabel('区域') ax3.set_ylabel('房屋总价') plt.show()
使用了pandas
的网络透视功能 groupby
分组排序。区域特征可视化直接采用 seaborn
完成,颜色使用调色板 palette
参数,颜色渐变,越浅说明越少,反之越多。
能够观察到:
f, [ax1,ax2] = plt.subplots(1, 2, figsize=(15, 5)) # 建房时间的分布状况 sns.distplot(df['Size'], bins=20, ax=ax1, color='r') sns.kdeplot(df['Size'], shade=True, ax=ax1) # 建房时间和出售价格的关系 sns.regplot(x='Size', y='Price', data=df, ax=ax2) plt.show()
经过 distplot
和 kdeplot
绘制柱状图观察 Size 特征的分布状况,属于长尾类型的分布,这说明了有不少面积很大且超出正常范围的二手房。
经过 regplot
绘制了 Size 和 Price 之间的散点图,发现 Size 特征基本与Price呈现线性关系,符合基本常识,面积越大,价格越高。可是有两组明显的异常点:1. 面积不到10平米,可是价格超出10000万;2. 一个点面积超过了1000平米,价格很低,须要查看是什么状况。
df.loc[df['Size']< 10]
通过查看发现这组数据是别墅,出现异常的缘由是因为别墅结构比较特殊(无朝向无电梯),字段定义与二手商品房不太同样致使爬虫爬取数据错位。也因别墅类型二手房不在咱们的考虑范围以内,故将其移除再次观察Size分布和Price关系。
df.loc[df['Size']>1000]
经观察这个异常点不是普通的民用二手房,极可能是商用房,因此才有1房间0厅确有如此大超过1000平米的面积,这里选择移除。
df = df[(df['Layout']!='叠拼别墅')&(df['Size']<1000)]
从新进行可视化发现就没有明显的异常点了。
f, ax1= plt.subplots(figsize=(20,20)) sns.countplot(y='Layout', data=df, ax=ax1) ax1.set_title('房屋户型',fontsize=15) ax1.set_xlabel('数量') ax1.set_ylabel('户型') plt.show()
这个特征真是不看不知道,各类厅室组合搭配,居然还有9室3厅,4室0厅等奇怪的结构。其中,2室一厅占绝大部分,其次是3室一厅,2室2厅,3室两厅。可是仔细观察特征分类下有不少不规则的命名,好比2室一厅与2房间1卫,还有别墅,没有统一的叫法。这样的特征确定是不能做为机器学习模型的数据输入的,须要使用特征工程进行相应的处理。
df['Renovation'].value_counts()
精装 11345
简装 8497
其余 3239
毛坯 576
南北
20
Name: Renovation, dtype: int64
发现Renovation装修特征中居然有南北,它属于朝向的类型,多是由于爬虫过程当中一些信息位置为空,致使“Direction”朝向特征出如今这里,因此须要清除
或替换掉
。
# 去掉错误数据“南北”,由于爬虫过程当中一些信息位置为空,致使“Direction”的特征出如今这里,须要清除或替换 df['Renovation'] = df.loc[(df['Renovation'] != '南北'), 'Renovation'] # 画幅设置 f, [ax1,ax2,ax3] = plt.subplots(1, 3, figsize=(20, 5)) sns.countplot(df['Renovation'], ax=ax1) sns.barplot(x='Renovation', y='Price', data=df, ax=ax2) sns.boxplot(x='Renovation', y='Price', data=df, ax=ax3) plt.show()
观察到,精装修的二手房数量最多,简装其次,也是咱们平平常见的。而对于价格来讲,毛坯类型倒是最高,其次是精装修。
初探数据的时候,咱们发现 Elevator 特征是有大量缺失值的,这对于咱们是十分不利的,首先咱们先看看有多少缺失值:
misn = len(df.loc[(df['Elevator'].isnull()), 'Elevator']) print('Elevator缺失值数量为:'+ str(misn))
Elevator 缺失值数量为:8237
这么多的缺失值怎么办呢?这个须要根据实际状况考虑,经常使用的方法有平均值/中位数填补法,直接移除,或者根据其余特征建模预测等。
这里咱们考虑填补法,可是有无电梯不是数值,不存在平均值和中位数,怎么填补呢?这里给你们提供一种思路:就是根据楼层 Floor 来判断有无电梯,通常的楼层大于6的都有电梯,而小于等于6层的通常都没有电梯。有了这个标准,那么剩下的就简单了。
# 因为存在个别类型错误,如简装和精装,特征值错位,故须要移除 df['Elevator'] = df.loc[(df['Elevator'] == '有电梯')|(df['Elevator'] == '无电梯'), 'Elevator'] # 填补Elevator缺失值 df.loc[(df['Floor']>6)&(df['Elevator'].isnull()), 'Elevator'] = '有电梯' df.loc[(df['Floor']<=6)&(df['Elevator'].isnull()), 'Elevator'] = '无电梯' f, [ax1,ax2] = plt.subplots(1, 2, figsize=(20, 10)) sns.countplot(df['Elevator'], ax=ax1) ax1.set_title('有无电梯数量对比',fontsize=15) ax1.set_xlabel('是否有电梯') ax1.set_ylabel('数量') sns.barplot(x='Elevator', y='Price', data=df, ax=ax2) ax2.set_title('有无电梯房价对比',fontsize=15) ax2.set_xlabel('是否有电梯') ax2.set_ylabel('总价') plt.show()
结果观察到,有电梯的二手房数量居多一些,毕竟高层土地利用率比较高,适合北京庞大的人群须要,而高层就须要电梯。相应的,有电梯二手房房价较高,由于电梯前期装修费和后期维护费包含内了(但这个价格比较只是一个平均的概念,好比无电梯的6层豪华小区固然价格更高了)。
grid = sns.FacetGrid(df, row='Elevator', col='Renovation', palette='seismic',size=4) grid.map(plt.scatter, 'Year', 'Price') grid.add_legend()
在Renovation和Elevator的分类条件下,使用 FaceGrid
分析 Year 特征,观察结果以下:
f, ax1= plt.subplots(figsize=(20,5)) sns.countplot(x='Floor', data=df, ax=ax1) ax1.set_title('房屋户型',fontsize=15) ax1.set_xlabel('数量') ax1.set_ylabel('户型') plt.show()
能够看到,6层二手房数量最多,可是单独的楼层特征没有什么意义,由于每一个小区住房的总楼层数都不同,咱们须要知道楼层的相对意义。另外,楼层与文化也有很重要联系,好比中国文化七上八下,七层可能受欢迎,房价也贵,而通常也不会有4层或18层。固然,正常状况下中间楼层是比较受欢迎的,价格也高,底层和顶层受欢迎度较低,价格也相对较低。因此楼层是一个很是复杂的特征,对房价影响也比较大。
本次分享旨在让你们了解如何用Python作一个简单的数据分析,对于刚刚接触数据分析的朋友无疑是一个很好的练习。不过,这个分析还存在不少问题须要解决,好比:
更多内容会慢慢介绍和分享,敬请期待。
欢迎关注微信公众号Python数据科学