draft: "Does General Intelligence Deflate ...?"
[Ultimately_Untrue_Thought.git] / content / drafts / does-general-intelligence-deflate-standardized-effect-sizes-of-cognitive-sex-differences.md
1 Title: Does General Intelligence Deflate Standardized Effect Sizes of Cognitive Sex Differences?
2 Date: 2020-10-01 05:00
3 Category: commentary
4 Tags: statistics
5 Status: draft
6
7 (SEXNET's own) Marco del Guidice points out[^mdg] that in the presence of measurement error, standardized effect size measures like [Cohen's _d_](https://rpsychologist.com/d3/cohend/) will underestimate the "true" effect size. Recall that _d_ is the difference in group means, divided by the pooled variance. Thus, holding _actual_ sex differences constant, more measurement error means more variance, which means smaller values of _d_. Here's some toy Python code illustrating this effect:
8
9 [^mdg]: Marco del Guidice, ["Measuring Sex Differences and Similarities"](https://marcodgdotnet.files.wordpress.com/2019/04/delgiudice_measuring_sex-differences-similarities_pre.pdf)
10
11 ```python
12 from math import sqrt
13 from statistics import mean, variance
14
15 from numpy.random import normal, seed
16
17 # seed the random number generator for reproducibility of given figures,
18 # commment this out to run a new experiment
19 seed(1)
20
21 def cohens_d(X, Y):
22     return (
23         (mean(X) + mean(Y)) /
24         sqrt(
25             (len(X)*variance(X) + len(Y)*variance(Y)) /
26             (len(X) + len(Y))
27         )
28     )
29
30 def population_with_error(μ, σ, n):
31     def trait():
32         return normal(μ, 1)
33     def measurement_error():
34         return normal(0, σ)
35     return [trait() + measurement_error() for _ in range(n)]
36
37
38 # trait differs by 1 standard deviation
39 adjusted_f = population_with_error(1, 0, 10000)
40 adjusted_m = population_with_error(0, 0, 10000)
41
42 # as above, but with 0.5 standard units measurment error
43 measured_f = population_with_error(1, 0.5, 10000)
44 measured_m = population_with_error(0, 0.5, 10000)
45
46 smart_d = cohens_d(adjusted_f, adjusted_m)
47 print(smart_d)  # 1.0193773432617055 — d≈1.0, as expected!
48
49 naïve_d = cohens_d(measured_f, measured_m)
50 print(naïve_d)  # 0.8953395386313235
51 ```
52
53 But doesn't a similar argument hold for non-error sources of variance that are "orthogonal" to the group difference? (Sorry, I know this is vague; I'm writing to the list in case any Actual Scientists can spare a moment to help me make my intuition more precise.) Like, suppose performance on some particular cognitive task can be modeled as the sum of the general intelligence factor (zero or negligible sex difference[^jensen]), and a special ability factor that does show sex differences. Then, even with zero _measurement_ error, _d_ would underestimate the difference between women and men _of the same general intelligence_.
54
55 [^jensen]: Arthur Jensen, _The g Factor_, Chapter 13
56
57 ```python
58 def performance(g, σ_g, s, n):
59     def general_ability():
60         return normal(g, σ_g)
61     def special_ability():
62         return normal(s, 1)
63     return [general_ability() + special_ability() for _ in range(n)]
64
65 # ♀ one standard deviation better than ♂ at the special factor
66 population_f = performance(0, 1, 1, 10000)
67 population_m = performance(0, 1, 0, 10000)
68
69 # ... but suppose we control/match for general intelligence
70 matched_f = performance(0, 0, 1, 10000)
71 matched_m = performance(0, 0, 0, 10000)
72
73 population_d = cohens_d(population_f, population_m)
74 print(population_d)  # 0.7287587808164793
75
76 matched_d = cohens_d(matched_f, matched_m)
77 print(matched_d)  # 1.018362581243161
78 ```