本文详解如何正确嵌套循环结构,确保每次随机生成的数值都独立驱动完整的机器学习建模与评估流程,避免仅对最后一个值执行计算的常见缩进错误。
本文详解如何正确嵌套循环结构,确保每次随机生成的数值都独立驱动完整的机器学习建模与评估流程,避免仅对最后一个值执行计算的常见缩进错误。
在您的原始代码中,问题核心在于作用域与缩进逻辑错误:第一个 for 循环仅执行了 randint() 生成和打印操作,而后续所有模型训练、预测与 R² 计算代码未被包含在该循环内,导致它们只在循环结束后运行一次——且此时 value 已被赋值为最后一次迭代的结果(即 35),因此 for n in [value] 实际等价于 for n in [35]。
要实现“对每一个随机数都完整执行一次建模与评估”,必须将整个建模流程整体缩进至第一层循环内部,使其成为循环体的一部分。以下是修正后的专业级实现:
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
# 设置全局随机种子(影响randint,但不直接影响sklearn模型)
seed(4)
# 存储每次迭代的R²结果,便于后续分析
r2_scores = []
for _ in range(20):
n = randint(0, 100) # 直接用n替代value,语义更清晰
print(n, end=', ')
# 每次使用不同的random_state进行数据划分,保证实验独立性
X_train, X_test, y_train, y_test = train_test_split(
df3_X1, df3_Y1,
test_size=0.25,
random_state=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=0))
]
# 构建堆叠模型(注意:final_estimator的random_state也建议设为n或固定值以增强可复现性)
stack = StackingRegressor(
estimators=estimators,
final_estimator=RandomForestRegressor(n_estimators=100, random_state=0)
)
# 训练与预测
Final_model = stack.fit(X_train, y_train)
predictions = Final_model.predict(X_test)
# 手动计算R²(等价于sklearn.metrics.r2_score,但显式展示逻辑)
y_bar = y_test.mean()
ss_tot = ((y_test - y_bar) ** 2).sum()
ss_res = ((y_test - predictions) ** 2).sum()
r2_score_val = 1 - (ss_res / ss_tot) if ss_tot != 0 else 0
print(f"r2_score is {r2_score_val:.6f}")
r2_scores.append((n, r2_score_val))
print('\nThe for loop is complete!')
print(f"Total evaluations: {len(r2_scores)}")✅ 关键修正点说明:
- 缩进即逻辑:所有建模、分割、训练、评估代码均缩进至 for _ in range(20): 下,确保每轮迭代独立执行;
- 变量命名优化:直接使用 n 作为循环内随机数变量,避免 value → [value] 的冗余转换;
- 结果结构化记录:通过 r2_scores.append((n, r2_score_val)) 显式保存每次的 random_state 与对应 R²,支持后续统计分析(如寻找最优 n);
- 数值稳定性防护:添加 if ss_tot != 0 判断,防止因 y_test 方差为零导致除零错误;
- 可复现性提示:虽 GradientBoostingRegressor 和 RandomForestRegressor 中 random_state=0 固定,但若需完全依赖 n 控制全部随机性,可将其替换为 random_state=n(需确保各组件兼容)。
⚠️ 注意事项:
立即学习“Python免费学习笔记(深入)”;
- 此类多轮随机实验会显著增加计算开销。如需高效调参,推荐改用 GridSearchCV 或 RandomizedSearchCV;
- train_test_split 的 random_state=n 仅控制数据划分的随机性,模型内部随机性由各自 random_state 参数决定;
- 若目标是评估不同 random_state 对模型稳定性的敏感度,建议额外记录标准差、置信区间等统计量。
通过以上重构,您将获得全部 20 个 r2_score 输出,真正实现“每个随机数驱动一次完整评估”的预期目标。










