• 随机森林随机回归预测Why do we try to predict happiness? Being able to predict happiness means that we are able to manipulate or try to improve certain components in order to increase our own happiness...

随机森林随机回归预测

Why do we try to predict happiness? Being able to predict happiness means that we are able to manipulate or try to improve certain components in order to increase our own happiness, and possibly national happiness for governments. I found Random Forest (RF) to be the simplest and most efficient package, so let’s get started!

为什么我们要尝试预测幸福？ 能够预测幸福意味着我们能够操纵或尝试改善某些组成部分，以增加我们自己的幸福，甚至可能增加政府的国民幸福。 我发现随机森林(RF)是最简单，最有效的软件包，所以让我们开始吧！

内容： (Contents:)

1. The Data

数据
2. Random Forest Model

随机森林模型
3. Data Cleaning

数据清理
4. Training and Testing

培训与测试
5. Feature Importances

功能重要性
6. Modifying number of variables

修改变量数
7. Evaluating the Model

评估模型

数据：(The Data:)

The data obtained from the #WorldValuesSurvey contains >290 questions & consist of ~69k responses after removing missing data for happiness levels. It is a cross-national survey across the years, and the questionnaire can be found on the website. In particular, we will be looking at the 2017–2020 data set. The size of the data set makes it optimal for machine learning.

#WorldValuesSurvey获得的数据包含超过290个问题，并在删除幸福水平缺失的数据后包含约69k响应。 这是多年来的跨国调查，其问卷可以在网站上找到。 特别是，我们将研究2017-2020年的数据集。 数据集的大小使其最适合机器学习。

随机森林模型：(Random Forest Model:)

To start with, we will be using the RF classifier* since we would like the machine to predict the level of happiness in groups (Very happy, Quite happy, Not very happy, Not at all happy).*side-note, a RF regressor is used when looking for a number that can take a range of values e.g any value between 0 and 1.

首先，我们将使用RF分类器*，因为我们希望机器预测小组中的幸福程度(非常高兴，非常高兴，不太高兴，根本不高兴)。 *旁注，当寻找一个可以取值范围(例如0到1之间的任何值)的数字时，将使用RF回归器。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn import metrics

数据清理：选择数据(Data cleaning: Selecting the data)

Let’s start by getting the columns of only the questions and removing negative values* in the responses to Q46 that asks about happiness levels.

让我们从仅获得问题的列开始，并在对Q46的询问中询问幸福水平的答案中删除负值*。

var="Q46"
df=df[df.columns[32:349]]
df=df[df[var]>0]

*Negative values are either respondents saying they don’t know, have no answer, were not asked or the response was missing. These values would make it harder for the machine to classify them, since it increases the number of categories and are not what we are looking for.

*负值是指受访者表示他们不知道，没有答案，没有被要求或答案丢失。 这些值会使机器更难以对其进行分类，因为这会增加类别的数量，而这并不是我们要寻找的。

The data set remaining is shown below:

剩余的数据集如下所示：

进一步的数据清理：(Further data cleaning:)

The next concern is that we would have to deal with missing values in other columns. There are 3 options to consider:

下一个需要考虑的问题是，我们将不得不处理其他列中缺失的值。 有3个选项可供考虑：

1. Replace the missing values with 0

将缺失的值替换为0
2. Replace the missing values with the mean

用均值替换缺失值
3. Drop the rows with missing values (data set becomes empty).

删除缺少值的行(数据集为空)。

Since the third option is not viable, we will have to check which option, 1 or 2, would give the highest accuracy. In this case, I found that replacing with 0 makes it more accurate.

由于第三个选项不可行，我们将必须检查哪个选项1或2将提供最高的准确性。 在这种情况下，我发现用0代替会使它更准确。

df.fillna(0, inplace=True)

准备火车标签：(Prepare train labels:)

Now we set the ‘label’ for the machine to recognize the feature that I want it to predict and split the data into train and test sets.

现在，我们为机器设置“标签”，以识别我希望它预测和将数据分为训练和测试集的功能。

train_labels = pd.DataFrame(df[var])
train_labels = np.array(df[var])
train_features= df.drop(var, axis = 1)
feature_list = list(train_features.columns)
train_features = np.array(train_features)
train_features, test_features, train_labels, test_labels = train_test_split(train_features, train_labels, test_size = 0.25, random_state = 42)

训练和测试模型：(Train and Test the Model:)

The process of training and testing is simple. To improve the predictive power and/or model speed, we can simply modify the parameters within the RF classifier.

培训和测试的过程很简单。 为了提高预测能力和/或模型速度，我们可以简单地在RF分类器中修改参数。

精度提高：(Increasing accuracy:)

n_estimators — number of trees the algorithm builds before majority voting

n_estimators-算法在多数表决之前构建的树数

max_features — maximum number of features random forest considers to split a node

max_features —随机森林考虑拆分节点的最大特征数

min_sample_leaf — the minimum number of leafs required to split an internal node.

min_sample_leaf —拆分内部节点所需的最小叶子数。

提高速度：(Increasing speed:)

n_jobs — number of processors it is allowed to use. If = 1, only use one processor. If =-1, no limit

n_jobs-允许使用的处理器数量。 如果= 1，则仅使用一个处理器。 如果= -1，则没有限制

random_state — makes the model’s output replicable i.e always produce the same results given the same hyperparameters and training data

random_state —使模型的输出可复制，即在给定相同的超参数和训练数据的情况下始终产生相同的结果

oob_score: random forest cross-validation method

oob_score：随机森林交叉验证方法

rf=RandomForestClassifier(n_estimators = 1000, oob_score = True, n_jobs = -1,random_state =42,max_features = “auto”, min_samples_leaf = 12)
rf.fit(train_features, train_labels)
predictions = rf.predict(test_features)
print(metrics.accuracy_score(test_labels, predictions))

The model takes 1.3 minutes to train ~52k training rows and >290 columns, and 1 second to test. The accuracy was 63.70%. If we had chosen to fill the missing values with the mean, the accuracy would be 63.55%. But what’s important is finding out what influences the machine’s prediction, since those would be the variables that we want to look at. We certainly cannot expect everyone to answer 290+ questions, or try to work on all 290 aspects to improve happiness (that’s going to cost a lot). So we’ll be looking at the feature importances.

该模型需要1.3分钟来训练约52k训练行和> 290列，并且需要1秒进行测试。 准确度是63.70％ 。 如果我们选择用平均值填充缺失值，则准确度将为63.55％ 。 但是重要的是找出影响机器预测的因素，因为这就是我们要查看的变量。 当然，我们当然不能期望每个人都能回答290多个问题，或者尝试在290个方面进行工作以提高幸福感(这将花费很多)。 因此，我们将研究功能的重要性。

功能重要性：(Feature Importances:)

If you recall, feature_list contains the columns of all other variables except Q46. The goal is to understand which are the variables that influence the prediction.

回想一下，feature_list包含除Q46之外的所有其他变量的列。 目的是了解哪些因素会影响预测。

importances = list(rf.feature_importances_)
feature_importances = [(feature, round(importance, 2)) for feature, importance in zip(feature_list, importances)]
feature_importances = sorted(feature_importances, key = lambda x: x[1], reverse = True)
[print('Variable: {:20} Importance: {}'.format(*pair)) for pair in feature_importances]
x_values = list(range(len(importances)))# Make a bar chart
plt.bar(x_values, importances, orientation = 'vertical', color = 'r', edgecolor = 'k', linewidth = 1.2)
# Tick labels for x axis
plt.xticks(x_values, feature_list, rotation='vertical')
# Axis labels and title
plt.ylabel('Importance'); plt.xlabel('Variable'); plt.title('Variable Importances');

Feature importances sum to 1 and what we notice is that certain variables have a greater influence over the prediction compared to the others, and almost every variable has some form of influence, albeit extremely small because there are just too many variables. The next thing is to continue improving our model to allow us to better understand happiness.

特征重要性的总和为1，我们注意到，与其他变量相比，某些变量对预测的影响更大，并且几乎每个变量都有某种形式的影响，尽管由于变量太多而影响很小。 接下来的事情是继续改进我们的模型，以使我们更好地了解幸福。

修改变量数：(Modifying the number of variables:)

Let’s take the top 20 features, and set up a new model using just these 20 variables (+ var itself). We’ll repeat the data cleaning and same RF model. I got an accuracy of 64.47%. If we had chosen to replace missing values with the mean, the accuracy would be 64.41%. What is surprising here is that with smaller number of variables, the model becomes more accurate (from 63.70% to 64.47%). This is likely because the other variables were generating noise in the model and causing it to be less accurate.

让我们采用前20个功能，并仅使用这20个变量(+ var本身)来建立新模型。 我们将重复数据清理和相同的RF模型。 我的准确度是64.47％。 如果我们选择用均值代替缺失值，则准确度将为64.41％ 。 令人惊讶的是，变量数量越少，模型变得越准确(从63.70％64.47％ )。 这可能是因为其他变量在模型中产生了噪音，并导致其准确性降低。

让我们再次看一下功能重要性：(Let’s look at the Feature Importances again:)

This time, it is clearer to tell which variables were more important. You may refer to the questionnaire found on WVS for more detailed information. I will give a summary of the topics that the questions covered.

这次，更清楚地指出哪些变量更重要。 您可以参考WVS上的调查表以获取更多详细信息。 我将总结这些问题涉及的主题。

评估模型：(Evaluating the model:)

Let’s look at the graph of actual vs predicted values for the first 200 test values. For greater visibility of the whole test set, let’s also do a simple count for the difference in values of predicted and actual (predicted minus actual).

让我们看一下前200个测试值的实际值与预测值的关系图。 为了更好地了解整个测试集，我们还对预期值和实际值(预期值减去实际值)之间的差进行简单计数。

The model appears to be slightly more negative than positive in predicting the happiness levels, but would still be considered otherwise balanced!

在预测幸福水平时，该模型似乎比肯定模型更具负面性，但在其他方面仍然可以认为是平衡的！

见解：(Insights:)

What I have done is to examine the key questions out of >290 in the WVS that is more relevant to happiness levels. This would mean that we can try to focus specifically on these aspects when examining happiness.

我要做的是研究WVS中超过290个与幸福感水平更相关的关键问题。 这意味着我们在检查幸福时可以尝试着重于这些方面。

Looking at the questionnaire, we would also notice that Q261 and Q262 are the same thing (age and year born), so we could remove 1 of them to include another feature. For Q266,267,268 (country of birth of the respondent and parents) they appear to be repeats, but are not exactly the same thing since immigration/cross-cultural marriage may occur. Nonetheless, we could consider removing 2 of them since the occurrence is minimal.

通过问卷调查，我们还会注意到Q261和Q262是相同的东西(年龄和出生年份)，因此我们可以删除其中的一个以包括另一个功能。 对于Q266,267,268(受访者和父母的出生国家)，它们似乎是重复的，但由于可能发生移民/跨文化婚姻，因此并非完全相同。 尽管如此，由于发生的可能性很小，我们可以考虑删除其中的2个。

常规主题是：(The general topics are:)

Individual level:Life satisfaction, health, finances, freedom, age, safety, religion, marriage, and family.National level:country, perception of corruption, democracy/political influence, national pride

个人层面：生活满意度，健康，财务，自由，年龄，安全，宗教，婚姻和家庭。 国家层面：国家，对腐败的看法，民主/政治影响，民族自豪感

In particular, health, finances and age were the top features that were deemed as important by the machine. In this sense, the individual level factors has a greater influence on one’s happiness level compared to the national level factors.

特别是，健康，财务和年龄是机器认为重要的重要功能。 从这个意义上说，个人水平因素比国家水平因素对一个人的幸福水平影响更大。

However, I noticed that the WVS did not have data on sleep hours, which was a key element that was observed in my earlier post. Nonetheless, it is still very much useful as we can consider those aspects for further analysis! I’ll be back with more insights into the correlation between those aspects and happiness, to determine how we can improve our happiness levels. Until then, remember to stay happy!

但是，我注意到WVS没有睡眠时间的数据，这是我早先文章中观察到的关键因素。 但是，它仍然非常有用，因为我们可以考虑对这些方面进行进一步分析！ 我将在这些方面与幸福之间的相关性方面提供更多见解，以确定我们如何提高幸福水平。 在此之前，请记住保持快乐！

随机森林随机回归预测

展开全文
• 随机森林气温预测数据+代码 随机森林回归模型 万事俱备，我们可以来建立随机森林模型啦，首先导入工具包，先建立1000个树试试吧，其他参数先用默认值，之后我们会再深入到调参任务中： # 导入算法 from sklearn....

随机森林气温预测数据+代码

随机森林回归模型

万事俱备，我们可以来建立随机森林模型啦，首先导入工具包，先建立1000个树试试吧，其他参数先用默认值，之后我们会再深入到调参任务中：

# 导入算法
from sklearn.ensemble import RandomForestRegressor

# 建模
rf = RandomForestRegressor(n_estimators= 1000, random_state=42)

# 训练
rf.fit(train_features, train_labels)

由于数据样本量还是非常小的，所以很快就可以得到结果了，这里我们先用MAPE指标来进行评估，也就是平均绝对百分误差，其实对于回归任务，评估方法还是比较多，给大家列出来几种，很简单就可以实现出来，也可以选择其他指标来进行评估：

测试

# 预测结果
predictions = rf.predict(test_features)

# 计算误差
errors = abs(predictions - test_labels)

# mean absolute percentage error (MAPE)
mape = 100 * (errors / test_labels)

print ('MAPE:',np.mean(mape))

MAPE: 6.011244187972058

可视化展示树

# 导入所需工具包
from sklearn.tree import export_graphviz
import pydot #pip install pydot

# 拿到其中的一棵树
tree = rf.estimators_[5]

# 导出成dot文件
export_graphviz(tree, out_file = 'tree.dot', feature_names = feature_list, rounded = True, precision = 1)

# 绘图
(graph, ) = pydot.graph_from_dot_file('tree.dot')

# 展示
graph.write_png("somefile.png")

print('The depth of this tree is:', tree.tree_.max_depth)

The depth of this tree is: 15

执行完上述代码，会在指定的目录下（如果只指定其名字，会在代码所在路径下）生成一个tree.png文件，这就是绘制好的一棵树的模型，如图 所示。树模型看起来有点太大，观察起来不太方便，可以使用参数限制决策树的规模， 预剪枝方案在这里可以派上用场。

预剪枝

# 限制一下树模型 n_estimators棵树采用的数据集都是独立自助采样的，最大深度和随机数种子
rf_small = RandomForestRegressor(n_estimators=10, max_depth = 3, random_state=42)
rf_small.fit(train_features, train_labels)

# 提取一颗树
tree_small = rf_small.estimators_[8]

# 保存
export_graphviz(tree_small, out_file = 'small_tree.dot', feature_names = feature_list, rounded = True, precision = 1)

(graph, ) = pydot.graph_from_dot_file('small_tree.dot')

graph.write_png('small_tree.png')

对生成的树模型中各项指标的含义进行了标识，看起来还是比较好理解，其中非叶子节点中包括 4项指标∶ 所选特征与切分点、评估结果、此节点样本数量、节点预测结果（回归中就是平均）。

特征重要性

讲解随机森林算法的时候，曾提到使用集成算法很容易得到其特征重要性，在sklearn工具包中也有现成的函数，调用起来非常容易∶

# 得到特征重要性
importances = list(rf.feature_importances_)

# 转换格式
feature_importances = [(feature, round(importance, 2)) for feature, importance in zip(feature_list, importances)]

# 排序
feature_importances = sorted(feature_importances, key = lambda x: x[1], reverse = True)

# 对应进行打印
[print('Variable: {:20} Importance: {}'.format(*pair)) for pair in feature_importances]

上述输出结果分别打印了当前特征及其所对应的特征重要性，绘制成图表分析起来更容易∶

上述代码可以可以明显发现，temp_1和average这两个特征的重要性占据总体的绝大部分，其他特征的重要性看起来微乎其微。

# 转换成list格式
x_values = list(range(len(importances)))

# 绘图
plt.bar(x_values, importances, orientation = 'vertical')

# x轴名字
plt.xticks(x_values, feature_list, rotation='vertical')

# 图名
plt.ylabel('Importance'); plt.xlabel('Variable'); plt.title('Variable Importances');

那么，只用最厉害的特征来建模，其效果会不会更好呢?其实并不能保证效果一定更好，但是速度肯定更快，先来看一下结果∶

# 选择最重要的那两个特征来试一试
rf_most_important = RandomForestRegressor(n_estimators= 1000, random_state=42)

# 拿到这俩特征
important_indices = [feature_list.index('temp_1'), feature_list.index('average')]
train_important = train_features[:, important_indices]
test_important = test_features[:, important_indices]

# 重新训练模型
rf_most_important.fit(train_important, train_labels)

# 预测结果
predictions = rf_most_important.predict(test_important)

errors = abs(predictions - test_labels)

# 评估结果

mape = np.mean(100 * (errors / test_labels))

print('mape:', mape)

6.229055723613811

从损失值上观察，并没有下降，反而上升了，说明其他特征还是有价值的，不能只凭特征重要性就否定部分特征数据，一切还要通过实验进行判断。
但是，当考虑时间效率的时候，就要好好斟酌一下是否应该剔除掉那些用处不大的特征以加快构建模型的速度。到目前为止，已经得到基本的随机森林模型，并可以进行预测，下面来看看模型的预测值与真实值之间的差异∶

# 日期数据
months = features[:, feature_list.index('month')]
days = features[:, feature_list.index('day')]
years = features[:, feature_list.index('year')]

# 转换日期格式
dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]
dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in dates]

# 创建一个表格来存日期和其对应的标签数值
true_data = pd.DataFrame(data = {'date': dates, 'actual': labels})

# 同理，再创建一个来存日期和其对应的模型预测值
months = test_features[:, feature_list.index('month')]
days = test_features[:, feature_list.index('day')]
years = test_features[:, feature_list.index('year')]

test_dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]

test_dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in test_dates]

predictions_data = pd.DataFrame(data = {'date': test_dates, 'prediction': predictions})

# 真实值
plt.plot(true_data['date'], true_data['actual'], 'b-', label = 'actual')

# 预测值
plt.plot(predictions_data['date'], predictions_data['prediction'], 'ro', label = 'prediction')
plt.xticks(rotation = '60');
plt.legend()

# 图名
plt.xlabel('Date'); plt.ylabel('Maximum Temperature (F)'); plt.title('Actual and Predicted Values');

通过上述输出结果的走势可以看出，模型已经基本能够掌握天气变化情况，接下来还需要深入数据，考虑以下几个问题。

1. 如果可利用的数据量增大，会对结果产生什么影响呢?
2. 加入新的特征会改进模型效果吗?此时的时间效率又会怎样?
展开全文
• - 《RandomForest：随机森林预测生物标记biomarker——分类》， 大家可以学习此文，实现分组挖掘两组或多组的特异Features，也可以展示特征的贡献度，获得分类评估的准确度，以及使用新数据进行预测，无监督的随机...

关于随机森林的简介和应用理论，请阅读之前分享的文章：

关于随机森林进行分类的入门实战，请阅读
之前分享的
- 《RandomForest：随机森林预测生物标记biomarker——分类》

大家可以学习此文，实现分组挖掘两组或多组的特异Features，也可以展示特征的贡献度，获得分类评估的准确度，以及使用新数据进行预测，无监督的随机森林等基础技能。

今天我们讲使用randomForest实现回归分析的实战代码。回归的应用主要包括时间序列预测模式，如预测股票、尸体死亡时间等。

本节不需要先难知识可也直接学习使用。

RandomForest安装与加载

# 安装
install.packages("randomForest")
# 加载
library(randomForest)

回归Classification

先了解一下输入数据格式，方便准备

使用R内置按天记录的空气质量数据

data(airquality)

数据包括157天中，臭氧、太阳强度、风和温度，部分有缺失。前4列属性数据，后2列时间月和日为分组数据。

Ozone Solar.R Wind Temp Month Day
1    41     190  7.4   67     5   1
2    36     118  8.0   72     5   2
3    12     149 12.6   74     5   3
4    18     313 11.5   62     5   4
5    NA      NA 14.3   56     5   5
6    28      NA 14.9   66     5   6

设置随机数种子保证结果可重复

set.seed(315)

随机森林回归臭氧与其它所有属性

ozone.rf= randomForest(Ozone ~ ., data=airquality, mtry=3,
importance=TRUE, na.action=na.omit)
print(ozone.rf)

结果如下：包括分析的命令，分析类型，树数量，重要的变量(Feature)个数，平均残差平方，解析率。

Call:
randomForest(formula = Ozone ~ ., data = airquality, mtry = 3,      importance = TRUE, na.action = na.omit)
Type of random forest: regression
Number of trees: 500
No. of variables tried at each split: 3

Mean of squared residuals: 304.4269
% Var explained: 72.26

查看每个变量的分类贡献度，显示仅保留两位小数可读性更好

round(importance(ozone.rf), 2)

%IncMSE IncNodePurity
Solar.R   10.40      10833.08
Wind      23.55      43838.66
Temp      47.13      53731.95
Month      2.04       1504.72
Day        0.91       6306.42

结果为每个相关变量对应两列值。%IncMSE是Increased in mean squared error (%)，直译为增长的错误率平方均值，即去除该变量后，对目标预测的准确度下降的低，可理解为对目标变量预测准确的贡献度。IncNodePurity是Increased node purity，是另一种评估的方法。这里我们只关注%IncMSE就够了。

varImpPlot(ozone.rf)

交叉验证cross-validation

# 先清空NA的样本，验证不允许有NA
airquality = na.omit(airquality)
myairquality= cbind(airquality[1:6], matrix(runif(96 * nrow(airquality)), nrow(airquality), 96))
# 交驻验证添加了随机数的训练集，分组，交叉验证的次数
result= rfcv(myairquality, airquality$Ozone, cv.fold=3) # 绘制错误率曲线，观查错误率与使用Markers数量的变化 with(result, plot(n.var, error.cv, log="x", type="o", lwd=2)) 我们看到一个现象，不是feature越多越好，无关的feature如果多了，反而错误率上升，会影响预测的准确度。 # 使用replicate进行多次交叉验证，可选 result= replicate(5, rfcv(myairquality, airquality$Ozone), simplify=FALSE)
error.cv= sapply(result, "[[", "error.cv")
matplot(result[[1]]\$n.var, cbind(rowMeans(error.cv), error.cv), type="l",
lwd=c(2, rep(1, ncol(error.cv))), col=1, lty=1, log="x",
xlab="Number of variables", ylab="CV Error")

多次验证结果类型，更能说明结果的可信度。

严谨总没有坏处，好的结果都是多角度证明的。

大家学习随机森林的分类、和回归。将来有时间，将带大家上手重复一些高水平文章中的分析，结合具体生物学问题会更有意思。

Reference

写在后面

为鼓励读者交流、快速解决科研困难，我们建立了“宏基因组”专业讨论群，目前己有国内外1500+ 一线科研人员加入。参与讨论，获得专业解答，欢迎分享此文至朋友圈，并扫码加主编好友带你入群，务必备注“姓名-单位-研究方向-职称/年级”。技术问题寻求帮助，首先阅读《如何优雅的提问》学习解决问题思路，仍末解决群内讨论，问题不私聊，帮助同行。

学习扩增子、宏基因组科研思路和分析实战，关注“宏基因组”

点击阅读原文，跳转最新文章目录阅读
https://mp.weixin.qq.com/s/5jQspEvH5_4Xmart22gjMA

展开全文
• 本文是Python商业数据挖掘实战的第3篇1 - 基于不平衡数据的反欺诈模型实战2 - Apriori算法实现智能推荐3- 随机森林预测宽带客户离网前言 组合算法也叫集成学习，在金融行...

本文是Python商业数据挖掘实战的第3篇

前言

组合算法也叫集成学习，在金融行业或非图像识别领域，效果有时甚至比深度学习还要好。能够理解基本原理并将代码用于实际的业务案例是本文的目标，本文将详细介绍如何利用Python实现集成学习中随机森林这个经典的方法来预测宽带客户的流失，主要将分为两个部分：

• 详细原理介绍

• Python代码实战

集成学习

本文的主角是随机森林，所以我们将以随机森林所属的分支 —— 装袋法 入手，深入浅出该集成学习方法的原理步骤。装袋法流程如下

乍一看图中的步骤可能有些复杂，现在来逐步拆解。装袋法中的装袋二字是精髓，顾名思义即将多个模型装入同一个袋子后，让这个袋子作为一个新的模型来实现预测需求，仅此而已。换句话说，即把多个模型组合起来形成一个新的大模型，这个大模型最终给出的预测结果是由这多个小模型综合决定的，决定方式为少数服从多数。

假设有10万条原始数据，用这些数据来做十棵决策树（当然也可以是其他模型），最后这10棵树将被装进了同一个袋子中。这时候取其中一条数据放入这个袋子，便会得出10个预测值(每棵树各一个)，假如其中三棵树给出的预测值为0，剩余的七棵给出的为1，那我们便可知道这个袋子对这个数据的预测结果为 0 的概率是 3/10。

为了更深入的理解装袋法，下面将回答三个与装袋法有关的常见问题

问：袋子中的每个模型使用的样本量范围应为多少合适？

答：如果是上面的例子，袋子里面有十棵树，源数据总量为 10万 条，则每棵树取用的样本量的最小值为最少是1w个(10w/10棵 = 1w/棵)，因为至少要保证不能浪费样本，但每棵树最多可取用多少样本呢？其实在样本量已知，同一袋子中模型个数为n的情况下，样本的选择比例为1/n ~ 0.8最好。每个小模型取用 100% 的样本是绝对没有意义的，那就跟没抽是一样的，这样也就没有体现出装袋，只有每个模型用到的数据都有一定的不同，组合起来后每个的投票（预测结果）也才有意义。

问：袋中模型们之间的相关性会影响最后的决策结果吗？

答：装袋法思路最重要的一点：袋子中每个模型之间不能相关，越不相关越好，这里的不相关主要体现在用于训练每个模型的样本不一样。其次，每个模型的精度越高越好，这样它的投票才更有价值。

PS：训练模型的样本不一样这一点可以理解为总统选举，抽 10 波选民来投票，这 10 波选民的差异性越大越好，这样一来，只有在选民千差万别的情况下你依然脱颖而出，才足以说明你的实力，如果这10波选民中每一波之间的差异性都很小，比如都是本来就偏袒于总统候选人，那投票结果的说服力就会大减。

问：上面所说的模型精度高是不是哪怕模型很复杂也可以，如果每个模型的精度高但都过度拟合怎么办？

答：在装袋法中，模型是越精确越好，哪怕是过度拟合的也没有关系。因为一个模型要想在训练集上做到越精确越好，而精确程度与模型的复杂度大多是成正比的，所以出现过拟合的情况也是正常且情有可原的。复杂和过度拟合只是对袋子中每个模型而言，因为最后都会被加权，所以整个袋子（整体）并不会出现过度拟合的情况。

随机森林

随机森林的实现步骤如下：

有关随机森林算法，本文说明以下几个问题

问：为什么在列上也要随机抽样？

答：在引入笔者最最喜欢的一个比喻之前，先来看一个实际的业务场景，来自某城市商业银行。我们有一大个电子表格存着大量的历史数据，大概50多个变量(50多列)，变量们来自几个不同的公司如人行，电信等(同一个客户在不同公司)，最后希望预测的是该客户是否会违约。电子表格组成如下：

而根据基础的业务知识可知，与银行有关的数据中往往会存在许多缺失值，以上图为例，通常情况下只有待预测的变量这一列的数据是齐全的，毕竟客户们是否违约这个行为的历史数据很容易查找，但蓝框和绿框这两部分的缺失值往往较多，而且较随意，具体随意程度参见下图：

红框表示数据缺失，这里只展示了部分行和部分列数据，如果这份数据表的规模为 4万行 * 50列，那这数据缺失的分布得有多随意啊 ????？？所以，到底该如何充分利用这残次不齐的数据就成了呈待解决的关键问题。这时候就可以祭出超级生动形象的 “岛屿 - 湖泊 - 椰子树”比喻了：

• 整个表格看成一座巨大的岛屿，岛屿的长和宽分别对应电子表格横轴长和纵轴的长度

• 表中缺失的数据段看成一个个分布随意的小湖泊，有数据的地方看成陆地

• 整个小岛地底埋藏着巨大的价值（数据价值），通过在随意的种树（用装袋法在行列上进行随机抽样）来吸取地底的养分，毕竟湖泊上种不了树，所以只要足够随机，就总能充分的利用陆地。

正因为是行列都随机，才能够做到真正的把整个数据表随机切分成多份，每个模型使用一份，只要模型的数量足够，总有模型能够在最大程度上获取数据集的价值。而且因变量的分类往往又是极不平衡的，可以参考原理+代码｜手把手教你使用Python实战反欺诈模型至于如何将这些种好的树的信息又再收集，便可以将陆地上比较近的几棵树上面再弄一个收集器，把这几棵树从陆地上收集到的养分再递进一层汇总，最终实现陆地养分汇总于树木，树木养分汇总于收集器，收集器养分汇总于更上层的另一个收集器，最终实现整片数据海洋中多个岛屿的信息汇总，这便是周志华团队和蚂蚁金服的合作的用分布式深度随机森林算法检测套现欺诈

随机森林第一步之后的操作完全可以参照集成学习——装袋法中提及的步骤。

问：既然每个模型给出的预测结果最后都会被加权，所以随机森林中每棵决策树的权重是多少？

问：装袋法中袋子中的模型越多越好吗？袋中用来训练每个模型的源数据比例也是越多越好吗？

答：袋子中模型多一点好，袋中用来训练每个模型的源数据比例小一点好，但这并不代表越多越好与越小越好，还得结合数据集特性和一些深层次的模型算法知识。

装袋法的优势如下：

• 准确率明显高于组合中任何单个分类器

• 对于较大的噪音，表现不至于很差，并且具有鲁棒性

• 不容易过度拟合

随机森林算法的优点

• 准确率有时可以和神经网络媳美，比逻辑回归高

• 对错误和离群点更加鲁棒性

• 决策树容易过度拟合的问题会随着森林的规模而削弱

• 大数据情况下速度快(分布式)，性能好

数据探索

import pandas as pd
import numpy as np

参数说明

df.rename(str.lower, axis='columns', inplace=True)

from collections import Counter
## Broadband:  Counter({0: 908, 1: 206}) 比较不平衡。
## 根据原理部分，可知随机森林是处理数据不平衡问题的利器

接着拆分测试集与训练集，客户id没有用，故丢弃cust_id,

X = df.iloc[:, 1:-1]
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=0.4, random_state=12345)

决策树建模

我们先进行完整的决策树建模来和随机森林进行对比

import sklearn.tree as tree

# 直接使用交叉网格搜索来优化决策树模型，边训练边优化
from sklearn.model_selection import GridSearchCV
# 网格搜索的参数：正常决策树建模中的参数 - 评估指标，树的深度，
## 最小拆分的叶子样本数与树的深度
param_grid = {'criterion': ['entropy', 'gini'],
'max_depth': [2, 3, 4, 5, 6, 7, 8],
'min_samples_split': [4, 8, 12, 16, 20, 24, 28]}
# 通常来说，十几层的树已经是比较深了

clf = tree.DecisionTreeClassifier()  # 定义一棵树
clfcv = GridSearchCV(estimator=clf, param_grid=param_grid,
scoring='roc_auc', cv=4)
# 传入模型，网格搜索的参数，评估指标，cv交叉验证的次数
## 这里也只是定义，还没有开始训练模型

clfcv.fit(X=X_train, y=y_train)

# 使用模型来对测试集进行预测
test_est = clfcv.predict(X_test)

# 模型评估
import sklearn.metrics as metrics

print("决策树准确度:")
print(metrics.classification_report(y_test,test_est))
# 该矩阵表格其实作用不大
print("决策树 AUC:")
fpr_test, tpr_test, th_test = metrics.roc_curve(y_test, test_est)
print('AUC = %.4f' %metrics.auc(fpr_test, tpr_test))

AUC 大于0.5是最基本的要求，可见模型精度还是比较糟糕的，决策树的调优技巧就不再过多展开，我们将在随机森林调优部分展示

随机森林建模

随机森林建模一样是使用网格搜索，有关Python实现随机森林建模的详细参数解释可以看代码的注释

param_grid = {
'criterion':['entropy','gini'],
'max_depth':[5, 6, 7, 8],    # 深度：这里是森林中每棵决策树的深度
'n_estimators':[11,13,15],  # 决策树个数-随机森林特有参数
'max_features':[0.3,0.4,0.5],
# 每棵决策树使用的变量占比-随机森林特有参数（结合原理）
'min_samples_split':[4,8,12,16]  # 叶子的最小拆分样本量
}

import sklearn.ensemble as ensemble # ensemble learning: 集成学习

rfc = ensemble.RandomForestClassifier()
rfc_cv = GridSearchCV(estimator=rfc, param_grid=param_grid,
scoring='roc_auc', cv=4)
rfc_cv.fit(X_train, y_train)

# 使用随机森林对测试集进行预测
test_est = rfc_cv.predict(X_test)
print('随机森林精确度...')
print(metrics.classification_report(test_est, y_test))
print('随机森林 AUC...')
fpr_test, tpr_test, th_test = metrics.roc_curve(test_est, y_test)
# 构造 roc 曲线
print('AUC = %.4f' %metrics.auc(fpr_test, tpr_test))

可以看到，模型的精度大大提升

为什么要打印梯度优化给出的最佳参数？打印梯度优化结果的最佳参数的目的是为了判断这个分类模型的各种参数是否在决策边界上，简言之，我们不希望决策边界限制了这个模型的效果。（通常这时候会先把复杂度放一边）

不难发现，参数max_depth, min_samples_split, 和n_estimators 这三个参数的范围设置可能有限制模型精度的可能，所以需要适当调整

"""
{'criterion': 'gini',
'max_depth': 8,  在最大值边界上，所以这个参数的最大值范围应该再调大
'max_features': 0.5,  也在最大值边界上，说明这个参数的最小值范围应该再调大
'min_samples_split': 4, 同理，在最小边界上，可考虑把范围调小
'n_estimators': 15 同理，在最大边界上，可以适当调大范围
"""
# 调整结果
param_grid = {
'criterion':['entropy','gini'],
'max_depth':[7, 8, 10, 12],
# 前面的 5，6 也可以适当的去掉，反正已经没有用了
'n_estimators':[11, 13, 15, 17, 19],  #决策树个数-随机森林特有参数
'max_features':[0.4, 0.5, 0.6, 0.7],
#每棵决策树使用的变量占比-随机森林特有参数
'min_samples_split':[2, 3, 4, 8, 12, 16]  # 叶子的最小拆分样本量

现在来查看再次建模的结果

此时都在决策边界内了，但其实调整参数是门技术活，并不只是通过决策边界这一单一指标来调整，后续推文会陆续更新。

小结

最后总结一下：随机森林是集成学习中非常经典的一种方法，基础原理简单，实现优雅，可即学即用。而且随机森林应用十分广泛，并不只是局限于常见的金融领域，只要数据不平衡或者随机缺失严重，都值得尝试。如果你也对本文使用的数据和代码感兴趣，可以在后台回复0726获取，我们下个案例见。

python爬虫人工智能大数据公众号

展开全文
• 本文仅从实战角度去观察，利用机器学习算法中，随机森林模型预测股票市场指数涨跌的准确率。 适合入门玩家 首先，我们导入所需要的模块 import numpy as np import pandas as pd import talib as ta #金融数据...
• 随机森林预测算法的实现

万次阅读 2019-05-01 16:33:51
本文拟采用随机森林实现空气质量的预测。 实现环境：python3.5 所需包：pandas 、numpy、matplotlib、csv等。引入包如下： import pandas as pd import numpy as np import matplotlib.pyplot as plt import ...
• 随机森林 1、集成学习方法 集成学习通过建立几个模型组合来解决单一预测问题 工作原理：生成多个分类器/模型，各自独立地学习和做出预测 这些预测最后结合成单预测，因此优于任何一个单分类做出的预测 2、随机森林 ...
• 随机森林 kaggle 数据挖掘 categories: 数据挖掘 mathjax: true 文章目录前言：1 数据预处理1.1 读入数据1.2 训练集与数据集1.2.1 查看数据完整性1.2.2 查看训练数据描述信息1.3.1 年龄数据简化分组2 数据可视化2.1...
• 在本文中，我们将以Scikit-learn的决策树和随机森林预测NBA获胜者。美国国家篮球协会（NBA）是北美主要的男子职业篮球联赛，被广泛认为是首屈一指的男子职业篮球联赛在世界上。它有30个团队（美国29个，加拿大1个）...
• 原文：《Predicting the direction of stock market prices using random forest》原文下载 机器学习已经广泛地应用在对于资产...发表在《Applied Mathematical Finance》的这篇文章利用随机森林算法对股价d天之后...
• **____本人想用随机森林的predict预测train1 ` ##预测 fraudscore.r (tree, train1.fraudscore) fraudscore.pre (fraudscore.r, train1)#这个会报错 > fraudscore.pre (fraudscore.r, train1) Warning ...
• 使用随机森林算法完成基本建模任务∶包括数据预处理、特征展示、完成建模并进行可视化展示分析。 分析数据样本量与特征个数对结果的影响∶在保证算法一致的前提下，增加数据样本个数，观察结果变
• 随机森林简介 R randomForest包 安装与加载 分类Classification 分类结果主坐轴分析 随机选取2/3预测，1/3验证 无监督分类 分层抽样 Reference 猜你喜欢 写在后面 随机森林简介 如果读者接触过决策树...
• NBA比赛通常是难分胜负，有些时候会在最后一刻才会决出胜负，因此，预测那支球队最后获胜会非常困难。...在此，我们将用到决策树和随机森林预测谁是某场NBA比赛的获胜队，决策树有两个主要的优势： （1）决策过程...
• 1. 2. 参考链接： https://www.jianshu.com/p/d0d7809007a1 http://blog.csdn.net/lulumi2016/article/details/52662069
•  随机森林分类器中的树的个数，最小样本数及最小子叶数都是可以修改的。我们可以通过循环尝试找出最佳参数。这里以树的个数为例。 from sklearn.ensemble import RandomForestClassifier a = [] b = [] for i in ...