python不使用库实现随机森林
时间: 2024-01-30 21:04:08 浏览: 75
如果你想自己实现随机森林算法,可以按照以下步骤进行:
1. 从原始数据集中随机抽取一部分数据(有放回),作为新的训练集。
2. 随机选择若干个特征(不放回),用于训练当前的决策树。
3. 在当前训练集上,使用决策树算法生成一棵决策树模型。
4. 重复步骤 1~3,生成多棵决策树模型。
5. 对于新的数据,将其输入到每棵决策树模型中,得到每棵树的预测结果。然后,根据这些预测结果,进行投票或取平均值,得到最终结果。
下面是一个简单的 Python 实现示例:
```python
import random
from collections import Counter
# 定义节点类
class Node:
def __init__(self, feature=None, threshold=None, left=None, right=None, value=None):
self.feature = feature # 分割特征
self.threshold = threshold # 分割阈值
self.left = left # 左子树
self.right = right # 右子树
self.value = value # 叶子节点的预测值
# 定义随机森林类
class RandomForest:
def __init__(self, n_estimators=10, max_depth=5, min_samples_split=2):
self.n_estimators = n_estimators # 决策树的数量
self.max_depth = max_depth # 决策树的最大深度
self.min_samples_split = min_samples_split # 分割节点所需最小样本数
self.trees = [] # 决策树列表
# 训练随机森林
def fit(self, X, y):
for i in range(self.n_estimators):
# 从原始数据集中随机抽取一部分数据(有放回),作为新的训练集。
indices = [random.randint(0, len(X) - 1) for _ in range(len(X))]
X_train = [X[j] for j in indices]
y_train = [y[j] for j in indices]
# 随机选择若干个特征(不放回),用于训练当前的决策树。
features = random.sample(range(len(X[0])), random.randint(1, len(X[0])))
# 在当前训练集上,使用决策树算法生成一棵决策树模型。
tree = self.build_tree(X_train, y_train, features, 0)
self.trees.append(tree)
# 构建决策树
def build_tree(self, X, y, features, depth):
# 若当前节点样本数小于 min_samples_split 或深度达到最大值,返回叶子节点
if len(y) < self.min_samples_split or depth == self.max_depth:
return Node(value=Counter(y).most_common(1)[0][0])
else:
# 选择最优分割特征和阈值
best_feature, best_threshold = self.get_best_split(X, y, features)
# 根据最优分割特征和阈值,将训练集分割成左右两部分
left_indices = [i for i in range(len(X)) if X[i][best_feature] < best_threshold]
right_indices = [i for i in range(len(X)) if X[i][best_feature] >= best_threshold]
# 若分割后左右子集合有一个为空,返回叶子节点
if not left_indices or not right_indices:
return Node(value=Counter(y).most_common(1)[0][0])
else:
# 递归构建左右子树
left = self.build_tree([X[i] for i in left_indices], [y[i] for i in left_indices], features, depth + 1)
right = self.build_tree([X[i] for i in right_indices], [y[i] for i in right_indices], features, depth + 1)
return Node(feature=best_feature, threshold=best_threshold, left=left, right=right)
# 选择最优分割特征和阈值
def get_best_split(self, X, y, features):
best_feature, best_threshold = None, None
best_gini = 1
# 遍历所有特征和阈值,选择最优分割特征和阈值
for feature in features:
for threshold in set([X[i][feature] for i in range(len(X))]):
left_indices = [i for i in range(len(X)) if X[i][feature] < threshold]
right_indices = [i for i in range(len(X)) if X[i][feature] >= threshold]
gini = len(left_indices) / len(y) * self.gini_impurity([y[i] for i in left_indices]) + \
len(right_indices) / len(y) * self.gini_impurity([y[i] for i in right_indices])
if gini < best_gini:
best_feature, best_threshold = feature, threshold
best_gini = gini
return best_feature, best_threshold
# 计算基尼不纯度
def gini_impurity(self, y):
p = [y.count(c) / len(y) for c in set(y)]
return 1 - sum([p[i] * p[j] for i in range(len(p)) for j in range(len(p)) if i != j])
# 对新的数据进行预测
def predict(self, X):
y_pred = []
for x in X:
# 将新数据输入到每棵决策树中,得到每棵树的预测结果
y_pred_tree = [self.traverse_tree(x, tree) for tree in self.trees]
# 根据这些预测结果,进行投票或取平均值,得到最终结果
y_pred.append(Counter(y_pred_tree).most_common(1)[0][0])
return y_pred
# 遍历决策树,对新数据进行预测
def traverse_tree(self, x, node):
if node.value is not None:
return node.value
else:
if x[node.feature] < node.threshold:
return self.traverse_tree(x, node.left)
else:
return self.traverse_tree(x, node.right)
```
在上面的代码中,我们定义了一个 `Node` 类来表示决策树节点,包含分割特征、分割阈值、左右子树和叶子节点的预测值等属性;定义了一个 `RandomForest` 类来表示随机森林模型,包含决策树数量、最大深度、分割节点所需最小样本数和决策树列表等属性,以及训练、预测和评估等方法。在训练方法中,我们按照随机森林算法的步骤,生成多棵决策树模型,并将它们保存在决策树列表中。在预测方法中,我们对新的数据,将其输入到每棵决策树模型中,得到每棵树的预测结果。然后,根据这些预测结果,进行投票或取平均值,得到最终结果。
阅读全文