做者:xiaoyupython
微信公衆號:Python數據科學bash
知乎: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
在這裏是咱們的目標變量,而後咱們繼續深刻觀察一下。ui
# 檢查缺失值狀況
lianjia_df.info()
複製代碼
23677
條數據,其中
Elevator
特徵有明顯的缺失值。
lianjia_df.describe()
複製代碼
上面結果給出了特徵值是數值的一些統計值,包括平均數,標準差,中位數,最小值,最大值,25%分位數,75%分位數。這些統計結果簡單直接,對於初始瞭解一個特徵好壞很是有用,好比咱們觀察到 Size 特徵
的最大值爲1019平米,最小值爲2平米,那麼咱們就要思考這個在實際中是否是存在的,若是不存在沒有意義,那麼這個數據就是一個異常值,會嚴重影響模型的性能。人工智能
固然,這只是初步觀察,後續咱們會用數據可視化來清晰的展現,並證明咱們的猜想。spa
# 添加新特徵房屋均價
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]
複製代碼
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()
複製代碼
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()
複製代碼
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()
複製代碼
本次分享旨在讓你們瞭解如何用Python作一個簡單的數據分析,對於剛剛接觸數據分析的朋友無疑是一個很好的練習。不過,這個分析還存在不少問題須要解決,好比:
更多內容會慢慢介紹和分享,敬請期待。
關注微信公衆號Python數據科學,獲取 120G
人工智能 學習資料。