Files
AIclinicalresearch/docs/03-业务模块/RVW-稿件审查系统/06-开发记录/RVW V2.0 统计验证规则说明书(专家评审版).md
HaHafeng f0736dbca1 feat(asl/extraction): Complete Tool 3 M1+M2 - skeleton pipeline and HITL workbench
M1 Skeleton Pipeline:
- Scatter-dispatch + Aggregator polling pattern (PgBoss)
- PKB ACL bridge (PkbBridgeService -> PkbExportService DTOs)
- ExtractionSingleWorker with DeepSeek-V3 LLM extraction
- PermanentExtractionError for non-retryable failures
- Phantom Retry Guard (idempotent worker)
- 3-step minimal frontend (Setup -> Progress -> Workbench)
- 4 new DB tables (extraction_templates, project_templates, tasks, results)
- 3 system templates seed (RCT, Cohort, QC)
- M1 integration test suite

M2 HITL Workbench:
- MinerU VLM integration for high-fidelity table extraction
- XML-isolated DynamicPromptBuilder with flat JSON output template
- fuzzyQuoteMatch validator (3-tier confidence scoring)
- SSE real-time logging via ExtractionEventBus
- Schema-driven ExtractionDrawer (dynamic field rendering from template)
- Excel wide-table export with flattenModuleData normalization
- M2 integration test suite

Critical Fixes (data normalization):
- DynamicPromptBuilder: explicit flat key-value output format with example
- ExtractionExcelExporter: handle both array and flat data formats
- ExtractionDrawer: schema-driven rendering instead of hardcoded fields
- ExtractionValidator: array-format quote verification support
- SSE route: Fastify register encapsulation to bypass auth for EventSource
- LLM JSON sanitizer: strip illegal control chars before JSON.parse

Also includes: RVW stats verification spec, SSA expert config guide

Tested: M1 pipeline test + M2 HITL test + manual frontend verification
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-25 18:29:20 +08:00

480 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# RVW V2.0 统计验证规则说明书
> **文档目的:** 供统计学专家评审和确认
> **版本:** v1.0
> **日期:** 2026-02-18
> **适用场景:** 医学期刊论文表格数据验证
---
## 目录
1. [概述](#概述)
2. [L1 算术验证规则](#l1-算术验证规则)
3. [L2 统计验证规则](#l2-统计验证规则)
4. [L2.5 一致性取证规则](#l25-一致性取证规则)
5. [容错阈值设置](#容错阈值设置)
6. [待评审问题清单](#待评审问题清单)
---
## 概述
### 验证层级架构
| 层级 | 名称 | 目标 | 复杂度 |
|------|------|------|--------|
| **L1** | 算术验证 | 检查基础计算(加减乘除)是否正确 | 低 |
| **L2** | 统计验证 | 逆向验证统计检验结果是否合理 | 中 |
| **L2.5** | 一致性取证 | 启发式规则,发现潜在数据问题 | 高 |
### 技术依赖
- **scipy.stats**用于统计计算t 分布、卡方分布、正态分布)
- **python-docx**Word 文档表格提取
- **正则表达式**:数据格式识别
---
## L1 算术验证规则
### 规则 L1-1百分比计算验证
**应用场景:** 分类变量描述统计(如 n (%) 格式)
**规则描述:**
对于格式为 `n (p%)` 的单元格,验证:
$$
\text{calculated\_percent} = \frac{n}{N} \times 100
$$
其中 N 为该列或该组的总数。
**判定条件:**
| 条件 | 判定 |
|------|------|
| `|reported_percent - calculated_percent| > 0.1%` | ❌ Error |
| `|reported_percent - calculated_percent| ≤ 0.1%` | ✅ Pass |
**示例:**
| 原始数据 | N | 报告值 | 计算值 | 判定 |
|---------|---|--------|--------|------|
| 45 (50.0%) | 90 | 50.0% | 50.0% | ✅ Pass |
| 45 (52.0%) | 90 | 52.0% | 50.0% | ❌ Error (差 2%) |
**识别模式(正则表达式):**
```
(\d+(?:\.\d+)?)\s*\(\s*(\d+(?:\.\d+)?)\s*%?\s*\)
```
**N 值获取策略:**
1. 首先从表头识别标记为 "n"、"N"、"Total"、"合计" 的列
2. 其次检查同行中是否有总数列
3. 最后尝试从上下文推断
---
### 规则 L1-2合计行验证
**应用场景:** 表格中的 Total/Sum/合计 行
**规则描述:**
对于标记为 "Total"、"Sum"、"合计"、"总计" 的行,验证该行的每个数值列是否等于上方各行之和。
$$
\text{Total}_{\text{col}} = \sum_{i=1}^{n-1} \text{Value}_{i, \text{col}}
$$
**判定条件:**
| 条件 | 判定 |
|------|------|
| `|reported_total - calculated_sum| > 0.5` | ❌ Error |
| `|reported_total - calculated_sum| ≤ 0.5` | ✅ Pass |
**示例:**
| 分组 | 人数 | 判定 |
|------|------|------|
| A 组 | 30 | - |
| B 组 | 25 | - |
| C 组 | 45 | - |
| **合计** | **100** | ✅ Pass (30+25+45=100) |
| **合计** | **110** | ❌ Error (30+25+45=100≠110) |
**识别关键词:**
- 英文total, sum, all
- 中文:合计, 总计, 总和
---
## L2 统计验证规则
### 规则 L2-1卡方检验 P 值逆向验证
**应用场景:** 分类变量组间比较(基线特征表、疗效比较表)
**规则描述:**
从表格中提取报告的 χ² 值根据自由度df反算 P 值,与报告的 P 值对比。
**计算公式:**
$$
P_{\text{calculated}} = 1 - F_{\chi^2}(\chi^2, df)
$$
其中 $F_{\chi^2}$ 是卡方分布的累积分布函数。
**自由度估计:**
- **默认 df = 1**(适用于大多数 2×2 比较)
- 对于 r×c 表df = (r-1) × (c-1)
**判定条件:**
| 条件 | 判定 |
|------|------|
| 显著性结论相反P<0.05 vs P≥0.05 | ❌ Error |
| `|P_reported - P_calculated| > 0.05` | ⚠️ Warning |
| `|P_reported - P_calculated| ≤ 0.05` | ✅ Pass |
**示例:**
| χ² 值 | df | 报告 P | 计算 P | 判定 |
|-------|-----|--------|--------|------|
| 57.52 | 1 | 0.001 | 0.0000 | ✅ Pass均显著 |
| 3.84 | 1 | 0.05 | 0.050 | ✅ Pass |
| 2.50 | 1 | 0.01 | 0.114 | ❌ Error显著性结论相反 |
**识别模式(正则表达式):**
```
# χ² 值识别
(?:χ[²2]|[χx]2|2)\s*[=:]\s*(\d+\.?\d*)
# P 值识别
[Pp][\s\-值]*[=<>≤≥]\s*(\d+\.?\d*)
```
**⚠️ 待专家确认:**
1. df=1 作为默认值是否合理?
2. 是否需要从表格结构推断实际自由度?
---
### 规则 L2-2T 检验 P 值逆向验证
**应用场景:** 连续变量两组比较Mean±SD 格式)
**规则描述:**
从表格中提取两组的 Mean±SD 和样本量 n使用独立样本 t 检验公式反算 P 值。
**计算公式:**
$$
t = \frac{|\bar{X}_1 - \bar{X}_2|}{\sqrt{\frac{SD_1^2}{n_1} + \frac{SD_2^2}{n_2}}}
$$
$$
df = n_1 + n_2 - 2
$$
$$
P_{\text{calculated}} = 2 \times (1 - F_t(t, df))
$$
其中 $F_t$ 是 t 分布的累积分布函数。
**判定条件:**
| 条件 | 判定 |
|------|------|
| `|P_reported - P_calculated| > 0.05` | ❌ Error |
| `0.01 < |P_reported - P_calculated| ≤ 0.05` | ⚠️ Warning |
| `|P_reported - P_calculated| ≤ 0.01` | ✅ Pass |
**示例:**
| 组1 Mean±SD | 组2 Mean±SD | n1 | n2 | 报告 P | 计算 P | 判定 |
|-------------|-------------|-----|-----|--------|--------|------|
| 65.2±10.5 | 58.3±9.8 | 50 | 48 | 0.001 | 0.0007 | ✅ Pass |
| 45.0±12.0 | 44.5±11.5 | 30 | 30 | 0.001 | 0.86 | ❌ Error |
**识别模式(正则表达式):**
```
# Mean±SD 格式
(\d+\.?\d*)\s*[±\+\-]\s*(\d+\.?\d*)
# 带括号的 SD 格式
(\d+\.?\d*)\s*\(\s*(\d+\.?\d*)\s*\)(?!\s*%)
```
**样本量获取策略:**
1. 从表头提取:`(n=50)``n=50``(50例)`
2. 从数据行提取:行首的 n 信息
3. 从上下文推断
**⚠️ 待专家确认:**
1. 使用 Welch's t-test不假设方差齐性是否更合适
2. 当前假设为独立样本 t 检验,是否需要区分配对 t 检验?
---
### 规则 L2-3CI 与 P 值逻辑一致性
**应用场景:** 回归分析结果表OR、HR、RR 及其 95% CI
**规则描述(黄金法则):**
95% 置信区间与 P 值之间存在严格的逻辑对应关系:
| 95% CI 与 1.0 的关系 | P 值要求 |
|--------------------|----------|
| CI 跨越 1.0 (如 0.8-1.2) | P **必须** ≥ 0.05(不显著) |
| CI 不跨越 1.0 (如 1.1-1.5) | P **必须** < 0.05(显著) |
**违反此规则 = 数据逻辑矛盾**
**判定条件:**
| 场景 | CI | P 值 | 判定 |
|------|-----|------|------|
| 矛盾 1 | 0.8-1.2(跨越 1 | 0.03<0.05 | ❌ Error |
| 矛盾 2 | 1.2-2.5(不跨越 1 | 0.10≥0.05 | ❌ Error |
| 正确 1 | 0.8-1.2(跨越 1 | 0.45≥0.05 | ✅ Pass |
| 正确 2 | 1.2-2.5(不跨越 1 | 0.01<0.05 | ✅ Pass |
**示例:**
| OR | 95% CI | 报告 P | 判定 |
|----|--------|--------|------|
| 1.5 | 1.2-2.0 | 0.001 | ✅ PassCI 不跨越 1P<0.05 |
| 0.9 | 0.7-1.1 | 0.30 | ✅ PassCI 跨越 1P≥0.05 |
| 1.3 | 0.9-1.8 | 0.02 | ❌ ErrorCI 跨越 1但 P<0.05 |
**识别模式(正则表达式):**
```
# OR/HR/RR 识别
(?:OR|HR|RR)\s*[=:]\s*(\d+\.?\d*)
# CI 识别(多种格式)
[\(\[]\s*(\d+\.?\d*)\s*[-–—,;]\s*(\d+\.?\d*)\s*[\)\]]
95%?\s*CI\s*[:\s]+(\d+\.?\d*)\s*[-–—,;to]+\s*(\d+\.?\d*)
```
**⚠️ 待专家确认:**
1. 此规则仅适用于比值指标OR、HR、RR对于回归系数β是否需要调整为 CI 跨越 0
2. 90% CI 和 95% CI 的判定标准应如何区分?
---
## L2.5 一致性取证规则
### 规则 L2.5-1SE 三角验证
**应用场景:** Logistic 回归、Cox 回归等报告 OR/HR/RR、95% CI 和 P 值的表格
**规则描述:**
利用 OR/HR 与 95% CI 的数学关系反推标准误SE再计算 Z 值和 P 值,与报告的 P 值对比。
**计算公式:**
$$
SE = \frac{\ln(CI_{\text{upper}}) - \ln(CI_{\text{lower}})}{3.92}
$$
3.92 = 2 × 1.96,对应 95% CI 的 Z 临界值)
$$
Z = \frac{|\ln(OR)|}{SE}
$$
$$
P_{\text{calculated}} = 2 \times (1 - \Phi(Z))
$$
其中 $\Phi$ 是标准正态分布的累积分布函数。
**判定条件:**
| 条件 | 判定 |
|------|------|
| `|P_reported - P_calculated| > 0.05` | ❌ Error |
| `0.01 < |P_reported - P_calculated| ≤ 0.05` | ⚠️ Warning |
| `|P_reported - P_calculated| ≤ 0.01` | ✅ Pass |
**示例:**
| OR | 95% CI | 报告 P | 计算 SE | 计算 Z | 计算 P | 判定 |
|----|--------|--------|---------|--------|--------|------|
| 2.0 | 1.2-3.3 | 0.008 | 0.258 | 2.69 | 0.007 | ✅ Pass |
| 1.5 | 1.0-2.25 | 0.001 | 0.206 | 1.97 | 0.049 | ❌ Error |
**⚠️ 待专家确认:**
1. SE 计算公式是否准确?是否需要考虑 CI 的不对称情况?
2. 对于 HR风险比此公式是否同样适用
---
### 规则 L2.5-2SD > Mean 检查
**应用场景:** 连续变量描述统计
**规则描述:**
对于**已知为正值的指标**如年龄、体重、血压、实验室指标标准差SD大于均值Mean通常是异常的可能暗示
1. 数据录入错误
2. SD 与 SEM 混淆
3. 数据分布异常
**计算公式:**
$$
CV = \frac{SD}{Mean}
$$
若 CV > 100%(即 SD > Mean则触发警告。
**判定条件:**
| 场景 | 判定 |
|------|------|
| 已知正值指标 + SD > Mean | ❌ Error |
| 未知指标类型 + SD > Mean | ⚠️ Warning建议核查 |
**已知正值指标关键词:**
| 类别 | 指标 |
|------|------|
| 人口学 | 年龄、身高、体重、BMI |
| 生命体征 | 收缩压、舒张压、心率、脉搏 |
| 血常规 | WBC、RBC、HGB、PLT |
| 生化 | 肌酐、尿素氮、血糖、ALT、AST、胆红素 |
| 其他 | 费用、时间、持续时间 |
**例外情况:**
- **差值指标**:如"治疗前后变化值"可正可负
- **某些偏态分布指标**:如住院天数(可能存在极端值)
**示例:**
| 指标 | Mean±SD | CV | 判定 |
|------|---------|-----|------|
| 年龄 | 65±12 | 18.5% | ✅ Pass |
| 体重 | 70±15 | 21.4% | ✅ Pass |
| 年龄 | 30±45 | 150% | ❌ ErrorSD>Mean |
| 变化值 | 5±12 | 240% | ⚠️ Warning可能合理 |
**⚠️ 待专家确认:**
1. CV > 100% 作为阈值是否合理?
2. 是否有其他需要排除的例外情况?
---
## 容错阈值设置
### 当前阈值配置
| 参数 | 值 | 说明 |
|------|-----|------|
| `PVALUE_ERROR_THRESHOLD` | 0.05 | P 值差异 > 此值 → Error |
| `PVALUE_WARNING_THRESHOLD` | 0.01 | P 值差异 > 此值 → Warning |
| `DEFAULT_TOLERANCE_PERCENT` | 0.1% | 百分比容错 ±0.1% |
| `CI_RELATIVE_TOLERANCE` | 2% | CI 端点相对误差 ±2% |
| `STAT_RELATIVE_TOLERANCE` | 5% | t/χ² 值相对误差 ±5% |
### 阈值设置依据
1. **P 值阈值 0.05**:当计算的 P 值与报告的 P 值差异超过 0.05 时,可能导致显著性结论相反,属于严重问题
2. **P 值阈值 0.01**0.01-0.05 之间的差异可能是舍入误差或计算方法差异,给予警告
3. **百分比容错 0.1%**:考虑四舍五入误差,允许 ±0.1% 的偏差
**⚠️ 待专家确认:**
1. 上述阈值是否合理?
2. 是否需要针对不同检验方法设置不同阈值?
---
## 待评审问题清单
### 高优先级(请专家重点关注)
| # | 问题 | 当前处理 | 请确认 |
|---|------|----------|--------|
| 1 | 卡方检验默认 df=1 | 适用于 2×2 比较 | 是否合理?如何推断多组比较? |
| 2 | T 检验使用 Welch's 还是 Student's | 当前用合并方差公式 | 是否应默认使用 Welch's |
| 3 | CI vs P 值规则中的 "1.0" | 仅适用于比值指标 | 回归系数应使用 0 |
| 4 | SE 三角公式的准确性 | 基于正态近似 | 对于小样本是否适用? |
| 5 | SD > Mean 的阈值 | CV > 100% 触发 | 是否过于严格? |
### 中优先级(功能扩展)
| # | 问题 | 说明 |
|---|------|------|
| 6 | 配对 T 检验验证 | 当前仅支持独立样本 |
| 7 | ANOVA P 值验证 | 多组比较 |
| 8 | 非参数检验验证 | Mann-Whitney、Wilcoxon |
| 9 | 相关性分析验证 | Pearson、Spearman |
### 低优先级(边缘情况)
| # | 问题 | 说明 |
|---|------|------|
| 10 | 90% CI vs 95% CI 区分 | 当前假设都是 95% CI |
| 11 | 单侧检验 vs 双侧检验 | 当前假设都是双侧 |
| 12 | Bonferroni 校正后的 P 值 | 多重比较场景 |
---
## 附录:识别模式汇总
### 正则表达式清单
```python
# 1. 百分比格式 n (%)
PERCENT_PATTERN = r"(\d+(?:\.\d+)?)\s*\(\s*(\d+(?:\.\d+)?)\s*%?\s*\)"
# 2. P 值
PVALUE_PATTERN = r"[Pp][\s\-值]*[=<>≤≥]\s*(\d+\.?\d*)"
# 3. 卡方值
CHI_SQUARE_PATTERN = r"(?:χ[²2]|[χx]2|2)\s*[=:]\s*(\d+\.?\d*)"
# 4. Mean±SD
MEAN_SD_PATTERN = r"(\d+\.?\d*)\s*[±\+\-]\s*(\d+\.?\d*)"
# 5. OR/HR/RR
EFFECT_SIZE_PATTERN = r"(?:OR|HR|RR)\s*[=:]\s*(\d+\.?\d*)"
# 6. 95% CI
CI_PATTERN = r"[\(\[]\s*(\d+\.?\d*)\s*[-–—,;]\s*(\d+\.?\d*)\s*[\)\]]"
```
---
**文档版本:** v1.0
**创建日期:** 2026-02-18
**待更新:** 专家评审反馈后更新