天天看點

機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)

文章目錄

    • 1. 資料分析
      • 1.1 訓練資料分析
        • (1)訓練資料前5條資料
        • (2)訓練資料大小
        • (3)訓練資料統計資訊
        • (4)訓練資料類型
        • (5)訓練資料缺失資料統計
        • (6)訓練資料缺失值可視化
        • (7)訓練資料缺失值相關性分析
        • (8)訓練資料标簽分布柱狀圖
        • (9)部分屬性與房價關系分析(箱狀圖和散點圖)
      • 1.2 測試資料分析
        • (1) 測試資料前5條資料
        • (2) 測試資料類型統計
        • (3) 測試資料大小
        • (4) 測試資料缺失值統計
        • (5) 測試資料缺失值可視化
        • (6) 測試資料缺失值相關性分析
      • 1.3 訓練資料和測試資料對比
        • (1) 資料類型對比
        • (2) 缺失資料對比
        • (3)資料分布統計與對比
          • 1) 對比離散資料
          • 2)對比連續資料
          • 3) 檢查數值型特征的線性程度
          • 4) 非數值型資料對比分析
      • 1.4 數值型資料缺失分析
      • 1.5 時序特征分析(包含年月日資訊的特征)
      • 1.6 資料相關性分析

很不容易,這個實戰項目肝了好幾天,借鑒了很多大佬的思路和代碼,也從中學習到了很多東西(我喜歡将經典的代碼複寫一遍,感覺這樣學習到的東西比CV大法會高一點點),因為這個項目的内容比較多,是以我将會分為4~5個blog進行梳理。

  • 第1個blog:資料分析
  • 第2個blog:資料預處理
  • 第3個blog:應用機器學習回歸分析算法進行模組化和預測
  • 第4個blog:應用pytorch設計深度學習模型

相關:

kaggle 比賽:House Prices - Advanced Regression Techniques

資料下載下傳位址:百度網盤 提取碼: w2t6

1. 資料分析

加載原始資料

# 加載原始資料
train_data = pd.read_csv('./data/California house price/house-prices-advanced-regression-techniques/train.csv')
test_data = pd.read_csv('./data/California house price/house-prices-advanced-regression-techniques/test.csv')
combined_df = pd.concat([train_data,test_data],axis=0)
           

1.1 訓練資料分析

(1)訓練資料前5條資料

# 檢視頭5條資料
train_data.head()
           
Id MSSubClass MSZoning LotFrontage LotArea Street Alley LotShape LandContour Utilities ... PoolArea PoolQC Fence MiscFeature MiscVal MoSold YrSold SaleType SaleCondition SalePrice
1 60 RL 65.00 8450 Pave NaN Reg Lvl AllPub ... NaN NaN NaN 2 2008 WD Normal 208500
1 2 20 RL 80.00 9600 Pave NaN Reg Lvl AllPub ... NaN NaN NaN 5 2007 WD Normal 181500
2 3 60 RL 68.00 11250 Pave NaN IR1 Lvl AllPub ... NaN NaN NaN 9 2008 WD Normal 223500
3 4 70 RL 60.00 9550 Pave NaN IR1 Lvl AllPub ... NaN NaN NaN 2 2006 WD Abnorml 140000
4 5 60 RL 84.00 14260 Pave NaN IR1 Lvl AllPub ... NaN NaN NaN 12 2008 WD Normal 250000

5 rows × 81 columns

(2)訓練資料大小

# 訓練資料的大小
train_data.shape
           
(1460, 81)

(3)訓練資料統計資訊

# 訓練資料資訊
train_data.info()
           
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1460 entries, 0 to 1459
Data columns (total 81 columns):
 #   Column         Non-Null Count  Dtype  
---  ------         --------------  -----  
 0   Id             1460 non-null   int64  
 1   MSSubClass     1460 non-null   int64  
 2   MSZoning       1460 non-null   object 
 3   LotFrontage    1201 non-null   float64
 4   LotArea        1460 non-null   int64  
 5   Street         1460 non-null   object 
 6   Alley          91 non-null     object 
 7   LotShape       1460 non-null   object 
 8   LandContour    1460 non-null   object 
 9   Utilities      1460 non-null   object 
 10  LotConfig      1460 non-null   object 
 11  LandSlope      1460 non-null   object 
 12  Neighborhood   1460 non-null   object 
 13  Condition1     1460 non-null   object 
 14  Condition2     1460 non-null   object 
 15  BldgType       1460 non-null   object 
 16  HouseStyle     1460 non-null   object 
 17  OverallQual    1460 non-null   int64  
 18  OverallCond    1460 non-null   int64  
 19  YearBuilt      1460 non-null   int64  
 20  YearRemodAdd   1460 non-null   int64  
 21  RoofStyle      1460 non-null   object 
 22  RoofMatl       1460 non-null   object 
 23  Exterior1st    1460 non-null   object 
 24  Exterior2nd    1460 non-null   object 
 25  MasVnrType     1452 non-null   object 
 26  MasVnrArea     1452 non-null   float64
 27  ExterQual      1460 non-null   object 
 28  ExterCond      1460 non-null   object 
 29  Foundation     1460 non-null   object 
 30  BsmtQual       1423 non-null   object 
 31  BsmtCond       1423 non-null   object 
 32  BsmtExposure   1422 non-null   object 
 33  BsmtFinType1   1423 non-null   object 
 34  BsmtFinSF1     1460 non-null   int64  
 35  BsmtFinType2   1422 non-null   object 
 36  BsmtFinSF2     1460 non-null   int64  
 37  BsmtUnfSF      1460 non-null   int64  
 38  TotalBsmtSF    1460 non-null   int64  
 39  Heating        1460 non-null   object 
 40  HeatingQC      1460 non-null   object 
 41  CentralAir     1460 non-null   object 
 42  Electrical     1459 non-null   object 
 43  1stFlrSF       1460 non-null   int64  
 44  2ndFlrSF       1460 non-null   int64  
 45  LowQualFinSF   1460 non-null   int64  
 46  GrLivArea      1460 non-null   int64  
 47  BsmtFullBath   1460 non-null   int64  
 48  BsmtHalfBath   1460 non-null   int64  
 49  FullBath       1460 non-null   int64  
 50  HalfBath       1460 non-null   int64  
 51  BedroomAbvGr   1460 non-null   int64  
 52  KitchenAbvGr   1460 non-null   int64  
 53  KitchenQual    1460 non-null   object 
 54  TotRmsAbvGrd   1460 non-null   int64  
 55  Functional     1460 non-null   object 
 56  Fireplaces     1460 non-null   int64  
 57  FireplaceQu    770 non-null    object 
 58  GarageType     1379 non-null   object 
 59  GarageYrBlt    1379 non-null   float64
 60  GarageFinish   1379 non-null   object 
 61  GarageCars     1460 non-null   int64  
 62  GarageArea     1460 non-null   int64  
 63  GarageQual     1379 non-null   object 
 64  GarageCond     1379 non-null   object 
 65  PavedDrive     1460 non-null   object 
 66  WoodDeckSF     1460 non-null   int64  
 67  OpenPorchSF    1460 non-null   int64  
 68  EnclosedPorch  1460 non-null   int64  
 69  3SsnPorch      1460 non-null   int64  
 70  ScreenPorch    1460 non-null   int64  
 71  PoolArea       1460 non-null   int64  
 72  PoolQC         7 non-null      object 
 73  Fence          281 non-null    object 
 74  MiscFeature    54 non-null     object 
 75  MiscVal        1460 non-null   int64  
 76  MoSold         1460 non-null   int64  
 77  YrSold         1460 non-null   int64  
 78  SaleType       1460 non-null   object 
 79  SaleCondition  1460 non-null   object 
 80  SalePrice      1460 non-null   int64  
dtypes: float64(3), int64(35), object(43)
memory usage: 924.0+ KB
           

(4)訓練資料類型

# 訓練資料類型統計
train_dtype = train_data.dtypes
train_dtype.value_counts()
           
object     43
 int64      35
 float64     3
 dtype: int64
           

(5)訓練資料缺失資料統計

# 訓練資料中的空值排序前20個
train_data.isnull().sum().sort_values(ascending=False).head(20)
           
PoolQC          1453
    MiscFeature     1406
    Alley           1369
    Fence           1179
    FireplaceQu      690
    LotFrontage      259
    GarageCond        81
    GarageType        81
    GarageYrBlt       81
    GarageFinish      81
    GarageQual        81
    BsmtExposure      38
    BsmtFinType2      38
    BsmtFinType1      37
    BsmtCond          37
    BsmtQual          37
    MasVnrArea         8
    MasVnrType         8
    Electrical         1
    Utilities          0
    dtype: int64
           

(6)訓練資料缺失值可視化

# 使用Misingno可視化缺失資料
msno.matrix(train_data)
           
機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)

(7)訓練資料缺失值相關性分析

# 使用misingno檢視缺失資料之間的相關性:表征一個變量的存在和不存在如何強烈地影響另一個的存在
# (比如說如果rate1和rate2的熱度值是1,那麼rate11缺失,rate2也必然缺失,兩者在缺失性之間是直接相關的)
msno.heatmap(train_data)
           
機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)

(8)訓練資料标簽分布柱狀圖

# 檢視訓練資料對應價格的分布
sns.displot(train_data['SalePrice'])
           
機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)

(9)部分屬性與房價關系分析(箱狀圖和散點圖)

檢視對房屋的整體評價和價格之箱狀圖:箱狀圖不受異常值的影響,可以相對穩定地描述資料的離散分布情況

機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)
# 可以看到整體評分越高其價格是越高的
overallQual_SalePrice = pd.concat([train_data['SalePrice'],train_data['OverallQual']],axis=1)
plt.figure(figsize=(8,6))
sns.boxplot(x='OverallQual',y='SalePrice',data=overallQual_SalePrice)
           
機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)
# 用箱狀圖檢視一下離散非數值型資料的分布
# 可以看到如果neighorhood是在stoneBr和NridgHt附近的話,價格會較高
Neighborhood_SalePrice = pd.concat([train_data['SalePrice'],train_data['Neighborhood']],axis=1)
plt.figure(figsize=(20,6))
sns.boxplot(x='Neighborhood',y='SalePrice',data=Neighborhood_SalePrice)
           
機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)
# 繪制和價格相關的特征的散點圖
TotalBsmtSF_SalePrice = pd.concat([train_data['SalePrice'],train_data['TotalBsmtSF']],axis=1)
plt.figure(figsize=(8,6))
TotalBsmtSF_SalePrice.plot.scatter(x='TotalBsmtSF',y='SalePrice',s=4,c='red')
           
機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)

1.2 測試資料分析

(1) 測試資料前5條資料

Id MSSubClass MSZoning LotFrontage LotArea Street Alley LotShape LandContour Utilities ... ScreenPorch PoolArea PoolQC Fence MiscFeature MiscVal MoSold YrSold SaleType SaleCondition
1461 20 RH 80.00 11622 Pave NaN Reg Lvl AllPub ... 120 NaN MnPrv NaN 6 2010 WD Normal
1 1462 20 RL 81.00 14267 Pave NaN IR1 Lvl AllPub ... NaN NaN Gar2 12500 6 2010 WD Normal
2 1463 60 RL 74.00 13830 Pave NaN IR1 Lvl AllPub ... NaN MnPrv NaN 3 2010 WD Normal
3 1464 60 RL 78.00 9978 Pave NaN IR1 Lvl AllPub ... NaN NaN NaN 6 2010 WD Normal
4 1465 120 RL 43.00 5005 Pave NaN IR1 HLS AllPub ... 144 NaN NaN NaN 1 2010 WD Normal

5 rows × 80 columns

(2) 測試資料類型統計

# 檢視測試資料中的資料類型統計
test_dtype = test_data.dtypes
test_dtype.value_counts()
           
object     43
int64      26
float64    11
dtype: int64
           

(3) 測試資料大小

test_data.shape
           
(1459, 80)
           

(4) 測試資料缺失值統計

PoolQC          1456
MiscFeature     1408
Alley           1352
Fence           1169
FireplaceQu      730
LotFrontage      227
GarageCond        78
GarageQual        78
GarageYrBlt       78
GarageFinish      78
GarageType        76
BsmtCond          45
BsmtQual          44
BsmtExposure      44
BsmtFinType1      42
BsmtFinType2      42
MasVnrType        16
MasVnrArea        15
MSZoning           4
BsmtHalfBath       2
dtype: int64
           

(5) 測試資料缺失值可視化

機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)

(6) 測試資料缺失值相關性分析

# 從這裡看出:其實我們的測試資料缺失比訓練資料更加嚴重
msno.heatmap(test_data)
           
機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)

1.3 訓練資料和測試資料對比

(1) 資料類型對比

主要發現一些資料類型是int64和float64的差別,對于我們的影響不是很大

# 将标簽值SalePrice去除,然後使用pandas的compare将兩個dataframe進行比較
train_dtype = train_dtype.drop('SalePrice')
train_dtype.compare(test_dtype)
           
self other
BsmtFinSF1 int64 float64
BsmtFinSF2 int64 float64
BsmtUnfSF int64 float64
TotalBsmtSF int64 float64
BsmtFullBath int64 float64
BsmtHalfBath int64 float64
GarageCars int64 float64
GarageArea int64 float64

(2) 缺失資料對比

null_train = train_data.isnull().sum()
null_test = test_data.isnull().sum()
null_train = null_train.drop('SalePrice')
null_comp_df = null_train.compare(null_test).sort_values(['self'],ascending=[False])
null_comp_df
           
self other
PoolQC 1453.00 1456.00
MiscFeature 1406.00 1408.00
Alley 1369.00 1352.00
Fence 1179.00 1169.00
FireplaceQu 690.00 730.00
LotFrontage 259.00 227.00
GarageType 81.00 76.00
GarageCond 81.00 78.00
GarageYrBlt 81.00 78.00
GarageFinish 81.00 78.00
GarageQual 81.00 78.00
BsmtFinType2 38.00 42.00
BsmtExposure 38.00 44.00
BsmtFinType1 37.00 42.00
BsmtCond 37.00 45.00
BsmtQual 37.00 44.00
MasVnrArea 8.00 15.00
MasVnrType 8.00 16.00
Electrical 1.00 0.00
GarageArea 0.00 1.00
GarageCars 0.00 1.00
MSZoning 0.00 4.00
Functional 0.00 2.00
KitchenQual 0.00 1.00
BsmtHalfBath 0.00 2.00
BsmtFullBath 0.00 2.00
TotalBsmtSF 0.00 1.00
BsmtUnfSF 0.00 1.00
BsmtFinSF2 0.00 1.00
BsmtFinSF1 0.00 1.00
Exterior2nd 0.00 1.00
Exterior1st 0.00 1.00
Utilities 0.00 2.00
SaleType 0.00 1.00

(3)資料分布統計與對比

統計資料類别數量:

  • 1)數值型特征數量
    • 離散特征數量(如果非獨立數值少于25個認為該特征為離散特征)
    • 連續特征數量
  • 2)非數值型資料數量
numerical_features = [col for col in train_data.columns if train_data[col].dtypes != 'O']
discrete_features = [col for col in numerical_features if len(train_data[col].unique()) < 25 and col not in ['Id']]
continuous_features = [feature for feature in numerical_features if feature not in discrete_features+['Id']]
categorical_features = [col for col in train_data.columns if train_data[col].dtype == 'O']

print("Total Number of Numerical Columns : ",len(numerical_features))
print("Number of discrete features : ",len(discrete_features))
print("No of continuous features are : ", len(continuous_features))
print("Number of non-numeric features : ",len(categorical_features))
           
Total Number of Numerical Columns :  38
Number of discrete features :  18
No of continuous features are :  19
Number of non-numeric features :  43
           

插入一個名為

Label

辨別訓練資料和測試資料的特征

combined_df['Label'] = "test"
combined_df['Label'][:1460] = "Train"
           
1) 對比離散資料
# 對比離散資料
"""
sns.hitplot(data,x,y,hue,ax)
data:pandas.Dataframe,numpy.ndarray,mapping,or sequence:input data
x,y : 指定x,y軸的變量
hue:确定繪圖顔色的變量
ax:預先定義的繪圖區域
"""
f,axes = plt.subplots(3,6,figsize=(30,10),sharex=False)
for i,feature in enumerate(discrete_features):
    sns.histplot(data=combined_df,x=feature,hue='Label',ax=axes[i%3,i//3])
           
機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)

上面離散分布的資料說明:

  • 很多資料可以重新分類為分類資料(非數值型資料),例如

    MSSublass

  • 很多特征以0和null值為主(例如

    PoolArea

    LowQualFinSF

    3SsnPorch

    ,

    MiscVal

    ),是以也以考慮将這些特征删除
2)對比連續資料
#對比連續資料
f,axes = plt.subplots(4,6,figsize=(30,15),sharex=False)
for i,feature in enumerate(continuous_features):
    sns.histplot(data=combined_df,x=feature,hue='Label',ax=axes[i%4,i//4])
           
機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)

上述連續資料對比說明:

  • 對于連續資料:訓練和測試資料的分布都基本相同
3) 檢查數值型特征的線性程度
# 檢查數值資料的線性分布
"""
橫軸為數值資料特征,縱軸為價格标簽
"""
f,axes = plt.subplots(7,6,figsize=(30,30),sharex=False)
for i,feature in enumerate(numerical_features):
    sns.scatterplot(data=combined_df,x=feature,y="SalePrice",ax=axes[i%7,i//7])
           
機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)

從上面可以發現很多特征關于價格标簽并非是線性的:

  • ‘SalePrice’ VS.‘BsmtUnfSF’,
  • ‘SalePrice’ VS.‘TotalBsmtSF’,
  • ‘SalePrice’ VS.‘GarageArea’,
  • ‘SalePrice’ VS.‘LotArea’,
  • ‘SalePrice’ VS.‘LotFrontage’,
  • ‘SalePrice’ VS.‘GrLivArea’,
  • ‘SalePrice’ VS.‘1stFlrSF’,
4) 非數值型資料對比分析
# 對比非數值型資料對比分析
f,axes = plt.subplots(7,7,figsize=(30,30),sharex=False)
for i,feature in enumerate(categorical_features):
    sns.countplot(data=combined_df,x=feature,hue="Label",ax=axes[i%7,i//7])
           
機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)

統計非數值型資料的對比統計結果:

  • 對于大多數特征而言,訓練和測試資料的分布是類似的
  • 一些特征存在主要的項目,可以考慮将一些次要項目合并在一起或者将這些列給删掉
  • ‘RoofMatl’,‘Street’,‘Condition2’,‘Utilities’,‘Heating’ (這些列應該删掉)
  • ‘Fa’ & ‘Po’ 在 ‘HeatingQC’, ‘FireplaceQu’, ‘GarageQual’ and 'GarageCond’這些特征中或許可以考慮将其合并
# 通過箱狀圖分析非數值型資料的分布(值取的對應價格)
f, axes = plt.subplots(7,7 , figsize=(30, 30), sharex=False)
for i, feature in enumerate(categorical_features):
    sort_list = sorted(combined_df.groupby(feature)['SalePrice'].median().items(), key= lambda x:x[1], reverse = True)
    order_list = [x[0] for x in sort_list ]
    sns.boxplot(data = combined_df, x = feature, y = 'SalePrice', order=order_list, ax=axes[i%7, i//7])
plt.show()
           
機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)

1.4 數值型資料缺失分析

# 檢查數值型資料的分布特征并填充均值
null_features_numerical = [col for col in combined_df.columns if combined_df[col].isnull().sum()>0 and col not in categorical_features]
plt.figure(figsize=(30,20))
sns.set()

warnings.simplefilter('ignore')
for i,var in enumerate(null_features_numerical):
    plt.subplot(4,3,i+1)
    sns.distplot(combined_df[var],bins=20,kde_kws={'linewidth':3,'color':'red'},label="original")
    sns.distplot(combined_df[var],bins=20,kde_kws={'linewidth':2,'color':'yellow'},label="mean")
           
機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)
# # 檢查數值型資料的分布特征并填充中位值
plt.figure(figsize=(30,20))
sns.set()
warnings.simplefilter("ignore")
for i,var in enumerate(null_features_numerical):
    plt.subplot(4,3,i+1)
    sns.distplot(combined_df[var],bins=20,kde_kws={'linewidth':3,'color':'red'},label="original")
    sns.distplot(combined_df[var],bins=20,kde_kws={'linewidth':2,'color':'yellow'},label="median")
           
機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)

1.5 時序特征分析(包含年月日資訊的特征)

year_feature = [col for col in combined_df.columns if "Yr" in col or 'Year' in col]
year_feature
           
['YearBuilt', 'YearRemodAdd', 'GarageYrBlt', 'YrSold']
           
# 然後檢查一下這些特征與銷售價格是否有關系
combined_df.groupby('YrSold')['SalePrice'].median().plot() # groupby().median()表示取每一組的中位數
plt.xlabel('Year Sold')
plt.ylabel('House Price')
plt.title('House price vs YearSold')
           
Text(0.5, 1.0, 'House price vs YearSold')
           
機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)
# 繪制其他三個特征與銷售價格的散點對應圖
# 可以看到随着時間的增加,價格是逐增加的
for feature in year_feature:
    if feature != 'YrSold':
        hs = combined_df.copy()
        plt.scatter(hs[feature],hs['SalePrice'])
        plt.xlabel(feature)
        plt.ylabel('SalePrice')
        plt.show()
           
機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)
機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)
機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)

1.6 資料相關性分析

# 使用熱力圖檢視特征之間的互相關系
corrmat = train_data.corr(method='spearman') # 計算不同資料之間的相系數
plt.figure(figsize=(20,10))
sns.heatmap(corrmat,cmap="YlGnBu", linewidths=.5)
           
機器學習/深度學習實戰——kaggle房價預測比賽實戰(資料分析篇)