# LAB 21 · 研究收束:让划分对应新样本 按问题继续 采集批次泄漏、随机/分组划分、两个基线的实测对照 对应课堂(1 页) 可先阅读已有结果,再决定是否运行。重算时请核对各节记录的数据、参数、环境与日期。 **学习路径:** [表示怎样迁移到新任务](/course/study/readout-transfer.html) ## 全讲收束:你的“新样本”究竟新在哪里? 从[P24 迁移评价](/course/pages/l3-r2-p24.html)或[P66 组件复用](/course/pages/l3-r2-p66.html)进入,不必先完成全部Lab。这个短练习把表示、定位和语言三条线带回同一个研究判断:测试划分是否对应未来使用条件? 先预测“记采集批次均值”和“只用x”的线性基线谁占优,再比较随机样本切分与整批次留出。两种划分均180/60,指标同为RMSE;改变的是测试问题。数据为12批次×20样本的合成构造,不是农业实测。[逐数结果与解释](/course/blocks/research-question-split-evidence.html)。 读完只需留下一个自己的具体问题:未来预测对象、新样本相对训练的变化、必须整组留出的单位、一个简单基线,以及能推翻当前解释的干预。先把本例批次偏置标准差3改成0提出预测,再考虑是否运行。原代码和2026-09-22保存输出保留。 这册不收纳其他主题的剩余材料。它的终点是形成可检验的评价设计;具体模型与训练继续回到所选的LAB01/02、LAB10、LAB13或LAB14。 [此段独立阅读](/course/notebook-blocks/d1b4823894e14c65b471615f74146ee8.html)展开完整实现代码 ``` # Writable ephemeral workspace for detached readonly cloud runs. import os, tempfile os.chdir(tempfile.mkdtemp(prefix='lec03_lab24_')) import numpy as np r=np.random.default_rng(24); groups=np.repeat(np.arange(12),20); x=r.normal(size=len(groups)); offsets=r.normal(0,3,12); y=.7*x+offsets[groups]+r.normal(0,.25,len(x)) random_test=np.zeros(len(x),bool); random_test[r.permutation(len(x))[:60]]=True group_test=groups>=9 def compare(test): train=~test; means={g:y[train&(groups==g)].mean() for g in np.unique(groups[train])} memorized=np.array([means.get(g,y[train].mean()) for g in groups[test]]) X=np.c_[x,np.ones(len(x))]; w=np.linalg.lstsq(X[train],y[train],rcond=None)[0] rmse=lambda p:float(np.sqrt(np.mean((p-y[test])**2))) return {'ntrain':int(train.sum()),'ntest':int(test.sum()),'overlapping_groups':len(set(groups[train])&set(groups[test])),'batch_mean_RMSE':rmse(memorized),'x_only_RMSE':rmse(X[test]@w)} print('random sample split',compare(random_test)); print('new batch split',compare(group_test)) assert compare(group_test)['overlapping_groups']==0 print('claim tested: does low random-split error predict performance in unseen acquisition groups?') ``` [此段独立阅读](/course/notebook-blocks/40cd76c6ca1443379cf6e888f570823a.html) ## 已完成的基准运行 以下保留2026-09-22本地独立 Python 进程的实际标准输出。当前整理没有重跑;Notebook 的云端执行记录与这份本地标准输出分开解释。 ``` random sample split {'ntrain': 180, 'ntest': 60, 'overlapping_groups': 12, 'batch_mean_RMSE': 0.7821631194429031, 'x_only_RMSE': 2.3574347161692795} new batch split {'ntrain': 180, 'ntest': 60, 'overlapping_groups': 0, 'batch_mean_RMSE': 2.115187164028426, 'x_only_RMSE': 1.798035324219997} claim tested: does low random-split error predict performance in unseen acquisition groups? ``` 先比较组重叠,再解释RMSE。随机划分中“批次均值”可能很好,是因为测试批次在训练中已出现;新批次的默认均值通常失效。x基线也未必足够好,因为目标仍含未知偏置。不能因此宣布x无用,也不能仅换复杂网络就假定问题解决。 把自己的研究改写为一个具体契约:预测时真正可取得哪些输入?新样本指新个体、新地点还是新时间?最简单而强的基线是什么?哪个分组必须整体留出?只有先固定这些问题,LAB01的冻结读出、LAB02的微调、LAB10的定位或LAB13的条件生成才有可比较的含义。下一步仅把偏置标准差3改成0,检验划分差距是否缩小;这是能改变本例解释的反证。不要将这组构造数据的单次RMSE推广为现实效应大小。 [此段独立阅读](/course/notebook-blocks/2808d2d9691f4492a32d74b6ab87a431.html) ## 旧版热身(历史参考) 旧版热身仅保留为历史参考,不参与当前基准运行;当前解释与计算以上方完整实验为准。 #### 展开查看旧版代码(仅展示,不执行) ``` contract={'input':'one observable object','target':'one checkable output','split':'by environment','baseline':'simple deterministic rule','metric':'task metric + failure slices','counterevidence':'condition that would change the claim'} for k,v in contract.items(): print(f'{k}: {v}') assert set(contract)=={'input','target','split','baseline','metric','counterevidence'} ``` [此段独立阅读](/course/notebook-blocks/40cb21de62644787b549a881181299e0.html)