1. 程式人生 > >機器學習:Kaggle 項目(房價:先進的回歸技術)

機器學習:Kaggle 項目(房價:先進的回歸技術)

版本 xpl 人工 default his 遠的 sys www. 分布

一、項目目錄

  • (一)數據加載
    1. 基礎統計
    2. 特征分類
    3. 基本分布(scatter)

  • (二)數據分析
    1. 正態性檢驗
      • 偏離度分析 (hist | scatter)
      • 峰度分析 (hist | scatter)
    2. 分散度分析 (box)
      • 特征本身分散度
      • SalePrice 的分散度
    3. 方差齊次檢驗
    4. 方差分析 (bar)
      • scipy.stats.f_oneway()
      • pandas.Series.corr()
    5. 協方差分析(-1~+1)
      • 協方差熱圖 (heatmap)
      • 協方最大關聯圖 (pairplot)

  • (三)數據處理
    1. 無效數據處理
      • 無效特征處理
      • 離群點處理
    2. 缺失值處理
      • NaN和NA的處理函數
      • 數值量:min,max,mean
      • 字符量 -- 僅做類型轉換
    3. 標準化(Normalization)處理
    4. 離散量編碼
      • One-Hot Encoding
      • 分組-均值-排序數值化
      • 以SalePrice為參考的數據
      • 沒有房價可做基準的數據處理

  • (四)機器學習
    1. 模型
      • MXNet
      • pytorch
      • TensorFlow
      • PaddlePaddle
    2. 訓練
    3. 煉丹
    4. 預測

二、數據加載

 1)將 train 數據集和 test 數據集合並

  • 主要代碼
    all_data = pd.concat([train.loc[:,first_feature : last_feature
    ], test.loc[:,first_feature : last_feature]])
  1. ‘first_feature‘:數據集的第一列,也就是第一種特征;
  2. ‘last_feature‘:數據集的最後一列,也就是最後一種特征;
  • 註意:

  1. 合並數據集時,去掉 test 數據集的 “預測值:y” 對應的那一列;
  2. 合並目標:合並後的數據集的每一列都是特征,不含其它信息;train 數據集和 test 數據集都是 DataFrame 數據,如果數據集首列的 “Id”,合並後去除 “Id” 這一列;
  • 查看合並之後的情況:

    print(train.shape, test.shape, all_data.shape)
  • 項目代碼

  1. 加載模塊
    %matplotlib inline
    import numpy as np
    import pandas as pd
    import scipy as sp
    from scipy import stats
    from matplotlib import pyplot as plt
    import seaborn as sns

  2. 本機的各模塊的版本最好與 Kaggle 一致
    import sys
    print(sys.version)
    print(np.__version__)
    print(pd.__version__)
    print(sp.__version__)

    技術分享圖片

  3. 加載數據
    train = pd.read_csv("./kaggle/train.csv")
    test = pd.read_csv("./kaggle/test.csv")
    all_data = pd.concat([train.loc[:,MSSubClass:SaleCondition],
                       test.loc[:,MSSubClass:SaleCondition]])
    all_data = all_data.reset_index(drop=True)
    # df_allX 少了 Id 和 SalePrice 兩列
    print(train.shape,  test.shape, all_data.shape) 

    技術分享圖片

 2)read_csv() 中如何處理 NA

  • 通常確實的值默認為 NA
  • pd.read_csv(file,... na_values=None, keep_default_na=True, ...)
  • na_values遇到該參數指定的字符時,即解析為 np.NaN(float型),無論此列是 numeric 型還是 object 型。
  1. 默認值‘‘、‘#N/A‘、‘#N/A N/A‘、‘#NA‘、‘-1.#IND‘、‘-1.#QNAN‘、‘-NaN‘、‘-nan‘、‘1.#IND‘、‘1.#QNAN‘、‘N/A‘、‘NA‘、‘NULL‘、‘NaN‘、‘nan‘

  • keep_default_na
  1. True:將csv 文件中的數字or字符串與 na_values 的 default 值進行匹配,命中即解析為 np.NaN
  2. False
    • na_values=[...] :與自定義的 na_values 匹配,命中即解析為 np.NaN
    • na_values不賦值:不解析相關字符串,保留為原字符串,副作用:會把數值型的feature錯誤的認成 object 型 —— so,不可取

 3)基礎統計

  • train.describe()

  • describe() 方法的用法,參考:Pandas 和 Series 的 describe() 方法

  1. 查看前五行的信息
    train.head()

    技術分享圖片

  2. 統計數據集
    train.describe().T

    技術分享圖片

 4)特征分類

  • 可以從不同的維度對特征進行分類:
  • 技術分享圖片
  1. 非字符量特征(此項目中為 numeric features)、字符量特征(object featrues)

    # 數值量特征
    feats_numeric = all_data.dtypes[all_data.dtypes != object].index.values
    # feats_numeric = [attr for attr in all_data.columns in all_data.dtypes[attr] != ‘boject‘]
    
    
    # 字符量特征
    feats_object = all_data.dtypes[all_data.dtypes == object].index.values
    # feats_object = [attr for attr in all_data.columns if all_data.dtypes[attr] == ‘object‘]
    # feats_object = train.select_dtypes(include = [‘object‘]).columns
    
    print(feats_numeric.shape, feats_object.shape)

    技術分享圖片

  2. 總共79個特征,pandas自動識別的 36個數值量,43個字符量。 —— 這是上表中第一個維度;
  3. 離散特征、連續特征

    # 離散的數值量,需要人工甄別
    feats_numeric_discrete = [MSSubClass, OverallQual, OverallCond]#戶型、整體質量打分、整體條件打分 -- 文檔中明確定義的類型量
    feats_numeric_discrete += [TotRmsAbvGrd, KitchenAbvGr, BedroomAbvGr, GarageCars, Fireplaces]# 房間數量
    feats_numeric_discrete += [FullBath, HalfBoth, BsmtHalfBath, BsmtFullBath]# 浴室
    feats_numeric_discrete += [MoSold, YrSold]# 年份、月份,看成離散型特征
    
    
    # 連續型特征
    feats_continu = feats_numeric.copy()
    
    # 離散型特征
    feats_discrete = feats_object.copy()
    
    for f in feats_numeric_discrete:
        feats_continu = np.delete(feats_continu, np.where(feats_continu == f))
        feats_discrete = np.append(feats_discrete, f)
        
    print(feats_continu.shape, feats_discrete.shape)

    # (22, ) (57, ):經過處理,得到表中第2個維度: 22個連續型特征,57個離散型特征;

 5)基本分布(scatter)

  • 繪圖函數
    def plotfeats(frame,feats,kind,cols=4):
        """批量繪圖函數。
        
        Parameters
        ----------
        frame : pandas.DataFrame
            待繪圖的數據
        
        feats : list 或 numpy.array
            待繪圖的列名稱
            
        kind : str
            繪圖格式:‘hist‘-直方圖;‘scatter‘-散點圖;‘hs‘-直方圖和散點圖隔行交替;‘box‘-箱線圖,每個feat一幅圖;‘boxp‘-Price做縱軸,feat做橫軸的箱線圖。
            
        cols : int
            每行繪制幾幅圖
        """
        rows = int(np.ceil((len(feats))/cols))
        if rows==1 and len(feats)<cols:
            cols = len(feats)
        #print("輸入%d個特征,分%d行、%d列繪圖" % (len(feats), rows, cols))
        if kind == hs: #hs:hist and scatter
            fig, axes = plt.subplots(nrows=rows*2,ncols=cols,figsize=(cols*5,rows*10))
        else:
            fig, axes = plt.subplots(nrows=rows,ncols=cols,figsize=(cols*5,rows*5))
            if rows==1 and cols==1:
                axes = np.array([axes])
            axes = axes.reshape(rows,cols) # 當 rows=1 時,axes.shape:(cols,),需要reshape一下
        i=0
        for f in feats:
            #print(int(i/cols),i%cols)
            if kind == hist:
                #frame.hist(f,bins=100,ax=axes[int(i/cols),i%cols])
                frame.plot.hist(y=f,bins=100,ax=axes[int(i/cols),i%cols])
            elif kind == scatter:
                frame.plot.scatter(x=f,y=SalePrice,ylim=(0,800000), ax=axes[int(i/cols),i%cols])
            elif kind == hs:
                frame.plot.hist(y=f,bins=100,ax=axes[int(i/cols)*2,i%cols])
                frame.plot.scatter(x=f,y=SalePrice,ylim=(0,800000), ax=axes[int(i/cols)*2+1,i%cols])
            elif kind == box:
                frame.plot.box(y=f,ax=axes[int(i/cols),i%cols])
            elif kind == boxp:
                sns.boxplot(x=f,y=SalePrice, data=frame, ax=axes[int(i/cols),i%cols])
            i += 1
        plt.show()

  • 繪圖:連續性特征與房價的關系

    plotfeats(train, feats_continu, kind=scatter, cols=6)

    技術分享圖片

  • 分析上圖

  • LotFrontage、LotArea、GrLivArea、1stFlrSF、2stFlrSF、GarageArea、BsmtFinSF1、TotalBsmtSF: 這幾個面積和距離和售價呈明顯正相關趨勢
    • LotFrontage:房子到街道的距離,大多在50-100英尺(15-30米),距離遠的是不是大多是豪宅?躲在山林深處……
    • LotArea:占地面積(包括房屋、花園、前後院……),均值是10516平方英尺(900+平方米),向往啊……
    • GrLivArea:地面以上整體面積
    • 1stFlrSF、2stFlrSF: 第1、 2層建築面積
    • GarageArea:車庫面積
    • BsmtFinSF1、BsmtFinSF2、TotalBsmtSF:地下室面積,很多房子還有第2個地下室
  • YearBuilt、YearRemodAdd、GarageYrBlt:從圖中可以看出,建造年限對售價雖正相關,但坡度較小,關聯度沒有上面幾個因素大,早點、晚點售價差不多

  • 繪圖:離散特征

機器學習:Kaggle 項目(房價:先進的回歸技術)