5D Library › 心理物理学、韦伯-费希纳定律与多感官贝叶斯整合的数学模型 · English

第二章 史蒂文斯幂定律与跨模态匹配

直接问感觉有多大

费希纳通过数最小可觉差来间接地测量感觉。20 世纪 50 年代,史蒂文斯换了一个直截了当的办法:直接请人给感觉打分。在量值估计法中,实验者先呈现一个标准刺激,告诉受试者它的感觉值是 10;然后呈现其他刺激,请受试者按比例报数,觉得两倍强就说 20,一半就说 5。在量值产生法中则反过来,实验者报出数字,受试者调整刺激直到感觉与数字相符。

史蒂文斯在许多感觉通道上得到同一种形式的结果:报出的数字与刺激强度成幂函数关系 (Stevens 1957),

S=aIn.S = aI^{\,n}.

在双对数坐标上它是一条直线,斜率就是指数 nn。1961 年,他在《科学》上发表了一篇题目就叫《向费希纳致敬,并废除他的定律》的文章 (Stevens 1961)。

指数与它们的测量条件

框架中列出了三个指数:亮度约 0.33,长度约 1.0,电击约 3.5。核对史蒂文斯的汇总表 (Stevens 1975),这三个数没有错,但每一个都有明确的测量条件:

感觉 指数 刺激条件
亮度 0.33 在黑暗中观看视角 5° 的目标
亮度 0.5 点光源;或短暂的闪光
视觉长度 1.0 投影的线段
响度 0.67 3000 赫兹纯音的声压
重量感 1.45 举起的重物
肌力 1.7 静态收缩(如握力)
电击 3.5 通过手指的电流

几点说明。亮度的指数随目标大小与呈现方式改变,所以「亮度指数 0.33」只适用于特定条件。响度 0.67 是相对声压而言;声强与声压的平方成正比,所以相对声强约为 0.33,这就是「每提高 10 分贝响度约加倍」的来源:100.33≈2.110^{0.33} \approx 2.1。指数小于 1 的感觉是压缩的,能把极宽的物理范围装进有限的感觉范围;指数大于 1 的感觉是扩张的,电流稍有增加,感觉就急剧变强,这对于提示伤害是有用的。

左:三种幂函数(刺激与感觉都以参照值为单位):亮度 n = 0.33 压缩,视觉长度 n = 1 成正比,电击 n = 3.5 扩张。右:跨模态匹配的模拟。用握力去匹配响度、电击与亮度时,双对数坐标上匹配的握力是一条直线,斜率等于两个指数之比 n_B/n_A。

量值估计法测到的是什么

量值估计法看起来很「直接」,但它依赖一个假设:人使用数字的方式与感觉成正比。对此有三种主要的批评。

第一,回归效应。史蒂文斯与格林鲍姆 1966 年发现,同一种感觉用量值估计法测得的指数偏小,用量值产生法测得的偏大:人在两种任务中都倾向于把回答向所用范围的中部收缩 (Stevens and Greenbaum 1966)。第二,情境与范围效应。波尔顿 1968 年列举了量值估计中的多种偏差,包括刺激范围、第一个标准刺激的取值与数字使用习惯的影响 (Poulton 1968);特格措尼安 1971 年提出,各种感觉测得的指数与该感觉通道刺激范围的对数大致成反比,指数可能更多反映了刺激范围,而不只是感觉本身的增长方式 (Teghtsoonian 1971)。第三,数字本身也是一种「感觉」。谢泼德 1981 年指出,如果人把内部感觉 SS 转换成数字时还经过一个幂函数 R=SmR = S^{\,m},那么测到的指数是 n×mn \times m,单靠量值估计无法把 nn 与 mm 分开 (Shepard 1981)。

下面的程序模拟三种感觉(真实指数取汇总表中的 0.33、1.0 与 3.5),每次判断都向范围中部收缩(系数 ρ=0.85\rho = 0.85),并带对数正态噪声;分别用量值估计与量值产生两种方法拟合指数。然后重复一遍,但假设受试者使用数字时有自己的指数 m=0.8m = 0.8。刺激范围是示意的。

推导

# Magnitude estimation and production with a "regression toward the middle" of the
# range (illustrative model of Stevens & Greenbaum 1966). True exponents from Stevens's
# table: brightness 0.33 (5 deg target, dark), visual length 1.0, electric shock 3.5.
# rho = 0.85 shrinks every judgement toward the middle of the range used; noise is
# log-normal (sd 0.10 in log10 units). Exponents are least-squares slopes on log axes.
import math, random

def slope(xs, ys):
    mx, my = sum(xs) / len(xs), sum(ys) / len(ys)
    return (sum((x - mx) * (y - my) for x, y in zip(xs, ys))
            / sum((x - mx) ** 2 for x in xs))

def experiment(rng, n, lo, hi, rho=0.85, m=1.0, reps=400):
    li = [lo + (hi - lo) * j / 9 for j in range(10)]          # log10 stimulus levels
    mid_s = n * (lo + hi) / 2                                  # log10 sensation, middle
    x_e, y_e, x_p, y_p = [], [], [], []
    for _ in range(reps):
        for x in li:                                           # estimation: number for I
            s = mid_s + rho * (n * x - mid_s)
            x_e.append(x); y_e.append(m * s + rng.gauss(0, 0.10))
        for x in li:                                           # production: I for number
            target = n * x                                     # number given (log10)
            s = mid_s + rho * (target - mid_s)
            x_p.append(s / n + rng.gauss(0, 0.10 / n)); y_p.append(m * target)
    return slope(x_e, y_e), slope(x_p, y_p)

if __name__ == "__main__":
    rng = random.Random(1957)
    rows = (("brightness", 0.33, 0.0, 4.0), ("visual length", 1.0, 0.0, 1.5),
            ("electric shock", 3.5, 0.0, 0.6))
    print("continuum       true n  range(log10 I)  estimation  production  geo. mean")
    for name, n, lo, hi in rows:
        e, p = experiment(rng, n, lo, hi)
        print(f"{name:15s} {n:6.2f} {hi - lo:10.1f} {e:13.2f} {p:11.2f}"
              f" {math.sqrt(e * p):10.2f}")
    print("repeat, with people using numbers through their own exponent m = 0.8:")
    for name, n, lo, hi in rows:
        e, p = experiment(rng, n, lo, hi, m=0.8)
        print(f"  {name:15s} estimation {e:4.2f}  production {p:4.2f}"
              f"  geo. mean {math.sqrt(e * p):4.2f}  (0.8 x n = {0.8 * n:.2f})")
# continuum       true n  range(log10 I)  estimation  production  geo. mean
# brightness        0.33        4.0          0.28        0.36       0.32
# visual length     1.00        1.5          0.85        1.11       0.97
# electric shock    3.50        0.6          2.98        3.99       3.45
# repeat, with people using numbers through their own exponent m = 0.8:
#   brightness      estimation 0.22  production 0.29  geo. mean 0.25  (0.8 x n = 0.26)
#   visual length   estimation 0.68  production 0.88  geo. mean 0.78  (0.8 x n = 0.80)
#   electric shock  estimation 2.38  production 3.18  geo. mean 2.75  (0.8 x n = 2.80)

在只有回归效应时,量值估计法得到的指数偏小(亮度 0.28、长度 0.85、电击 2.98),量值产生法偏大(0.36、1.11、3.99),两者的几何平均(0.32、0.97、3.45)接近真实值,这也是史蒂文斯与格林鲍姆的建议。几何平均略低于真值,是因为量值产生法中受试者调整刺激时的误差使回归斜率变平。第二组结果说明谢泼德的论点:受试者使用数字的指数为 0.8 时,三种感觉的几何平均都变成了约 0.8n0.8n(0.25、0.78、2.75),而且从数据本身看不出任何异常。量值估计法给出的指数,是感觉与数字使用方式的混合。

跨模态匹配

史蒂文斯用一种不用数字的方法回应这类批评:跨模态匹配。受试者调整一种感觉(例如握力)的强度,使它与另一种感觉(例如响度)「一样强」。如果两种感觉分别是 SA=IAnAS_A = I_A^{\,n_A} 与 SB=IBnBS_B = I_B^{\,n_B},令二者相等,得到

IA=IBnB/nA.I_A = I_B^{\,n_B/n_A}.

所以在双对数坐标上,匹配结果应当是一条斜率为 nB/nAn_B/n_A 的直线。框架中「用 A 去匹配 B 时幂指数等于 nB/nAn_B/n_A」的写法是对的。史蒂文斯 1959 年用响度、振动与电击做了这样的实验,匹配得到的斜率与从各自量值估计得到的指数之比大致相符 (Stevens 1959)。

下面的程序模拟五组匹配(握力的指数取汇总表中「肌力」的 1.7),先不加回归效应,再加上 ρ=0.85\rho = 0.85;然后把同一对感觉正反各匹配一次。最后一部分是另一种情形:两种感觉都服从费希纳的对数定律,S=kln⁡(I/I0)S = k\ln(I/I_0),用二分法找出使二者相等的强度。

推导

# Cross-modality matching. If S_A = I_A^nA and S_B = I_B^nB, adjusting A until it feels as
# strong as B gives I_A = I_B^(nB / nA): on log axes a line of slope nB / nA. Simulated
# with matching noise (sd 0.05 log10) and the same regression toward the middle (rho).
# Exponents from Stevens's table (handgrip: "muscle force, static contraction" 1.7).
import math, random
N = {"loudness": 0.67, "brightness": 0.33, "length": 1.0, "shock": 3.5, "handgrip": 1.7}

def slope(xs, ys):
    mx, my = sum(xs) / len(xs), sum(ys) / len(ys)
    return (sum((x - mx) * (y - my) for x, y in zip(xs, ys))
            / sum((x - mx) ** 2 for x in xs))

def match(rng, a, b, rho=1.0, span=1.0, reps=300):
    """adjust continuum a to match b; return the fitted slope of log I_a on log I_b"""
    xb = [span * j / 9 for j in range(10)]
    mid = N[b] * span / 2
    xs, ys = [], []
    for _ in range(reps):
        for x in xb:
            s = mid + rho * (N[b] * x - mid)                   # felt strength, regressed
            xs.append(x); ys.append(s / N[a] + rng.gauss(0, 0.05))
    return slope(xs, ys)

if __name__ == "__main__":
    rng = random.Random(1959)
    print("adjust A to match B        predicted nB/nA   simulated   with rho = 0.85")
    pairs = (("handgrip", "loudness"), ("handgrip", "shock"), ("handgrip", "brightness"),
             ("loudness", "shock"), ("length", "brightness"))
    for a, b in pairs:
        print(f"  {a:9s} <- {b:10s} {N[b] / N[a]:15.3f} {match(rng, a, b):11.3f}"
              f" {match(rng, a, b, 0.85):13.3f}")
    s1, s2 = match(rng, "loudness", "shock", 0.85), match(rng, "shock", "loudness", 0.85)
    print(f"regression: slope(A<-B) x slope(B<-A) = {s1:.3f} x {s2:.3f} = {s1 * s2:.3f}"
          " (1 without)")
    # Two Fechner laws S = k ln(I / I0), thresholds 0.2 and 3: match A to B by bisection.
    ka, kb, a0, b0 = 1.0, 2.5, 0.2, 3.0
    def matched(ib):
        lo, hi = 0.0, 50.0                                     # search in log I_a
        for _ in range(100):
            mid = (lo + hi) / 2
            weaker = ka * (mid - math.log(a0)) < kb * math.log(ib / b0)
            lo, hi = (mid, hi) if weaker else (lo, mid)
        return math.exp(hi)
    ib = [3 * 10 ** x for x in (0.5, 1.0, 1.5, 2.0)]
    sl = [math.log(matched(y) / matched(x)) / math.log(y / x) for x, y in zip(ib, ib[1:])]
    print("two Fechner (log) laws matched: log-log slopes",
          ", ".join(f"{v:.3f}" for v in sl), f"(kB / kA = {kb / ka})")
# adjust A to match B        predicted nB/nA   simulated   with rho = 0.85
#   handgrip  <- loudness             0.394       0.389         0.331
#   handgrip  <- shock                2.059       2.061         1.753
#   handgrip  <- brightness           0.194       0.191         0.169
#   loudness  <- shock                5.224       5.225         4.437
#   length    <- brightness           0.330       0.330         0.282
# regression: slope(A<-B) x slope(B<-A) = 4.439 x 0.160 = 0.712 (1 without)
# two Fechner (log) laws matched: log-log slopes 2.500, 2.500, 2.500 (kB / kA = 2.5)

没有回归效应时,模拟的斜率与预测的 nB/nAn_B/n_A 一致(例如握力匹配电击:2.059 与 2.061)。加上回归效应,所有斜率都变小约 15%。把响度去匹配电击、再把电击去匹配响度,两个斜率的乘积在没有回归效应时应当正好是 1,这里只有 0.712。这个检验是有用的:正反两个方向的斜率之积明显小于 1,提示存在回归效应。

最后一行更重要。两种感觉都服从对数定律时,跨模态匹配同样得到一条直线,斜率等于两个对数系数之比 kB/kA=2.5k_B/k_A = 2.5。麦凯 1963 年指出了这一点:如果人比较的是两种感觉的内部(对数)表征,跨模态匹配与量值估计都会产生幂函数,即使每种感觉本身服从的是费希纳定律 (MacKay 1963)。所以跨模态匹配检验的是一组感觉之间的内部一致性,它不能在费希纳与史蒂文斯之间作出裁决。

注

费希纳与史蒂文斯测的不是同一件事。 费希纳的方法基于辨别(两个刺激能否区分),史蒂文斯的方法基于判断(这个刺激有多强)。一个感觉通道可以在辨别上服从韦伯定律,同时在量值判断上表现为幂函数。两条「定律」都是对特定实验程序结果的概括,而不是神经系统中某个可以直接读出的量。

假说 · 尚未验证

尚未确立:一个人「怎样使用数字」是跨感觉通道稳定的个人特征。 如果谢泼德所说的数字使用指数 mm 因人而异,那么同一个人在几种不同感觉上测得的指数应当一同偏高或一同偏低,彼此正相关。如果在校正了测量信度之后,同一批人在三种以上感觉通道上的指数彼此没有相关,这个假说就是错的。

本章小结

史蒂文斯的量值估计法在许多感觉上得到幂函数 S=aInS = aI^{\,n}。框架中的三个指数(亮度 0.33、长度 1.0、电击 3.5)都与汇总表一致,但各有特定的测量条件:亮度指数随目标大小与呈现时间改变,响度 0.67 是相对声压而言。量值估计受回归效应、范围与情境的影响,测到的是感觉与数字使用方式的混合。跨模态匹配的斜率等于两个指数之比,这一点程序完全重现;但两条对数定律互相匹配同样得到幂函数,所以它不能证明幂定律优于对数定律。下一章从单一感觉转向多种感觉的合成。

参考文献

MacKay, Donald M. 1963. “Psychophysics of Perceived Intensity: A Theoretical Basis for Fechner’s and Stevens’ Laws.” Science 139 (3560): 1213–16.
Poulton, E. C. 1968. “The New Psychophysics: Six Models for Magnitude Estimation.” Psychological Bulletin 69 (1): 1–19.
Shepard, Roger N. 1981. “Psychological Relations and Psychophysical Scales: On the Status of ‘Direct’ Psychophysical Measurement.” Journal of Mathematical Psychology 24 (1): 21–57.
Stevens, S. S. 1957. “On the Psychophysical Law.” Psychological Review 64 (3): 153–81. https://doi.org/10.1037/h0046162.
Stevens, S. S. 1959. “Cross-Modality Validation of Subjective Scales for Loudness, Vibration, and Electric Shock.” Journal of Experimental Psychology 57 (4): 201–9.
Stevens, S. S. 1961. “To Honor Fechner and Repeal His Law.” Science 133 (3446): 80–86. https://doi.org/10.1126/science.133.3446.80.
Stevens, S. S. 1975. Psychophysics: Introduction to Its Perceptual, Neural, and Social Prospects. Edited by Geraldine Stevens. Wiley.
Stevens, S. S., and H. B. Greenbaum. 1966. “Regression Effect in Psychophysical Judgment.” Perception & Psychophysics 1 (5): 439–46.
Teghtsoonian, Robert. 1971. “On the Exponents in Stevens’ Law and the Constant in Ekman’s Law.” Psychological Review 78 (1): 71–80.

Fan, Y. (2026). Psychophysics, the Weber-Fechner Law and Optimal Bayesian Multisensory Integration: From Stevens's Power Law and the McGurk Effect to Sensory Substitution, Read Beside Classical Chinese Thought on the Six Senses [心理物理学、韦伯-费希纳定律与多感官贝叶斯整合的数学模型] (Version 1.0.0). 5D Library. https://doi.org/10.5281/zenodo.23788548 · Licensed under Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0).