博客地址:https://blog.csdn.net/CoderPai/article/details/96499505 点击阅读原文,更好的阅读体验
CoderPai 是一个专注于人工智能在量化交易应用的算法实战平台,主要关注人工智能在量化交易上面的应用。如果你对人工智能感兴趣,请快快关注 “CoderPai” 微信号(coderpai)吧。
(一)机器学习中的集成学习入门
(二)bagging 方法
(三)使用Python进行交易的随机森林算法
(四)Python中随机森林的实现与解释
(五)如何用 Python 从头开始实现 Bagging 算法
(六)如何利用Python从头开始实现随机森林算法(当前文章)
介绍
随机森林是集成学习中一个主要的算法。简而言之,集成方法是一种将几个弱学习器的预测结果进行组合,最终形成一个强学习器的方法。可以直观的猜测一下,随机森林通过减少过拟合来达到比决策树更好的效果。决策树和随机森林都可用于回归和分类问题。在这篇文章中,我们利用随机森林来解决一些问题。
理论
在开始编写代码之前,我们需要了解一些基本理论:
1.特征bagging:自举过程是一种从原始样本中进行又放回的采样。在特征 bagging 过程中,我们从原始特征中进行随机特征采样,并且把采样到的特征传递到不同的树上面。(不采用放回的采集,因为具有冗余特征是没有意义的)。这样做事为了减少树之间的相关性。我们的目标就是制作高度不相关的决策树。
2.聚合:使随机森林比决策树更好的核心是聚合不相关的树。我们的想法是创建几个浅层的树模型,然后将它们平均化以创建更好的随机森林,这样可以将一些随机误差的平均值变为零。在回归的情况下,我们可以平均每个树的预测(平均值),而在分类问题的情况下,我们可以简单的取每个树投票的大多数类别。
Python 代码
要从头开始编码我们的随机森林,我们将遵循自上而下的方法。我们将从一个黑盒子开始,并进一步将其分解为几个黑盒子,抽象级别越来越低,细节越来越多,直到我们最终达到不再抽象的程度。
随机森林类
我们正在创建一个随机森林回归器,如果你想创建一个分类器,那么只需要对此代码进行细微的调整就行了。首先,我们需要知道我们的黑盒子的输入和输出是什么,所以我们需要知道定义我们的随机森林的参数是:
x:训练集的自变量。为了保持简单,我不单独创建一个 fit 方法,因此基类构造函数将接受训练集;
y:监督学习所需的相应因变量(随机森林是一种监督学习技术);
n_trees:我们合作创建随机森林的不相关树的数量;
n_features:要采样并传递到每棵树的要素数量,这是特征bagging 发生的位置。它可以是 sqrt ,log2 或者整数。在 sqrt 的情况下,对于每个树采样的特征的数量是总特征的平方根,在 log2 的情况下是总特征的对数基数 2;
sample_size:随机选择并传递到每个树的行数。这通常等于总行数,但在某些情况下可以减少以提高性能并降低树的相关性(树的 bagging 方法是一种完全独立的机器学习技术);
depth:每个决策树的深度。更高的深度意味着更多的分裂,这增加了每棵树的过度拟合倾向,但由于我们聚集了几个不相关的树木,所以过度拟合单个树木几乎不会对整个森林造成干扰;
minleaf:节点中导致进一步拆分所需的最小行数。降低 minleaf,树的深度会越高;
让我们开始定义我们的随机森林类。
class RandomForest():
def __init__(self, x, y, n_trees, n_features, sample_sz, depth=10, min_leaf=5):
np.random.seed(12)
if n_features == 'sqrt':
self.n_features = int(np.sqrt(x.shape[1]))
elif n_features == 'log2':
self.n_features = int(np.log2(x.shape[1]))
else:
self.n_features = n_features
print(self.n_features, "sha: ",x.shape[1])
self.x, self.y, self.sample_sz, self.depth, self.min_leaf = x, y, sample_sz, depth, min_leaf
self.trees = [self.create_tree() for i in range(n_trees)]
def create_tree(self):
idxs = np.random.permutation(len(self.y))[:self.sample_sz]
f_idxs = np.random.permutation(self.x.shape[1])[:self.n_features]
return DecisionTree(self.x.iloc[idxs], self.y[idxs], self.n_features, f_idxs,
idxs=np.array(range(self.sample_sz)),depth = self.depth, min_leaf=self.min_leaf)
def predict(self, x):
return np.mean([t.predict(x) for t in self.trees], axis=0)