项目场景:
我提取敏感数据,举例常用敏感数据例如身份证号手机号,姓名和地点还有一些机构名字,因此我面向这些敏感数据,调用StanfordCoreNLP包,来解决大多数敏感数据,那会问了,为什么不自己训练模型来弄呢,对于我来说第一点太麻烦了,第二点主要也是因为没有具体标签如果只是为了做项目调用别的工具包,不寒碜。我以医院病历为例(就三条伪数据,简述一下如何做的)
StanfordCoreNLP包
我将StanfordCoreNLP包上传到百度云链接:https://pan.baidu.com/s/1I7uZ0CNVu2Dl1maSXH58FA
提取码:5fdm
读取医院名:
医院的名称我试过用命名体识别中机构来搞,不太行,可能医院标签缺少吧,如果要自己训练可以参考我前面写的命名体识别,可以自己训练。这里我就用了医院字典,那医院名是哪来的百度一下你就知道,这里我就以南京为例
# 读取医院名
Hospital=[]
with open("./yiyuan.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
# 去除换行符
result = ([x.strip() for x in lines if x.strip() != ''])
# 将整理好字典提取成为全局字典
for x in result:
Hospital.append(x)
我们先把敏感词语找到用find函数,find结果不等于-1就是找到了,然后用****来代替
# 医院机构
for yy in range(len(Hospital)):
if example[index].find(Hospital[yy])!=-1:
print('医院名: '+Hospital[yy])
example[index]=example[index].replace(Hospital[yy], '****')
人名的筛选
这里用stanford包来解决,为什么不用jieba因为效果不好,虽然jieba快但是识别不准,多用来做分词。为此只要找到 nlp.ner(example[index])[iname][1] == ‘PERSON’ 就可以将人名去除。
for iname in range(0, len(nlp.ner(example[index]))):
if nlp.ner(example[index])[iname][1] == 'PERSON':
namestring = nlp.ner(example[index])[iname][0]
print('人名: ' + namestring)
example[index] = example[index].replace(namestring, '****')
地点的筛选
这里依旧用是用stanford包来用但是注意的是,地点这里我们不仅要筛选掉地点,还要筛选掉机构城市,省份这种一系列有关地址的,因为这一系列都可能与一个地址有关。谨慎多写好过少写。
for i in range(0, len(nlp.ner(example[index]))):
if nlp.ner(example[index])[i][1] == 'FACILITY':
Location.append(nlp.ner(example[index])[i][0])
if nlp.ner(example[index])[i][1] == 'STATE_OR_PROVINCE' or nlp.ner(example[index])[i][1] == 'CITY' or nlp.ner(example[index])[i][1] == 'GPE' or nlp.ner(example[index])[i][1] == 'LOCATION':
Location.append(nlp.ner(example[index])[i][0])
for iloction in range(len(Location)):
print('地点: ',Location[iloction])
example[index] = example[index].replace(Location[iloction], '****')
数字的筛选
数字的筛选有关手机号身份证号,这里我们也做了详细了描写,这里要注意了,你要将容错加入,比如人家多输入了一位或者少输入一位,这种基础容错要考虑到。代码如下
pattern1 = "(13\d{7,11}|14[5|7]\d{6,10}|15\d{7,11}|166\d{6,10}|17[3|6|7]\d{6,10}|18\d{7,11})"
phone_list1 = re.compile(pattern1)
p = phone_list1.findall(example[index])
# p = re.match(phone_list1, example[index])
# if p:
for iNum in range(len(p)):
print('手机号: ', p[iNum])
example[index] = example[index].replace(p[iNum], '****')
# 身份证号
pattern2 = r"1[1,2,4,5]\d{13,17}x|1[1,2,4,5]\d{13,17}X|1[1,2,4,5]\d{14,18}|[2,3,4,5,6]\d{14,18}X|[2,3,4,5,6]\d{14,18}x|[2,3,4,5,6]\d{15,19}"
# 字符串形式的正则表达式
id_list1 = re.compile(pattern2)
id = id_list1.findall(example[index])
# 获取字符串
for iId in range(len(id)):
print('身份证号: ', id[iId])
example[index] = example[index].replace(id[iId], '****')
github地址如下:https://github.com/zhichen-roger/Natural-language-processing-based-data-desensitisation.git