# 随机森林的Python代码实现详解
## 1. 随机森林算法概述
随机森林是一种基于集成学习的Bagging算法,通过构建多个决策树并结合它们的预测结果来提高模型的准确性和鲁棒性[ref_1]。该算法的核心思想在于通过**数据随机采样**和**特征随机选择**来创建多样化的决策树,从而降低过拟合风险[ref_5]。
| 算法特性 | 说明 |
|---------|------|
| 集成方式 | Bagging(自助聚合) |
| 基学习器 | 决策树(通常为CART算法) |
| 随机性来源 | 样本随机抽样 + 特征随机选择 |
| 预测方式 | 分类:投票;回归:平均 |
## 2. 基础随机森林实现
### 2.1 使用scikit-learn库的完整示例
```python
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report
from sklearn.datasets import load_iris
# 加载示例数据集 - 鸢尾花分类
iris = load_iris()
X = iris.data # 特征矩阵
y = iris.target # 目标变量
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
# 创建随机森林分类器
rf_classifier = RandomForestClassifier(
n_estimators=100, # 决策树数量
max_depth=5, # 树的最大深度
min_samples_split=2, # 内部节点再划分所需最小样本数
min_samples_leaf=1, # 叶子节点最少样本数
max_features='sqrt', # 每次分裂时考虑的特征数
random_state=42, # 随机种子
bootstrap=True # 是否使用bootstrap采样
)
# 训练模型
rf_classifier.fit(X_train, y_train)
# 预测测试集
y_pred = rf_classifier.predict(X_test)
# 评估模型性能
accuracy = accuracy_score(y_test, y_pred)
print(f"模型准确率: {accuracy:.4f}")
print("\n分类报告:")
print(classification_report(y_test, y_pred, target_names=iris.target_names))
```
### 2.2 随机森林回归示例
```python
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.datasets import load_boston
import matplotlib.pyplot as plt
# 加载波士顿房价数据集
boston = load_boston()
X = boston.data
y = boston.target
# 数据划分
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
# 创建随机森林回归器
rf_regressor = RandomForestRegressor(
n_estimators=100,
max_depth=10,
random_state=42
)
# 训练模型
rf_regressor.fit(X_train, y_train)
# 预测
y_pred = rf_regressor.predict(X_test)
# 评估回归性能
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"均方误差(MSE): {mse:.4f}")
print(f"决定系数(R²): {r2:.4f}")
```
## 3. 实际应用案例:股票预测
以下是一个基于随机森林的股票涨跌预测实例,展示了如何处理真实世界的时间序列数据[ref_2]:
```python
import akshare as ak
import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import StandardScaler
def prepare_stock_data(symbol="000001", period="1year"):
"""
准备股票数据特征
"""
# 获取股票历史数据
stock_data = ak.stock_zh_a_hist(symbol=symbol, period=period)
# 计算技术指标
stock_data['MA5'] = stock_data['收盘'].rolling(window=5).mean() # 5日移动平均
stock_data['MA20'] = stock_data['收盘'].rolling(window=20).mean() # 20日移动平均
stock_data['Volatility'] = stock_data['收盘'].rolling(window=5).std() # 波动率
# 创建目标变量:次日涨跌(1表示上涨,0表示下跌)
stock_data['Target'] = (stock_data['收盘'].shift(-1) > stock_data['收盘']).astype(int)
# 清理缺失值
stock_data = stock_data.dropna()
return stock_data
# 准备特征和目标变量
stock_df = prepare_stock_data()
features = ['开盘', '收盘', '最高', '最低', '成交量', 'MA5', 'MA20', 'Volatility']
X = stock_df[features]
y = stock_df['Target']
# 特征标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 划分训练测试集
split_point = int(len(X_scaled) * 0.8)
X_train, X_test = X_scaled[:split_point], X_scaled[split_point:]
y_train, y_test = y[:split_point], y[split_point:]
# 训练随机森林模型
rf_stock = RandomForestClassifier(
n_estimators=50,
max_depth=7,
random_state=42
)
rf_stock.fit(X_train, y_train)
# 评估模型
stock_accuracy = rf_stock.score(X_test, y_test)
print(f"股票预测准确率: {stock_accuracy:.4f}")
```
## 4. 特征重要性分析
随机森林的一个重要优势是能够评估特征的重要性[ref_4]:
```python
# 获取特征重要性
feature_importance = rf_classifier.feature_importances_
# 创建特征重要性DataFrame
importance_df = pd.DataFrame({
'feature': iris.feature_names,
'importance': feature_importance
}).sort_values('importance', ascending=False)
print("特征重要性排序:")
print(importance_df)
# 可视化特征重要性
plt.figure(figsize=(10, 6))
plt.barh(importance_df['feature'], importance_df['importance'])
plt.xlabel('特征重要性')
plt.title('随机森林特征重要性分析')
plt.gca().invert_yaxis()
plt.tight_layout()
plt.show()
```
## 5. 手动实现简化版随机森林
为了更好地理解算法原理,下面展示一个简化版的手动实现:
```python
from sklearn.tree import DecisionTreeClassifier
from sklearn.utils import resample
import numpy as np
class SimpleRandomForest:
"""简化版随机森林实现"""
def __init__(self, n_estimators=10, max_features=None, random_state=None):
self.n_estimators = n_estimators
self.max_features = max_features
self.random_state = random_state
self.trees = []
self.feature_indices = []
def fit(self, X, y):
"""训练随机森林"""
np.random.seed(self.random_state)
n_samples, n_features = X.shape
# 确定每次分裂考虑的特征数
if self.max_features is None:
self.max_features = int(np.sqrt(n_features))
for i in range(self.n_estimators):
# 1. 自助采样 (Bootstrap)
X_bootstrap, y_bootstrap = resample(X, y, random_state=self.random_state + i)
# 2. 特征随机选择
feature_idx = np.random.choice(
n_features, size=self.max_features, replace=False
)
# 3. 训练决策树
tree = DecisionTreeClassifier(random_state=self.random_state + i)
tree.fit(X_bootstrap[:, feature_idx], y_bootstrap)
self.trees.append(tree)
self.feature_indices.append(feature_idx)
def predict(self, X):
"""预测"""
predictions = []
for tree, feature_idx in zip(self.trees, self.feature_indices):
pred = tree.predict(X[:, feature_idx])
predictions.append(pred)
# 多数投票
predictions = np.array(predictions)
final_pred = []
for i in range(X.shape[0]):
votes = predictions[:, i]
final_pred.append(np.argmax(np.bincount(votes)))
return np.array(final_pred)
# 测试手动实现的随机森林
simple_rf = SimpleRandomForest(n_estimators=20, random_state=42)
simple_rf.fit(X_train, y_train)
simple_pred = simple_rf.predict(X_test)
simple_accuracy = accuracy_score(y_test, simple_pred)
print(f"手动实现随机森林准确率: {simple_accuracy:.4f}")
```
## 6. 参数调优与最佳实践
### 6.1 网格搜索参数优化
```python
from sklearn.model_selection import GridSearchCV
# 定义参数网格
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [3, 5, 7, None],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4],
'max_features': ['auto', 'sqrt', 'log2']
}
# 网格搜索
grid_search = GridSearchCV(
RandomForestClassifier(random_state=42),
param_grid,
cv=5,
scoring='accuracy',
n_jobs=-1
)
grid_search.fit(X_train, y_train)
print("最佳参数:", grid_search.best_params_)
print("最佳交叉验证分数:", grid_search.best_score_)
```
### 6.2 关键参数说明
| 参数 | 说明 | 推荐值 |
|------|------|--------|
| n_estimators | 决策树数量 | 100-500 |
| max_depth | 树的最大深度 | 5-30或None |
| min_samples_split | 分裂所需最小样本数 | 2-10 |
| min_samples_leaf | 叶节点最小样本数 | 1-4 |
| max_features | 分裂时考虑的特征数 | 'sqrt'或'log2' |
| bootstrap | 是否使用自助采样 | True |
## 7. 模型评估与验证
```python
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
# 交叉验证
cv_scores = cross_val_score(rf_classifier, X, y, cv=5, scoring='accuracy')
print(f"交叉验证准确率: {cv_scores.mean():.4f} (+/- {cv_scores.std() * 2:.4f})")
# 学习曲线
from sklearn.model_selection import learning_curve
train_sizes, train_scores, test_scores = learning_curve(
rf_classifier, X, y, cv=5, train_sizes=np.linspace(0.1, 1.0, 10)
)
plt.figure(figsize=(10, 6))
plt.plot(train_sizes, train_scores.mean(axis=1), 'o-', label='训练得分')
plt.plot(train_sizes, test_scores.mean(axis=1), 'o-', label='验证得分')
plt.xlabel('训练样本数')
plt.ylabel('准确率')
plt.title('随机森林学习曲线')
plt.legend()
plt.grid(True)
plt.show()
```
随机森林作为一种强大的集成学习算法,在分类和回归任务中都表现出色。通过合理的参数调优和特征工程,可以获得更好的预测性能。在实际应用中,建议结合具体业务场景和数据特点来选择合适的参数配置[ref_6]。