本文详解如何正确嵌套循环结构,确保后续模型训练与评估逻辑对前一轮生成的每个随机数独立执行,避免因缩进错误导致仅处理最后一个值的问题。
本文详解如何正确嵌套循环结构,确保后续模型训练与评估逻辑对前一轮生成的每个随机数独立执行,避免因缩进错误导致仅处理最后一个值的问题。
在您的原始代码中,存在一个典型的作用域与缩进逻辑错误:第一个 for 循环仅包含 randint() 生成和打印语句,而模型划分、堆叠回归训练、R² 计算等关键逻辑未被纳入该循环体内,因此实际只在循环结束后用最后一次赋值的 value(即 35)执行了一次评估。
要为全部 20 个随机种子分别独立运行完整的建模流程,必须将整个下游计算逻辑整体缩进,使其成为外层循环的子块。以下是修正后的专业级实现:
from random import seed, randint
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingRegressor, RandomForestRegressor
from sklearn.svm import SVR
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
from sklearn.ensemble import StackingRegressor
from sklearn.metrics import r2_score as sklearn_r2 # 推荐使用标准库函数
# 设置全局随机种子(控制randint序列)
seed(4)
# 存储每次实验的R²结果,便于后续分析
r2_results = []
print("Generated seeds:", end=" ")
for _ in range(20):
n = randint(0, 100) # 使用n替代value,语义更清晰
print(n, end=", ")
# --- 每个种子独立执行完整建模流程 ---
X_train, X_test, y_train, y_test = train_test_split(
df3_X1, df3_Y1,
test_size=0.25,
random_state=n # 关键:此处使用当前种子n
)
# 定义参数与估计器
params = {
'n_estimators': 500,
'max_depth': 4,
'min_samples_split': 5,
'learning_rate': 0.01,
'loss': 'ls'
}
estimators = [
('svr', make_pipeline(StandardScaler(), SVR(kernel='rbf', C=0.6))),
('gb', GradientBoostingRegressor(random_state=n)) # 建议也使用n保证可复现性
]
stack = StackingRegressor(
estimators=estimators,
final_estimator=RandomForestRegressor(n_estimators=100, random_state=n)
)
# 训练与预测
Final_model = stack.fit(X_train, y_train)
predictions = Final_model.predict(X_test)
# 手动计算R²(或直接调用sklearn)
y_bar = y_test.mean()
ss_tot = ((y_test - y_bar) ** 2).sum()
ss_res = ((y_test - predictions) ** 2).sum()
r2_manual = 1 - (ss_res / ss_tot) if ss_tot != 0 else 0
# 推荐方式(更鲁棒,自动处理边界情况)
r2_sklearn = sklearn_r2(y_test, predictions)
print(f"\nSeed {n}: R² (manual) = {r2_manual:.4f}, R² (sklearn) = {r2_sklearn:.4f}")
r2_results.append((n, r2_sklearn))
print("\nThe for loop is complete!")
print(f"Total experiments: {len(r2_results)}")✅ 关键修正点总结:
- 缩进即逻辑归属:所有建模、评估代码必须与 n = randint(...) 处于同一缩进层级,成为 for 循环体的一部分;
- 变量命名优化:用 n 直接代表当前随机种子,避免 value → [value] 的冗余转换;
- 可复现性增强:GradientBoostingRegressor 和 RandomForestRegressor 的 random_state 也设为 n,确保全流程可控;
- 推荐使用 sklearn.metrics.r2_score:它已内置数值稳定性处理(如分母为零保护),比手动实现更可靠;
- 结果结构化存储:通过 r2_results 列表记录每轮 (seed, r2),便于后续统计(如最佳种子筛选、分布可视化)。
⚠️ 注意事项:
立即学习“Python免费学习笔记(深入)”;
- 若 df3_X1/df3_Y1 数据量较大,20 次完整训练可能耗时较长,可考虑添加 tqdm 进度条;
- StackingRegressor 在小样本下易过拟合,建议配合交叉验证(如 cross_val_score)评估泛化性;
- 随机种子范围 randint(0, 100) 仅生成 101 个可能值,若需更高多样性,可扩大范围(如 randint(0, 9999))。
通过以上重构,您将获得全部 20 个种子对应的 R² 分数,真正实现“基于前序循环结果的连续计算”,为超参敏感性分析或随机性鲁棒性验证奠定基础。










