機器學習:隨機森林演算法及其實現
阿新 • • 發佈:2018-12-31
文章目錄
隨機森林演算法描述:
如何對features進行bootstrap?
我們需要一個feature_bound引數,每次把可以選擇的features打亂,從種選出log(d)個,每次選擇feature劃分時都是這麼選擇。
原來的決策樹程式碼,是在結點的可選node維度列表裡選取:
for feat in self.feats:
現在修改加入隨機性:
feat_len = len(self.feats)
# 預設沒有隨機性
if feature_bound is None:
indices = range(0, feat_len)
elif feature_bound == "log":
# np.random.permutation(n):將陣列打亂後返回
indices = np.random.permutation(feat_len)[:max(1, int(log2(feat_len)))]
else:
indices = np.random.permutation(feat_len)[:feature_bound]
tmp_feats = [self.feats[i] for i in indices]
for feat in tmp_feats:
實際上這個是拉斯維加斯隨機演算法,把確定性演算法的某一步修改成隨機概率方式。
演算法程式碼實現:
# 匯入我們自己實現的決策樹模型
# 匯入我們自己實現的決策樹模型
from c_CvDTree.Tree import *
import numpy as np
class RandomForest(ClassifierBase):
# 建立一個決策樹字典,以便呼叫
_cvd_trees = {
"id3": ID3Tree,
"c45": C45Tree,
"cart" : CartTree
}
def __init__(self):
super(RandomForest, self).__init__()
self._trees = []
# 實現計算的函式
@staticmethod
def most_appearance(arr):
u, c = np.unique(arr, return_counts=True)
return u[np.argmax(c)]
# 預設使用 10 棵 CART 樹、預設 k = log(d)
def fit(self, x, y, sample_weight=None, tree="cart", epoch=10, feature_bound="log",
*args, **kwargs):
x, y = np.atleast_2d(x), np.array(y)
n_sample = len(y)
for _ in range(epoch):
tmp_tree = RandomForest._cvd_trees[tree](*args, **kwargs)
# 每次選取n_sample個樣本
_indices = np.random.randint(n_sample, size=n_sample)
if sample_weight is None:
_local_weight = None
else:
_local_weight = sample_weight[_indices]
_local_weight /= _local_weight.sum()
# 針對樣本進行訓練,生成樹
tmp_tree.fit(x[_indices], y[_indices],
sample_weight=_local_weight, feature_bound=feature_bound)
# 把生成的樹放入森林列表
self._trees.append(deepcopy(tmp_tree))
# 對個體決策樹進行簡單組合
# 把10棵樹的判斷的類別放入列表裡,這裡可能是多個樣本所以是matrix,
# 把每個樣本的類別出現次數最多的類別,即為輸出結果
def predict(self, x):
_matrix = np.array([_tree.predict(x) for _tree in self._trees]).T
return np.array([RandomForest.most_appearance(rs) for rs in _matrix])