【2023年第十一届泰迪杯数据挖掘挑战赛】A题:新冠疫情防控数据的分析 建模方案及python代码详解


更新时间:2023-3-30

1 题目

一、背景

自2019年底至今,全国各地陆续出现不同程度的新冠病毒感染疫情,如何控制疫情蔓 延、维持社会生活及经济秩序的正常运行是疫情防控的重要课题。大数据分析为疫情的精准 防控提供了高效处置、方便快捷的工具,特别是在人员的分类管理、传播途径追踪、疫情研 判等工作中起到了重要作用,为卫生防疫部门的管理决策提供了可靠依据。疫情数据主要包 括人员信息.csv、场所信息.csv、个人自查上报信息.csv、场所码扫码信息.csv、核酸采样检测信息.csv、疫苗接种信息.csv。本赛题提供了某市新冠疫情防疫系统的相关数据信息,请根据这些数据信息进行综合分 析,主要任务包括数据仓库设计、疫情传播途径追踪、传播指数估计及疫情趋势研判等。

(1)人员信息表:附件2.csv

序号字段名字段说明字段类型默认值
1user_id人员id:人员的唯一标识bigint(20)
2openid微信OpenIDvarchar(64)null
3.gender性别:男、女varchar(2)null
4nation民族varchar(20)null
5age年龄intnull
6birthdate出生日期varchar(20)null
7create_time创建时间timestampnull

(2)场地信息表:附件3.csv

序号字段名字段说明字段类型默认值
1grid_point_id场所id:场所的唯一标识bigint(20)
2name场所名varchar (255)null
3.point_type场所类型varchar (50)nnulnulll
4x_coordinateX坐标(单位:米)decimal(12,2)null
5y_coordinateY坐标(单位:米)decimal(12,2)null
6create_time创建时间timestampnull

(3)个人自查上报信息表:附件4.csv

NO.字段名字段说明字段类型默认值
1sno序列号:自查记录的唯一标 识bigint(20)
2user_id人员ID:对应于”人员信息表”中的user_id . ID长整型数字(20)
3.x_coordinate上报地点的x坐标小数(12,2)null
4y_coordinate上报地点的y坐标小数(12,2)null
5symptom症状:1 发热、2 乏力、3 干 咳、4 鼻塞、5 流涕、6 腹泻、 7 呼吸困难、8 无症状varchar (100)null
6nucleic_acid_result核酸检测结果:0 阴性、1 阳 性、2 未知(非必填)varchar (10)null
7resident_flag是否常住居民:0未知,1是,2否intnull
8dump_time上报时间timestampnull

(4)场所码扫码信息表:附件5.csv

序号字段名字段说明字段类型默认值
1sno序列号:扫码记录的唯一标 识bigint(20)
2grid_point_id场所ID:对应于”场所信息表”中的grid_point_idbigint(20)
3user_id人员ID:对应于”人员信息表”中的user_id . IDbigint(20)
4temperature体温doublenull
5create_time扫码记录时间timestampnull

(5)核酸采样检测信息表:附件6.csv

序号字段名字段说明字段类型默认值
1sno序列号:核酸采样记录的唯 一标识bigint(20)
2user_id人员ID:对应于”人员信息表”中的user_id . IDbigint(20)null
3cysj采样日期和时间timestampnull
4jcsj检测日期和时间timestampnull
5jg检测结果:阴性、阳性、未 知varchar (50)null
6grid_point_id场所ID:对应于”场所信息表”中的grid_point_idbigint(20)

(6)疫苗接种信息表:附件7.csv

序号字段名字段说明字段类型默认值
1sno序列号:疫苗接种记录的唯 一标识bigint(20)
2inject_sn接种流水号varchar(50)
3user_id人员ID:对应于”人员信息表”中的user_id . IDvarchar(50)
4age接种者年龄intnull
5gender性别:1 男、2 女varchar(10)null
6birthdate出生日期varchar(50)null
7inject_date接种日期timestampnull
8inject_times针次:1 第一针、2 第二针、 3 加强针varchar(30)null
9vaccine_type疫苗类型:1 灭活疫苗、2 重 组蛋白疫苗、3 病毒载体疫 苗、4 核酸疫苗、5 减毒疫苗varchar(30)null

二、问题

  1. 根据核酸检测中阳性人员的出行时间与场所追踪密接者,将结果保存到“result1.csv”文件中,文件模板格式如下
序号密接者ID密接日期密接场所ID阳性人员ID
  1. 由问题1的结果,根据密接者的出行时间与场所追踪相应的次密接者,将结果保存到“result2.csv”文件中,文件模板如下。
序号次密接者ID次密接日期次密接场所ID密接者ID
  1. 建立模型,分析接种疫苗对病毒传播指数的影响。

  2. 根据阳性人员的数量及辐射范围,分析确定需要重点管控的场所。

  3. 为了更精准地进行疫情防控和人员管理,你认为还需要收集哪些相关数据。基于这些数据构建模型,分析其精准防控的效果。

注在解决上述问题时,要求结合赛题提供的数据信息表建立数据仓库,实现数据治理的内容,请在论文中明确阐述做了哪些数据治理工作,具体是如何实现的。

2 思路及实现

2.1 问题一

  1. 从核酸采样检测信息表中筛选出检测结果为阳性的数据,获取这些阳性人员的用户ID。
  2. 根据阳性人员的用户ID,从场所码扫码信息表中筛选出这些人员在检测日期前后的扫码记录,获取他们的出行场所和时间。
  3. 根据密接定义,确定密接者的时间范围。在阳性人员的出行时间前后24小时内出现在同一场所的其他人员即为密接者。
  4. 将结果保存到”result1.csv”文件中,包括密接者的ID、密接日期、密接场所ID、阳性人员ID。
import pandas as pd
import datetime as dt

# 读取数据
df_nucleic = pd.read_csv('核酸采样检测信息.csv')
df_scan = pd.read_csv('场所码扫码信息.csv')

# 筛选出检测结果为阳性的数据
positive_users = df_nucleic[df_nucleic['jg']=='阳性']['user_id'].unique()

# 初始化结果DataFrame
result = pd.DataFrame(columns=['序号', '密接者ID', '密接日期', '密接场所ID', '阳性人员ID'])
idx = 1

# 遍历每个阳性人员的出行记录,查找密接者
for user in positive_users:
    # 获取该阳性人员的出行记录
    user_scan = df_scan[df_scan['user_id']==user]
    for _, row in user_scan.iterrows():
        # 获取该阳性人员的出行时间和场所
        scan_time = row['create_time']
        scan_place = row['grid_point_id']
        
        。。。略,请下载完整代码
        
        # 查找在时间范围内出现在同一场所的其他人员
        nearby_users = df_scan[(df_scan['grid_point_id']==scan_place) & 
                               (df_scan['create_time']>=start_time.isoformat()) &
                               (df_scan['create_time']<=end_time.isoformat()) &
                               (df_scan['user_id']!=user)]['user_id'].unique()
        
        # 将查找到的密接者添加到结果中
        for nearby_user in nearby_users:
            result = result.append({'序号': idx, '密接者ID': nearby_user, 
                                    '密接日期': scan_time, '密接场所ID': scan_place, '阳性人员ID': user}, ignore_index=True)
            idx += 1

# 保存结果到文件
result.to_csv('result1.csv', index=False)

2.2 问题二

需要首先根据问题1的结果,找到所有的密接者及其出行时间与场所。然后,对于每个密接者,需要查找在密接者出行时间与场所之后,也在同一场所出现过的人,这些人就是该密接者的次密接者。最后,将结果保存到“result2.csv”文件中。

以下是实现思路和Python代码:

。。。略,请下载完整代码

import pandas as pd

# 读取result1.csv文件
df_result1 = pd.read_csv('result1.csv')

# 创建一个空的DataFrame,用于记录所有的次密接者
df_result2 = pd.DataFrame(columns=['序号', '次密接者ID', '次密接日期', '次密接场所ID', '密接者ID'])

# 遍历所有的密接者
for i in range(len(df_result1)):
    # 获取当前密接者的出行时间、场所和ID
    start_time = df_result1.loc[i, '出行时间']
    place_id = df_result1.loc[i, '场所ID']
    user_id = df_result1.loc[i, '密接者ID']
    
    。。。略,请下载完整代码
    
    # 遍历所有的符合条件的人,将其记录为次密接者
    for j in range(len(df_place)):
        user_id2 = df_place.iloc[j]['user_id']
        date = df_place.iloc[j]['create_time']
        place_id2 = df_place.iloc[j]['grid_point_id']
        
        # 如果该人不是当前密接者,并且还没有被记录为密接者或次密接者,则将其记录为次密接者
        if user_id2 != user_id and user_id2 not in df_result1['密接者ID'].values and user_id2 not in df_result2['次密接者ID'].values:
            df_result2 = df_result2.append({'序号': len(df_result2)+1, '次密接者ID': user_id2, '次密接日期': date, '次密接场所ID': place_id2, '密接者ID': user_id}, ignore_index=True)

# 将结果保存到result2.csv文件中
df_result2.to_csv('result2.csv', index=False)

2.3 问题三

分析接种疫苗对病毒传播指数的影响需要考虑以下几个方面:

  1. 接种疫苗对个体感染新冠病毒的概率的影响。
  2. 接种疫苗对个体感染新冠病毒后传播给其他人的概率的影响。
  3. 接种疫苗对社区疫情的传播指数的影响。

在分析这些影响之前,需要先对疫苗接种信息进行数据清洗和预处理,包括数据去重、缺失值处理、异常值处理等。然后,可以将疫苗接种信息与其他表格进行关联,获取个体的感染、传播以及社区疫情的信息。接下来可以使用机器学习算法,如逻辑回归、决策树、随机森林等,建立模型,评估接种疫苗对病毒传播指数的影响。

需要注意的是,由于新冠病毒的传播机制及疫苗接种的效果还存在许多未知因素,因此建立模型时需要对模型的假设和前提条件进行充分的讨论和验证。此外,在进行模型评估和结果解释时,需要考虑到模型的局限性和不确定性。

(1)第一方面:接种疫苗对个体感染新冠病毒的概率的影响。

。。。略,请下载完整代码

import pandas as pd
import numpy as np

# 读取相关表格数据并进行预处理
# 人员信息表
user_df = pd.read_csv("人员信息表.csv")
user_df["age"] = pd.to_numeric(user_df["age"])
user_df["birthdate"] = pd.to_datetime(user_df["birthdate"])
user_df["create_time"] = pd.to_datetime(user_df["create_time"])

# 场所信息表
place_df = pd.read_csv("场所信息表.csv")
place_df["x_coordinate"] = pd.to_numeric(place_df["x_coordinate"])
place_df["y_coordinate"] = pd.to_numeric(place_df["y_coordinate"])
place_df["create_time"] = pd.to_datetime(place_df["create_time"])

# 个人自查上报信息表
self_check_df = pd.read_csv("个人自查上报信息表.csv")
self_check_df["symptom"] = pd.to_numeric(self_check_df["symptom"])
self_check_df["nucleic_acid_result"] = pd.to_numeric(self_check_df["nucleic_acid_result"])
self_check_df["resident_flag"] = pd.to_numeric(self_check_df["resident_flag"])
self_check_df["dump_time"] = pd.to_datetime(self_check_df["dump_time"])

# 场所码扫码信息表
scan_df = pd.read_csv("场所码扫码信息表.csv")
scan_df["temperature"] = pd.to_numeric(scan_df["temperature"])
scan_df["create_time"] = pd.to_datetime(scan_df["create_time"])

# 核酸采样检测信息表
nucleic_df = pd.read_csv("核酸采样检测信息表.csv")
nucleic_df["cysj"] = pd.to_datetime(nucleic_df["cysj"])
nucleic_df["jcsj"] = pd.to_datetime(nucleic_df["jcsj"])

# 疫苗接种信息表
vaccine_df = pd.read_csv("疫苗接种信息表.csv")
vaccine_df["age"] = pd.to_numeric(vaccine_df["age"])
vaccine_df["gender"] = pd.to_numeric(vaccine_df["gender"])
vaccine_df["birthdate"] = pd.to_datetime(vaccine_df["birthdate"])
vaccine_df["inject_date"] = pd.to_datetime(vaccine_df["inject_date"])
vaccine_df["inject_times"] = pd.to_numeric(vaccine_df["inject_times"])
vaccine_df["vaccine_type"] = pd.to_numeric(vaccine_df["vaccine_type"])

# 计算接种疫苗和未接种疫苗人员的感染新冠病毒概率,并进行比较
# 筛选出确诊病例
。。。略,请下载完整代码

# 计算接种过疫苗的人员感染新冠病毒的情况
vaccinated_diagnosed = diagnosed_df.merge(vaccine_df, on="user_id", how="inner")
vaccinated_diagnosed_count = len(vaccinated_diagnosed)
vaccinated_count = len(vaccine_df)
vaccinated_ratio = vaccinated_diagnosed_count / vaccinated_count

# 计算未接种疫苗的人员感染新冠病毒的情况
。。。略,请下载完整代码

# 比较接种过疫苗和未接种疫苗的人员感染新冠病毒的概率
。。。略,请下载完整代码

(2)第二方面:接种疫苗对个体感染新冠病毒后传播给其他人的概率的影响。

  1. 接种疫苗对个体免疫力提高的影响:可以将接种过疫苗和未接种疫苗的人员分别计算出其免疫力水平,并进行比较。
import pandas as pd

# 读取数据
。。。略,请下载完整代码

# 合并数据
df = pd.merge(person_info, check_info, on="user_id", how="left")
df = pd.merge(df, vaccine_info, on="user_id", how="left")

# 分别计算接种过疫苗和未接种疫苗的人员感染新冠病毒的概率
vaccinated = df[df["inject_sn"].notna()]
unvaccinated = df[df["inject_sn"].isna()]

vaccinated_infection_rate = vaccinated[vaccinated["nucleic_acid_result"] == 1].shape[0] / vaccinated.shape[0]
unvaccinated_infection_rate = unvaccinated[unvaccinated["nucleic_acid_result"] == 1].shape[0] / unvaccinated.shape[0]

# 比较接种过疫苗和未接种疫苗的人员感染新冠病毒的概率
if vaccinated_infection_rate < unvaccinated_infection_rate:
    print("接种疫苗对个体感染新冠病毒的概率有所降低")
else:
    print("接种疫苗对个体感染新冠病毒的概率未明显降低")

# 分别计算接种过疫苗和未接种疫苗的人员感染新冠病毒后传播给其他人的概率
。。。略,请下载完整代码

# 比较接种过疫苗和未接种疫苗的人员感染新冠病毒后传播给其他人的概率
if vaccinated_spread_rate < unvaccinated_spread_rate:
    print("接种疫苗对个体感染新冠病毒后传播给其他人的概率有所降低")
else:
    print("接种疫苗对个体感染新冠病毒后传播给其他人的概率未明显降低")

# 分别计算接种过疫苗和未接种疫苗的人员社区疫情的传播指数
vaccinated_index = vaccinated[vaccinated["nucleic_acid_result"] == 1]["spread_index"].mean()
unvaccinated_index = unvaccinated[unvaccinated["nucleic_acid_result"] == 1]["spread_index"].mean()

# 比较接种过疫苗和未接种疫苗的人员社区疫情的传播指数
if vaccinated_index < unvaccinated_index:
	print("接种疫苗对社区疫情的传播指数有所降低")
else:
	print("接种疫苗对社区疫情的传播指数未明显降低")

(3)第三步:分析接种疫苗对社区疫情传播指数的影响

# 计算社区疫情的传播指数,即一个感染者平均会传染给多少其他人
def calculate_community_spread_factor(data, vaccinated=True):
    # 获取感染者的人数和接触者的人数
    infected_count, exposed_count = get_infected_and_exposed_counts(data, vaccinated=vaccinated)
    
    # 如果没有感染者或接触者,则返回0
    if infected_count == 0 or exposed_count == 0:
        return 0
    
    # 计算平均每个感染者会传染给多少其他人
    community_spread_factor = exposed_count / infected_count
    
    return community_spread_factor
# 加载数据
data = load_data()

# 计算未接种疫苗的个体感染新冠病毒的概率
prob_unvaccinated_infected = calculate_prob_infected(data, vaccinated=False)
print("未接种疫苗的个体感染新冠病毒的概率:{:.2%}".format(prob_unvaccinated_infected))

# 计算接种疫苗的个体感染新冠病毒的概率
prob_vaccinated_infected = calculate_prob_infected(data, vaccinated=True)
print("接种疫苗的个体感染新冠病毒的概率:{:.2%}".format(prob_vaccinated_infected))

# 计算未接种疫苗的感染者会传播给其他人的概率
prob_unvaccinated_spread = calculate_prob_spread(data, vaccinated=False)
print("未接种疫苗的感染者会传播给其他人的概率:{:.2%}".format(prob_unvaccinated_spread))

# 计算接种疫苗的感染者会传播给其他人的概率
prob_vaccinated_spread = calculate_prob_spread(data, vaccinated=True)
print("接种疫苗的感染者会传播给其他人的概率:{:.2%}".format(prob_vaccinated_spread))

# 计算未接种疫苗的社区疫情传播指数
unvaccinated_spread_factor = calculate_community_spread_factor(data, vaccinated=False)
print("未接种疫苗的社区疫情传播指数:{:.2f}".format(unvaccinated_spread_factor))

# 计算接种疫苗的社区疫情传播指数
vaccinated_spread_factor = calculate_community_spread_factor(data, vaccinated=True)
print("接种疫苗的社区疫情传播指数:{:.2f}".format(vaccinated_spread_factor))

2.4 问题四

需要首先从个人自查上报信息表和核酸采样检测信息表中获取所有阳性人员的数量和位置,然后通过场所码扫码信息表和场所信息表中的位置信息来确定辐射范围内的场所,并对这些场所进行分析,以确定需要重点管控的场所。

。。。略,请下载完整代码

import pandas as pd
import math

# 加载数据表格
user_info_df = pd.read_csv('人员信息表.csv')
place_info_df = pd.read_csv('场所信息表.csv')
self_report_df = pd.read_csv('个人自查上报信息表.csv')
scan_info_df = pd.read_csv('场所码扫码信息表.csv')
nucleic_acid_df = pd.read_csv('核酸采样检测信息表.csv')
vaccine_df = pd.read_csv('疫苗接种信息表.csv')

# 获取所有阳性人员的数量和位置信息
。。。略,请下载完整代码
# 确定辐射范围内的场所
affected_places = []
for index, row in place_info_df.iterrows():
    for user in positive_users:
        distance = math.sqrt((user['x_coordinate'] - row['x_coordinate'])**2 + (user['y_coordinate'] - row['y_coordinate'])**2)
        if distance <= RADIUS:
            affected_places.append(row['grid_point_id'])
            break

# 分析需要重点管控的场所
high_risk_places = []
for place_id in affected_places:
    scan_info = scan_info_df.loc[scan_info_df['grid_point_id'] == place_id]
    temperature = scan_info['temperature'].mean()
    if temperature >= TEMPERATURE_THRESHOLD:
        high_risk_places.append(place_id)

# 输出结果
print('阳性人员数量:', len(positive_users))
print('受影响的场所数量:', len(affected_places))
print('需要重点管控的场所数量:', len(high_risk_places))
print('需要重点管控的场所ID:', high_risk_places)

在此实现中,首先通过遍历核酸采样检测信息表来获取所有阳性人员的数量和位置信息。然后,我们遍历场所信息表中的所有场所,将其与阳性人员的位置进行比较,从而确定其是否在辐射范围内。在找到所有受影响的场所之后,我们遍历场所码扫码信息表来获取这些场所的体温信息,并将其与正常范围的体温进行比较,以确定是否存在可疑人员。最后,我们可以根据受影响场所中可疑人员的数量来确定需要加强管控的场所。

接下来,我们可以通过核酸采样检测信息表(nucleic_acid_info)和个人自查上报信息表(self_report_info)来确定阳性人员的数量和辐射范围。

首先,我们需要将核酸采样检测信息表和个人自查上报信息表按照用户ID进行合并,得到每个用户的检测结果和上报信息。然后,我们筛选出阳性用户的数据,并统计阳性人员数量和其所在场所的坐标。最后,我们可以根据这些坐标和辐射范围,确定需要重点管控的场所。

import pandas as pd
import numpy as np

# 读取数据
user_info = pd.read_csv('user_info.csv')
place_info = pd.read_csv('place_info.csv')
self_report_info = pd.read_csv('self_report_info.csv')
qr_code_info = pd.read_csv('qr_code_info.csv')
nucleic_acid_info = pd.read_csv('nucleic_acid_info.csv')
vaccine_info = pd.read_csv('vaccine_info.csv')

# 根据用户ID合并核酸采样检测信息表和个人自查上报信息表
user_report = pd.merge(nucleic_acid_info[['user_id', 'nucleic_acid_result']], self_report_info[['user_id', 'x_coordinate', 'y_coordinate']], on='user_id', how='outer')

# 筛选出阳性用户的数据
positive_users = user_report[user_report['nucleic_acid_result'] == 1].dropna()

# 统计阳性人员数量
num_positive_users = len(positive_users)

# 获取阳性人员所在场所的坐标
positive_places = pd.merge(place_info[['grid_point_id', 'x_coordinate', 'y_coordinate']], qr_code_info[['grid_point_id', 'user_id']], on='grid_point_id', how='inner')
positive_places = pd.merge(positive_users[['user_id', 'x_coordinate', 'y_coordinate']], positive_places, on='user_id', how='inner')
positive_places = positive_places[['x_coordinate', 'y_coordinate']]

# 确定需要重点管控的场所
mean_x = np.mean(positive_places['x_coordinate'])
mean_y = np.mean(positive_places['y_coordinate'])
radius = np.max(np.sqrt((positive_places['x_coordinate'] - mean_x)**2 + (positive_places['y_coordinate'] - mean_y)**2))

在以上代码中,我们首先读取了所有需要用到的表格数据,然后通过pandas的merge函数按照用户ID合并了核酸采样检测信息表和个人自查上报信息表,并筛选出了阳性用户的数据。接着,我们通过merge函数将阳性用户所在场所的坐标获取到,并计算了坐标的平均值和标准差,从而确定了需要重点管控的场所。

2.5 问题五

除了已有的数据,为了更精准地进行疫情防控和人员管理,以下是可能有用的相关数据:

  1. 病例转运记录:记录病例从发病地点到就诊医院的路线、交通工具、时间等信息,以帮助追踪疫情传播路径。
  2. 近期行动轨迹:记录病例近期的行动轨迹,如所在城市、所去的场所、时间等信息,以帮助确定可能受影响的场所和人员,并进行针对性的防控措施。
  3. 人员健康信息:记录人员的健康状况、病史、医疗用药等信息,以帮助医护人员对患者进行诊治和疫情分析。
  4. 常住人口信息:记录常住人口的基本信息、居住地址、工作单位、社会关系等信息,以便进行常住人口的健康管理和防控措施。
  5. 联系人信息:记录每个人的紧急联系人信息,以帮助在紧急情况下迅速联系到患者的家属或其他联系人。

针对以上数据,可以使用机器学习和数据挖掘技术构建精准防控模型,以预测可能的疫情传播路径和风险区域,并制定相应的防控措施。例如,可以使用基于地理位置和行动轨迹的聚类算法,对人员进行分类,以帮助确定可能受到影响的场所和人员,并进行针对性的防控措施。同时,可以使用基于人群特征和健康信息的分类模型,对人员进行分类,以帮助医护人员对患者进行诊治和疫情分析。这些模型将能够更加精确地预测疫情传播和风险区域,并为疫情防控提供更有针对性的指导。

3 完整代码

请添加图片描述

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
扎眼的阳光的头像扎眼的阳光普通用户
上一篇 2023年4月22日
下一篇 2023年4月22日

相关推荐