# 独家 | XGBoost介绍：用监督学习来预测期望寿命

## XGBoost：是什么？

XGBoost是一种Python框架，它可以让我们使用提升树进行多核并行训练。在R语言中同样可以使用XGBoost，但在这里我们不多做介绍。

## 提升树和随机森林：不同之处

XGBoost的官方文档：

《统计学习导论》：

https://www.bookdepository.com/book/9781461471370/?a_aid=strikingloo&chan=ws

## 在Python上使用XGBoost

XGBoost的API相当简单明了，但是我们还是要学一些关于超参数的知识。首先我要向你们展示今天的任务。

HDI数据集包含很多关于大部分国家发展水平的信息，涉及到多个领域和多方面的度量，跨越了数十年的时间维度。针对今天的文章，我决定只选取最新的可用数据——2017年，以接近目前的实际情况。

#### 1. 用Pandas进行数据预处理

{country: {metric1: value1, metric2: value2, etc.}
for country in countries }

import pandas as pd
import xgboost as xgb

df = df[['dimension','indicator_name','iso3','country_name','2017']]
df.shape # (25636, 5)
df = df.dropna() # getting rid of NaNs

df.shape #(12728, 5)
df.iso3.unique().shape # 195 countries

df['indicator_name'].unique()

indicator_data = df[df['indicator_name']==indicator]
zipped_values = zip(list(indicator_data['iso3']), list(indicator_data['2017']))
for k, v in zipped_values:
try:
dictionary[k][indicator] = v
except:
print("failed with key: "+k+" on "+indicator)

indic = {}
indicators = [
'Share of seats in parliament (% held by women)',
'Infants lacking immunization, measles (% of one-year-olds)',
'Youth unemployment rate (female to male ratio)',
'Expected years of schooling (years)',
'Expected years of schooling, female (years)',
'Expected years of schooling, male (years)',
'Unemployment, total (% of labour force)',
'Unemployment, youth (% ages 15–24)',
'Vulnerable employment (% of total employment)',
]
for indicator in indicators:

final_df = pd.DataFrame(indic).transpose()

#### 2. 特征相关性分析

import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
fig = sns.heatmap(final_df.corr())
plt.title("Correlation Heatmap")
plt.tight_layout()
plt.savefig("correlation_heatmap", figsize=(96,72))

#### 3. 训练XGBoost模型

# The features we use to train the model obviously can't contain the label.
train_features = [feature for feature in list(final_df) if feature != life_expec]

train_df = final_df.iloc[:150][train_features]
train_label = final_df.iloc[:150][life_expec]

test_df = final_df.iloc[150:][train_features]
test_label = final_df.iloc[150:][life_expec]

import xgboost as xgb

dtrain = xgb.DMatrix(train_df, label=train_label)
dtest = xgb.DMatrix(test_df, label=test_label)
# specify parameters via map
param = {'max_depth':6,
'eta':1,  #this is the default value anyway
'colsample_bytree':1  #this is the default value anyway
}

num_round = 15
initial_trees = xgb.train(param, dtrain, num_round)

## XGBoost 超参数入门

max_depth 指的是在集合中允许每棵树所到达的最大深度。如果这个参数很大，那么树就倾向于更复杂，在其他条件相同的情况下，通常会更快地出现过拟合（）。

eta是学习率。就像我前面说过的一样，这个值会在拟合下一棵树之前乘以每棵树的输出，并在预测时将这些乘积求和。如果将eta设置成默认值1，它就没有任何作用。如果设置成小一点的数，这个模型的收敛时间会慢一些，但一般情况下拟合数据的情况会更好（存在过拟合风险）。它的作用与神经网络的学习率相似。

colsample_bytree指的是，对于每棵树产生分支时，有多少可用的列。默认值是1，代表着“所有都可用”。我们可能会设置一个较小的数值，这样所有的树就不会反复地只用那些最好用的特征。这样，这个模型对于不同数据分布的鲁棒性更好，而且过拟合的情况更少。

## 评估我们的结果

import math

def msesqrt(std, test_label, preds):
squared_errors = [diff*diff for diff in (test_label - preds)]
return math.sqrt(sum(squared_errors)/len(preds))

msesqrt(std, test_label, first_preds) # 4.02

2017年的预期寿命标准差略大于7（我用Pandas检查过），所以不要嘲笑我的均方根误差是4！整个训练过程超级快，尽管这么小的数据集并没有充分利用XGBoost的多核功能。

## 超参数调优：让我们来进行迭代

param = {'max_depth':5,
'eta':.1,
'colsample_bytree':.75
}
num_round = 40
new_tree = xgb.train(param, dtrain, num_round)
# make prediction
new_preds = new_tree.predict(dtest)

## 理解XGBoost的决策：特征重要性

article on Medium对此提供了清晰的讲解，在看到这篇文章之前我并不是特别理解这些方法，只能把它们机械地联系在一起，实际上这只是用不同方式来解释同样一件事而已。

article on Medium：

## 总结

XGBoost为我们提供了一个很好的回归模型，甚至可以协助我们理解它是用哪些特征去做预测的。

Intro to XGBoost: Predicting Life Expectancy with Supervised Learning

https://www.kdnuggets.com/2019/05/intro-xgboost-predicting-life-expectancy-supervised-learning.html

+ 订阅