从数据出发看公民科学素质变化

前言

两年前,承蒙有关部门的老师邀请,对公民科学素质的变化规律做了点分析。今年,最新一次即第十一次公民科学素质抽样调查结果已经公布,刚好趁这个机会更新一下数据,做一下简单的分析和预测,也算是为全民科普做一点点贡献。

问题:中国公民科学素质估计

问题简介

科学素质对于个人的重要性就毋庸多言了,要不然也不会有千奇百怪的人和事情。对于一个国家也是如此,因此掌握本国国民的科学素质情况,并针对性地采取调整政策等举措,是非常有必要的。

那么如何掌握公民的科学素质呢?显然这并不是一件容易的事,虽然直觉判断实际也是采用类似人口普查(抽查)的方法,但是人口普查只要数人头就可以了,科学素质的评价就复杂多了:我可能学历很高,但不见得是个文化人或者知识分子;同样地,哪怕人家学历低,科学素养也是有可能不知道高到哪里去的啦。

Solar System Cartogram

为了解决评价的问题,中国自1992年起引入了美国人Miller提出一套衡量公民科学素质的测试体系,而美国也采用这套体系对评估本国公民的科学素质。自2016年起,中国建立了自己的一套“本土化”的测试体系,叫《中国公民科学素质基准》(并引起了一些争议)。这样,只要看抽样人群中通过测试的人口的百分比,也就大致可以估摸出国家的公民科学素质情况。

根据网上可以查到的公开资料可知,美国从上世纪80年代开始先后做了8次测试(1992-2016),而我们国家如果取2001年之后较为可靠的数据,到今天差不多也有8次(2001-2021)。

从图中可以看出,美国公民科学素质领先于中国,但是美国近年来的增长已经趋缓,而中国公民科学素质则进入快速增长阶段。

现在美国人对我们横挑鼻子竖挑眼,还在各种科技上“卡脖子”,我心里也是憋着一口气,美国没有资格居高临下同中国讲话。知耻而后勇,认识到公民科学素质的重要性,就特别弄清楚一个问题:中美之间差距有多少年呢?到2025年,中国公民科学素质会达到多少水平呢?

基本假设

正所谓,开篇一张图,剩下全靠编。 好的开头,是成功的一半。

要回答这两个问题,在没有更多数据的情况下,引入一些基本且合理的假设是必要的:

  • 公民科学素质的提高路径具有相似性;
  • 公民科学素质的提高符合“S-曲线”。

由于公民科学素质的提高与公民的受教育水平、社会发展水平密切相关,所以即使是不同国家,如果遵循发展的客观规律,国民科学素质的提高也应当具有相似性,尤其是对于中美这种经济、人口体量相似的国家,所以不妨认为第一个假设成立。

根据百度百科的说明,S型曲线(S-Curve)多存在于分类评定模型(Logit model),逻辑回归(Logistic regression)模型,属于多重变数分析范畴,是社会学、生物统计学、临床、数量心理学、市场营销等统计实证分析的常用方法。从实证数据来看采用S-曲线描述公民科学素质是合理的,所以不妨认为第二个假设成立。

模型选择

我们选用的模型为最经典的Sigmoid函数,标准Sigmoid函数如下图所示:

由于我们x-y坐标的特殊性,需要进行平移和缩放,所以模型为

f(x)=a1+eb(xc)+df(x)=\frac{a}{1+e^{-b(x-c)}}+d

其中各个参数的含义:

  • a–函数f(x)在纵轴的变化范围,反映了公民科学素质变化的增量;
  • b–对x的缩放,反映了公民科学素质变化的速度;
  • c–对x的平移,反映了数据所处的阶段;
  • d–函数f(x)的平移量,反映了公民科学素质的初始禀赋。

此外,容易发现f(x)的值域为(a, a+d)。

那么,现在问题、假设和工具都有了,我们来做一些分析。

建模分析

基于美国数据建模

根据上图可知,虽然美国的调查次数不多,但是时间跨度相对较大,那么我们首先以美国的数据作为基准,建立模型(代码为Python 3):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
from scipy.optimize import curve_fit
import matplotlib as mpl
font_name = "Arial Unicode MS"
mpl.rcParams['font.family']=font_name
mpl.rcParams['axes.unicode_minus']=False
mpl.rcParams['figure.figsize']=(15,9)
mpl.style.use('ggplot')

year_us = np.asarray([1988, 1995, 1997, 1999, 2004, 2005, 2008, 2015, 2020])
sciq_us = np.asarray([10, 12, 14.7, 17.3, 24.5, 27.3, 28.2, 28.5, 29.5])
year_cn = np.asarray([2001, 2005, 2007, 2010, 2013, 2015, 2018, 2020])
sciq_cn = np.asarray([1.44, 1.6, 2.25, 3.27, 4.48, 6.2, 8.47, 10.57])

def func(x, a, b, c,d):
return a / (1+np.exp(-b*(x-c)))+d

接下来,我们针对美国数据,估计aabbccdd

1
2
3
4
5
6
7
8
9
10
mean_year_us = np.mean(year_us)
std_year_us = np.std(year_us)
year_us_normalized = stats.zscore(year_us)
print(mean_year_us, std_year_us)

params_us, pcov = curve_fit(func, year_us_normalized,sciq_us, p0=[1,0,0,0])
print(f'a: {params_us[0]}\n'
f'b: {params_us[1]}\n'
f'c: {params_us[2]}\n'
f'd: {params_us[3]}\n')
1
2
3
4
5
6
7
mean_year_us:  2003.4444444444443
std_year_us: 9.441175904999112

a: 19.387495709028222
b: 3.490582791206227
c: -0.3462142933009988
d: 9.761449947006334

基于估计的道德参数,我们看一下拟合的结果,需要注意的是,我们对年份进行了规范化处理。

1
2
3
4
5
6
7
8
9
10
11
12
xx = np.linspace(1987,2021, 690)
xx_normalized = (xx-mean_year_us)/std_year_us
yy=func(xx_normalized,params_us[0],params_us[1], params_us[2], params_us[3])

plt.figure(figsize=(20,10))
plt.plot(xx, yy, label='拟合曲线')
plt.plot(year_us, sciq_us, 'r.', label='美国公民素质实际值')
plt.xlabel('年 份', fontsize=20)
plt.ylabel('公民素质', fontsize=20)
plt.title('基于美国数据建模', fontsize=40)
plt.legend(loc='upper left', fontsize=15)
plt.show()

output_13_0

上图为基于美国数据的拟合结果,可以看出曲线拟合的效果较好,说明了假设和拟合模型的合理性。

考虑到,美国1988年的公民科学素质约为10%(我国目前的水平与之相仿 [1]),那么:

  • 我们将美国数据建立的模型外推5年,即美国1993年的估计值,可以认为是我国2025年的水平;
  • 根据我国2020年实际的科学素质调查结果,可以看与美国水平相当的年份。

计算代码如下:

1
2
3
4
5
6
7
8
9
10
# 估计我国2025的公民科学素质
year_to_est = 1993
year_to_est_normalized = (year_to_est -mean_year_us)/std_year_us
func(year_to_est_normalized, params_us[0],params_us[1], params_us[2], params_us[3])

# 估计我国2020年相当于美国的年份
# 需要用到Sigmoid函数的反函数
literacy_cn_2020 = 10.57
(np.log(params_us[0]/(literacy_cn_2020 -params_us[3])-1)/(-params_us[1])+params_us[2]) * std_year_us+mean_year_us

计算得到,我国2025年的估计值,即美国1993年的估计值,为11.04,而我们2020年实际值10.57对应年份为1991.69,也就是说接近美国1992年的水平。

根据上面这两个结果,我们去判断中美至今的差距,前者实际上暗含了中美之间相差 20201988=322020-1988=32 年,而后者则表明差距为 20201991.7=28.32020-1991.7=28.3年。所以直接用美国的模型套在中国上面如果没有低估,至少也是不够准确的。

中美数据联合建模

上面的做法只考虑了美国的数据,而忽视了我国的实际国情以及在科普方面的发展情况,所以更为合理的方式是同时利用中国和美国的数据进行联合建模,也就是用中国数据修正美国模型。但是,考虑到美国数据是中国数据的未来(即最开始图形中红色曲线是蓝色曲线向右延伸),其中最大的问题是中国2020年的“10”,与美国1988年的“10”,是两者对应的,还是两者有交错(中国2020已经超过美国1988),或者是两者有间隔(中国2020尚未达到美国1988)?

为了解决这一问题,我们假设美国1988与中国2020之间的间隔为i,当i>0时,说明两者有间隔;当i<0时,说明两者有交错。显然,当i过大或者过小时,误差都会增大,那么我们不断改变i的取值,当模型拟合误差最小时,就是合理的间隔。

计算代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
sse=[]
# 先把美国的年份加32年,放在中国数据前面
year_us_mod = year_us + 32
intervals = np.arange(-10,10,0.1)
for i in intervals:
x = np.append(year_cn, year_us_mod+i)
y = np.append(sciq_cn, sciq_us)
x_n = stats.zscore(x)
mean_x = np.mean(x)
std_x = np.std(x)
popt, pcov = curve_fit(func, x_n, y, p0=[10,4,-0.5,10])
residuals = y - func(x_n, popt[0], popt[1], popt[2], popt[3])
sse.append(np.sum(residuals**2))

interval_min = intervals[np.argmin(sse)]
mse = min(sse)
print(interval_min)

plt.figure(figsize=(20,10))
plt.plot(intervals,sse, label='拟合误差SSE')
plt.plot(interval_min, mse_min, 'ro', label='最小值点')
plt.xlabel('间隔年份', fontsize=20)
plt.ylabel('SSE', fontsize=20)
plt.title('拟合误差随间隔变化', fontsize=40)
plt.legend(loc='upper right', fontsize=15)
plt.show()

output_19_1

跟预料的一样,曲线出现了一个呈现“先单调减,再单调增”的变化趋势,误差最小处的间隔为-4.4,这意味着中国2020年的水平实际超过美国1988年的水平4.4年,也就是说通过中美数据联合估计,美国领先中国水平在 324.4=27.632-4.4=27.6 年左右。

基于这个结果,再做一下参数估计,看一下拟合出的S曲线的形状。具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
i = interval_min
x = np.append(year_cn, year_us_mod[1:]+i)
y = np.append(sciq_cn, sciq_us[1:])
x_n = stats.zscore(x)
mean_x = np.mean(x)
std_x = np.std(x)
params_all, pcov = curve_fit(func, x_n, y, p0=[20,4,-0.5,10])


xx = np.linspace(min(x)-1,max(x)+1, 100)
xx_normalized = (xx-mean_x)/std_x
yy=func(xx_normalized,params_all[0],params_all[1], params_all[2], params_all[3])

plt.figure(figsize=(20,10))
plt.plot(xx, yy, label='拟合曲线')
plt.plot(year_cn, sciq_cn, 'r.', label='中国公民素质实际值')
plt.plot(year_us_mod+i, sciq_us, 'g*', label='美国公民素质实际值\n(领先27.6年)')
plt.xlabel('年 份', fontsize=20)
plt.ylabel('公民素质(%)', fontsize=20)
plt.title('基于中美数据联合建模', fontsize=40)
plt.legend(loc='upper left', fontsize=15)
plt.show()

output_21_0

可以看出,与单纯使用美国数据相比,曲线拟合得更好。此时,估计中国2025年的公民科学素质为16.30。具体代码如下:

1
2
3
year_to_est = 2025
year_to_est_normalized = (year_to_est -mean_x)/std_x
func(year_to_est_normalized, params_all[0],params_all[1], params_all[2], params_all[3])

剔除部分美国数据建模

美国数据单独建模

前面我们都是采用全部的数据进行建模,但是数据并不是全都可靠的,比如美国2020年的数据是预估而非实际的数据。此外,2004与2005年相差一年,但是两个数据相差2.8,可能两者保留一个较为合理。

剔除2004和2020的数据

剔除2004和2020的数据可以发现,2004年的估计值显著高于实际值,而2020年的估计值显著低于预测值,类似前面,我们以1993年的美国数据作为中国2025年的预测值,可以得到剔除2004、2020数据后,预测中国2025年为10.90,2035年为25.04

output_29_1

剔除2005和2020的数据

类似地,如果我们剔除2005年和2020年的数据,保留2004年的数据,然后进行上述分析,那么剔除2005、2020数据后,预测中国2025年为11.09,2035年为23.61

中美数据联合建模

联合建模的过程实际上是“判断合理间隔->组合数据->建模->估计”,因此我们需要重新估计合理的间隔

剔除2004和2020的数据

由于代码与前面类似,此处不再重复,只给出最终结果,此时间隔估计为 4.1-4.1,误差曲线如下所示。

output_39_1

对中国的预测值分别为

1
2
2020年预测值:16.023731748891755
2035年预测值:26.427438392500473

剔除2005和2020的数据

此时的情况为:

1
2
3
最小误差间隔:-3.7
2025年预测值:15.736954956581535
2035年预测值:26.15149346169582

仅基于中国数据建模

前面自始至终都在用美国的数据,好像没有就做不了似的。真的这样吗?我们考虑仅使用中国数据建模的情况,看是否合理。容易计算得到:

1
2
3
4
5
6
7
2025年预测值:15.107628577160016
2035年预测值:19.510388352723403

a: 19.497243806717997
b: 1.2441857580138587
c: 1.468669299535217
d: 0.9374480559134637

output_47_1

从拟合的图形可以看出,可以知道未来的最高水平不会超过21,显然是不合理的。这也是为什么必须要引入美国的数据。

综合分析

建模结果分析

综合以上分析,我们得到如下结果:

序号 方案 2025估计值 2035估计值
1 美国完整数据 11.04 24.10
2 中美完整数据 16.30 26.96
3 美国不含04、20 10.90 25.04
4 美国不含05、20 11.09 23.61
5 中美不含美04、20 16.12 26.52
6 中美不含美05、20 15.73 26.15
7 中国完整数据 15.10 19.51

由上表可以发现:

  • 对于2025年(短期)的估计,基于美国数据的估计值在11左右,引入中国数据的估计值在15左右;
  • 对于2035(长期)的估计,基于中国的数据估计值不足20,引入美国数据的估计值在25左右。
  • 如果单纯采用中国数据(方案7)或者美国数据(方案1、3、4),预测值显著小于联合采用中美数据的预测值(方案2、5、6);
  • 采用联合数据更为合理,剔除04、05以及2020数据有一定影响,但影响不大。

通过对上表的分析,我们又可以得到以下结论:

  • 短期预测必须要引入中国数据,长期预测必须要引入美国数据;
  • 单纯采用中国或美国数据,数据量较小,无法覆盖到S曲线的前段和后段,导致估计的偏差较大;
  • 基于方案7可以确定15.10作为2025估计值下界,基于方案2可以确定16.30作为2025估计值上界。

中美数据差异的影响

对中美分别建模,然后估计其参数,可以发现两者的差别是非常巨大的:

参数 中国 美国
a 19.49 19.39
b 1.24 3.49
c 1.47 -0.35
d 0.94 9.76

由于我们在计算时首先对时间进行了规范化,所以两者在参数b和c上不好直接比较,但是比较a和d可以发现,如果中美分别建模,那么中国的初始禀赋(1.11)远远低于美国(10.01),而且增量也同样显著小于美国,这似乎表明中国人的科学素质生来就比美国人要差得多,而且即使再怎么努力,也永远比不上美国人(中国最高为21,美国最高为29),这显然是非常不合理的。那么为什么会出现这种情况呢?

最主要的原因是有两个:

  1. 数据量太小,我们可以看到,一个模型有4个参数,我们对于每一个模型只有七八个观测值,其可靠性不会太高;
  2. 数据的时间跨度太小,从发展规律来讲,公民素质的提升可能是50年甚至更长的事情(即S曲线的跨度),但是拥有的数据跨度只有20年左右,而且,这20年并不是均匀分布在整个跨度上的,而是集中于前半段(中国)或者后半段(美国)。
  3. 缺乏先验知识的引入,例如中美所观测的数据分别在什么阶段上,例如中国明显还在起步阶段,但是这一信息并不被模型所知晓,所以8.47已经到了S曲线的上半段,而在人看来显然是不合理的。

如此说来,采用中美数据进行联合建模也就更为合理、更加可信

但是,采用中美数据进行联合建模也有一个问题:中美被认为符合相同的分布,换言之,中美之间由于人口、经济、政策等方面造成的差异被忽视了。一个可以考虑的做法是,认为中美之间的数据存在某种映射关系,但是这种映射关系即使是最简单的平移缩放,也需要4个参数,这就又变成了十几个观测值拟合8个参数,其可靠性又会被诟病。

如果有需要,可以通过人为调整数据或者限定模型参数,但是需要通过多种方式对结果进行验证。此外,未来更多数据的加入,也有助于提高模型的可靠性和说服力。

Science

(我也差点没看出是啥公式,另外"It works, bitches"又扯出了理查德·道金斯。。。)

结论

综合以上分析,我们认为2025年中国公民科学素质预计可以达到15甚至16以上

按照惯例,今年的“十四五”规划会制定相应目标,让我们看一下是否与政策一致,并且期待2025乃至2035年的检验。

The Difference


  1. 1.2016年制定的“十三五”目标为2020年达到10%,最新统计结果显示2021年达到了10.57%