文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

【第十一届泰迪杯数据挖掘挑战赛】A 题:新冠疫情防控数据的分析 思路+代码(持续更新)

2023-09-07 08:57

关注

【第十一届泰迪杯数据挖掘挑战赛】A 题:新冠疫情防控数据的分析 思路+代码(持续更新)

问题背景

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

解决问题

  1. 根据核酸检测中阳性人员的出行时间与场所追踪密接者,将结果保存到
    “result1.csv”文件中(文件模板见附件 1 中的 result1.csv)。
  2. 由问题 1 的结果,根据密接者的出行时间与场所追踪相应的次密接者,将结果保存
    到“result2.csv”文件中(文件模板见附件 1 中的 result2.csv)。
  3. 建立模型,分析接种疫苗对病毒传播指数的影响。
  4. 根据阳性人员的数量及辐射范围,分析确定需要重点管控的场所。
  5. 为了更精准地进行疫情防控和人员管理,你认为还需要收集哪些相关数据。基于这
    些数据构建模型,分析其精准防控的效果。
    在解决上述问题时,要求结合赛题提供的数据信息表建立数据仓库,实现数据治理
    的内容,请在论文中明确阐述做了哪些数据治理工作,具体是如何实现的。
    !!注意:以下代码是在Aistudio上面写的,因此就没有建立相关数据库,根据题目要求你们自行建立数据库,然后在代码中进行读取就好了。

代码下载

代码下载地址:第十一届泰迪杯数据挖掘挑战赛-ABC-Baseline

数据分析

  1. 导入常用的包
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from tqdm import tqdm import warnings warnings.filterwarnings('ignore')%matplotlib inline 
  1. 导入文件的时候发现,附件的编码有问题,因此我们需要封装一个获取文件编码的函数
# 获取文件编码import chardet def detect_encoding(file_path):    with open(file_path,'rb') as f:        data = f.read()        result = chardet.detect(data)        return result['encoding']
  1. 读入所有附件
# 读取人员信息表df_people = pd.read_csv('../datasets/附件2.csv',encoding = detect_encoding('../datasets/附件2.csv'))# 读取场所信息表df_place = pd.read_csv('../datasets/附件3.csv',encoding = detect_encoding('../datasets/附件3.csv'))# 个人自查上报信息表df_self_check = pd.read_csv('../datasets/附件4.csv',encoding = detect_encoding('../datasets/附件4.csv'))# 场所码扫码信息表df_scan = pd.read_csv('../datasets/附件5.csv',encoding = detect_encoding('../datasets/附件5.csv'))# 核算采样检测信息表df_nucleic_acid = pd.read_csv('../datasets/附件6.csv',encoding = detect_encoding('../datasets/附件6.csv'))# 提交示例1result = pd.read_csv('../datasets/result1.csv',encoding = detect_encoding('../datasets/result1.csv'))# 提交示例2result1 = pd.read_csv('../datasets/result2.csv',encoding = detect_encoding('../datasets/result2.csv'))
  1. 简单的查看一下提交示例
# 查看提交示例result.head()result1.head()

在这里插入图片描述
在这里插入图片描述

  1. 各附件的描述性统计
# 数据描述性统计def summary_stats_table(data):    '''    a function to summerize all types of data    分类型按列的数据分布与异常值统计    '''    # count of nulls    # 空值数量    missing_counts = pd.DataFrame(data.isnull().sum())    missing_counts.columns = ['count_null']    # numeric column stats    # 数值列数据分布统计    num_stats = data.select_dtypes(include=['int64','float64']).describe().loc[['count','min','max','25%','50%','75%']].transpose()    num_stats['dtype'] = data.select_dtypes(include=['int64','float64']).dtypes.tolist()    # non-numeric value stats    # 非数值列数据分布统计    non_num_stats = data.select_dtypes(exclude=['int64','float64']).describe().transpose()    non_num_stats['dtype'] = data.select_dtypes(exclude=['int64','float64']).dtypes.tolist()    non_num_stats = non_num_stats.rename(columns={"first": "min", "last": "max"})    # merge all     # 聚合结果    stats_merge = pd.concat([num_stats, non_num_stats], axis=0, join='outer', ignore_index=False, keys=None,              levels=None, names=None, verify_integrity=False, copy=True, sort=False).fillna("").sort_values('dtype')    column_order = ['dtype', 'count', 'count_null','unique','min','max','25%','50%','75%','top','freq']    summary_stats = pd.merge(stats_merge, missing_counts, left_index=True, right_index=True, sort=False)[column_order]    return(summary_stats)

以下分析结果均基于示例数据

以下分析结果均基于示例数据

以下分析结果均基于示例数据

以下分析结果均基于示例数据

以下分析结果均基于示例数据

  1. 数据可视化建议
    数据分析时可以做以下可视化

    单表可视化

    1. 人员信息表:可以进行人口统计学分析,如性别、年龄、民族等分布情况,还可以通过人员 ID 与其他表格进行关联分析。

    2. 场所信息表:可以进行地理信息分析,如场所分布情况、场所类型分布情况、场所密度等分析。

    3. 个人自查上报信息表:可以进行疫情监测分析,如症状分布情况、症状与核酸检测结果的关联分析、上报人员的位置分布情况等分析。

    4. 场所码扫码信息表:可以进行疫情监测分析,如扫码记录分布情况、扫码记录与核酸检测结果的关联分析等。

    5. 核酸采样检测信息表:可以进行疫情监测分析,如阳性人员的分布情况、核酸检测阳性率分析、阳性人员的接触场所与密切接触者分析等。

    关联分析

    1. 个人自查上报信息表和核酸采样检测信息表:可以分析个人上报的症状与核酸检测结果之间的关系,以及症状与检测结果对不同年龄、性别、民族等人群的影响。

    2. 场所信息表和场所码扫码信息表:可以分析不同场所的扫码情况,了解人们在哪些场所更容易扫码;也可以分析场所内体温异常者的情况,了解哪些场所的防疫工作存在漏洞。

    3. 个人自查上报信息表和场所码扫码信息表:可以根据个人自查上报的症状,分析不同场所的症状发生情况,了解哪些场所的防疫措施需要进一步加强。

    4. 核酸采样检测信息表和个人自查上报信息表、场所码扫码信息表:可以分析阳性人员的出行情况,追踪密接者,及时采取隔离措施。

Task1

Baseline实现了根据某个阳性人员的核酸检测记录,找出他在检测前后14天内去过的场所,然后再找出去过这些场所的人员,进而确定可能的密接者。具体的实现步骤如下:

  1. 首先,通过传入的阳性人员ID,在核酸检测记录中筛选出该阳性人员的检测记录,并获取阳性者的采样与检测时间。

  2. 接着,根据阳性人员在采样时的场所ID,确定第一个阳性人员所在的场所列表。

  3. 然后,通过阳性人员的ID与场所码扫码信息表进行拼接,获取阳性人员前后十四天所去的场所(第二个阳性人员所在的场所列表)。

  4. 将两个场所列表进行合并并去重。

  5. 最后,根据场所码扫码信息表中的所有User_id与场所信息表合并,通过场所列表和时间进行筛选,从而追踪密接者ID

Baseline实现了基于核酸检测记录,找出阳性人员在检测前后14天内去过的场所,并通过这些场所找出可能的密接者。

# 获取阳性者信息positive_user_id = df_nucleic_acid[df_nucleic_acid['jg'] =='阳性']['user_id'].values.tolist()def Potential_contacts(df_people,df_place,df_self_check,df_scan,df_nucleic_acid,positive_user_id):    # 筛选出阳性者的核酸检测记录    df_positive_test = df_nucleic_acid[df_nucleic_acid['user_id'] == positive_user_id]    # 获取阳性者的检测时间    positive_test_time = pd.to_datetime(df_positive_test['cysj'].iloc[0])    df_self_check['dump_time'] = pd.to_datetime(df_self_check['dump_time'])    df_scan['create_time'] =  pd.to_datetime(df_scan['create_time'])    # 获得阳性人员核酸检测的场所    positive_users_place1 = pd.merge(df_positive_test, df_place, on='grid_point_id')['name'].tolist()    # 获得阳性人员在测验时间前后14天去的场所    positive_users_place2 = pd.merge(df_positive_test, df_scan, on='user_id')[['user_id','create_time','cysj','grid_point_id_y']]    # 计算前14天和后14天    delta = pd.Timedelta(days=14)    # 计算最小时间和最大时间    min_date = positive_users_place2['cysj'] - pd.Timedelta(days=14)    max_date = positive_users_place2['cysj'] + pd.Timedelta(days=14)    # 筛选出符合要求的数据    mask = (positive_users_place2['create_time'] >= min_date) & (positive_users_place2['create_time'] <= max_date)    positive_users_place2 = positive_users_place2.loc[mask, ['user_id', 'grid_point_id_y']]    positive_users_place2 = positive_users_place2.rename(columns={'grid_point_id_y': 'grid_point_id'})    positive_users_place2 = pd.merge(positive_users_place2, df_place, on='grid_point_id')['name'].tolist()    # 将两个列表合并去重    positive_place = list(set(positive_users_place1+positive_users_place2))    # 获取去过上述场所的人员    # 按照密接时间筛选    df_potential_contacts = df_scan[(df_scan['create_time'] >= positive_test_time - pd.Timedelta('14D')) & (df_scan['create_time'] <= positive_test_time + pd.Timedelta('14D'))]    # 按照场所筛选    df_potential_contacts = df_potential_contacts[df_potential_contacts['grid_point_id'].isin(df_place[df_place['name'].isin(positive_place)]['grid_point_id'])]    # 整合信息并按照要求输出    result = pd.DataFrame({        '序号': range(1, len(df_potential_contacts)+1),        '密接者ID': df_potential_contacts['user_id'].values,        '密接日期': df_potential_contacts['create_time'].dt.date.astype(str),        '密接场所ID': df_potential_contacts['grid_point_id'].values,        '阳性人员ID': [positive_user_id] * len(df_potential_contacts)    })    return result

为本题封装了名为 Potential_contacts的函数,该函数的目的是找到所有可能与阳性者有接触的人员信息。

函数的具体逻辑如下:

  1. 从 df_nucleic_acid 中获取 positive_user_id 对应的阳性者的核酸检测记录和检测时间。
  2. 将 df_self_check 和 df_scan 数据框中的时间列转换为 datetime 类型。
  3. 从 df_place 中获取 positive_user_id 在核酸检测时间点去过的场所列表 positive_users_place1。
  4. 从 df_scan 中获取 positive_user_id 在核酸检测时间点前后 14 天去过的场所列表 positive_users_place2。
  5. 将 positive_users_place1 和 positive_users_place2 合并去重得到 positive_place,即 positive_user_id 去过的所有场所。
  6. 从 df_scan 中筛选出在 positive_test_time 前后 14 天有扫码记录的人员(即潜在密接者)df_potential_contacts。
  7. 从 df_place 中筛选出 positive_place 中的场所,并将这些场所的 grid_point_id 与 df_potential_contacts 中的 grid_point_id 匹配得到所有潜在密接者的位置信息。

整合潜在密接者的信息和阳性者的信息,并返回一个数据框,其中包含序号、密接者 ID、密接日期、密接场所 ID 和阳性人员 ID 等信息。

Task2

def get_sub_contacts(df_potential_contacts, df_scan):    # 修改列名,方便拼接    df_potential_contacts = df_potential_contacts.rename(columns = {'密接场所ID':'grid_point_id'})    # 筛选出所有在密接者场所出入过的UserID    contacts = pd.merge(df_potential_contacts,df_scan,on='grid_point_id')    # 去除密接者ID    contacts = contacts.drop(contacts[contacts['密接者ID'] == contacts['user_id']].index)    # 计算前后半个小时    delta = pd.Timedelta(minutes=30)    # 筛选出次密接者    mask = (contacts['create_time'] >= contacts['密接日期']-delta) & (contacts['create_time'] <= contacts['密接日期']+delta)    contacts = contacts[mask]    # 整合信息并按照要求输出    result = pd.DataFrame({        '序号': range(1, len(contacts)+1),        '次密接者ID': contacts['user_id'].values,        '次密接日期': contacts['create_time'].values,        '次密接场所ID': contacts['grid_point_id'].values,        '阳性人员ID': contacts['密接者ID'].values    })    return result

该函数的具体逻辑如下:

  1. 将df_potential_contacts中的 "密接场所ID "列重命名为 “grid_point_id”。
  2. 合并df_potential_contacts和df_scan中的grid_point_id列,以找到所有曾与密接者去过同一地点的用户。
  3. 删除任何用户ID与密接者ID相匹配的行,因为我们不想包括自我接触。
  4. 在密接者日期周围设置一个30分钟的时间窗口,筛选出在这时间区间内与密接者接触的用户。

为了找到次密接者,我们需要了解密接者密接期间所在的地点和与之接触的人员。

  1. 因此,该函数首先将两个表格 (df_potential_contacts 和 df_scan)合并,找到所有在与密接者相同的场所出现过的用户。

  2. 接下来,该函数将筛选出密接者密接时间的前后半小时内有过接触的用户。

    具体地,该函数使用 Pandas 库中的 Timedelta 函数设置一个时间窗口,

    然后将 create_time 列中的日期和时间与 密接日期 进行比较,筛选出在这个时间窗口内的接触记录。

  3. 最后,根据result格式输出答案

Task3

病毒传播指数可以根据现有的数据表格中的核酸采样检测信息表和场所码扫码信息表来计算。一种常用的方法是使用传染病流行病学中的基本再生数R0,它代表一个感染者平均会传染多少其他人。

首先,我们可以根据场所码扫码信息表中的数据计算每个场所的平均体温,并根据该平均体温和感染者的体温来确定感染概率。最后,我们可以使用基本再生数公式(R0 = 感染概率 × 平均接触人数)来计算病毒传播指数。

具体步骤如下:

将计算出的病毒传播指数与接种疫苗信息表中的数据进行比较,分析接种疫苗对病毒传播指数的影响。

  1. 第一步:确定每个场所的温度分布的平均值和标准偏差
df_scan['temperature_mean'] = df_scan.groupby('grid_point_id')['temperature'].transform('mean')df_scan['temperature_std'] = df_scan.groupby('grid_point_id')['temperature'].transform('std')
  1. 第二步:根据场所码扫码信息表和核酸采样信息表,确定感染者的平均体温
df_positive = pd.merge(df_scan, df_nucleic_acid[df_nucleic_acid['jg'] == '阳性'][['user_id']], on='user_id', how='inner')df_positive['temperature_mean_positive'] = df_positive.groupby('grid_point_id')['temperature'].transform('mean')
  1. 第三步:计算感染概率
df_positive['infection_prob'] = np.exp(-((df_positive['temperature_mean_positive'] - df_positive['temperature_mean']) ** 2) / (2 * df_positive['temperature_std'] ** 2))
  1. 第四步:根据密接者表中的数据,确定平均接触人数
# 根据阳性人员ID和密接场所ID进行分组,并统计每个组内密接者数量grouped = result1.groupby(['阳性人员ID', '密接场所ID'])['密接者ID'].count().reset_index()# 将统计结果返回到原数据集中result1 = pd.merge(result1, grouped, on=['阳性人员ID', '密接场所ID'], how='left')result1_count = result1.rename(columns={'密接者ID_y': '密接者数量'})result1_count['平均接触人数'] = result1_count.groupby(['阳性人员ID', '密接场所ID'])['密接者数量'].transform('mean')df_positive = pd.merge(result1_count, df_positive, left_on='阳性人员ID', right_on='user_id')
  1. 第五步:根据感染概率和每个感染者在每个场所的平均接触次数计算病毒传播指数。
df_positive['label'] = df_positive['infection_prob'] * df_positive['平均接触人数']
  1. 第六步:与疫苗接种信息表合并
# 疫苗接种信息表df_vaccine_info = pd.read_csv('../datasets/附件7.csv',encoding = detect_encoding('../datasets/附件7.csv'))df = pd.merge(df_vaccine_info, df_positive, on='user_id')# 去除没有label的数据df = df.dropna()
  1. 第七步:拟合数据,分析特征重要性
col = ['age', 'gender','inject_times', 'vaccine_type','label']df = df[col]# 对类别列进行数值编码(你也可以用其它编码进行特征工程)from sklearn.preprocessing import LabelEncoderfrom sklearn.ensemble import RandomForestRegressor# 创建 LabelEncoder 对象le = LabelEncoder()# 对 nject_times 和 vaccine_type 进行数值编码df['nject_times'] = le.fit_transform(df['nject_times'])df['vaccine_type'] = le.fit_transform(df['vaccine_type'])# 创建随机森林回归模型rf = RandomForestRegressor(n_estimators=100, random_state=2023)# 拟合数据X= df.drop('label',axis=1)y = df['label']rf.fit(X, y)# 得到特征重要性importances = rf.feature_importances_# 将特征重要性排序indices = np.argsort(importances)[::-1]# 将特征名称按照重要性排序names = [f'Feature {i}' for i in range(X.shape[1])]sorted_names = [names[i] for i in indices]# 绘制特征重要性柱状图plt.figure()plt.title("Feature Importance")plt.bar(range(X.shape[1]), importances[indices])plt.xticks(range(X.shape[1]), sorted_names, rotation=90)plt.show()

Task3的方案属于抛砖引玉,参考思路即可

Task4

等更新就好

来源地址:https://blog.csdn.net/weixin_62338855/article/details/129252401

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯