做者: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]
複製代碼
經觀察這個異常點不是普通的民用二手房,極可能是商用房,因此纔有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數據科學,獲取 120G
人工智能 學習資料。