R语言中的包外错误估计(Out-of-Bag Error Estimation)

100 篇文章 ¥59.90 ¥99.00
本文介绍了在R语言中如何使用随机森林的包外错误估计来评估模型性能。通过`randomForest`包构建随机森林模型,利用未被训练样本进行误差估计,从而得到模型的泛化能力。示例代码展示了从数据加载到模型构建,再到包外错误率计算的完整过程,这种方法可作为模型选择的依据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

R语言中的包外错误估计(Out-of-Bag Error Estimation)

在机器学习中,包外错误估计(Out-of-Bag Error Estimation)是一种用于评估随机森林模型性能的方法。随机森林是一种基于决策树的集成学习算法,它通过构建多个决策树并进行投票来进行预测。而包外错误估计则是利用随机森林中每棵树未使用的样本来评估模型的泛化误差。

在R语言中,通过使用"randomForest"包可以很方便地进行随机森林模型的构建和包外错误估计。下面是一个简单的示例代码:

# 安装和加载randomForest包
install.packages("randomForest")
library(randomForest)

# 加载示例数据集iris
data(iris)

# 构建随机森林模型
rf_model <- randomForest(Species ~ ., data = iris, ntree = 100, keep.inbag = TRUE)

# 输出包外错误率
oob_error <- 1 - rf_model$err.rate[nrow(rf_model$err.rate), "OOB"]
print(paste("Out-of-Bag Error:", oob_error))

在上面的代码中,首先我们安装并加载了"randomForest"包,然后加载了R语言自带的示例数据集iris。接着我们使用randomForest函数构建了一个随机森林模型rf_model,其中Species是目标变量,

joblib.externals.loky.process_executor._RemoteTraceback: """ Traceback (most recent call last): File "C:\Users\DELL\AppData\Local\Programs\Python\Python311\Lib\site-packages\joblib\externals\loky\process_executor.py", line 490, in _process_worker r = call_item() ^^^^^^^^^^^ File "C:\Users\DELL\AppData\Local\Programs\Python\Python311\Lib\site-packages\joblib\externals\loky\process_executor.py", line 291, in __call__ return self.fn(*self.args, **self.kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\DELL\AppData\Local\Programs\Python\Python311\Lib\site-packages\joblib\parallel.py", line 606, in __call__ return [func(*args, **kwargs) for func, args, kwargs in self.items] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\DELL\AppData\Local\Programs\Python\Python311\Lib\site-packages\joblib\parallel.py", line 606, in <listcomp> return [func(*args, **kwargs) for func, args, kwargs in self.items] ^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\DELL\AppData\Local\Programs\Python\Python311\Lib\site-packages\sklearn\utils\parallel.py", line 139, in __call__ return self.function(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\DELL\AppData\Local\Programs\Python\Python311\Lib\site-packages\sklearn\model_selection\_validation.py", line 866, in _fit_and_score estimator.fit(X_train, y_train, **fit_params) File "C:\Users\DELL\AppData\Local\Programs\Python\Python311\Lib\site-packages\sklearn\base.py", line 1389, in wrapper return fit_method(estimator, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\DELL\AppData\Local\Programs\Python\Python311\Lib\site-packages\sklearn\ensemble\_forest.py", line 448, in fit raise ValueError("Out of bag estimation only available if bootstrap=True") ValueError: Out of bag estimation only available if bootstrap=True """ The above exception was the direct cause of the following exception: Traceback (most recent call last): File "D:\python\电力负荷预测.py", line 77, in <module> random_search.fit(X_train, y_train) File "C:\Users\DELL\AppData\Local\Programs\Python\Python311\Lib\site-packages\sklearn\base.py", line 1389, in wrapper return fit_method(estimator, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\DELL\AppData\Local\Programs\Python\Python311\Lib\site-packages\sklearn\model_selection\_search.py", line 1024, in fit self._run_search(evaluate_candidates) File "C:\Users\DELL\AppData\Local\Programs\Python\Python311\Lib\site-packages\sklearn\model_selection\_search.py", line 1951, in _run_search evaluate_candidates( File "C:\Users\DELL\AppData\Local\Programs\Python\Python311\Lib\site-packages\sklearn\model_selection\_search.py", line 970, in evaluate_candidates out = parallel( ^^^^^^^^^ File "C:\Users\DELL\AppData\Local\Programs\Python\Python311\Lib\site-packages\sklearn\utils\parallel.py", line 77, in __call__ return super().__call__(iterable_with_config) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\DELL\AppData\Local\Programs\Python\Python311\Lib\site-packages\joblib\parallel.py", line 2071, in __call__ return output if self.return_generator else list(output) ^^^^^^^^^^^^ File "C:\Users\DELL\AppData\Local\Programs\Python\Python311\Lib\site-packages\joblib\parallel.py", line 1681, in _get_outputs yield from self._retrieve() File "C:\Users\DELL\AppData\Local\Programs\Python\Python311\Lib\site-packages\joblib\parallel.py", line 1783, in _retrieve self._raise_error_fast() File "C:\Users\DELL\AppData\Local\Programs\Python\Python311\Lib\site-packages\joblib\parallel.py", line 1858, in _raise_error_fast error_job.get_result(self.timeout) File "C:\Users\DELL\AppData\Local\Programs\Python\Python311\Lib\site-packages\joblib\parallel.py", line 757, in get_result return self._return_or_raise() ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\DELL\AppData\Local\Programs\Python\Python311\Lib\site-packages\joblib\parallel.py", line 772, in _return_or_raise raise self._result ValueError: Out of bag estimation only available if bootstrap=True
最新发布
05-15
你遇到的问题是因为在使用 `oob_score=True` 时,`bootstrap` 参数必须设置为 `True`。`oob_score` 是基于未用于构建每棵树的数据(即袋数据)来进行评估的,因此只有当 `bootstrap=True` 时才有意义。 为了解决这个问题,我们需要确保在调优参数时,`oob_score` 和 `bootstrap` 参数保持一致。具体来说,如果设置了 `oob_score=True`,那么 `bootstrap` 必须为 `True`。 此,为了避免过多的参数组合导致不必要的计算开销,可以考虑减少参数空间的范围或使用 `GridSearchCV` 对关键参数进行更细粒度的搜索。 以下是修正后的代码: ### 修正后的代码 ```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, MinMaxScaler from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error, mean_absolute_percentage_error import numpy as np import matplotlib.pyplot as plt import matplotlib from scipy.stats import randint, uniform from sklearn.feature_selection import SelectFromModel # 设置中文字体 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)'] # 特征选择:使用特征重要性选择重要特征 rf_initial = RandomForestRegressor(random_state=42) selector = SelectFromModel(rf_initial, threshold='mean') X_selected = selector.fit_transform(X, y) selected_features = X.columns[selector.get_support()] print("Selected Features:", selected_features) # 标准化特征 scaler = MinMaxScaler() # 使用 MinMaxScaler 缩放特征 X_scaled = scaler.fit_transform(X_selected) X_scaled_df = pd.DataFrame(X_scaled, columns=selected_features) # 分割数据为训练集和测试集 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], # 保证 bootstrap 为 True 'max_features': ['sqrt', 'log2'] + list(np.linspace(0.1, 1.0, 10)), # 添加合理的浮点数值 'oob_score': [True], # 保证 oob_score 为 True 'criterion': ['squared_error', 'friedman_mse', 'absolute_error', 'poisson'] # 使用有效的损失函数 } rf_model = RandomForestRegressor(random_state=42) # 使用随机搜索进行超参数调优 random_search = RandomizedSearchCV( estimator=rf_model, param_distributions=param_dist, n_iter=200, # 增加迭代次数以覆盖更多参数组合 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_rmse = cross_val_score(best_rf_model, X_train, y_train, cv=5, scoring='neg_mean_squared_error') cv_scores_mae = cross_val_score(best_rf_model, X_train, y_train, cv=5, scoring='neg_mean_absolute_error') cv_scores_r2 = cross_val_score(best_rf_model, X_train, y_train, cv=5, scoring='r2') print(f'Random Forest CV RMSE: {-np.sqrt(-cv_scores_rmse.mean()):.2f}') print(f'Random Forest CV MAE: {-cv_scores_mae.mean():.2f}') print(f'Random Forest CV R^2: {cv_scores_r2.mean():.4f}') # 在测试集上进行预测 y_pred_rf = best_rf_model.predict(X_test) # 计算多种评估指标 rmse_rf = np.sqrt(mean_squared_error(y_test, y_pred_rf)) mae_rf = mean_absolute_error(y_test, y_pred_rf) mape_rf = mean_absolute_percentage_error(y_test, y_pred_rf) r2_test = r2_score(y_test, y_pred_rf) print(f'Random Forest Test RMSE: {rmse_rf:.2f}') print(f'Random Forest Test MAE: {mae_rf:.2f}') print(f'Random Forest Test MAPE: {mape_rf:.4f}') print(f'Random Forest Test R^2: {r2_test:.4f}') # 特征重要性分析 importances = best_rf_model.feature_importances_ feature_importances = pd.Series(importances, index=selected_features) 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. **保证 `bootstrap` 和 `oob_score` 一致性**: - 将 `bootstrap` 和 `oob_score` 参数都固定为 `True`,确保袋分数计算有效。 2. **确保参数合理性**: - 限制 `bootstrap` 和 `oob_score` 参数,避免无效组合。 通过这些修正,`RandomizedSearchCV` 应该可以顺利运行,并且找到合理的参数组合。如果有任何问题或需要进一步调整,请告诉我! ### 进一步优化建议 1. **减少参数空间**:如果调优时间过长,可以适当减少参数范围或调优次数。 2. **使用 `GridSearchCV`**:对于关键参数,可以考虑使用 `GridSearchCV` 进行更细粒度的搜索。 3. **模型集成**:可以尝试集成多个模型(如 Bagging、Stacking)以提高模型的鲁棒性和泛化能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值