「直方图的默认分箱是一份1926年的遗嘱」:n 从 100 涨到一百万,图还是那 20 根柱子
【锚点】这一篇只钉一个判断:直方图上柱子的宽度不是数据的属性,是【软件默认值】的属性;而多数绘图库的默认值来自一个为「纸笔累加」设计的 1926 年规则,它在 n 变大时几乎不动。
【显式】先把默认值摆出来。R 的 hist() 默认 breaks=”Sturges”;numpy.histogram 默认 bins=10;matplotlib 的 hist 默认 bins=10;pandas 的 .hist() 默认 bins=10;ggplot2 的 geom_histogram 默认 bins=30。Sturges 规则本身是 k = 1 + log2(n)(Sturges, H. A., 1926, The choice of a class interval, JASA 21(153): 65–66)。
【隐式】这个公式的来历值得看一眼:k=1+log2 n 的推导前提是数据近似正态、且分箱要服务于「手工累加频数」——把 n 写成 2 的幂次累加结构,正是为了让纸上的加法少几行。所以箱数随 n 只以【对数】增长:n=100 → 8 箱;n=1,000 → 11 箱;n=1,000,000 → 21 箱。而 Scott (1979) 与 Freedman–Diaconis (1981) 的箱宽按 n(-1/3) 收缩,箱数按 n(1/3) 增长:n=106 时 FD 规则给出的箱数常在【两百量级】。两者相差一个数量级。
【细微】后果不是「图不好看」,是【形状被抹掉】。当真实分布是双峰、且两峰间距小于默认箱宽时,默认直方图给出一个干净的单峰。更麻烦的是这个错误【稳定复现】:换机器、换作者、换年份,只要还在用默认值,就还是单峰。可重复性在这里的含义不是「能不能跑出同一张图」,而是「同一张图能不能重复地骗过所有人」。
【极难发现】再深一层:默认值是有【年代】的。Sturges 1926 年面对的约束是纸笔累加,n 是几十到几百,log2 规则在那个区间对正态数据近似合理。它活到今天不是因为它在 n=106 时仍然对,而是因为它【被写进了默认参数】。默认参数是引用的一种形态:一旦进入 API,就不再被检验,只被继承——这和「被抹除的引用」是同一机制的两面,被引用得太多以至于不再被阅读。
【流程节点链路】数据生成 → 调用 hist() / histogram() 且不指定 bins → 库读取默认(Sturges / 10 / 30)→ 箱宽由 n 的对数或一个常数决定 → 大 n 下箱宽远大于真实结构尺度 → 多峰与离群结构被合并 → 读者看到一张平滑单峰图 → 结论写进论文 → 无人回溯到箱宽这个参数。
【可以马上做的三件事】 ① 显式写 bins 或 binwidth,并把它当作分析参数报告,和报告 α、报告缺失值处理方式同等对待; ② 同时跑 Sturges 与 Freedman–Diaconis 两套,如果形状变了,那本身就是结果,而不是噪声; ③ n > 10^4 时,直方图基本该让位给【ECDF】——ECDF 没有任何分箱参数,这是它比直方图更可重复的核心理由,不是审美偏好。
【留给你的问题】我们要求作者公开数据与代码,却不要求公开绘图参数。那么当一张图的形状依赖于一个没人报告的参数时,「可重复」这三个字到底重复的是什么?







0 Comments