tidypptsda 有五个验证函数,用来在自己的数据上比较各种方法和参数设置。本文逐个介绍它们的每个参数、默认值、什么时候需要改,以及结果中每一列的含义,并给出可以直接照抄的例子。各方法的原理和在示例数据上的结论,见《方法验证》。
| 想回答的问题 | 用哪个函数 | 输入 |
|---|---|---|
| 哪种体重异常值检测方法更好? | validate_outliers() |
prep_visits() 的结果 |
| 哪种生长曲线更适合本批次?外推用曲线还是切线? | validate_adg() |
clean_weight() 的结果 |
| 缺失的日体重用线性插值还是生长曲线填? | validate_weight_fill() |
clean_weight() 的结果 |
| 缺失的日采食用哪种插补方法? | validate_adfi() |
calc_adfi() 和 clean_weight() 的结果 |
| 几套完整的质控设置,哪套在猪缺数据时最稳? | validate_truncation() |
prep_visits() 的结果 |
前四个函数各看一个步骤,快;validate_truncation()
重跑整条流程,慢,但最接近实际,最终决定用哪套设置时以它为准。
五个函数的思路相同:故意破坏或隐藏一部分数据,再看各方法能把结果恢复到什么程度。被隐藏的日子会先删掉,再对剩下的记录重新清洗,被隐藏的数据不会以任何方式参与计算(1.5.0 起)。
下面的例子都用包里的示例数据,先准备好输入:
visits <- prep_visits(nedap, verbose = 0) # 访问记录
weight <- clean_weight(visits, verbose = 0) # 体重质控
adg <- calc_adg(weight, verbose = 0) # 日增重
adfi <- calc_adfi(visits, adg, verbose = 0) # 日采食
# 汇总表保留 3 位有效数字,方便阅读
tidy <- function(x) x$summary[, lapply(.SD, function(v) if (is.double(v)) signif(v, 3) else v)]五个函数都有下面这几个参数,含义相同:
| 参数 | 默认 | 含义 | 什么时候改 |
|---|---|---|---|
reps |
3 或 5 | 重复次数。每次重新随机加误差或隐藏日子,结果取平均 | 猪少(几十头)时增加到 5–10,猪多(几百头)时 1–2 次就够 |
max_pigs |
NULL(全部) |
随机抽取最多这么多头猪参与验证(validate_truncation()
用 pigs 指定) |
数据量大、只想快速看结论时,用 300 左右 |
seed |
1 | 随机种子。同样的数据和参数,结果完全相同 | 想看结果对随机性是否敏感时,换几个种子比较 |
cores |
1 | 并行的 CPU 核数 | 电脑核数多、内存充足时用 2–4;内存不够时子进程会被系统杀掉,会有提示 |
verbose |
1 | 0:不显示;1:显示概况、进度条和结果表 | 写在脚本里批量运行时用 0 |
隐藏数据的方式用一个字符串描述,字母表示类型,数字表示多少。validate_weight_fill()
和 validate_adfi()
用前四种,validate_truncation() 用后三种:
| 写法 | 含义 | 模拟的情况 |
|---|---|---|
"random30" |
随机隐藏 30% 有记录的日子 | 零散缺测 |
"blocks3" |
隐藏 3 段连续的日子,每段 3–10 天 | 几次短期不进站、耳标读取失败 |
"late20" |
隐藏区间开头的 20 天 | 晚进站 |
"early15" |
隐藏区间结尾的 15 天 | 早出栏 |
"gap10" |
隐藏区间中间连续 10 天(只用于
validate_truncation()) |
测定中断 |
数字可以随意改,例如
"random50"、"blocks6"、"late10"、"early30";可以一次给几个场景,例如
scenarios = c("late10", "late20", "late30"),看缺得越多误差怎么变化。
五个函数都返回 ppt_validation 对象,是一个列表:
$summary:汇总表,每种方法(和场景)一行,主要看这个;$per_pig、$per_rep、$cv、$truncation
等:每头猪、每次重复的明细,用来找出误差大的猪;$settings:本次验证用的全部参数,保存结果时一起保存,方便以后复查。直接打印对象会显示汇总表:
vf <- validate_adfi(adfi, weight)
vf # 汇总表
vf$summary # 同上,是 data.table,可以排序、筛选、导出
vf$per_pig # 每头猪的误差verbose = 1 时,先显示一行概况,然后按
[1/3]、[2/3]
编号显示各个阶段,最后打印结果表:
── Validating feed intake imputation ───────────────────────────────
ℹ 29 pigs with coverage >= 0.8 · 3 methods · 2 scenarios · 2 repetitions · body weight without the hidden days
⠼ [2/3] Body weight per mask ■■■■■■■■······· 11/20 | ETA 1m
✔ [1/3] Leave-one-out population curves 0.0s
✔ [2/3] Body weight per mask (4 masks) 2.8s
✔ [3/3] Imputing the hidden days (29 pigs x 4 masks x 3 methods) 1.3s
✔ Done in 4.1s · details in $summary
ADFI error (mean absolute error, % of the recorded ADFI)
random30 late20
loess_pop 1.05 1.34*
loess_lm 1.05* 4.49
linear 1.06 4.49
*。“最好”指误差最小、相关最高、偏差最接近 0;对照行(例如
none)不参与比较;一列的值全部相同时不标。在一个约 700 头猪的 NEDAP 批次上,用 2 个核心、全部默认参数:
| 函数 | 耗时 | 最慢的阶段 |
|---|---|---|
validate_outliers() |
约 4.5 分钟 | 用每种方法清洗加了误差的数据 |
validate_adg() |
约 3 分钟 | 拟合曲线;重新清洗 5 个折约 1 分钟 |
validate_weight_fill() |
约 5 分钟 | 填充;重新清洗 12 个隐藏方案约 1.5 分钟 |
validate_adfi() |
约 5.5 分钟 | 20 个隐藏方案的体重重算约 4 分钟 |
validate_truncation() |
与 设置数 × 场景数 × 重复次数 成正比 | 每次重跑整条流程约 20–40 秒 |
想快一些:减少 reps、减少场景或方法、用
max_pigs 抽样,或者增加 cores。
validate_outliers():体重异常值检测方法
做法:找出各方法都认为没有问题的”干净记录”,随机挑一部分加上人为误差,再用每种方法清洗,看人为误差被找出多少、好记录被误删多少、ADG 偏了多少。
validate_outliers(visits, qc = qc_config(), methods = list(...), rate = 0.05,
size = c(3, 15), direction = c("both", "down", "up"), reps = 3,
max_pigs = NULL, seed = 1, reference = c("consensus", "qc"),
verbose = 1, cores = 1)| 参数 | 默认 | 含义 | 什么时候改 |
|---|---|---|---|
visits |
— |
prep_visits() 的结果 |
— |
qc |
qc_config() |
除异常值方法以外的所有质控设置(体重范围、适应期等) | 你的批次用了非默认设置时,传入同一套设置 |
methods |
7 种组合 | 要比较的方法,带名字的列表,名字是结果中显示的方法名,值是
weight_outlier 的取值;加上 "track"
表示先做逐日回溯追踪 |
只想比较几种方法时,列出这几种 |
rate |
0.05 | 加误差的干净记录比例 | 想模拟误差多的秤时,用 0.1 或 0.2 |
size |
c(3, 15) |
误差大小的范围(kg),在其中均匀随机 | 只关心大误差时用 c(10, 30);关心小误差时用
c(1, 5)
|
direction |
"both" |
"both":随机加或减;"down":只偏低(猪只有前腿站在秤上);"up":只偏高(两头猪同时上秤) |
实际误差多数偏低,可以单独用 "down" 检验一次 |
reference |
"consensus" |
干净记录怎么定:"consensus"
是所有被比较方法都保留的记录,哪种方法都不占便宜;"qc"
是只按 qc 的方法判定(1.5.0 之前的做法) |
一般不改 |
默认比较的 7 种方法:
| 名字 | 内容 |
|---|---|
track+rlm+loess |
默认设置:先逐日回溯追踪,再用稳健回归和 LOESS |
track |
只做追踪 |
rlm、loess、stl、sd
|
只用这一种方法(不追踪) |
rlm+loess |
稳健回归和 LOESS(不追踪) |
结果中还有一行
none:只做体重范围检查、不做异常值检测,作为对照。
例子
# 只比较三种方法,误差偏低,重复 1 次(示例;实际用默认的 3 次)
vo <- validate_outliers(visits,
methods = list(default = c("track", "rlm", "loess"),
loess = "loess",
stl = "stl"),
direction = "down", reps = 1, verbose = 0)
tidy(vo)
#> method sensitivity false_positive_rate precision adg_bias adg_rmse adg_spearman n_pigs
#> <char> <num> <num> <num> <num> <num> <num> <num>
#> 1: none 0.00842 0.00e+00 1.000 0.3670 2.940 0.999 29
#> 2: default 0.93500 5.07e-03 0.909 0.3290 1.640 0.999 29
#> 3: loess 0.91400 8.24e-05 0.998 0.0572 0.806 1.000 29
#> 4: stl 0.94200 2.14e-03 0.959 0.0532 0.782 0.999 29自己组合方法时,列表的每个元素是一组方法:
methods = list(
"追踪+loess" = c("track", "loess"), # 先追踪,再用 LOESS
"rlm+stl" = c("rlm", "stl"), # 任一方法判为异常即剔除(outlier_combine = "any",默认)
"只追踪" = "track"
)结果中的列
| 列 | 含义 | 怎么看 |
|---|---|---|
sensitivity |
人为误差中被找出的比例 | 越高越好 |
false_positive_rate |
干净记录中被误删的比例 | 越低越好 |
precision |
被判为异常的记录中,确实是人为误差的比例 | 越高越好 |
adg_bias、adg_rmse
|
ADG 与干净记录算出的 ADG 之差的平均值、均方根(g/d) | 越接近 0 越好 |
adg_spearman |
ADG 排名与参照的相关 | 越接近 1 越好 |
n_pigs |
参与比较的猪数 |
$settings$n_clean 是干净记录的条数。
怎么用结果做决定:先看 sensitivity 和
false_positive_rate 的平衡,再看
adg_rmse。零散的随机误差对 ADG 影响很小,各方法 ADG
的差别主要来自误删了哪些好记录;集中出现的误差(例如秤漂移)这个检验看不出来,要结合
plot_adg() 的图检查。
validate_adg():生长曲线与外推方式
做法:两种检验。交叉验证:把每头猪的日子按连续几天切成块,轮流留出一部分块,用其余的记录拟合曲线,预测留出的体重;截断检验:隐藏测定开头或结尾若干天,重新算 ADG,与同一模型用全部记录算出的 ADG 比较。
validate_adg(weight, models = c("poly1", "poly2", "poly3", "gompertz"), extrap = NULL,
k = 5, block_days = 7, cv_limit = 10, trim_days = c(10, 20),
qc = weight$settings, max_pigs = NULL, seed = 1, verbose = 1, cores = 1)| 参数 | 默认 | 含义 | 什么时候改 |
|---|---|---|---|
weight |
— |
clean_weight() 的结果 |
— |
models |
4 种 | 要比较的曲线:"poly1"(直线)、"poly2"(二次)、"poly3"(三次)、"gompertz"
|
只想比较两三种时列出来,省时间 |
extrap |
NULL |
记录范围之外怎么外推:"start"(只在首个记录之前用切线)、"curve"(沿曲线)、"tangent"(两端都用切线),可以给几个。NULL
表示用 weight 的设置 |
想比较外推方式时,例如
c("start", "curve", "tangent")
|
k |
5 | 交叉验证的折数 | 一般不改 |
block_days |
7 | 交叉验证中每块的天数 |
1
表示按单天留出,留出日子两边都有记录,误差会偏小,只用于和 1.5.0
之前的结果对比 |
cv_limit |
10 | 交叉验证误差超过多少 kg 的猪算”预测失败”,计入
cv_share_over
|
一般不改 |
trim_days |
c(10, 20) |
截断检验隐藏开头或结尾的天数,每个数字都会做开头(late)和结尾(early)两种 |
想看缺得更多时用 c(10, 20, 30)
|
qc |
weight$settings |
体重清洗规则和区间(重新清洗时用) | 一般不改 |
比较外推方式时,模型名后面会加上外推方式,例如
poly2+tangent;"curve" 不加后缀。
例子
va <- validate_adg(weight, models = c("poly1", "poly2", "gompertz"), trim_days = 20, verbose = 0)
tidy(va)
#> model cv_rmse cv_mae cv_share_over bias_late20 rmse_late20 spearman_late20 n_late20
#> <char> <num> <num> <num> <num> <num> <num> <int>
#> 1: poly1+start 1.76 1.41 0 -5.10 29.0 0.939 29
#> 2: poly2+start 1.75 1.40 0 9.87 28.2 0.947 29
#> 3: gompertz+start 1.54 1.21 0 5.83 26.8 0.937 29
#> bias_early20 rmse_early20 spearman_early20 n_early20
#> <num> <num> <num> <int>
#> 1: 0.236 51.9 0.971 29
#> 2: 14.100 49.9 0.976 29
#> 3: -0.114 52.0 0.981 29比较外推方式:
va_t <- validate_adg(weight, models = "poly2", extrap = c("start", "curve", "tangent"),
trim_days = c(10, 20), verbose = 0)
tidy(va_t)[, .(model, cv_rmse, rmse_late10, rmse_late20, rmse_early10, rmse_early20)]
#> model cv_rmse rmse_late10 rmse_late20 rmse_early10 rmse_early20
#> <char> <num> <num> <num> <num> <num>
#> 1: poly2+start 1.75 31.3 28.2 23 49.9
#> 2: poly2 1.85 33.9 44.8 23 49.9
#> 3: poly2+tangent 1.72 31.4 28.4 22 50.0结果中的列
| 列 | 含义 | 怎么看 |
|---|---|---|
cv_rmse、cv_mae
|
交叉验证中,每头猪留出体重的预测误差(kg)的中位数 | 越小越好;反映曲线描述数据的能力 |
cv_share_over |
误差超过 cv_limit 的猪的比例 |
越低越好;灵活的曲线(poly3)可能在个别猪身上外推出离谱的值,看这一列 |
bias_late10、rmse_late10
|
隐藏开头 10 天后,ADG 的平均偏差、均方根误差(g/d) | 越接近 0 越好;反映外推的稳定性 |
spearman_late10 |
ADG 排名与全部数据的相关 | 越接近 1 越好 |
n_late10 |
截断后仍有 ADG 的猪数 | |
..._early10 等 |
同上,隐藏结尾 |
明细:$cv
是每头猪、每个模型的交叉验证误差;$truncation
是每头猪截断前后的 ADG。
怎么用结果做决定:交叉验证总是偏向灵活的模型,但差别通常只有零点几公斤;测定期没有覆盖整个体重区间的猪多时,更应该看截断检验。先看
calc_adg() 结果中 adg_type 的分布:大多数猪是
observed 时,选哪种曲线影响很小。
找出交叉验证误差大的猪,检查它们的图:
va$cv[order(-rmse)][1:5]
#> responder model rmse mae
#> <char> <char> <num> <num>
#> 1: 15967 poly2+start 4.289022 3.340279
#> 2: 15967 poly1+start 4.219711 3.852471
#> 3: 15967 gompertz+start 3.971131 3.074910
#> 4: 15626 poly2+start 3.242105 2.037071
#> 5: 15961 poly1+start 2.887381 2.371369validate_weight_fill():日体重的填充方法
做法:先用全部记录算出每头猪的区间和 ADG 作为参照,再隐藏区间内一部分有记录的日子(删掉这些日子的全部体重记录,剩下的重新清洗),用每种方法重新填充,比较填充的日体重和 ADG。
validate_weight_fill(weight, methods = c("linear", "poly1", "poly2", "poly3", "gompertz"),
extrap = NULL, scenarios = c("random30", "blocks3", "late20", "early15"),
reps = 3, max_pigs = NULL, seed = 1, verbose = 1, cores = 1)| 参数 | 默认 | 含义 | 什么时候改 |
|---|---|---|---|
weight |
— |
clean_weight()
的结果,它的设置($settings)用于所有计算 |
— |
methods |
5 种 |
"linear":calc_adg()
的做法,两个有记录的日子之间线性插值,首尾用 curve_model
的曲线;"poly1"…"gompertz":所有缺失的日子都用该曲线 |
一般保留 "linear",再加一两种曲线对比 |
extrap |
NULL |
同 validate_adg(),主要影响
late、early 场景 |
比较外推方式时 |
scenarios |
4 种 | 隐藏方式,见第 2 节 | 按实际缺失情况选,例如晚进站多就用
c("late10", "late20", "late30")
|
例子
vw <- validate_weight_fill(weight, methods = c("linear", "poly2"),
scenarios = c("blocks3", "late20", "early15"), reps = 1, verbose = 0)
tidy(vw)
#> scenario method daily_rmse daily_mae daily_bias adg_bias adg_rmse adg_spearman n_pigs
#> <char> <char> <num> <num> <num> <num> <num> <num> <int>
#> 1: blocks3 linear+start 0.928 0.672 0.0170 -0.797 5.12 0.997 29
#> 2: blocks3 poly2+start 1.420 1.140 -0.0305 -5.900 9.87 0.993 29
#> 3: late20 linear+start 2.430 1.670 0.3530 -6.770 50.40 0.922 29
#> 4: late20 poly2+start 2.700 2.120 0.7580 -10.900 51.70 0.913 29
#> 5: early15 linear+start 1.540 1.240 0.2860 11.900 44.20 0.986 29
#> 6: early15 poly2+start 1.520 1.250 -0.1000 7.430 43.50 0.985 29结果中的列
| 列 | 含义 | 怎么看 |
|---|---|---|
daily_rmse、daily_mae
|
被隐藏日子的填充体重与实测日体重之差的均方根、平均绝对值(kg) | 越小越好 |
daily_bias |
平均差(kg) | 越接近 0 越好 |
adg_bias、adg_rmse
|
ADG 与参照 ADG 之差(g/d) | 越接近 0 越好 |
adg_spearman |
ADG 排名与参照的相关 | 越接近 1 越好 |
n_pigs |
有结果的猪数 |
$per_pig 中每头猪、每个场景、每次重复各一行。
怎么用结果做决定:区间中间的零散缺失,线性插值通常最好;开头、结尾缺失时,各方法都只能靠曲线,差别不大,而误差远大于中间缺失——保证区间两端有记录,比选择填充方法更重要。
validate_adfi():日采食的插补方法
做法:只用区间内记录比较完整的猪。隐藏一部分有记录的日子,用每种方法重新插补,在原本有记录的日子上算 ADFI,与实测的 ADFI 比较。
validate_adfi(adfi, weight = NULL, methods = c("loess_pop", "loess_lm", "linear"),
scenarios = c("random30", "blocks3", "late20", "early15"), reps = 5,
min_coverage = 0.8, max_pigs = NULL, seed = 1, verbose = 1, cores = 1)| 参数 | 默认 | 含义 | 什么时候改 |
|---|---|---|---|
adfi |
— |
calc_adfi() 的结果,它的设置用于所有计算 |
— |
weight |
NULL |
clean_weight()
的结果。建议总是传入:被隐藏日子的体重记录也一并删掉,日体重用剩下的记录重新计算,和猪真的没进站时一样;不传时沿用全部数据的日体重,会给出警告,结果偏乐观 |
— |
methods |
3 种 |
"loess_pop":短缺口 LOESS,长缺口和开头用群体曲线 ×
个体比例(验证时群体曲线不含被验证的猪);"loess_lm":LOESS
+ 单猪体重回归;"linear":线性插值 + 单猪回归 |
一般不改 |
scenarios |
4 种 | 隐藏方式,见第 2 节 | 按实际缺失情况选 |
reps |
5 | 重复次数 | 猪多时 2 次就够 |
min_coverage |
0.8 | 区间内有记录日子的比例不低于这个值的猪才参与 | 合格的猪太少(少于 3 头会报错)时降到 0.7 |
例子
vf <- validate_adfi(adfi, weight, scenarios = c("random30", "late20"), reps = 2, verbose = 0)
tidy(vf)
#> scenario method mean_abs_error_pct p95_abs_error_pct bias_pct spearman daily_rmse n_pigs
#> <char> <char> <num> <num> <num> <num> <num> <int>
#> 1: random30 loess_pop 1.05 2.75 0.0831 0.990 455 29
#> 2: random30 loess_lm 1.05 2.65 0.0970 0.990 455 29
#> 3: random30 linear 1.06 3.45 0.1290 0.983 491 29
#> 4: late20 loess_pop 1.34 3.50 -0.2970 0.980 321 29
#> 5: late20 loess_lm 4.49 7.06 4.2600 0.954 679 29
#> 6: late20 linear 4.49 7.06 4.2600 0.954 679 29结果中的列
| 列 | 含义 | 怎么看 |
|---|---|---|
mean_abs_error_pct |
个体 ADFI 误差绝对值的平均,占实测 ADFI 的百分比 | 越小越好 |
p95_abs_error_pct |
同上,95% 分位数:误差最大的那 5% 的猪 | 越小越好 |
bias_pct |
平均偏差(%) | 越接近 0 越好;偏差会让缺数据的猪在排名中系统性占便宜或吃亏 |
spearman |
ADFI 排名与实测的相关 | 越接近 1 越好 |
daily_rmse |
被隐藏日子的日采食误差(g/d) | 越小越好 |
n_pigs |
参与比较的猪数 |
怎么用结果做决定:开头缺失时 loess_pop
通常明显更好;结尾缺失时三种方法相同(末个记录之后都用这头猪自己的回归)。
validate_truncation():整条流程
做法:先用每套设置跑一遍全部数据作参照。选出测定区间被完整覆盖的猪,随机分组;每次删掉一组猪在开头、结尾或中间若干天的全部访问(体重和采食),其余猪保持完整,从
clean_weight()
起重跑整条流程,再换下一组。比较这些猪截断后与全部数据的
ADG、ADFI、FCR。
validate_truncation(visits, settings = qc_config(),
scenarios = c("late10", "late20", "early10", "early20", "gap10"),
share = 0.5, reps = 5, top = 0.2, pigs = NULL, seed = 1,
verbose = 1, cores = 1)| 参数 | 默认 | 含义 | 什么时候改 |
|---|---|---|---|
visits |
— |
prep_visits() 的结果 |
— |
settings |
qc_config() |
要比较的质控设置:一个
qc_config(),或带名字的列表,名字是结果中显示的设置名 |
比较几套设置时,见下面的例子 |
scenarios |
5 种 |
"late<d>"、"early<d>"、"gap<d>",按第一套设置的区间计算 |
按实际缺失情况选 |
share |
0.5 | 每次截断的猪的比例。猪分成 round(1 / share)
组,轮流截断,每次重复中每头猪恰好被截断一次 |
想模拟”只有少数猪缺数据”时用 0.25(分 4 组,重跑次数加倍) |
reps |
5 | 重复次数,每次重新随机分组 | 几百头猪时 1–2 次就够;二三十头猪时 5–10 次 |
top |
0.2 | 计算 top_agree 时的”最好的猪”的比例 |
选留比例不同时改,例如 0.1 |
pigs |
NULL |
只截断这些猪 | 只关心某些猪时;默认是区间被完整覆盖、有 FCR 的猪 |
总的重跑次数 = 设置数 × 场景数 × 重复次数 × 组数,决定了耗时。
例子
vt <- validate_truncation(
visits,
settings = list(default = qc_config(),
curve = qc_config(curve_extrap = "curve")),
scenarios = c("late20", "early20"), reps = 1, verbose = 0
)
vt$summary[trait == "fcr", .(setting, scenario, mae_pct = signif(mae_pct, 3),
spearman = signif(spearman, 3), slope = signif(slope, 3),
top_agree, n, n_lost)]
#> setting scenario mae_pct spearman slope top_agree n n_lost
#> <char> <char> <num> <num> <num> <num> <num> <num>
#> 1: default late20 1.83 0.922 1.010 0.75 21 0
#> 2: curve late20 3.41 0.768 0.849 0.75 21 0
#> 3: default early20 2.76 0.947 1.050 0.75 21 0
#> 4: curve early20 2.77 0.947 1.050 0.75 21 0结果中的列(每个设置、场景和性状
adg、adfi、fcr
一行,取各次重复的平均)
| 列 | 含义 | 怎么看 |
|---|---|---|
bias |
截断后 − 全部数据的平均差 | 越接近 0 越好 |
rmse、mae_pct
|
均方根误差、平均相对误差(%) | 越小越好 |
pearson、spearman
|
与全部数据结果的相关、排名相关 | 越接近 1 越好 |
slope |
截断后对全部数据的回归斜率 | 越接近 1 越好;小于 1 表示个体差异被压缩 |
top_agree |
全部数据下最好的 top
的猪,截断后仍在最好之列的比例 |
越高越好;猪少时很粗 |
n、n_lost
|
有结果的猪数;截断后失去结果的猪数 | 截断太多时,猪会因测定期太短被剔除 |
..._sd |
各次重复之间的标准差 | 差别小于标准差时不可信 |
明细:$per_rep 是每次重复的指标;$per_pig
是每头猪的全部数据值和截断值。
怎么用结果做决定:育种上最关心 FCR 的
spearman、slope 和
top_agree,其次是 bias。几套设置的差别小于
_sd 时,说明差别不可信,增加 reps 再看。
一个新的测定站或新的批次,建议按下面的顺序:
visits <- prep_visits(read_station("数据/"))
weight <- clean_weight(visits, cores = 4)
adg <- calc_adg(weight, cores = 4)
adfi <- calc_adfi(visits, adg, cores = 4)
table(adg$per_pig$adg_type) # 有多少猪的区间要靠外推
# 1. 各步骤分别看(快,可以抽样)
vo <- validate_outliers(visits, max_pigs = 300, cores = 4)
va <- validate_adg(weight, extrap = c("start", "curve"), max_pigs = 300, cores = 4)
vw <- validate_weight_fill(weight, max_pigs = 300, cores = 4)
vf <- validate_adfi(adfi, weight, max_pigs = 300, cores = 4)
# 2. 根据上面的结果,挑两三套候选设置,用整条流程比较
vt <- validate_truncation(visits,
settings = list(default = qc_config(),
poly1 = qc_config(curve_model = "poly1")),
reps = 2, cores = 4)
# 3. 保存结果和所用参数
saveRDS(list(vo = vo, va = va, vw = vw, vf = vf, vt = vt), "验证结果.rds")
fwrite(vt$summary, "验证_整体截断.csv", bom = TRUE)确定设置之后,同一个育种群体固定使用这套设置,不要逐批更换,否则年度之间的差异可能来自方法而不是猪。
太慢了怎么办? 用 max_pigs = 300
抽样;减少 reps、场景或方法;增加
cores。几百头猪时,重复 1–2
次的结果已经很稳定(各次重复的标准差接近 0)。
用了多核反而卡住或报错?
每个子进程都要占用内存,内存不够时子进程会被系统杀掉,提示 “parallel
worker stopped without a result”。减少 cores,或用
cores = 1。在 Windows 上,多核要求本包是正式安装的(不是用
devtools::load_all() 加载的)。
每次运行结果不同? 结果由 seed
决定,同样的数据、参数和种子,结果完全相同。换种子后差别很大,说明猪太少或重复次数太少,增加
reps。
validate_adfi() 提示 “Only n pigs with coverage
>= 0.8”? 区间记录完整的猪太少,降低
min_coverage,例如 0.7。
validate_truncation() 提示 “at least 6 are
needed”? 区间被完整覆盖的猪不到 6
头,无法分组比较。这类批次可以用前四个函数,或把几个批次合在一起验证。
validate_adfi() 警告 “weight is not
given”? 传入 clean_weight()
的结果:validate_adfi(adfi, weight)。
validate_outliers() 报错 “must be a named
list”? methods 的每个元素都要有名字,例如
list(rlm = "rlm"),而不是 list("rlm")。
结果和《方法验证》里的数字不一样? 那篇文章用的是包里的示例数据(二三十头猪);你的批次猪数、站型、进站体重都不同,结论可能不同,这正是要在自己的数据上验证的原因。