Kaggle系列-房價預測-EDA
Kaggle系列
接觸數據科學領域一段時間了,最近開始kaggle之旅,這系列博客主要是記錄自己的學習過程,由于還是大二,屬于初學者,能力有限,參考了很多大佬的優秀notebook。歡迎志同道合的朋友在評論席留言一同組隊學習。
數據鏈接下面是kaggle房價預測的一個EDA
# 導入基本的庫
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import scipy.stats as stats
import sklearn.linear_model as linear_model
import seaborn as sns
import xgboost as xgb
from sklearn.model_selection import KFold
from sklearn.manifold import TSNE
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from IPython.display import HTML, display
pd.options.display.max_rows = 1000 # 設置最大可見行1000
pd.options.display.max_columns = 20 # 設置最大可見列20
數據導入
# 讀取數據
train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')
train.head()

將數據進行分類
# 數值型
quantitative = [f for f in train.columns if train.dtypes[f] != 'object'] # 通過列表推導式來接受數值型數據和類別型數據
quantitative.remove('SalePrice')
quantitative.remove('Id')
# category
qualitative = [f for f in train.columns if train.dtypes[f] == 'object']
print(train.shape)
print(len(quantitative))
print(len(qualitative))
結果表明
有1460個訓練數據實例和1460個測試數據實例。
特征總數等于81,其中36個是定量特征,43個是分類+ Id和SalePrice。
查看缺失數據和異常
missing = train.isnull().sum()
missing = missing[missing>0]
missing.sort_values(inplace=True)
missing.plot.bar()

19個屬性的值缺失,其中4個超過50%。
大多數情況下,NA意味著缺少按屬性描述的主題,例如缺少游泳池,圍墻,沒有車庫和地下室。
觀察saleprice分布
import scipy.stats as st
y = train['SalePrice']
plt.figure(1); plt.title('Johnson SU')
sns.distplot(y, kde=False, fit=st.johnsonsu)
plt.figure(2); plt.title('Normal')
sns.distplot(y, kde=False, fit=st.norm)
plt.figure(3); plt.title('Log Norm')
sns.distplot(y, kde=False, fit=st.lognorm)



顯然,SalePrice不遵循正態分布,因此在執行回歸之前必須先對其進行轉換。
雖然對數轉換做得很好,但最合適的方法是無限的Johnson分布。
下面對特征進行正態性檢驗
test_normality = lambda x: stats.shapiro(x.fillna(0))[1] < 0.01
normal = pd.DataFrame(train[quantitative])
normal = normal.apply(test_normality)
print(not normal.all())
結果為False
說明所有的特征都不符合正態分布
對于category數據
- 使用定性變量,我們可以實現兩種方法。
第一個是檢查SalePrice關于變量值的分布并枚舉它們。
其次,為每個可能的類別創建虛擬變量。
# 通過這些category的數據對saleprice的影響可視化分析
for c in qualitative:
train[c] = train[c].astype('category')
if train[c].isnull().any():
train[c] = train[c].cat.add_categories(['MISSING'])
train[c] = train[c].fillna('MISSING')
def boxplot(x, y, **kwargs):
sns.boxplot(x=x, y=y)
x=plt.xticks(rotation=90)
f = pd.melt(train, id_vars=['SalePrice'], value_vars=qualitative )
g = sns.FacetGrid(f, col='variable', col_wrap=2, sharex=False, sharey=False, height=5)
g = g.map(boxplot, 'value', 'SalePrice')

關于SalePrice,某些類別似乎比其他類別更為多樣化。
街道對房價產生很大影響。
最高的似乎是Partial SaleCondition。
所擁有的財富似乎大大提高了價格。
類別值之間的差異也有所不同。
進行方差分析
- 不同總體直接的均值是否存在差異,原假設是 h 0 : a 1 = a 2 = a 3 h0:a1=a2=a3 h0:a1=a2=a3
def anova(frame):
anv = pd.DataFrame()
anv['feature'] = qualitative
pvals = []
for c in qualitative:
samples = []
for cls in frame[c].unique():
s = frame[frame[c] == cls]['SalePrice'].values
samples.append(s)
pval = stats.f_oneway(*samples)[1]
pvals.append(pval)
anv['pval'] = pvals
return anv.sort_values('pval')
a = anova(train)
a['disparity'] = np.log(1./a['pval'].values)
sns.barplot(data=a, x='feature', y='disparity')
x=plt.xticks(rotation=90)

這是類別變量對SalePrice的影響的快速估計。對于每個變量,SalePrices根據類別值劃分為不同的集合。然后使用方差分析測試集是否具有相似的分布。如果變量的影響較小,則設定均值應相等。pval的減少是分區多樣性增加的標志。
相關性分析
- 減少冗余問題,或者避免多重共線性的影響,我們一般選取特征的時候選取不相關的
def spearman(frame, features):
spr = pd.DataFrame()
spr['feature'] = features
spr['spearman'] = [frame[f].corr(frame['SalePrice'], 'spearman') for f in feartures]
spr = spr.sort_values('spearman')
plt.figure(figsize=(6, 0.25*len(feartures)))
sns.barplot(data=spr, y='feature', x='spearman', orient='h')
feartures = quantitative + qual_encoded
spearman(train, feartures)
在本題情況下,使用Spearman相關性更好,因為即使它們是非線性的,它也可以獲取變量之間的關系。綜合質量是制定房價的主要標準。街道影響很大,部分本身具有內部價值,但某些地區的房屋也傾向于具有相同的特征,從而導致相似的估值。
斯皮爾曼相關系數和皮爾遜相關系數區別如下
- 1連續數據,正態分布,線性關系,用pearson相關系數是最恰當,當然用spearman相關系數也可以,效率沒有pearson相關系數高。
- 2上述任一條件不滿足,就用spearman相關系數,不能用pearson相關系數。
- 3兩個定序測量數據(順序變量)之間也用spearman相關系數,不能用pearson相關系數。
- 4Pearson相關系數的一個明顯缺陷是,作為特征排序機制,他只對線性關系敏感。如果關系是非線性的,即便兩個變量具有一一對應的關系,Pearson相關性也可能會接近0。
- 上述因為數據不滿足正態分布,且存在一部分的定類數據因此我們使用spearman相關系數
接下來觀察數值型數據和category數據不同特征之間的相關性
plt.figure(1)
corr = train[quantitative+['SalePrice']].corr()
sns.heatmap(corr)
plt.figure(2)
corr = train[qual_encoded+['SalePrice']].corr()
sns.heatmap(corr)


變量之間有許多強相關性。車庫似乎與房屋建于同一年,地下室的面積通常與一樓相同,這是顯而易見的。車庫面積與汽車數量密切相關。鄰居與許多其他變量相關聯,這證實了同一地區的房屋具有相同特征的想法。居住類型與高等級的廚房呈負相關。
Pairplots
- 看每一個特征與y的關系
def pairplot(x, y, **kwargs):
ts = pd.DataFrame({'time': x, 'val': y})
plt.scatter(ts['time'], ts['val'])
plt.xticks(rotation=90)
f = pd.melt(train, id_vars=['SalePrice'], value_vars=quantitative+qual_encoded)
g = sns.FacetGrid(f, col='variable', col_wrap=2, sharex=False, sharey=False)
g = g.map(pairplot, 'value', 'SalePrice')

參考資料
郵箱:ypj1981834607@163.com

浙公網安備 33010602011771號