【机器学习入门与实际】数据挖掘-二手车价格交易预测(含EDA摸索、特色工程、特色优化、模型交融等)
note:我的项目链接以及码源见文末
1.赛题简介
理解赛题
- 赛题详情
- 数据详情
- 预测指标
- 剖析赛题
- 数据读取pandas
- 分类指标评估计算示例
- 回归指标评估计算示例
EDA摸索
- 载入各种数据迷信以及可视化库
- 载入数据
- 总览数据详情
- 判断数据缺失和异样
- 理解预测值的散布
- 特色分为类别特色和数字特色,并对类别特色查看unique散布
- 数字特征分析
- 类别特征分析
- 用pandas_profiling生成数据报告
特色工程
- 导入数据
- 删除异常值
- 特色结构
- 特色筛选
建模调参,相干原理介绍与举荐
- 线性回归模型
- 决策树模型
- GBDT模型
- XGBoost模型
- LightGBM模型
- 举荐教材
- 读取数据
- 线性回归 & 五折穿插验证 & 模仿实在业务状况
- 多种模型比照
- 模型调参
模型交融
- 回归\分类概率-交融
- 分类模型交融
- 一些其它办法
- 本赛题示例
1.1 数据阐明
较量要求参赛选手依据给定的数据集,建设模型,二手汽车的交易价格。
来自 Ebay Kleinanzeigen 报废的二手车,数量超过 370,000,蕴含 20 列变量信息,为了保障
较量的公平性,将会从中抽取 10 万条作为训练集,5 万条作为测试集 A,5 万条作为测试集
B。同时会对名称、车辆类型、变速箱、model、燃油类型、品牌、公里数、价格等信息进行
脱敏。
一般而言,对于数据在较量界面都有对应的数据详情介绍(匿名特色除外),阐明列的性质特色。理解列的性质会有助于咱们对于数据的了解和后续剖析。
Tip:匿名特色,就是未告知数据列所属的性质的特色列。
train.csv
- 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'(依据汽车的评论、标签等大量信息失去的embedding向量)【人工结构 匿名特色】
数字全都脱敏解决,都为label encoding模式,即数字模式
1.2预测指标
本赛题的评估规范为MAE(Mean Absolute Error):
$$MAE=\frac{\sum_{i=1}^{n}\left|y_{i}-\hat{y}_{i}\right|}{n}$$
其中$y_{i}$代表第$i$个样本的实在值,其中$\hat{y}_{i}$代表第$i$个样本的预测值。
个别问题评估指标阐明:
什么是评估指标:
评估指标即是咱们对于一个模型成果的数值型量化。(有点相似与对于一个商品评估打分,而这是针对于模型成果和现实成果之间的一个打分)
一般来说分类和回归问题的评估指标有如下一些模式:
分类算法常见的评估指标如下:
- 对于二类分类器/分类算法,评估指标次要有accuracy, [Precision,Recall,F-score,Pr曲线],ROC-AUC曲线。
- 对于多类分类器/分类算法,评估指标次要有accuracy, [宏均匀和微均匀,F-score]。
对于回归预测类常见的评估指标如下:
- 均匀绝对误差(Mean Absolute Error,MAE),均方误差(Mean Squared Error,MSE),均匀相对百分误差(Mean Absolute Percentage Error,MAPE),均方根误差(Root Mean Squared Error), R2(R-Square)
均匀绝对误差
均匀绝对误差(Mean Absolute Error,MAE):均匀绝对误差,其能更好地反映预测值与实在值误差的理论状况,其计算公式如下:
$$MAE=\frac{1}{N} \sum_{i=1}^{N}\left|y_{i}-\hat{y}_{i}\right|$$
均方误差
均方误差(Mean Squared Error,MSE),均方误差,其计算公式为:
$$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$表达式为:
$$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,表明回归平方和占总平方和的比例越大,回归线与各观测点越靠近,用x的变动来解释y值变动的局部就越多,回归的拟合水平就越好。所以$R^2$也称为拟合优度(Goodness of Fit)的统计量。
$y_{i}$示意实在值,$\hat{y}_{i}$示意预测值,$\overline{y}_{i}$示意样本均值。得分越高拟合成果越好。
1.3剖析赛题
- 此题为传统的数据挖掘问题,通过数据迷信以及机器学习深度学习的方法来进行建模失去后果。
- 此题是一个典型的回归问题。
- 次要利用xgb、lgb、catboost,以及pandas、numpy、matplotlib、seabon、sklearn、keras等等数据挖掘罕用库或者框架来进行数据挖掘工作。
2.数据摸索
# 下载数据!wget http://tianchi-media.oss-cn-beijing.aliyuncs.com/dragonball/DM/data.zip# 解压下载好的数据!unzip data.zip
# 导入函数工具## 根底工具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 timewarnings.filterwarnings('ignore')%matplotlib inline## 模型预测的from sklearn import linear_modelfrom sklearn import preprocessingfrom sklearn.svm import SVRfrom sklearn.ensemble import RandomForestRegressor,GradientBoostingRegressor## 数据降维解决的from sklearn.decomposition import PCA,FastICA,FactorAnalysis,SparsePCAimport lightgbm as lgbimport xgboost as xgb## 参数搜寻和评估的from sklearn.model_selection import GridSearchCV,cross_val_score,StratifiedKFold,train_test_splitfrom sklearn.metrics import mean_squared_error, mean_absolute_error
2.1 数据读取
## 通过Pandas对于数据进行读取 (pandas是一个很敌对的数据读取函数库)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=' ')## 输入数据的大小信息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 数据简要浏览
## 通过.head() 简要浏览读取数据的模式Train_data.head()
<div>
<style scoped>
.dataframe tbody tr th:only-of-type { vertical-align: middle;}.dataframe tbody tr th { vertical-align: top;}.dataframe thead th { text-align: right;}
</style>
SaleID | name | regDate | model | brand | bodyType | fuelType | gearbox | power | kilometer | ... | v_5 | v_6 | v_7 | v_8 | v_9 | v_10 | v_11 | v_12 | v_13 | v_14 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 736 | 20040402 | 30.0 | 6 | 1.0 | 0.0 | 0.0 | 60 | 12.5 | ... | 0.235676 | 0.101988 | 0.129549 | 0.022816 | 0.097462 | -2.881803 | 2.804097 | -2.420821 | 0.795292 | 0.914762 |
1 | 1 | 2262 | 20030301 | 40.0 | 1 | 2.0 | 0.0 | 0.0 | 0 | 15.0 | ... | 0.264777 | 0.121004 | 0.135731 | 0.026597 | 0.020582 | -4.900482 | 2.096338 | -1.030483 | -1.722674 | 0.245522 |
2 | 2 | 14874 | 20040403 | 115.0 | 15 | 1.0 | 0.0 | 0.0 | 163 | 12.5 | ... | 0.251410 | 0.114912 | 0.165147 | 0.062173 | 0.027075 | -4.846749 | 1.803559 | 1.565330 | -0.832687 | -0.229963 |
3 | 3 | 71865 | 19960908 | 109.0 | 10 | 0.0 | 0.0 | 1.0 | 193 | 15.0 | ... | 0.274293 | 0.110300 | 0.121964 | 0.033395 | 0.000000 | -4.509599 | 1.285940 | -0.501868 | -2.438353 | -0.478699 |
4 | 4 | 111080 | 20120103 | 110.0 | 5 | 1.0 | 0.0 | 0.0 | 68 | 5.0 | ... | 0.228036 | 0.073205 | 0.091880 | 0.078819 | 0.121534 | -1.896240 | 0.910783 | 0.931110 | 2.834518 | 1.923482 |
<p>5 rows × 31 columns</p>
</div>
2.3 数据信息查看
## 通过 .info() 简要能够看到对应一些数据列名,以及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 float64dtypes: float64(20), int64(10), object(1)memory usage: 35.5+ MB
## 通过 .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 float64dtypes: float64(20), int64(9), object(1)memory usage: 11.4+ MB
2.4 数据统计信息浏览
## 通过 .describe() 能够查看数值特色列的一些统计信息Train_data.describe()
<div>
<style scoped>
.dataframe tbody tr th:only-of-type { vertical-align: middle;}.dataframe tbody tr th { vertical-align: top;}.dataframe thead th { text-align: right;}
</style>
SaleID | name | regDate | model | brand | bodyType | fuelType | gearbox | power | kilometer | ... | v_5 | v_6 | v_7 | v_8 | v_9 | v_10 | v_11 | v_12 | v_13 | v_14 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
count | 150000.000000 | 150000.000000 | 1.500000e+05 | 149999.000000 | 150000.000000 | 145494.000000 | 141320.000000 | 144019.000000 | 150000.000000 | 150000.000000 | ... | 150000.000000 | 150000.000000 | 150000.000000 | 150000.000000 | 150000.000000 | 150000.000000 | 150000.000000 | 150000.000000 | 150000.000000 | 150000.000000 |
mean | 74999.500000 | 68349.172873 | 2.003417e+07 | 47.129021 | 8.052733 | 1.792369 | 0.375842 | 0.224943 | 119.316547 | 12.597160 | ... | 0.248204 | 0.044923 | 0.124692 | 0.058144 | 0.061996 | -0.001000 | 0.009035 | 0.004813 | 0.000313 | -0.000688 |
std | 43301.414527 | 61103.875095 | 5.364988e+04 | 49.536040 | 7.864956 | 1.760640 | 0.548677 | 0.417546 | 177.168419 | 3.919576 | ... | 0.045804 | 0.051743 | 0.201410 | 0.029186 | 0.035692 | 3.772386 | 3.286071 | 2.517478 | 1.288988 | 1.038685 |
min | 0.000000 | 0.000000 | 1.991000e+07 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.500000 | ... | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | -9.168192 | -5.558207 | -9.639552 | -4.153899 | -6.546556 |
25% | 37499.750000 | 11156.000000 | 1.999091e+07 | 10.000000 | 1.000000 | 0.000000 | 0.000000 | 0.000000 | 75.000000 | 12.500000 | ... | 0.243615 | 0.000038 | 0.062474 | 0.035334 | 0.033930 | -3.722303 | -1.951543 | -1.871846 | -1.057789 | -0.437034 |
50% | 74999.500000 | 51638.000000 | 2.003091e+07 | 30.000000 | 6.000000 | 1.000000 | 0.000000 | 0.000000 | 110.000000 | 15.000000 | ... | 0.257798 | 0.000812 | 0.095866 | 0.057014 | 0.058484 | 1.624076 | -0.358053 | -0.130753 | -0.036245 | 0.141246 |
75% | 112499.250000 | 118841.250000 | 2.007111e+07 | 66.000000 | 13.000000 | 3.000000 | 1.000000 | 0.000000 | 150.000000 | 15.000000 | ... | 0.265297 | 0.102009 | 0.125243 | 0.079382 | 0.087491 | 2.844357 | 1.255022 | 1.776933 | 0.942813 | 0.680378 |
max | 149999.000000 | 196812.000000 | 2.015121e+07 | 247.000000 | 39.000000 | 7.000000 | 6.000000 | 1.000000 | 19312.000000 | 15.000000 | ... | 0.291838 | 0.151420 | 1.404936 | 0.160791 | 0.222787 | 12.357011 | 18.819042 | 13.847792 | 11.147669 | 8.658418 |
<p>8 rows × 30 columns</p>
</div>
TestA_data.describe()
<div>
<style scoped>
.dataframe tbody tr th:only-of-type { vertical-align: middle;}.dataframe tbody tr th { vertical-align: top;}.dataframe thead th { text-align: right;}
</style>
SaleID | name | regDate | model | brand | bodyType | fuelType | gearbox | power | kilometer | ... | v_5 | v_6 | v_7 | v_8 | v_9 | v_10 | v_11 | v_12 | v_13 | v_14 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
count | 50000.000000 | 50000.000000 | 5.000000e+04 | 50000.000000 | 50000.000000 | 48587.000000 | 47107.000000 | 48090.000000 | 50000.000000 | 50000.000000 | ... | 50000.000000 | 50000.000000 | 50000.000000 | 50000.000000 | 50000.000000 | 50000.000000 | 50000.000000 | 50000.000000 | 50000.000000 | 50000.000000 |
mean | 174999.500000 | 68542.223280 | 2.003393e+07 | 46.844520 | 8.056240 | 1.782185 | 0.373405 | 0.224350 | 119.883620 | 12.595580 | ... | 0.248669 | 0.045021 | 0.122744 | 0.057997 | 0.062000 | -0.017855 | -0.013742 | -0.013554 | -0.003147 | 0.001516 |
std | 14433.901067 | 61052.808133 | 5.368870e+04 | 49.469548 | 7.819477 | 1.760736 | 0.546442 | 0.417158 | 185.097387 | 3.908979 | ... | 0.044601 | 0.051766 | 0.195972 | 0.029211 | 0.035653 | 3.747985 | 3.231258 | 2.515962 | 1.286597 | 1.027360 |
min | 150000.000000 | 0.000000 | 1.991000e+07 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.500000 | ... | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | -9.160049 | -5.411964 | -8.916949 | -4.123333 | -6.112667 |
25% | 162499.750000 | 11203.500000 | 1.999091e+07 | 10.000000 | 1.000000 | 0.000000 | 0.000000 | 0.000000 | 75.000000 | 12.500000 | ... | 0.243762 | 0.000044 | 0.062644 | 0.035084 | 0.033714 | -3.700121 | -1.971325 | -1.876703 | -1.060428 | -0.437920 |
50% | 174999.500000 | 52248.500000 | 2.003091e+07 | 29.000000 | 6.000000 | 1.000000 | 0.000000 | 0.000000 | 109.000000 | 15.000000 | ... | 0.257877 | 0.000815 | 0.095828 | 0.057084 | 0.058764 | 1.613212 | -0.355843 | -0.142779 | -0.035956 | 0.138799 |
75% | 187499.250000 | 118856.500000 | 2.007110e+07 | 65.000000 | 13.000000 | 3.000000 | 1.000000 | 0.000000 | 150.000000 | 15.000000 | ... | 0.265328 | 0.102025 | 0.125438 | 0.079077 | 0.087489 | 2.832708 | 1.262914 | 1.764335 | 0.941469 | 0.681163 |
max | 199999.000000 | 196805.000000 | 2.015121e+07 | 246.000000 | 39.000000 | 7.000000 | 6.000000 | 1.000000 | 20000.000000 | 15.000000 | ... | 0.291618 | 0.153265 | 1.358813 | 0.156355 | 0.214775 | 12.338872 | 18.856218 | 12.950498 | 5.913273 | 2.624622 |
<p>8 rows × 29 columns</p>
</div>
3.数据分析
#### 1) 提取数值类型特色列名numerical_cols = Train_data.select_dtypes(exclude = 'object').columnsprint(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').columnsprint(categorical_cols)
Index(['notRepairedDamage'], dtype='object')
#### 2) 构建训练和测试样本## 抉择特色列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]## 提前特色列,标签列结构训练样本和测试样本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)
## 定义了一个统计函数,不便后续信息统计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) 统计标签的根本散布信息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
## 绘制标签的统计图,查看标签散布plt.hist(Y_data)plt.show()plt.close()
#### 4) 缺省值用-1填补X_data = X_data.fillna(-1)X_test = X_test.fillna(-1)
4. 模型训练与预测(特色工程、模型交融)
4.1 利用xgb进行五折穿插验证查看模型的参数成果
## 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折穿插验证形式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模型函数
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 切分数据集(Train,Val)进行模型训练,评估和预测
## 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进行两模型的后果加权交融
## 这里咱们采取了简略的加权交融的形式val_Weighted = (1-MAE_lgb/(MAE_xgb+MAE_lgb))*val_lgb+(1-MAE_xgb/(MAE_xgb+MAE_lgb))*val_xgbval_Weighted[val_Weighted<0]=10 # 因为咱们发现预测的最小值有正数,而真实情况下,price为负是不存在的,由此咱们进行对应的后修改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## 查看预测值的统计进行plt.hist(Y_data)plt.show()plt.close()
4.5.输入后果
sub = pd.DataFrame()sub['SaleID'] = TestA_data.SaleIDsub['price'] = sub_Weightedsub.to_csv('./sub_Weighted.csv',index=False)
sub.head()
5. 我的项目具体开展
因篇幅内容限度,将原学习我的项目拆解成多个notebook不便学习,只需一键fork。
5.1 数据分析详解
载入各种数据迷信以及可视化库:
- 数据迷信库 pandas、numpy、scipy;
- 可视化库 matplotlib、seabon;
- 其余;
载入数据:
- 载入训练集和测试集;
- 简略察看数据(head()+shape);
数据总览:
- 通过describe()来相熟数据的相干统计量
- 通过info()来相熟数据类型
判断数据缺失和异样
- 查看每列的存在nan状况
- 异样值检测
理解预测值的散布
- 总体散布详情(无界约翰逊散布等)
- 查看skewness and kurtosis
- 查看预测值的具体频数
- 特色分为类别特色和数字特色,并对类别特色查看unique散布
数字特征分析
- 相关性剖析
- 查看几个特色得 偏度和峰值
- 每个数字特色得散布可视化
- 数字特色相互之间的关系可视化
- 多变量相互回归关系可视化
类型特征分析
- unique散布
- 类别特色箱形图可视化
- 类别特色的小提琴图可视化
- 类别特色的柱形图可视化类别
- 特色的每个类别频数可视化(count_plot)
- 用pandas_profiling生成数据报告
5.2 特色工程
异样解决:
- 通过箱线图(或 3-Sigma)剖析删除异常值;
- BOX-COX 转换(解决有偏散布);
- 长尾截断;
特色归一化/标准化:
- 标准化(转换为规范正态分布);
- 归一化(抓换到 [0,1] 区间);
- 针对幂律散布,能够采纳公式: $log(\frac{1+x}{1+median})$
数据分桶:
- 等频分桶;
- 等距分桶;
- Best-KS 分桶(相似利用基尼指数进行二分类);
- 卡方分桶;
缺失值解决:
- 不解决(针对相似 XGBoost 等树模型);
- 删除(缺失数据太多);
- 插值补全,包含均值/中位数/众数/建模预测/多重插补/压缩感知补全/矩阵补全等;
- 分箱,缺失值一个箱;
特色结构:
- 结构统计量特色,报告计数、求和、比例、标准差等;
- 工夫特色,包含绝对工夫和相对工夫,节假日,双休日等;
- 地理信息,包含分箱,散布编码等办法;
- 非线性变换,包含 log/ 平方/ 根号等;
- 特色组合,特色穿插;
- 仁者见仁,智者见智。
特色筛选
- 过滤式(filter):先对数据进行特征选择,而后在训练学习器,常见的办法有 Relief/方差抉择发/相关系数法/卡方检验法/互信息法;
- 包裹式(wrapper):间接把最终将要应用的学习器的性能作为特色子集的评估准则,常见办法有 LVM(Las Vegas Wrapper) ;
- 嵌入式(embedding):联合过滤式和包裹式,学习器训练过程中主动进行了特征选择,常见的有 lasso 回归;
降维
- PCA/ LDA/ ICA;
- 特征选择也是一种降维。
5.3 模型优化
线性回归模型:
- 线性回归对于特色的要求;
- 解决长尾散布;
- 了解线性回归模型;
模型性能验证:
- 评估函数与指标函数;
- 穿插验证办法;
- 留一验证办法;
- 针对工夫序列问题的验证;
- 绘制学习率曲线;
- 绘制验证曲线;
嵌入式特征选择:
- Lasso回归;
- Ridge回归;
- 决策树;
模型比照:
- 罕用线性模型;
- 罕用非线性模型;
模型调参:
- 贪婪调参办法;
- 网格调参办法;
- 贝叶斯调参办法;
5.4模型交融
简略加权交融:
- 回归(分类概率):算术平均交融(Arithmetic mean),几何平均交融(Geometric mean);
- 分类:投票(Voting)
- 综合:排序交融(Rank averaging),log交融
stacking/blending:
- 构建多层模型,并利用预测后果再拟合预测。
boosting/bagging(在xgboost,Adaboost,GBDT中曾经用到):
- 多树的晋升办法
训练:
预测:
6.总结
二手车预测我的项目是十分经典我的项目,数据挖掘实际(二手车价格预测)的内容来自 Datawhale与天池联结发动的,当初通过整顿和调整让更多对机器学习感兴趣能够上手实战一下
因篇幅内容限度,将原学习我的项目拆解成多个notebook不便学习,只需一键fork。
我的项目链接:
一键fork间接运行,所有我的项目码源都在外面
https://www.heywhale.com/mw/project/64367e0a2a3d6dc93d22054f
机器学习数据挖掘专栏:
https://www.heywhale.com/home/column/64141d6b1c8c8b518ba97dcc
参考链接:
https://github.com/datawhalechina/team-learning-data-mining/tree/master/SecondHandCarPriceForecast
本文参加了「SegmentFault 思否写作挑战赛」,欢送正在浏览的你也退出
https://segmentfault.com/a/1190000043648149