數(shù)據(jù)挖掘-二手車價(jià)格交易預(yù)測(cè)(含EDA探索、特征工程、特征優(yōu)化、模型融合等)
【機(jī)器學(xué)習(xí)入門(mén)與實(shí)踐】數(shù)據(jù)挖掘-二手車價(jià)格交易預(yù)測(cè)(含EDA探索、特征工程、特征優(yōu)化、模型融合等)
note:項(xiàng)目鏈接以及碼源見(jiàn)文末
1.賽題簡(jiǎn)介
了解賽題
賽題概況
數(shù)據(jù)概況
預(yù)測(cè)指標(biāo)
分析賽題
數(shù)據(jù)讀取pandas
分類指標(biāo)評(píng)價(jià)計(jì)算示例
回歸指標(biāo)評(píng)價(jià)計(jì)算示例
EDA探索
載入各種數(shù)據(jù)科學(xué)以及可視化庫(kù)
載入數(shù)據(jù)
總覽數(shù)據(jù)概況
判斷數(shù)據(jù)缺失和異常
了解預(yù)測(cè)值的分布
特征分為類別特征和數(shù)字特征,并對(duì)類別特征查看unique分布
數(shù)字特征分析
類別特征分析
用pandas_profiling生成數(shù)據(jù)報(bào)告
特征工程
導(dǎo)入數(shù)據(jù)
刪除異常值
特征構(gòu)造
特征篩選
建模調(diào)參,相關(guān)原理介紹與推薦
線性回歸模型
決策樹(shù)模型
GBDT模型
XGBoost模型
LightGBM模型
推薦教材
讀取數(shù)據(jù)
線性回歸 & 五折交叉驗(yàn)證 & 模擬真實(shí)業(yè)務(wù)情況
多種模型對(duì)比
模型調(diào)參
模型融合
回歸\分類概率-融合
分類模型融合
一些其它方法
本賽題示例
1.1 數(shù)據(jù)說(shuō)明
比賽要求參賽選手根據(jù)給定的數(shù)據(jù)集,建立模型,二手汽車的交易價(jià)格。
來(lái)自 Ebay Kleinanzeigen 報(bào)廢的二手車,數(shù)量超過(guò) 370,000,包含 20 列變量信息,為了保證 比賽的公平性,將會(huì)從中抽取 10 萬(wàn)條作為訓(xùn)練集,5 萬(wàn)條作為測(cè)試集 A,5 萬(wàn)條作為測(cè)試集 B。同時(shí)會(huì)對(duì)名稱、車輛類型、變速箱、model、燃油類型、品牌、公里數(shù)、價(jià)格等信息進(jìn)行 脫敏。
一般而言,對(duì)于數(shù)據(jù)在比賽界面都有對(duì)應(yīng)的數(shù)據(jù)概況介紹(匿名特征除外),說(shuō)明列的性質(zhì)特征。了解列的性質(zhì)會(huì)有助于我們對(duì)于數(shù)據(jù)的理解和后續(xù)分析。 Tip:匿名特征,就是未告知數(shù)據(jù)列所屬的性質(zhì)的特征列。
train.csv
name - 汽車編碼
regDate - 汽車注冊(cè)時(shí)間
model - 車型編碼
brand - 品牌
bodyType - 車身類型
fuelType - 燃油類型
gearbox - 變速箱
power - 汽車功率
kilometer - 汽車行駛公里
notRepairedDamage - 汽車有尚未修復(fù)的損壞
regionCode - 看車地區(qū)編碼
seller - 銷售方
offerType - 報(bào)價(jià)類型
creatDate - 廣告發(fā)布時(shí)間
price - 汽車價(jià)格
v0', 'v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7', 'v8', 'v9', 'v10', 'v11', 'v12', 'v13','v_14'(根據(jù)汽車的評(píng)論、標(biāo)簽等大量信息得到的embedding向量)【人工構(gòu)造 匿名特征】
數(shù)字全都脫敏處理,都為label encoding形式,即數(shù)字形式
1.2預(yù)測(cè)指標(biāo)
本賽題的評(píng)價(jià)標(biāo)準(zhǔn)為MAE(Mean Absolute Error):
$$ MAE=\frac{\sum{i=1}^{n}\left|y{i}-\hat{y}{i}\right|}{n} $$ 其中$y{i}$代表第$i$個(gè)樣本的真實(shí)值,其中$\hat{y}_{i}$代表第$i$個(gè)樣本的預(yù)測(cè)值。
一般問(wèn)題評(píng)價(jià)指標(biāo)說(shuō)明:
什么是評(píng)估指標(biāo):
評(píng)估指標(biāo)即是我們對(duì)于一個(gè)模型效果的數(shù)值型量化。(有點(diǎn)類似與對(duì)于一個(gè)商品評(píng)價(jià)打分,而這是針對(duì)于模型效果和理想效果之間的一個(gè)打分)
一般來(lái)說(shuō)分類和回歸問(wèn)題的評(píng)價(jià)指標(biāo)有如下一些形式:
分類算法常見(jiàn)的評(píng)估指標(biāo)如下:
對(duì)于二類分類器/分類算法,評(píng)價(jià)指標(biāo)主要有accuracy, [Precision,Recall,F(xiàn)-score,Pr曲線],ROC-AUC曲線。
對(duì)于多類分類器/分類算法,評(píng)價(jià)指標(biāo)主要有accuracy, [宏平均和微平均,F(xiàn)-score]。
對(duì)于回歸預(yù)測(cè)類常見(jiàn)的評(píng)估指標(biāo)如下:
平均絕對(duì)誤差(Mean Absolute Error,MAE),均方誤差(Mean Squared Error,MSE),平均絕對(duì)百分誤差(Mean Absolute Percentage Error,MAPE),均方根誤差(Root Mean Squared Error), R2(R-Square)
平均絕對(duì)誤差?平均絕對(duì)誤差(Mean Absolute Error,MAE):平均絕對(duì)誤差,其能更好地反映預(yù)測(cè)值與真實(shí)值誤差的實(shí)際情況,其計(jì)算公式如下: $$ MAE=\frac{1}{N} \sum{i=1}^{N}\left|y{i}-\hat{y}_{i}\right| $$
均方誤差?均方誤差(Mean Squared Error,MSE),均方誤差,其計(jì)算公式為: $$ MSE=\frac{1}{N} \sum{i=1}^{N}\left(y{i}-\hat{y}_{i}\right)^{2} $$
R2(R-Square)的公式為: 殘差平方和: $$ SS{res}=\sum\left(y{i}-\hat{y}{i}\right)^{2} $$ 總平均值: $$ SS{tot}=\sum\left(y{i}-\overline{y}{i}\right)^{2} $$
其中$\overline{y}$表示$y$的平均值 得到$R^2$表達(dá)式為: $$ R^{2}=1-\frac{SS{res}}{SS{tot}}=1-\frac{\sum\left(y{i}-\hat{y}{i}\right)^{2}}{\sum\left(y_{i}-\overline{y}\right)^{2}} $$ $R^2$用于度量因變量的變異中可由自變量解釋部分所占的比例,取值范圍是 0~1,$R^2$越接近1,表明回歸平方和占總平方和的比例越大,回歸線與各觀測(cè)點(diǎn)越接近,用x的變化來(lái)解釋y值變化的部分就越多,回歸的擬合程度就越好。所以$R^2$也稱為擬合優(yōu)度(Goodness of Fit)的統(tǒng)計(jì)量。
$y{i}$表示真實(shí)值,$\hat{y}{i}$表示預(yù)測(cè)值,$\overline{y}_{i}$表示樣本均值。得分越高擬合效果越好。
1.3分析賽題
此題為傳統(tǒng)的數(shù)據(jù)挖掘問(wèn)題,通過(guò)數(shù)據(jù)科學(xué)以及機(jī)器學(xué)習(xí)深度學(xué)習(xí)的辦法來(lái)進(jìn)行建模得到結(jié)果。
此題是一個(gè)典型的回歸問(wèn)題。
主要應(yīng)用xgb、lgb、catboost,以及pandas、numpy、matplotlib、seabon、sklearn、keras等等數(shù)據(jù)挖掘常用庫(kù)或者框架來(lái)進(jìn)行數(shù)據(jù)挖掘任務(wù)。
2.數(shù)據(jù)探索
# 下載數(shù)據(jù)!wget http://tianchi-media.oss-cn-beijing.aliyuncs.com/dragonball/DM/data.zip# 解壓下載好的數(shù)據(jù)!unzip data.zip
# 導(dǎo)入函數(shù)工具## 基礎(chǔ)工具import numpy as npimport pandas as pdimport warningsimport matplotlibimport matplotlib.pyplot as pltimport seaborn as snsfrom scipy.special import jnfrom IPython.display import display, clear_outputimport time
warnings.filterwarnings('ignore')
%matplotlib inline## 模型預(yù)測(cè)的from sklearn import linear_modelfrom sklearn import preprocessingfrom sklearn.svm import SVRfrom sklearn.ensemble import RandomForestRegressor,GradientBoostingRegressor## 數(shù)據(jù)降維處理的from sklearn.decomposition import PCA,FastICA,FactorAnalysis,SparsePCAimport lightgbm as lgbimport xgboost as xgb## 參數(shù)搜索和評(píng)價(jià)的from sklearn.model_selection import GridSearchCV,cross_val_score,StratifiedKFold,train_test_splitfrom sklearn.metrics import mean_squared_error, mean_absolute_error
2.1 數(shù)據(jù)讀取
## 通過(guò)Pandas對(duì)于數(shù)據(jù)進(jìn)行讀取 (pandas是一個(gè)很友好的數(shù)據(jù)讀取函數(shù)庫(kù))Train_data = pd.read_csv('/home/aistudio/dataset/used_car_train_20200313.csv', sep=' ')
TestA_data = pd.read_csv('/home/aistudio/dataset/used_car_testA_20200313.csv', sep=' ')## 輸出數(shù)據(jù)的大小信息print('Train data shape:',Train_data.shape)
print('TestA data shape:',TestA_data.shape)
Train data shape: (150000, 31)
TestA data shape: (50000, 30)
2.2 數(shù)據(jù)簡(jiǎn)要瀏覽
## 通過(guò).head() 簡(jiǎn)要瀏覽讀取數(shù)據(jù)的形式Train_data.head()
SaleIDnameregDatemodelbrandbodyTypefuelTypegearboxpowerkilometer...v_5v_6v_7v_8v_9v_10v_11v_12v_13v_14007362004040230.061.00.00.06012.5...0.2356760.1019880.1295490.0228160.097462-2.8818032.804097-2.4208210.7952920.9147621122622003030140.012.00.00.0015.0...0.2647770.1210040.1357310.0265970.020582-4.9004822.096338-1.030483-1.7226740.245522221487420040403115.0151.00.00.016312.5...0.2514100.1149120.1651470.0621730.027075-4.8467491.8035591.565330-0.832687-0.229963337186519960908109.0100.00.01.019315.0...0.2742930.1103000.1219640.0333950.000000-4.5095991.285940-0.501868-2.438353-0.4786994411108020120103110.051.00.00.0685.0...0.2280360.0732050.0918800.0788190.121534-1.8962400.9107830.9311102.8345181.923482
5 rows × 31 columns
2.3 數(shù)據(jù)信息查看
## 通過(guò) .info() 簡(jiǎn)要可以看到對(duì)應(yīng)一些數(shù)據(jù)列名,以及NAN缺失信息Train_data.info()
<class 'pandas.core.frame.DataFrame'>RangeIndex: 150000 entries, 0 to 149999Data columns (total 31 columns): # ? Column ? ? ? ? ? ? Non-Null Count ? Dtype ?--- ?------ ? ? ? ? ? ? -------------- ? ----- ? 0 ? SaleID ? ? ? ? ? ? 150000 non-null ?int64 ? 1 ? name ? ? ? ? ? ? ? 150000 non-null ?int64 ? 2 ? regDate ? ? ? ? ? ?150000 non-null ?int64 ? 3 ? model ? ? ? ? ? ? ?149999 non-null ?float64 4 ? brand ? ? ? ? ? ? ?150000 non-null ?int64 ? 5 ? bodyType ? ? ? ? ? 145494 non-null ?float64 6 ? fuelType ? ? ? ? ? 141320 non-null ?float64 7 ? gearbox ? ? ? ? ? ?144019 non-null ?float64 8 ? power ? ? ? ? ? ? ?150000 non-null ?int64 ? 9 ? kilometer ? ? ? ? ?150000 non-null ?float64 10 ?notRepairedDamage ?150000 non-null ?object
11 ?regionCode ? ? ? ? 150000 non-null ?int64 ? 12 ?seller ? ? ? ? ? ? 150000 non-null ?int64 ? 13 ?offerType ? ? ? ? ?150000 non-null ?int64 ? 14 ?creatDate ? ? ? ? ?150000 non-null ?int64 ? 15 ?price ? ? ? ? ? ? ?150000 non-null ?int64 ? 16 ?v_0 ? ? ? ? ? ? ? ?150000 non-null ?float64 17 ?v_1 ? ? ? ? ? ? ? ?150000 non-null ?float64 18 ?v_2 ? ? ? ? ? ? ? ?150000 non-null ?float64 19 ?v_3 ? ? ? ? ? ? ? ?150000 non-null ?float64 20 ?v_4 ? ? ? ? ? ? ? ?150000 non-null ?float64 21 ?v_5 ? ? ? ? ? ? ? ?150000 non-null ?float64 22 ?v_6 ? ? ? ? ? ? ? ?150000 non-null ?float64 23 ?v_7 ? ? ? ? ? ? ? ?150000 non-null ?float64 24 ?v_8 ? ? ? ? ? ? ? ?150000 non-null ?float64 25 ?v_9 ? ? ? ? ? ? ? ?150000 non-null ?float64 26 ?v_10 ? ? ? ? ? ? ? 150000 non-null ?float64 27 ?v_11 ? ? ? ? ? ? ? 150000 non-null ?float64 28 ?v_12 ? ? ? ? ? ? ? 150000 non-null ?float64 29 ?v_13 ? ? ? ? ? ? ? 150000 non-null ?float64 30 ?v_14 ? ? ? ? ? ? ? 150000 non-null ?float64
dtypes: float64(20), int64(10), object(1)
memory usage: 35.5+ MB
## 通過(guò) .columns 查看列名Train_data.columns
Index(['SaleID', 'name', 'regDate', 'model', 'brand', 'bodyType', 'fuelType', ? ? ? 'gearbox', 'power', 'kilometer', 'notRepairedDamage', 'regionCode', ? ? ? 'seller', 'offerType', 'creatDate', 'price', 'v_0', 'v_1', 'v_2', 'v_3', ? ? ? 'v_4', 'v_5', 'v_6', 'v_7', 'v_8', 'v_9', 'v_10', 'v_11', 'v_12', ? ? ? 'v_13', 'v_14'],
? ? ?dtype='object')
TestA_data.info()
<class 'pandas.core.frame.DataFrame'>RangeIndex: 50000 entries, 0 to 49999Data columns (total 30 columns): # ? Column ? ? ? ? ? ? Non-Null Count ?Dtype ?--- ?------ ? ? ? ? ? ? -------------- ?----- ? 0 ? SaleID ? ? ? ? ? ? 50000 non-null ?int64 ? 1 ? name ? ? ? ? ? ? ? 50000 non-null ?int64 ? 2 ? regDate ? ? ? ? ? ?50000 non-null ?int64 ? 3 ? model ? ? ? ? ? ? ?50000 non-null ?float64 4 ? brand ? ? ? ? ? ? ?50000 non-null ?int64 ? 5 ? bodyType ? ? ? ? ? 48587 non-null ?float64 6 ? fuelType ? ? ? ? ? 47107 non-null ?float64 7 ? gearbox ? ? ? ? ? ?48090 non-null ?float64 8 ? power ? ? ? ? ? ? ?50000 non-null ?int64 ? 9 ? kilometer ? ? ? ? ?50000 non-null ?float64 10 ?notRepairedDamage ?50000 non-null ?object
11 ?regionCode ? ? ? ? 50000 non-null ?int64 ? 12 ?seller ? ? ? ? ? ? 50000 non-null ?int64 ? 13 ?offerType ? ? ? ? ?50000 non-null ?int64 ? 14 ?creatDate ? ? ? ? ?50000 non-null ?int64 ? 15 ?v_0 ? ? ? ? ? ? ? ?50000 non-null ?float64 16 ?v_1 ? ? ? ? ? ? ? ?50000 non-null ?float64 17 ?v_2 ? ? ? ? ? ? ? ?50000 non-null ?float64 18 ?v_3 ? ? ? ? ? ? ? ?50000 non-null ?float64 19 ?v_4 ? ? ? ? ? ? ? ?50000 non-null ?float64 20 ?v_5 ? ? ? ? ? ? ? ?50000 non-null ?float64 21 ?v_6 ? ? ? ? ? ? ? ?50000 non-null ?float64 22 ?v_7 ? ? ? ? ? ? ? ?50000 non-null ?float64 23 ?v_8 ? ? ? ? ? ? ? ?50000 non-null ?float64 24 ?v_9 ? ? ? ? ? ? ? ?50000 non-null ?float64 25 ?v_10 ? ? ? ? ? ? ? 50000 non-null ?float64 26 ?v_11 ? ? ? ? ? ? ? 50000 non-null ?float64 27 ?v_12 ? ? ? ? ? ? ? 50000 non-null ?float64 28 ?v_13 ? ? ? ? ? ? ? 50000 non-null ?float64 29 ?v_14 ? ? ? ? ? ? ? 50000 non-null ?float64
dtypes: float64(20), int64(9), object(1)
memory usage: 11.4+ MB
2.4 數(shù)據(jù)統(tǒng)計(jì)信息瀏覽
## 通過(guò) .describe() 可以查看數(shù)值特征列的一些統(tǒng)計(jì)信息Train_data.describe()
SaleIDnameregDatemodelbrandbodyTypefuelTypegearboxpowerkilometer...v_5v_6v_7v_8v_9v_10v_11v_12v_13v_14count150000.000000150000.0000001.500000e+05149999.000000150000.000000145494.000000141320.000000144019.000000150000.000000150000.000000...150000.000000150000.000000150000.000000150000.000000150000.000000150000.000000150000.000000150000.000000150000.000000150000.000000mean74999.50000068349.1728732.003417e+0747.1290218.0527331.7923690.3758420.224943119.31654712.597160...0.2482040.0449230.1246920.0581440.061996-0.0010000.0090350.0048130.000313-0.000688std43301.41452761103.8750955.364988e+0449.5360407.8649561.7606400.5486770.417546177.1684193.919576...0.0458040.0517430.2014100.0291860.0356923.7723863.2860712.5174781.2889881.038685min0.0000000.0000001.991000e+070.0000000.0000000.0000000.0000000.0000000.0000000.500000...0.0000000.0000000.0000000.0000000.000000-9.168192-5.558207-9.639552-4.153899-6.54655625%37499.75000011156.0000001.999091e+0710.0000001.0000000.0000000.0000000.00000075.00000012.500000...0.2436150.0000380.0624740.0353340.033930-3.722303-1.951543-1.871846-1.057789-0.43703450%74999.50000051638.0000002.003091e+0730.0000006.0000001.0000000.0000000.000000110.00000015.000000...0.2577980.0008120.0958660.0570140.0584841.624076-0.358053-0.130753-0.0362450.14124675%112499.250000118841.2500002.007111e+0766.00000013.0000003.0000001.0000000.000000150.00000015.000000...0.2652970.1020090.1252430.0793820.0874912.8443571.2550221.7769330.9428130.680378max149999.000000196812.0000002.015121e+07247.00000039.0000007.0000006.0000001.00000019312.00000015.000000...0.2918380.1514201.4049360.1607910.22278712.35701118.81904213.84779211.1476698.658418
8 rows × 30 columns
TestA_data.describe()
SaleIDnameregDatemodelbrandbodyTypefuelTypegearboxpowerkilometer...v_5v_6v_7v_8v_9v_10v_11v_12v_13v_14count50000.00000050000.0000005.000000e+0450000.00000050000.00000048587.00000047107.00000048090.00000050000.00000050000.000000...50000.00000050000.00000050000.00000050000.00000050000.00000050000.00000050000.00000050000.00000050000.00000050000.000000mean174999.50000068542.2232802.003393e+0746.8445208.0562401.7821850.3734050.224350119.88362012.595580...0.2486690.0450210.1227440.0579970.062000-0.017855-0.013742-0.013554-0.0031470.001516std14433.90106761052.8081335.368870e+0449.4695487.8194771.7607360.5464420.417158185.0973873.908979...0.0446010.0517660.1959720.0292110.0356533.7479853.2312582.5159621.2865971.027360min150000.0000000.0000001.991000e+070.0000000.0000000.0000000.0000000.0000000.0000000.500000...0.0000000.0000000.0000000.0000000.000000-9.160049-5.411964-8.916949-4.123333-6.11266725%162499.75000011203.5000001.999091e+0710.0000001.0000000.0000000.0000000.00000075.00000012.500000...0.2437620.0000440.0626440.0350840.033714-3.700121-1.971325-1.876703-1.060428-0.43792050%174999.50000052248.5000002.003091e+0729.0000006.0000001.0000000.0000000.000000109.00000015.000000...0.2578770.0008150.0958280.0570840.0587641.613212-0.355843-0.142779-0.0359560.13879975%187499.250000118856.5000002.007110e+0765.00000013.0000003.0000001.0000000.000000150.00000015.000000...0.2653280.1020250.1254380.0790770.0874892.8327081.2629141.7643350.9414690.681163max199999.000000196805.0000002.015121e+07246.00000039.0000007.0000006.0000001.00000020000.00000015.000000...0.2916180.1532651.3588130.1563550.21477512.33887218.85621812.9504985.9132732.624622
8 rows × 29 columns
3.數(shù)據(jù)分析
#### 1) 提取數(shù)值類型特征列名numerical_cols = Train_data.select_dtypes(exclude = 'object').columns
print(numerical_cols)
Index(['SaleID', 'name', 'regDate', 'model', 'brand', 'bodyType', 'fuelType', ? ? ? 'gearbox', 'power', 'kilometer', 'regionCode', 'seller', 'offerType', ? ? ? 'creatDate', 'price', 'v_0', 'v_1', 'v_2', 'v_3', 'v_4', 'v_5', 'v_6', ? ? ? 'v_7', 'v_8', 'v_9', 'v_10', 'v_11', 'v_12', 'v_13', 'v_14'],
? ? ?dtype='object')
categorical_cols = Train_data.select_dtypes(include = 'object').columns
print(categorical_cols)
Index(['notRepairedDamage'], dtype='object')
#### 2) 構(gòu)建訓(xùn)練和測(cè)試樣本## 選擇特征列feature_cols = [col for col in numerical_cols if col not in ['SaleID','name','regDate','creatDate','price','model','brand','regionCode','seller']]
feature_cols = [col for col in feature_cols if 'Type' not in col]## 提前特征列,標(biāo)簽列構(gòu)造訓(xùn)練樣本和測(cè)試樣本X_data = Train_data[feature_cols]
Y_data = Train_data['price']
X_test ?= TestA_data[feature_cols]
print('X train shape:',X_data.shape)
print('X test shape:',X_test.shape)
X train shape: (150000, 18)
X test shape: (50000, 18)
## 定義了一個(gè)統(tǒng)計(jì)函數(shù),方便后續(xù)信息統(tǒng)計(jì)def Sta_inf(data):
? ?print('_min',np.min(data))
? ?print('_max:',np.max(data))
? ?print('_mean',np.mean(data))
? ?print('_ptp',np.ptp(data))
? ?print('_std',np.std(data))
? ?print('_var',np.var(data))
#### 3) 統(tǒng)計(jì)標(biāo)簽的基本分布信息print('Sta of label:')
Sta_inf(Y_data)
Sta of label:
_min 11
_max: 99999
_mean 5923.327333333334_ptp 99988
_std 7501.973469876635_var 56279605.942732885
## 繪制標(biāo)簽的統(tǒng)計(jì)圖,查看標(biāo)簽分布plt.hist(Y_data)
plt.show()
plt.close()
#### 4) 缺省值用-1填補(bǔ)X_data = X_data.fillna(-1)
X_test = X_test.fillna(-1)
4. 模型訓(xùn)練與預(yù)測(cè)(特征工程、模型融合)
4.1 利用xgb進(jìn)行五折交叉驗(yàn)證查看模型的參數(shù)效果
## xgb-Modelxgr = xgb.XGBRegressor(n_estimators=120, learning_rate=0.1, gamma=0, subsample=0.8,\
? ? ? ?colsample_bytree=0.9, max_depth=7) #,objective ='reg:squarederror'scores_train = []
scores = []## 5折交叉驗(yàn)證方式sk=StratifiedKFold(n_splits=5,shuffle=True,random_state=0)for train_ind,val_ind in sk.split(X_data,Y_data):
? ?train_x=X_data.iloc[train_ind].values
? ?train_y=Y_data.iloc[train_ind]
? ?val_x=X_data.iloc[val_ind].values
? ?val_y=Y_data.iloc[val_ind]
? ?xgr.fit(train_x,train_y)
? ?pred_train_xgb=xgr.predict(train_x)
? ?pred_xgb=xgr.predict(val_x)
? ?score_train = mean_absolute_error(train_y,pred_train_xgb)
? ?scores_train.append(score_train)
? ?score = mean_absolute_error(val_y,pred_xgb)
? ?scores.append(score)
print('Train mae:',np.mean(score_train))
print('Val mae',np.mean(scores))
4.2 定義xgb和lgb模型函數(shù)
def build_model_xgb(x_train,y_train):
? ?model = xgb.XGBRegressor(n_estimators=150, learning_rate=0.1, gamma=0, subsample=0.8,\
? ? ? ?colsample_bytree=0.9, max_depth=7) #, objective ='reg:squarederror'
? ?model.fit(x_train, y_train) ? ?return modeldef build_model_lgb(x_train,y_train):
? ?estimator = lgb.LGBMRegressor(num_leaves=127,n_estimators = 150)
? ?param_grid = { ? ? ? ?'learning_rate': [0.01, 0.05, 0.1, 0.2],
? ?}
? ?gbm = GridSearchCV(estimator, param_grid)
? ?gbm.fit(x_train, y_train) ? ?return gbm
4.3 切分?jǐn)?shù)據(jù)集(Train,Val)進(jìn)行模型訓(xùn)練,評(píng)價(jià)和預(yù)測(cè)
## Split data with valx_train,x_val,y_train,y_val = train_test_split(X_data,Y_data,test_size=0.3)
print('Train lgb...')
model_lgb = build_model_lgb(x_train,y_train)
val_lgb = model_lgb.predict(x_val)
MAE_lgb = mean_absolute_error(y_val,val_lgb)
print('MAE of val with lgb:',MAE_lgb)
print('Predict lgb...')
model_lgb_pre = build_model_lgb(X_data,Y_data)
subA_lgb = model_lgb_pre.predict(X_test)
print('Sta of Predict lgb:')
Sta_inf(subA_lgb)
print('Train xgb...')
model_xgb = build_model_xgb(x_train,y_train)
val_xgb = model_xgb.predict(x_val)
MAE_xgb = mean_absolute_error(y_val,val_xgb)
print('MAE of val with xgb:',MAE_xgb)
print('Predict xgb...')
model_xgb_pre = build_model_xgb(X_data,Y_data)
subA_xgb = model_xgb_pre.predict(X_test)
print('Sta of Predict xgb:')
Sta_inf(subA_xgb)
4.4進(jìn)行兩模型的結(jié)果加權(quán)融合
## 這里我們采取了簡(jiǎn)單的加權(quán)融合的方式val_Weighted = (1-MAE_lgb/(MAE_xgb+MAE_lgb))*val_lgb+(1-MAE_xgb/(MAE_xgb+MAE_lgb))*val_xgb
val_Weighted[val_Weighted<0]=10 # 由于我們發(fā)現(xiàn)預(yù)測(cè)的最小值有負(fù)數(shù),而真實(shí)情況下,price為負(fù)是不存在的,由此我們進(jìn)行對(duì)應(yīng)的后修正print('MAE of val with Weighted ensemble:',mean_absolute_error(y_val,val_Weighted))
sub_Weighted = (1-MAE_lgb/(MAE_xgb+MAE_lgb))*subA_lgb+(1-MAE_xgb/(MAE_xgb+MAE_lgb))*subA_xgb## 查看預(yù)測(cè)值的統(tǒng)計(jì)進(jìn)行plt.hist(Y_data)
plt.show()
plt.close()
4.5.輸出結(jié)果
sub = pd.DataFrame()
sub['SaleID'] = TestA_data.SaleID
sub['price'] = sub_Weighted
sub.to_csv('./sub_Weighted.csv',index=False)
sub.head()
5. 項(xiàng)目詳細(xì)展開(kāi)
因篇幅內(nèi)容限制,將原學(xué)習(xí)項(xiàng)目拆解成多個(gè)notebook方便學(xué)習(xí),只需一鍵fork。
5.1 數(shù)據(jù)分析詳解
載入各種數(shù)據(jù)科學(xué)以及可視化庫(kù):
數(shù)據(jù)科學(xué)庫(kù) pandas、numpy、scipy;
可視化庫(kù) matplotlib、seabon;
其他;
載入數(shù)據(jù):
載入訓(xùn)練集和測(cè)試集;
簡(jiǎn)略觀察數(shù)據(jù)(head()+shape);
數(shù)據(jù)總覽:
通過(guò)describe()來(lái)熟悉數(shù)據(jù)的相關(guān)統(tǒng)計(jì)量
通過(guò)info()來(lái)熟悉數(shù)據(jù)類型
判斷數(shù)據(jù)缺失和異常
查看每列的存在nan情況
異常值檢測(cè)
了解預(yù)測(cè)值的分布
總體分布概況(無(wú)界約翰遜分布等)
查看skewness and kurtosis
查看預(yù)測(cè)值的具體頻數(shù)
特征分為類別特征和數(shù)字特征,并對(duì)類別特征查看unique分布
數(shù)字特征分析
相關(guān)性分析
查看幾個(gè)特征得 偏度和峰值
每個(gè)數(shù)字特征得分布可視化
數(shù)字特征相互之間的關(guān)系可視化
多變量互相回歸關(guān)系可視化
類型特征分析
unique分布
類別特征箱形圖可視化
類別特征的小提琴圖可視化
類別特征的柱形圖可視化類別
特征的每個(gè)類別頻數(shù)可視化(count_plot)
用pandas_profiling生成數(shù)據(jù)報(bào)告

5.2 特征工程
異常處理:
通過(guò)箱線圖(或 3-Sigma)分析刪除異常值;
BOX-COX 轉(zhuǎn)換(處理有偏分布);
長(zhǎng)尾截?cái)啵?/p>
特征歸一化/標(biāo)準(zhǔn)化:
標(biāo)準(zhǔn)化(轉(zhuǎn)換為標(biāo)準(zhǔn)正態(tài)分布);
歸一化(抓換到 [0,1] 區(qū)間);
針對(duì)冪律分布,可以采用公式: $log(\frac{1+x}{1+median})$
數(shù)據(jù)分桶:
等頻分桶;
等距分桶;
Best-KS 分桶(類似利用基尼指數(shù)進(jìn)行二分類);
卡方分桶;
缺失值處理:
不處理(針對(duì)類似 XGBoost 等樹(shù)模型);
刪除(缺失數(shù)據(jù)太多);
插值補(bǔ)全,包括均值/中位數(shù)/眾數(shù)/建模預(yù)測(cè)/多重插補(bǔ)/壓縮感知補(bǔ)全/矩陣補(bǔ)全等;
分箱,缺失值一個(gè)箱;
特征構(gòu)造:
構(gòu)造統(tǒng)計(jì)量特征,報(bào)告計(jì)數(shù)、求和、比例、標(biāo)準(zhǔn)差等;
時(shí)間特征,包括相對(duì)時(shí)間和絕對(duì)時(shí)間,節(jié)假日,雙休日等;
地理信息,包括分箱,分布編碼等方法;
非線性變換,包括 log/ 平方/ 根號(hào)等;
特征組合,特征交叉;
仁者見(jiàn)仁,智者見(jiàn)智。
特征篩選
過(guò)濾式(filter):先對(duì)數(shù)據(jù)進(jìn)行特征選擇,然后在訓(xùn)練學(xué)習(xí)器,常見(jiàn)的方法有 Relief/方差選擇發(fā)/相關(guān)系數(shù)法/卡方檢驗(yàn)法/互信息法;
包裹式(wrapper):直接把最終將要使用的學(xué)習(xí)器的性能作為特征子集的評(píng)價(jià)準(zhǔn)則,常見(jiàn)方法有 LVM(Las Vegas Wrapper) ;
嵌入式(embedding):結(jié)合過(guò)濾式和包裹式,學(xué)習(xí)器訓(xùn)練過(guò)程中自動(dòng)進(jìn)行了特征選擇,常見(jiàn)的有 lasso 回歸;
降維

PCA/ LDA/ ICA;
特征選擇也是一種降維。
5.3 模型優(yōu)化
線性回歸模型:
線性回歸對(duì)于特征的要求;
處理長(zhǎng)尾分布;
理解線性回歸模型;
模型性能驗(yàn)證:
評(píng)價(jià)函數(shù)與目標(biāo)函數(shù);
交叉驗(yàn)證方法;
留一驗(yàn)證方法;
針對(duì)時(shí)間序列問(wèn)題的驗(yàn)證;
繪制學(xué)習(xí)率曲線;
繪制驗(yàn)證曲線;
嵌入式特征選擇:
Lasso回歸;
Ridge回歸;
決策樹(shù);
模型對(duì)比:
常用線性模型;
常用非線性模型;
模型調(diào)參:

貪心調(diào)參方法;
網(wǎng)格調(diào)參方法;
貝葉斯調(diào)參方法;
5.4模型融合
簡(jiǎn)單加權(quán)融合:
回歸(分類概率):算術(shù)平均融合(Arithmetic mean),幾何平均融合(Geometric mean);
分類:投票(Voting)
綜合:排序融合(Rank averaging),log融合
stacking/blending:
構(gòu)建多層模型,并利用預(yù)測(cè)結(jié)果再擬合預(yù)測(cè)。
boosting/bagging(在xgboost,Adaboost,GBDT中已經(jīng)用到):
訓(xùn)練:
多樹(shù)的提升方法

預(yù)測(cè):

6.總結(jié)
二手車預(yù)測(cè)項(xiàng)目是非常經(jīng)典項(xiàng)目,數(shù)據(jù)挖掘?qū)嵺`(二手車價(jià)格預(yù)測(cè))的內(nèi)容來(lái)自 Datawhale與天池聯(lián)合發(fā)起的,現(xiàn)在通過(guò)整理和調(diào)整讓更多對(duì)機(jī)器學(xué)習(xí)感興趣可以上手實(shí)戰(zhàn)一下
因篇幅內(nèi)容限制,將原學(xué)習(xí)項(xiàng)目拆解成多個(gè)notebook方便學(xué)習(xí),只需一鍵fork。
項(xiàng)目鏈接:
一鍵fork直接運(yùn)行,所有項(xiàng)目碼源都在里面
https://www.heywhale.com/mw/project/64367e0a2a3d6dc93d22054f
機(jī)器學(xué)習(xí)數(shù)據(jù)挖掘?qū)冢?https://www.heywhale.com/home/column/64141d6b1c8c8b518ba97dcc