冠状病毒数据研究

前言:

大家好。由于最近冠状病毒肆虐,大家都被迫困在家里,今天晚上闲来无事,就突然想做个冠状病毒确诊人数的预测。这里面有三个主要内容:1、数据获取 2、画出来图看看数据的走势 3、建立模型进行未来数据的预测。大家可以分段看一下,完整的代码在我的GitHub上面,可以直接下载:GitHub地址

数据获取:

这个在网上找了一个数据获取的实时接口(url地址),返回的是json数据
然后用python从这个url中读取实时数据即可。代码如下:

import urllib.request
import json
from pandas.io.json import json_normalize


def get_data(url):
    resp = urllib.request.urlopen(url)
    json_data = json.loads(resp.read())
    with open("data.json", 'w', encoding='utf-8') as json_file:
        json.dump(json_data, json_file, indent=4, ensure_ascii=False)
    return json_data


if __name__ == '__main__':
    test_json = get_data('https://www.tianqiapi.com/api?version=epidemic&appid=23035354&appsecret=8YvlPNrz')
    history_json = test_json["data"]["history"]
    data = json_normalize(history_json)
    data.sort_index(ascending=False, inplace=True)
    data.reset_index(drop=True, inplace=True)
    print(data)

得到的数据如下所示:
在这里插入图片描述

画出来图看看数据的走势:

画图很简单没啥说的,参照下面的代码即可:

def plot_data(df_data):
    plt.figure()
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    plt.subplot(1, 2, 1)
    plt.title("全国冠状病毒疫情趋势(一)", fontsize=20)
    df_data["date"] = pd.to_datetime(df_data["date"])
    df_data.set_index('date', inplace=True)
    df_data['confirmedNum'].plot()
    df_data['suspectedNum'].plot()
    plt.legend(["确诊", "疑似"], loc="lower right", fontsize=18)
    for a, b in zip(df_data.index, df_data['confirmedNum']):
        plt.text(a, b, '%d' % b, ha='center', va='bottom', fontsize=12)
    for a, b in zip(df_data.index, df_data['suspectedNum']):
        plt.text(a, b, '%d' % b, ha='center', va='bottom', fontsize=12)
    plt.ylabel("数量", fontsize=18)  # 设置纵轴单位
    plt.xlabel("时间", fontsize=18)  # 设置横轴单位
    plt.subplot(1, 2, 2)
    plt.title("全国冠状病毒疫情趋势(二)", fontsize=20)
    df_data['curesNum'].plot()
    df_data['deathsNum'].plot()
    plt.legend(["治愈", "死亡"], loc="lower right", fontsize=18)
    for a, b in zip(df_data.index, df_data['curesNum']):
        plt.text(a, b, '%d' % b, ha='center', va='bottom', fontsize=12)
    for a, b in zip(df_data.index, df_data['deathsNum']):
        plt.text(a, b, '%d' % b, ha='center', va='bottom', fontsize=12)
    plt.ylabel("数量", fontsize=18)  # 设置纵轴单位
    plt.xlabel("时间", fontsize=18)  # 设置横轴单位
    plt.show()

建立模型进行未来数据的预测:

# 自定义函数 e指数形式
def func(x, a, b, c):
    return a * np.sqrt(x) * (b * np.square(x) + c)
# 拟合数据
def fit_data(df_data):
    # 定义x、y散点坐标
    x = range(len(df_data))
    x = np.array(x)
    print('xxxxxx', x)
    num = df_data["confirmedNum"].to_list()
    y = np.array(num)
    # 非线性最小二乘法拟合
    popt, pcov = curve_fit(func, x, y)
    # 获取popt里面是拟合系数
    print(popt)
    a = popt[0]
    b = popt[1]
    c = popt[2]
    yvals = func(x, a, b, c)  # 拟合y值
    print('popt:', popt)
    print('系数a:', a)
    print('系数b:', b)
    print('系数c:', c)
    print('系数pcov:', pcov)
    print('系数yvals:', yvals)
    # 绘图
    plt.plot(x, y, 's', label='原始数据')
    plt.plot(x, yvals, 'r', label='拟合数据')
    plt.xlabel('时间')
    plt.ylabel('数量')
    plt.legend(loc=4)  # 指定legend的位置右下角
    plt.title('非线形最小二乘法拟合')
    x_next = len(df_data) + 1
    y_next = func(x_next, a, b, c)
    print("预计明天全国总确诊人数:%d" % y_next)
    plt.show()

当然还可以用其他拟合方法,也可用RNN、LSTM等深度学习的方法或随机森林等机器学习方法,当使用这些方法的时候就要将其他三种数据(疑似人数、死亡人数、治愈人数)也加入到模型的特征数据中进行训练了。

本文只是用最简单的非线性最小二乘方法进行拟合的。

这里存在一个问题,就是历史数据中没有拐点信息,所以当出现拐点时通过拟合数据得到的预测结果有可能会不准确,
这个要有心里准备的哦。

2月2号24点确诊人数:17238人,2月3号24点模型预测确诊人数:21236,2月3号24点实际确诊人数:20471,2月4号晚24点模型预测确诊人数:29309,实际结果等今天晚上24点才知道(这个数据会偏高)

发布了197 篇原创文章 · 获赞 35 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/PoGeN1/article/details/104166164
今日推荐