(1)预测基于官方公布数据,结果仅供参考,之后的数据,还是以官方为准;
(2)本文不作任何建议,更无意制造恐慌、造谣,仅表示一个简单的数据分析结果;
(3)目前,新型肺炎处于上升趋势,增长速度较快。随着后续管控防治手段的提升和药物的研制,病情发展曲线完全可能大不相同,本文出现过拟合现象纯属正常;
(4)现在要做的事情是:别出门!别出门!别出门!
本学期学习了《计算方法》课程,讲到了多项式拟合相关内容。因为是个选修课所以期末水过去了。
寒假期间新型冠状病毒肺炎来势汹汹,宅在家里不出门的同时想起来当时上课的一些内容可以用来做一下预测,所以写了这篇文章,发表一点自己的观点,本文数据纯属预测,无论预测是否存在较大误差,都不要相信,一切以官方为准。
数据其实可以通过直接访问网页链接来解析获取,这里的话放假懒得写前端,我为了省事直接手动输入数组了:
(数据截止到2月4日0时,公布的2月3日00:00——24:00前一日的数据)
在后续绘图的过程中,我将横坐标改为日期的形式,用来表示每天的病例人数,用到了matlab中的日历类型。
首先,使用datetime函数,指定开始日期:
t1=datetime(2020,1,18);
由于绘图时横坐标需要精确到每天,故将每天的datetime类型通过for循环存入数组:
for i=1:length(x1)
data1=[data1,t1+caldays(i)];
% caldays自增,获取数组内的日期格式数据,便于绘图,下同
end
利用caldays函数进行日期的加减运算。
这样,使用第二段代码中data1这个数组作为横坐标就能绘制日期横坐标的图了。
多项式拟合是用一个多项式展开去拟合包含数个分析格点的一小块分析区域中的所有观测点,得到观测数据的客观分析场。展开系数用最小二乘拟合确定。
多项式拟合,将一组数据尽可能的映射到一个多项式函数上,反映这一组数据之间的一个函数关系。故可以使用多项式拟合方法对于数据的未来走向进行一定程度上的预测。
对多项式进行曲线拟合可以使用polyfit函数,该函数能够很好地进行曲线拟合,用法MATLAB程序代码为:
p = polyfit(x,y,n)
其中,x为横坐标,在本文中,为自2020-01-18开始的天数(1代表2020-01-19,以此类推)
y为纵坐标,在本为中,为自2020-01-18开始每日的累计感染人数。
n为拟合的多项式次数。
在本文中,n=4,即多项式的最高次数为4。选取原因如下:
1、一次、二次函数单调性太过明显,线性和指数级别的单调增加不能良好反映疫情的发展状况;
2、三次以上的拟合情况,我进行了实验,结果如下:
以上反映的是多项式最高次数n取3、5、6的情况,据分析,n=3时,单调递增显然不符合疫情发展趋势,n=5和6时就更夸张了——100天内有上亿的人被感染,这尼玛生化危机啊。。。。
所以3、5、6和更高次的拟合都不符合目前的实际情况。
那么当n=4时,图像是这个样子:
我们发现在四次多项式拟合中疫情出现了拐点,虽然在拐点之后,函数是单调递减的,但是,结合目前国家的大力防控措施,我们可以姑且认为,四次多项式在拐点之前的增长是具有一定参考价值的。
因此,在后续的数据分析环节中,本文只讨论“拐点”前的情况。(拐点后的情况要依据治愈人数确定,本文不讨论)
拟合代码实现如下:
p1 = polyfit(x1, y1, 4); % 累计人数 四次函数
画图函数实现如下:(使用polyval函数预测每日感染人数)
plot(date,polyval(p1,z),'r')
hold on;
plot(data1, y1, '*')
hold on;
xlabel('时间');
ylabel('感染人数');
grid on;
我们通过将1月18日统计数据开始后的天数代入函数,使用polyval函数计算每日的感染人数,并绘制图像,得到的“拐点前”预测结果如下:
日期 | 预测感染人数(次日零点统计) |
2.4 | 23550 |
2.5 | 26940 |
2.6 | 30461 |
2.7 | 34074 |
2.8 | 41392 |
2.9 | 44993 |
2.10 | 48476 |
2.11 | 51777 |
2.12 | 54826 |
2.13 | 57549 |
2.14 | 59867 |
2.15 | 61693 |
2.16 | 62940 |
2.17 | 63511 |
2.18后 | 拐点 |
由此分析,疫情将在不久的2月15日至2月20日期间出现“拐点”,即累计感染人数显著降低。
新增确诊人数为累计感染人数的一阶导数。
刚才我们在累计感染人数中使用了4次多项式拟合,故在新增确诊人数的拟合中选择3次多项式。
拟合结果如下:
新增确诊人数的拟合是独立于确诊总人数做的实验,本文的这两组实验互相独立。
于是通过ployval函数和绘图,我们得到以下结果:
日期 | 预测新增确诊病例(次日公布) |
2.4 | 3382 |
2.5 | 3612 |
2.6 | 3818 |
2.7 | 3996 |
2.8 | 4142 |
2.9 | 4251 |
2.10 | 4318 |
2.11 | 4341 |
2.12 | 4313 |
2.13 | 4231 |
2.14 | 4090 |
2.15 | 3886 |
2.16 | 3615 |
2.17 | 3273 |
2.18 | 2854 |
2.19 | 2355 |
2.20 | 1771 |
2.21 | 1099 |
2.22后 | 更低 |
钟南山院士说,元宵节期间会出现疫情的拐点。如果以单日新增病例数量不再增加为拐点,那么本模型中的拐点确实出现在元宵节附近。在一周之内,单日确诊人数或将达到最多4000-4500之间,之后,新增病例将显著下降。
重申一遍:本文仅为预测结论,不提供任何建议,更无意造谣和制造恐慌。
灾难无情,人间有爱。今天是立春节气,要相信没有一个春天它不会到来。相信在不久的将来,我国将完全控制疫情,取得这场抗击疫情战役的伟大胜利。等到武汉的樱花盛开之时,全国人民都将再次造访这座美丽的城市。
武汉加油!中国加油!
写这段话的时候是3月中旬,全国范围内的疫情应该来说快要结束了,距离我这篇文章有一个半月。
现对本文的预测进行复盘分析:
1、拐点预测:以国内感染人数峰值作为拐点来看,本文预测为2月15日——2月20日之间,实际为2月17日(当日存在住院病例58097例),符合;
2、拐点预测:以新增感染人数开始下降来看,除2月12日第六版诊疗方案放宽了对于确诊病例的定义,导致当日增加1万人以上,新增人数最多为2月4日,单日3892例,即拐点出现在2月4日,符合本文“在元宵节前”的预测;
3、总感染人数:本文预测至峰值时累计约63000人,后续虽然确诊降低,但是累计还会有所升高,最终达到70000人左右:实际情况是2月12日的第六版诊疗方案的标准导致新增1万余人新确诊,以今天(3.16)现有确诊8万例来看,若不考虑诊疗方案变化而多出的1万人,则模型预测相对准确。
严防境外输入!中国加油!世界加油!
x1 = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]; % 累计天数
x2 = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]; % 新增天数
data1 = []; % 累计和新增天数横坐标
data2 = [];
new = []; % 将预测的新增和累计存入数组
total = [];
y1 = [291,391,440,571,830,1287,1975,2744,4515,5974,7711,9692,11791,14411,17205,20438]; % 累计
y2 = [77,149,131,259,444,688,769,1771,1459,1737,1982,2102,2590,2829,3235]; % 新增
z = [];
date = [];
t1=datetime(2020,1,18);
for i=1:length(x1)
data1=[data1,t1+caldays(i)];
end
for i=1:length(x2)
data2=[data2,t1+caldays(i+1)];
end
for i=1:33
z=[z,i];
date=[date,t1+caldays(i)];
end
p1 =polyfit(x1, y1, 4); % 累计 四次函数
p2 =polyfit(x2, y2, 3); % 新增是累计的一阶导数 三次函数
for i=16:40
new=[new,polyval(p2,i)];
end
for i=17:35
total=[total,polyval(p1,i)];
end
plot(date,polyval(p1,z),'r')
hold on;
plot(date,polyval(p2,z),'b')
hold on;
plot(data1, y1, '*')
hold on;
plot(data2, y2, 'o')
grid on;