“华为杯”第十五届中国研究生数学建模竞赛-对恐怖袭击事件记录数据的量化分析(Python,Pandas,Scikit-learn,PyTorch,Matplotlib,seaborn)

首先先说一下编程的工具

  • Python:编程语言
  • Pandas:数据处理,清洗,分析的工具
  • Scikit-learn:机器学习工具箱
  • PyTorch:深度学习搭建神经网络,训练等的工具
  • Matplotlib,seaborn:可视化工具

数据集中的每一行记录了一起恐怖袭击事件的信息,分为以下几部分进行了记录:

  • GTD的标志号和日期:每一起事件发生的起讫时间等。
  • 事件信息:每一起事件的时间,地点,人物,内容,过程,原因,入选标准等相关信息。
  • 事件发生的地点:包括国家、地区、城市和地理位置信息等
  • 攻击信息:解释攻击类型如:暗杀、劫持、绑架、路障事件、轰炸 /爆炸、武装突袭、徒手攻击等的信息。
  • 武器信息:记录了事件中所使用的武器类型如生物武器、化学武器、轻武器、爆炸物/炸弹/炸药、假武器、燃烧武器、致乱武器及其子类型等等。
  • 目标/受害者信息:为每一个事件记录了多达三个目标/受害者的信息。
  • 凶手信息:每一事件记录多达三名凶手的信息。包括凶手所在组织的名称、宣称对袭击负责的细节。
  • 伤亡和后果:包括人员伤亡、财产损失、人质或绑架的受害者、索要赎金等信息
  • 附加信息和来源:这个字段是用来说明与攻击有关的额外细节的。包含无法在上述任一字段中说明的信息等其他一些信息。
    其中每个类别下面又分为多个子段进行更详细的记录。
    数据集中一共包括三种数据类型:数值型,文本型,分类标记型
    我们要完成的任务,读题:
  • 依据 危害性对恐怖袭击事件 分级:对灾难性事件比如地震、交通事故、气象灾害等等进行分级是社会管理中的重要工作。通常的分级一般采用主观方法,由权威组织或部门选择若干个主要指标,强制规定分级标准,如我国《道路交通事故处理办法》第六条规定的交通事故等级划分标准,主要按照 人员伤亡经济损失程度划分。但恐怖袭击事件的危害性 不仅取决于人员伤亡和经济损失这两个方面,还与发生的 时机、地域、针对的对象等等诸多因素有关,因而采用上述分级方法 难以形成统一标准。请你们依据附件 1 以及其它有关信息,结合现代信息处理技术, 借助数学建模方法建立基于数据分析的量化分级模型,将附件 1给出的事件按危害程度从高到低分为一至五级,列出近二十年来危害程度最高的十大恐怖袭击事件,并给出表 1 中事件的分级。
  • 依据事件特征 发现恐怖袭击事件制造者:附件 1 中有多起恐怖袭击事件尚未确定作案者。如果将可能是同一个恐怖组织或个人在不同时间、不同地点多次作案的若干案件串联起来 统一组织侦査,有助于提高破案效率,有利于尽早发现新生或者隐藏的恐怖分子。请你们针对在 2015、2016年度发生的、尚未有组织或个人宣称负责的恐怖袭击事件,运用数学建模方法寻找上述可能性,即 将可能是同一个恐怖组织或个人在不同时间、不同地点多次作案的若干案件归为一类,对应的未知作案组织或个人标记不同的代号,并按该组织或个人的危害性从大到小选出其中的前5 个,记为 1 号-5 号。 再对表 2 列出的恐袭事件,按嫌疑程度对 5个嫌疑人排序,并将结果填入下表(表中样例的意思是:对事件编号为 XX 的事件,3 号的嫌疑最大,其次是 4 号,最后是 5号),如果认为某嫌疑人关系不大,也可以保留空格。
  • 对未来反恐态势的分析:对未来反恐态势的分析评估有助于提高反恐斗争的针对性和效率。请你们依据附件 1 并 结合因特网上的有关信息,建立适当的数学模型,研究 近三年来恐怖袭击事件发生的 主要原因、时空特性、蔓延特性、级别分布等规律,进而 分析研判下一年全球或某些重点地区的反恐态势,用图/表给出你们的研究结果,提出你们对反恐斗争的见解和建议。
  • 自由发挥:你们认为通过数学建模还可以发挥附件 1 数据的哪些作用?给出你们的模型和方法。

关于数据集的问题:

  • 数据类型不统一:数据集是数据值类型,文本类型,分类类型多种的混合,所以首先要想办法将数据集的数据类型进行统一。可以利用自然语言处理中的方法,将文本类型的数据嵌入为向量,我看了好几篇一等论文,对于文本类型的数据直接扔掉了,文本类型中也包含着大量有用的信息,比如通过summary-对于事件描述的这一列,我们直接可以得知这起恐怖事件对于社会的影响。数据值类型的列直接按照它原先的记录进行保留。分类类型一律转为one-hot的形式。所以最后这个数据集的形式是每一列都是数字。每一年的恐怖袭击事件作为一个矩阵,不同年份的恐怖袭击事件堆叠在一起形成一个三维张量。
  • 缺失值:数据集中的有些列是因为自身子段的属性导致了存在大量的缺失值,这种列不能直接删除,可以给它缺失的数据一个特殊标记。有的列存在大量的缺失值是因为客观原因无法确定,对于这种,统计这一列缺失值的统计信息,设定一个阈值,如果缺的太多,直接把这一列删除,因为它已经对于最终问题的解决提供不了太多有帮助的信息。
  • 数据特征冗余:最初的数据集是一个特征(列)数为135的一个文件(样本(行)数无所谓,越多越好),即使经过我们上一步删除一些缺失值过多的列,即使假设删除了一半,最后也还会有60多列,所以必须对数据集使用特征降维的方法,这样才能方便我们接下来的一系列分析,常用的降维方法首先想到的就是机器学习中的PCA,LDA,深度学习中的Encoder-Decoder结构也能做降维,后面我会编程实现一下,验证效果。

关于机器学习,深度学习模型的问题:

  • 没有标签:最严重的问题。机器学习,深度学习的软肋,深度学习的另一个软肋-数据规模的问题,对于这个问题还好,我看了一下数据集有20多万的样本,足够了。标签的问题不解决,管你多牛b的机器学习,深度学习方法,都用不了。想到的解决方法有:人工标注,题目中不是已经限制为是一个5分类问题,标注大约6万条就足够训练用的。利用聚类算法产生标签,根据这个标签进行训练,但是这种方式,模型的准确度严重依赖于聚类算法的准确性。利用Encoder-Decoder结构,数据集整理完成之后训练一个Encoder-Decoder结构,训练完成后,拿出Encoder部分接一个分类层直接分类,其中Encoder-Decoder可以利用带有多头注意力机制的Transformer,因为数据集中带有时序性的信息。
  • 模型的验证问题:如何验证学习到的模型的准确性,如果模型真的从数据集中学习到了知识,那么如果我令恐怖袭击事件发起人那列作为target,让模型进行预测,也就是我对模型定义一个预测这个恐怖袭击事件发起人的任务,如果它分类的很好,那么我可以认为它真的从数据集中学习到了相应的知识,我可以使用这个模型。(自然语言处理中的Mark思想,遮盖住一句话中的一些词语,让模型进行预测,有个专业术语叫self-supervised)

对于题目中让我们解决的几个任务的处理:

  • 题目让我们完成对于每一起恐怖袭击事件进行分类,总共分为5个类别,然后给了我们一个表格,让我们把表格中的事件也进行分类,找出近20年来的重大恐怖袭击事件。5分类问题,数据处理后,训练一个带有多头注意力的Encoder-Decoder结构,文本类型的列进行完词嵌入之后,整句话的词向量表示会很长,接一个前馈神经网络进行压缩,放在Encoder-Decoder结构中一起训练,训练完成后,提取Encoder结构,对于Encoder的输出利用聚类进行分类。查找表格中事件的分类,查找所有第一分类的事件。
  • 利用第一问训练完毕的Encoder结构,外接分类层,冻结Encoder浅层的参数权重,将恐怖袭击事件发起人那列作为label进行分类层参数,以及Encoder深层参数的训练。按照我们第一问的分类结果,在第一类事件中计算不同恐怖组织的危害性,选取前5个,改变分类层的分类个数,预测题目中的事件,根据分类层softmax后的概率将嫌疑排序。
  • 同理还是利用训练完毕的Encoder,题目让我们发现近三年来恐怖袭击事件发生的主要原因、时空特性、蔓延特性、级别分布等规律。提取近三年的数据作为训练集,还是上面提到的self-supervised思想,让发现谁的规律,分类层就分谁,根据概率找主要原因,主要的地点,级别分布第一问已经做完了直接可视化结果就可以。最后的预测是根据我们图表中的信息给出的。
  • 第4问仿照前面的思想就可以。

(以下是代码部分)


import numpy as np
import pandas as pd
import warnings

warnings.filterwarnings('ignore')

pd.set_option('display.max_columns', 20)

data = pd.read_excel('1993.xlsx')

data_of_GTD = data.iloc[:, :7].copy()

data_of_location = data.iloc[:, 7:18].copy()

data_of_info = data[
    ['summary', 'crit1', 'crit2', 'crit3', 'doubtterr', 'alternative', 'alternative_txt', 'multiple', 'related']].copy()

sup_list = [['attacktype' + str(i), 'attacktype' + str(i) + '_txt'] for i in range(1, 4)]

index_columns = ['success', 'suicide']
index_columns += sup_list[0]
index_columns += sup_list[1]
index_columns += sup_list[2]
data_of_attack = data[index_columns].copy()

sup_list = [['targtype' + str(i), 'targtype' + str(i) + '_txt', 'targsubtype' + str(i), 'targsubtype' + str(i) + '_txt',
             'corp' + str(i), 'target' + str(i), 'natlty' + str(i), 'natlty' + str(i) + '_txt'] for i in range(1, 4)]
index_columns = []
index_columns += sup_list[0]
index_columns += sup_list[1]
index_columns += sup_list[2]
data_of_target = data[index_columns].copy()

index_columns = ['gname', 'gsubname']
sup_list = [['gname' + str(i), 'gsubname' + str(i)] for i in range(2, 4)]
index_columns += sup_list[0]
index_columns += sup_list[1]
index_columns.append('motive')
sup_list = [['guncertain' + str(i)] for i in range(1, 4)]
index_columns += sup_list[0]
index_columns += sup_list[1]
index_columns += sup_list[2]
index_columns.append('individual')
index_columns.append('nperps')
index_columns.append('nperpcap')
index_columns.append('claimed')
index_columns.append('claimmode')
index_columns.append('claimmode_txt')
sup_list = [['claim' + str(i), 'claimmode' + str(i), 'claimmode' + str(i) + '_txt'] for i in range(2, 4)]
index_columns += sup_list[0]
index_columns += sup_list[1]
index_columns.append('compclaim')
data_of_murder = data[index_columns].copy()

index_columns = []
sup_list = [['weaptype' + str(i), 'weaptype' + str(i) + '_txt', 'weapsubtype' + str(i), 'weapsubtype' + str(i) + '_txt']
            for i in range(1, 5)]
index_columns += sup_list[0]
index_columns += sup_list[1]
index_columns += sup_list[2]
index_columns += sup_list[3]
index_columns.append('weapdetail')
data_of_weapon = data[index_columns].copy()

data_of_result = data.iloc[:, 99:125].copy()

data_of_append = data.iloc[:, 125:135].copy()

data_with_resolution = data_of_GTD[data_of_GTD.resolution.notnull()]

from datetime import datetime

index_list = data_with_resolution.index
start_time = [str(data_with_resolution['iyear'][index_list[i]]) + '-' + str(
    data_with_resolution['imonth'][index_list[i]]) + '-' + str(data_with_resolution['iday'][index_list[i]]) for i in
              range(len(data_with_resolution.index))]

start_time = pd.to_datetime(start_time)

end_time = pd.to_datetime(data_with_resolution['resolution'])

time_diff = pd.to_timedelta(end_time - start_time).dt.days * 24

for i in index_list:
    data_of_GTD['resolution'][i] = time_diff[i]

data_of_GTD.resolution.fillna(0, inplace=True)

delete_columns = ['iyear', 'imonth', 'iday', 'approxdate', 'extended']
data_of_GTD.drop(delete_columns, inplace=True, axis=1)
print("处理之后的GTD信息为:")
print(data_of_GTD.head(2))

data_of_location.drop(['country_txt'], inplace=True, axis=1)

data_of_location.drop(['region_txt'], inplace=True, axis=1)

data_of_location.drop(['latitude', 'longitude', 'specificity'], inplace=True, axis=1)

data_of_location.location.fillna('UNK', inplace=True)
print("处理之后的事件发生的地点信息为:")
print(data_of_location.head(2))

data_of_info.summary.fillna('UNK', inplace=True)

data_of_info['crit1_crit2_crit3_doubtterr'] = data_of_info['crit1'].map(str) + data_of_info['crit2'].map(str) + \
                                              data_of_info['crit3'].map(str) + \
                                              data_of_info['doubtterr'].map(str)
data_of_info.drop(['crit1', 'crit2', 'crit3', 'doubtterr'], inplace=True, axis=1)

data_of_info.drop(['alternative', 'alternative_txt'], inplace=True, axis=1)

data_of_info.drop(['multiple'], inplace=True, axis=1)
data_of_info.drop(['related'], inplace=True, axis=1)
print("处理之后的事件信息:")
print(data_of_info.head(2))

data_of_attack.attacktype1.fillna(10, inplace=True)
data_of_attack.attacktype2.fillna(10, inplace=True)
data_of_attack.attacktype3.fillna(10, inplace=True)

data_of_attack.attacktype1_txt.fillna('UNK', inplace=True)
data_of_attack.attacktype2_txt.fillna('UNK', inplace=True)
data_of_attack.attacktype3_txt.fillna('UNK', inplace=True)

unique_list = data_of_attack['attacktype1_txt'].unique()

unique_value_map = {}
for index, value in enumerate(unique_list):
    unique_value_map[value] = index

data_of_attack['attacktype1_txt'] = data_of_attack['attacktype1_txt'].apply(lambda x: int(unique_value_map[x]))

unique_list = data_of_attack['attacktype2_txt'].unique()

unique_value_map = {}
for index, value in enumerate(unique_list):
    unique_value_map[value] = index

data_of_attack['attacktype2_txt'] = data_of_attack['attacktype2_txt'].apply(lambda x: int(unique_value_map[x]))

unique_list = data_of_attack['attacktype3_txt'].unique()

unique_value_map = {}
for index, value in enumerate(unique_list):
    unique_value_map[value] = index

data_of_attack['attacktype3_txt'] = data_of_attack['attacktype3_txt'].apply(lambda x: int(unique_value_map[x]))
print("处理完之后的攻击信息:")
print(data_of_attack.head(2))

print('处理完之后的目标信息:')
print(data_of_target.head(2))

delete_columns = ['gsubname']
sup_list = [['gname' + str(i), 'gsubname' + str(i)] for i in range(2, 4)]
delete_columns += sup_list[0]
delete_columns += sup_list[1]
delete_columns.append('motive')
sup_list = [['guncertain' + str(i)] for i in range(1, 4)]
delete_columns += sup_list[0]
delete_columns += sup_list[1]
delete_columns += sup_list[2]
delete_columns.append('individual')
delete_columns.append('nperps')
delete_columns.append('nperpcap')
delete_columns.append('claimed')
delete_columns.append('claimmode')
delete_columns.append('claimmode_txt')
sup_list = [['claim' + str(i), 'claimmode' + str(i), 'claimmode' + str(i) + '_txt'] for i in range(2, 4)]
delete_columns += sup_list[0]
delete_columns += sup_list[1]
delete_columns.append('compclaim')
data_of_murder.drop(delete_columns, inplace=True, axis=1)

print("处理完之后的凶手信息:")
print(data_of_murder.head(2))

data_of_weapon.drop(['weapdetail'], inplace=True, axis=1)

print("处理完之后的武器信息:")
print(data_of_weapon.head(2))

data_of_result.propextent.fillna(4, inplace=True)

delete_columns = [
    'propextent_txt', 'propvalue', 'propcomment',
    'nhostkid', 'nhostkidus', 'nhours', 'ndays',
    'divert', 'kidhijcountry', 'ransom',
    'ransomamt', 'ransomamtus', 'ransompaid',
    'ransomnote', 'hostkidoutcome_txt', 'nreleased'
]
data_of_result.drop(delete_columns, inplace=True, axis=1)
print("处理完之后的事件结果信息:")
print(data_of_result.head(2))

data_of_append.addnotes.fillna('UNK', inplace=True)
data_of_append.scite1.fillna('UNK', inplace=True)
data_of_append.scite2.fillna('UNK', inplace=True)
data_of_append.scite3.fillna('UNK', inplace=True)

data_of_append['addnotes_scite1_scite2_scite3'] = data_of_append['addnotes'].map(str) + data_of_append['scite1'].map(
    str) + data_of_append['scite2'].map(str) + data_of_append['scite3'].map(str)
data_of_append.drop('dbsource', inplace=True, axis=1)
data_of_append['INT_LOG_INT_IDEO_INT_MISC_INT_ANY'] = data_of_append['INT_LOG'].apply(lambda x: abs(x)).map(str) + \
                                                      data_of_append[
                                                          'INT_IDEO'].apply(lambda x: abs(x)).map(str) + data_of_append[
                                                          'INT_MISC'].apply(lambda x: abs(x)).map(str) + \
                                                      data_of_append['INT_ANY'].apply(lambda x: abs(x)).map(str)
delete_columns = ['addnotes', 'scite1', 'scite2', 'scite3', 'INT_LOG', 'INT_IDEO', 'INT_MISC', 'INT_ANY']
data_of_append.drop(delete_columns, inplace=True, axis=1)
data_of_append.drop(['related'], inplace=True, axis=1)
print('处理完之后的附加信息为:')
print(data_of_append.head(2))

Original: https://blog.csdn.net/Talantfuck/article/details/124536542
Author: _Old_Summer
Title: “华为杯”第十五届中国研究生数学建模竞赛-对恐怖袭击事件记录数据的量化分析(Python,Pandas,Scikit-learn,PyTorch,Matplotlib,seaborn)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/764907/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球