python如何确定拐点_使用Python检测新冠肺炎疫情拐点,抗疫成果明显!
python如何确定拐点_使⽤Python检测新冠肺炎疫情拐点,抗
疫成果明显!
1 简介
拐点检测(Knee point detection),指的是在具有上升或下降趋势的曲线中,在某⼀点之后整体趋势明显发⽣变化,这样的点就称为拐点(如图1所⽰,在蓝⾊标记出的点之后曲线陡然上升):
图1
本⽂就将针对Python中⽤于拐点检测的第三⽅包kneed进⾏介绍,并以新型冠状肺炎数据为例,出各指标数学意义上的拐点。
2 基于kneed的拐点检测
2.1 kneed基础
肘部法则来确定某些关键参数,如K-means中聚类个数k、DBSCAN中的搜索半径eps等。
许多算法都需要利⽤肘部法则
肘部,即拐点时,⼈为通过观察来确定位置的⽅式不严谨,需要⼀套有数学原理⽀撑的检测⽅法。
在⾯对需要确定所谓肘部
Jeannie Albrecht等⼈在Finding a “Kneedle” in a Haystack: Detecting Knee Points in System Behavior(你可以在⽂章开头的Github仓库中到)中从曲率的思想出发,针对离散型数据,结合离线、在线的不同应⽤场景以及Angle-based、Menger Curvature、EWMA等算法,提出了⼀套拐点检测⽅法。
kneed就是对这篇论⽂所提出算法的实现。
使⽤pip install kneed完成安装之后,下⾯我们来了解其主要⽤法:
2.1.1 KneeLocator
KneeLocator是kneed中⽤于检测拐点的模块,其主要参数如下:
x x:待检测数据对应的横轴数据序列,如时间点、⽇期等 y y:待检测数据序列,在x条件下对应的值,如x为星期⼀,对应的y为降⽔量
curve:str型,指明曲线之上区域是凸集还是凹集,concave代S:float型,默认为1,敏感度参数,越⼩对应拐点被检测出得越快 curve
表凹,convex代表凸 direction
online:bool direction:str型,指明曲线初始趋势是增还是减,increasing表⽰增,decreasing表⽰减 online 型,⽤于设置在线/离线识别模式,True表⽰在线,False表⽰离线;在线模式下会沿着x轴从右向左识别出每⼀个局部拐点,并在其中选择最优的拐点;离线模式下会返回从右向左检测到的第⼀个局部拐点
KneeLocator在传⼊参数实例化完成计算后,可返回的我们主要关注的属性如下:
all_elbows及 knee
黎明之前 结局elbow_y:返回检测到的最优拐点对应的y all_elbows
knee_y及 elbow_y
knee及 elbow
elbow:返回检测到的最优拐点对应的x knee_y
all_knees_y:返回检测到的所有局部拐点对应的y
all_elbows_y及 all_knees_y
all_knees
all_knees:返回检测到的所有局部拐点对应的x all_elbows_y
curve与direction参数⾮常重要,⽤它们组合出想要识别出的拐点模式。
以余弦函数为例,在oonline设置为True时,分别在curve='concave'+direction='increasing'、
curve='concave'+direction='decreasing'、curve='convex'+direction='increasing'和curve='convex'+direction='decreasing'参数组合下对同⼀段余弦曲线进⾏拐点计算:
import matplotlib.pyplot as plt
from matplotlib import style
import numpy as np
from kneed import KneeLocator
style.use('seaborn-whitegrid')农业生产的谚语
x = np.arange(1, 3, 0.01)*np.pi
y = np.cos(x)
# 计算各种参数组合下的拐点
kneedle_cov_inc = KneeLocator(x,
y,
curve='convex',
direction='increasing',
online=True)
kneedle_cov_dec = KneeLocator(x,
y,
curve='convex',
direction='decreasing',
online=True)
kneedle_con_inc = KneeLocator(x,
y,
curve='concave',
direction='increasing',
online=True)
kneedle_con_dec = KneeLocator(x,
y,
curve='concave',
direction='decreasing',
online=True)
fig, axe = plt.subplots(2, 2, figsize=[12, 12])
axe[0, 0].plot(x, y, 'k--')
axe[0, 0].annotate(s='Knee Point', xy=(kneedle_cov_inc.knee+0.2, kneedle_cov_inc.knee_y), fontsize=10)
axe[0, 0].scatter(x=kneedle_cov_inc.knee, y=kneedle_cov_inc.knee_y, c='b', s=200, marker='^', alpha=1)
axe[0, 0].set_title('convex+increasing')
axe[0, 0].fill_between(np.arange(1, 1.5, 0.01)*np.pi, np.cos(np.arange(1, 1.5, 0.01)*np.pi), 1, alpha=0.5, color='red')
axe[0, 0].set_ylim(-1, 1)
axe[0, 1].plot(x, y, 'k--')
axe[0, 1].annotate(s='Knee Point', xy=(kneedle_cov_dec.knee+0.2, kneedle_cov_dec.knee_y), fontsize=10)
axe[0, 1].scatter(x=kneedle_cov_dec.knee, y=kneedle_cov_dec.knee_y, c='b', s=200, marker='^', alpha=1)
axe[0, 1].fill_between(np.arange(2.5, 3, 0.01)*np.pi, np.cos(np.arange(2.5, 3, 0.01)*np.pi), 1, alpha=0.5, color='red')
axe[0, 1].set_title('convex+decreasing')
axe[0, 1].set_ylim(-1, 1)
axe[1, 0].plot(x, y, 'k--')
axe[1, 0].annotate(s='Knee Point', xy=(kneedle_con_inc.knee+0.2, kneedle_con_inc.knee_y), fontsize=10)
axe[1, 0].scatter(x=kneedle_con_inc.knee, y=kneedle_con_inc.knee_y, c='b', s=200, marker='^', alpha=1)
axe[1, 0].fill_between(np.arange(1.5, 2, 0.01)*np.pi, np.cos(np.arange(1.5, 2, 0.01)*np.pi), 1, alpha=0.5, color='red') axe[1, 0].set_title('concave+increasing')
axe[1, 0].set_ylim(-1, 1)
axe[1, 1].plot(x, y, 'k--')
axe[1, 1].annotate(s='Knee Point', xy=(kneedle_con_dec.knee+0.2, kneedle_con_dec.knee_y), fontsize=10)
axe[1, 1].scatter(x=kneedle_con_dec.knee, y=kneedle_con_dec.knee_y, c='b', s=200, marker='^', alpha=1)
axe[1, 1].fill_between(np.arange(2, 2.5, 0.01)*np.pi, np.cos(np.arange(2, 2.5, 0.01)*np.pi), 1, alpha=0.5, color='red') axe[1, 1].set_title('concave+decreasing')
axe[1, 1].set_ylim(-1, 1)
# 导出图像
plt.savefig('图2.png', dpi=300)
图中红⾊区域分别对应符合参数条件的搜索区域,蓝⾊三⾓形为每种参数组合下由kneed检测到的最优拐点:
图2
下⾯我们扩⼤余弦函数中x的范围,绘制出提取到的所有局部拐点:
x = np.arange(0, 6, 0.01)*np.pi
y = np.cos(x)
# 计算convex+increasing参数组合下的拐点
360杀毒卸载不了kneedle = KneeLocator(x,
y,
curve='convex',
direction='increasing',
online=True)
fig, axe = plt.subplots(figsize=[8, 4])
axe.plot(x, y, 'k--')
axe.annotate(s='Knee Point', xy=(kneedle.knee+0.2, kneedle.knee_y), fontsize=10)
axe.set_title('convex+increasing')
一劳永逸的意思axe.fill_between(np.arange(1, 1.5, 0.01)*np.pi, np.cos(np.arange(1, 1.5, 0.01)*np.pi), 1, alpha=0.5, color='red')
axe.fill_between(np.arange(3, 3.5, 0.01)*np.pi, np.cos(np.arange(3, 3.5, 0.01)*np.pi), 1, alpha=0.5, color='red')
axe.fill_between(np.arange(5, 5.5, 0.01)*np.pi, np.cos(np.arange(5, 5.5, 0.01)*np.pi), 1, alpha=0.5, color='red')
axe.scatter(x=list(kneedle.all_knees), s(list(kneedle.all_knees)), c='b', s=200, marker='^', alpha=1)
axe.set_ylim(-1, 1)
# 导出图像
plt.savefig('图3.png', dpi=300)
得到的结果如图3所⽰,其中注意,在使⽤kneed检测拐点时,落在最左或最右的拐点是⽆效拐点:
图3
2.2 探索新冠肺炎疫情数据
接下来我们尝试将上⽂介绍的kneed应⽤到新冠肺炎数据上,来探究各个指标数学意义上的拐点是否已经出现。
你可以在本⽂开头提到的我的Github仓库对应本⽂路径下到下⽂使⽤到的数据,更新时间为2020-02-18 22:55:07
2020-02-18 22:55:07,下⾯开始我们的分析。
⾸先我们读⼊DXYArea.csv⽂件,并查看其信息,为了后⾯⽅便处理我们在读⼊时将updateTime列提前解析为时间格式:
import pandas as pd
raw = pd.read_csv('DXYArea.csv', parse_dates=['updateTime'])
raw.info()
99977是什么意思图4
查看其第⼀⾏信息: 
图5
累计疑似⼈数、累计治愈⼈数
累计死亡⼈数信息。
深圳机场累计治愈⼈数和累计死亡⼈数
累计确诊⼈数、累计疑似⼈数
可以看到,原始数据中包含了省、市信息,以及对应省及市的最新累计确诊⼈数
治愈率、死亡率
死亡率随时间(单位:天)变化下的曲线,是否已经出现数学
⽇新增确诊⼈数、治愈率
累计确诊⼈数、⽇新增确诊⼈数
我们的⽬的是检测全国范围内,累计确诊⼈数
意义上的拐点(由于武汉市数据变化的复杂性和特殊性,下⾯的分析只围绕除武汉市之外的其他地区进⾏)。
⾸先我们对所有市取每天最晚⼀次更新的数据作为当天正式的记录值:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。