交付出件箱
← 返回出件箱
眼轴百分位「同龄排第几」落地方案 · gpt-6-astra 第二意见
来源:gpt-6-astra(经 yundou · effort=medium · 488s)· 2026-09-17
长官口径:就用 5411 条自己的孩子当参照群做经验排名,不引外部常模。
定位:第二意见 · 涉及代码/数据结论仍需自己 grep/实测核对,不直接当结论。
一句话结论:可以直接落地——把清洗后的基线记录固化成一个版本化参照库,计算"眼轴值在同龄参照儿童中的经验百分位";非整岁用相邻年龄锚点插值;样本少就按固定规则扩年龄窗,并在接口/页面标明。全程不引外部常模。核心算法就是"同年龄窗经验排名 + 相邻年龄百分位插值",不需要训练模型。
⚠️ 关键口径:5411 条原始记录 ≠ 5411 个可比较儿童(有复诊/双眼拆行/无效记录),最终必须返回真实人数。
1. 先固定排名含义
- 百分位越高 = 眼轴在本库同龄儿童中越长
- 文案:"在本库同龄参照儿童中,眼轴约处于第 82 百分位;按从短到长排的 100 个孩子里约第 82 位"(100 人是直观换算,非真抽 100 人)
- 相同眼轴值用并列居中排名(low + 等值人数一半)
- 不写成"近视风险 82%",不自动贴正常/异常标签
2. 数据清洗:一名儿童、一条基线、一个固定眼别
- 最低字段:child_id / visit_id / birth_date / exam_date / sex / 左右眼眼轴 / device_model / quality_flag / source_row_id
- 主口径:默认右眼,每个儿童只取一次基线,左眼另建库,不把左右眼当两个儿童,不用左眼补右眼
- 清洗顺序:原始原样入暂存→统一格式单位→去重→按 child_id 合并同一儿童→定基线(有标记用标记,否则用最早检查)→日期不早于出生→眼轴须有效正数→离群点只标记不删→缺生日不进年龄排名
- 年龄:
age_years = (exam_date - birth_date).days / 365.2425,内部保精度,别先四舍五入成整岁
- 出清洗报告:原始/去重后/唯一儿童数/有效基线儿童数/左右眼有效参照人数/排除原因
3. 入库结构:原始层 + 基线层 + 参照层(版本化)
- 三张表:
reference_version(版本+清洗报告)、child_baseline(每儿童一行基线)、reference_anchor(每锚点存排序好的眼轴数组)
- 每次清洗规则/样本/参数变化生成新版本,不覆盖旧版本;用户查询数据默认不自动加入参照库(避免排名悄悄变)
4. 分组:年龄为主,眼别分开,性别可选
- 第一版默认:眼别 × 年龄(男女合并),页面写明"男女合并参照"
- 同时预计算 眼别×年龄×性别,用户明确选"同性别比较"才启用;样本不足不静默切回合并
- 第一版不按是否近视/屈光度/学校拆(会改变比较对象+稀释样本)
5. 年龄锚点 + 小样本规则(工程阈值,非医学标准)
- 整数年龄为锚点,初始窗 ±0.5 岁(如 8 岁 = 7.5≤age<8.5)
- 样本不足扩窗:半宽候选 0.5→0.75→1.0 岁,目标 100 人
- n≥100 可用;30≤n<100 可用但标
low_sample;n<30 该锚点不可用;扩过窗标 expanded_window
- 不无限扩窗;最大半宽 1 岁仍不足就返回无法计算
- 相邻锚点可能含同一儿童,展示"两组实际参照人数"要去重不能相加
6. 百分位公式(经验 ECDF · 并列居中)
P(x) = 100 × (L + 0.5E) / n(L=小于 x 人数,E=等于 x 人数)
- 用 NUMERIC/Decimal 存眼轴避免浮点误差破坏相等判断
- 例:100 人里 79 人 <24.00、6 人 =24.00 → P = 100×(79+3)/100 = 82
7. 非整岁:插的是"百分位",不是眼轴值
- 8.3 岁查:先在 8 岁锚点算该眼轴百分位 P8、9 岁锚点算 P9,再按年龄加权
P(8.3) = 0.7×P8 + 0.3×P9
- 边界:非整岁必须两个可用锚点;不跨无效锚点连更远年龄;不外推;超范围返回
age_out_of_range,不硬给 P50
8. 后端接口
POST /api/v1/axial-length/percentile:传 version/birth_date/exam_date/eye/axial_length_mm/sex_group,后端统一算年龄
- 返回:percentile / display_position / direction / method / 各锚点(n/窗/权重/百分位) / reference_n_unique / warnings
- 不足返回
insufficient_reference(percentile=null + 原因)
- 另给
GET /reference-info:版本/清洗报告/各分组可用年龄范围/锚点人数
- 5411 规模很小,锚点数组启动时全加载内存 + 二分查找,不需复杂服务
9. 前端展示
- 主卡:眼轴值 + "本库同龄排名 约第 81/100 位(从短到长,越靠后越长)" + 比较年龄 + 参照范围
- 用"短→长"中性色进度条,不默认红黄绿风险分区
- 展开:算法/两个锚点组人数窗/版本/"仅本库相对位置,非全国常模,非疾病风险"
- 小样本/边界:扩窗提示、30-99人提示"稳定性有限"、无法算显示原因、接近端点用 P99、P0/P100 不写"第0个/超过所有"
10. 上线验收清单(10 条)
重复导入不变人数排名 / 左右眼不混 / 全相同值查同值返 P50 / 低于全部返 P0 高于返 P100 / 固定年龄眼轴增大百分位不降 / 非整岁=两锚点加权 / 29·30·99·100 人边界行为 / 扩窗重叠人数正确去重 / 无效锚点或超范围不外推 / 同版本同输入多次一致
最终交付三块:一个清洗+生成参照版本的脚本、一个百分位查询接口、一个排名展示组件。