好的,决定系数($R^2$)是一个常用的评估指标,用于衡量模型预测值与真实值之间的拟合程度。$R^2$ 的值范围从负无穷到 1,值越接近 1 表示模型的拟合效果越好。
我们可以在训练和测试集上计算决定系数,并将其输出。以下是更新后的代码,包含决定系数的计算和输出:
```python
import pandas as pd
from sklearn.model_selection import train_test_split, RandomizedSearchCV, cross_val_score
from sklearn.ensemble import RandomForestRegressor
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error, r2_score
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
from scipy.stats import randint, uniform
# 设置中文字体
matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 使用黑体显示中文
matplotlib.rcParams['axes.unicode_minus'] = False # 解决负号 '-' 显示为方块的问题
# 加载数据
data = pd.read_csv('2016年电工数学建模竞赛负荷预测数据集.csv')
# 查看前几行数据确保正确加载
print(data.head())
# 检查是否有缺失值并处理
print(data.isnull().sum())
data.fillna(data.mean(), inplace=True) # 使用均值填充缺失值
# 创建新特征
data['日期'] = pd.to_datetime(data.index) # 假设日期是索引
data['星期几'] = data['日期'].dt.weekday
data['月份'] = data['日期'].dt.month
data['是否节假日'] = data['日期'].apply(lambda x: 1 if x.day_name() in ['Saturday', 'Sunday'] else 0)
# 更新特征矩阵
X = data[['最高温度℃', '最低温度℃', '平均温度℃', '相对湿度(平均)', '降雨量(mm)', '星期几', '月份', '是否节假日']]
y = data['日需求负荷(KWh)']
# 标准化特征
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
X_scaled_df = pd.DataFrame(X_scaled, columns=X.columns)
# 分割数据为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_scaled_df, y, test_size=0.2, random_state=42)
# 定义随机森林超参数空间
param_dist = {
'n_estimators': randint(100, 501),
'max_depth': [None] + list(range(10, 51, 10)),
'min_samples_split': randint(2, 11),
'min_samples_leaf': randint(1, 5),
'bootstrap': [True, False],
'max_features': ['sqrt', 'log2'] + list(np.linspace(0.1, 1.0, 10)), # 添加合理的浮点数值
'oob_score': [True, False], # 使用袋外分数进行评估
'criterion': ['mse', 'mae'], # 损失函数的选择
}
rf_model = RandomForestRegressor(random_state=42)
# 使用随机搜索进行超参数调优
random_search = RandomizedSearchCV(
estimator=rf_model,
param_distributions=param_dist,
n_iter=100,
cv=5,
verbose=2,
random_state=42,
n_jobs=-1,
error_score='raise' # 确保捕获所有错误
)
random_search.fit(X_train, y_train)
# 输出最佳参数
print("Best Parameters:", random_search.best_params_)
# 使用最佳参数训练模型
best_rf_model = random_search.best_estimator_
# 交叉验证评估
cv_scores = cross_val_score(best_rf_model, X_train, y_train, cv=5, scoring='neg_mean_squared_error')
print(f'Random Forest CV RMSE: {-np.sqrt(-cv_scores.mean()):.2f}')
# 在测试集上进行预测
y_pred_rf = best_rf_model.predict(X_test)
# 计算均方根误差(RMSE)作为评估指标
rmse_rf = np.sqrt(mean_squared_error(y_test, y_pred_rf))
print(f'Random Forest Test RMSE: {rmse_rf:.2f}')
# 计算决定系数 R^2
r2_train = r2_score(y_train, best_rf_model.predict(X_train))
r2_test = r2_score(y_test, y_pred_rf)
print(f'Random Forest Train R^2: {r2_train:.4f}')
print(f'Random Forest Test R^2: {r2_test:.4f}')
# 特征重要性分析
importances = best_rf_model.feature_importances_
feature_importances = pd.Series(importances, index=X.columns)
feature_importances.sort_values(ascending=False).plot(kind='bar', figsize=(10, 6))
plt.title('特征重要性')
plt.show()
# 绘制预测值和实际值的对比图
plt.figure(figsize=(10, 6))
plt.plot(y_test.values, label='实际值', color='blue', marker='o')
plt.plot(y_pred_rf, label='RF预测值', color='red', marker='x')
plt.title('实际值 vs 随机森林预测值')
plt.xlabel('样本索引')
plt.ylabel('日需求负荷 (KWh)')
plt.legend()
plt.grid(True)
plt.show()
# 使用袋外分数评估模型(如果使用 oob_score=True)
if hasattr(best_rf_model, 'oob_score_'):
print(f'OOB Score: {best_rf_model.oob_score_:.4f}')
```
### 关键改进点
1. **计算决定系数 $R^2$**:
- 使用 `r2_score` 函数计算训练集和测试集上的决定系数。
- 输出训练集和测试集上的决定系数,以便评估模型的拟合程度和泛化能力。
2. **输出决定系数**:
- 在训练和测试集上分别计算并输出决定系数,帮助你更好地理解模型的表现。
通过这些改进,你可以获得更全面的模型评估结果,包括均方根误差(RMSE)和决定系数($R^2$)。如果有任何问题或需要进一步调整,请告诉我!