【隐私保护】使用Python从文本中删除个人信息:第一部分

news2024/9/23 1:34:08

自我介绍

  • 做一个简单介绍,酒架年近48 ,有20多年IT工作经历,目前在一家500强做企业架构.因为工作需要,另外也因为兴趣涉猎比较广,为了自己学习建立了三个博客,分别是【全球IT瞭望】,【架构师酒馆】和【开发者开聊】,有更多的内容分享,谢谢大家收藏。
  • 企业架构师需要比较广泛的知识面,了解一个企业的整体的业务,应用,技术,数据,治理和合规。之前4年主要负责企业整体的技术规划,标准的建立和项目治理。最近一年主要负责数据,涉及到数据平台,数据战略,数据分析,数据建模,数据治理,还涉及到数据主权,隐私保护和数据经济。 因为需要,比如数据资源入财务报表,另外数据如何估值和货币化需要财务和金融方面的知识,最近在学习财务,金融和法律。打算先备考CPA,然后CFA,如果可能也想学习法律,备战律考。
  • 欢迎爱学习的同学朋友关注,也欢迎大家交流。微信小号【ca_cea】

实现Python隐私文本过滤器,通过删除个人身份信息(PII)来保护用户的隐私。

GDPR是欧盟制定的《通用数据保护条例》。其目的是保护所有欧洲居民的数据。保护数据也是开发人员的内在价值。通过控制对列和行的访问,保护行/列数据结构中的数据相对容易。但是免费文本呢?

为了满足我们的隐私要求,我们可以调整自由文本字段的内容,用标签取代与隐私相关的信息。文本的含义没有改变,但不能通过匿名化与个人相关。目标是翻译以下文本(日期为荷兰语):

The possibilities have increased since 2014, especially compared to2012, hè Kees? The system has different functions to manipulate data. The date is 12–01–2021 (or 12 jan 2021 or 12 januari 2021).
You can reach me at nam@provider.com and I live in Rotterdam. My address is Maasstraat 13, 1234AB. My name is Thomas de Vries and I have Acne. Oh , I use ranitidine for this.

并将其替换为

The possibilities have increased since <NUMBER>, especially compared to<NUMBER>, hè <NAME>? The system has different functions to manipulate data. The date is <DATE> (or <DATE> or <DATE>).
You can reach me at <EMAIL> and I live in <PLACE>. My address is <ADRESS> <NUMBER>, <POSTALCODE>. My name is <NAME> <NAME> and I have <DISEASE>. Oh , I use <MEDICINE> for this.

本文介绍了一个简单的隐私过滤器,它将执行以下操作:

  • 用标签<DATE>替换日期
  • 将URL替换为标签<URL>
  • 将电子邮件地址替换为<email>
  • 将邮政编码替换为<POSTALCODE>
  • 将数字替换为<NUMBER>
  • 用<PLACE>替换城市和地区
  • 将街道名称替换为<street>
  • 将名字和姓氏替换为<NAME>
  • 用<疾病>替换疾病
  • 将药品名称替换为<medicine>

添加后两个是因为医疗信息需要额外的护理。发生的次数会很低,但当这些信息被泄露时,影响会很大。

前四个动作将用正则表达式执行,而最后五个动作将由替换函数实现。我们的隐私过滤器类具有以下结构:

import re
from flashtext import KeywordProcessor

class PrivacyFilter:

    def __init__(self):
        ...

    def initialize(self):
        ...

    def remove_numbers(self, text):
        ...

    def remove_dates(self, text):
        ...

    def remove_email(self, text):
        ...

    def remove_postal_codes(self, text):
        ...

    def filter(self, inputtext):
        text = self.remove_dates(text)
        text = self.remove_email(text)
        text = self.remove_postal_codes(text)
        text = self.remove_numbers(text)
        ...

if __name__ == "__main__":
    sentence = ...
    pfilter = PrivacyFilter()
    pfilter.initialize()
    print(pfilter.filter(sentence))

PrivacyFilter类实现了不同的过滤器。在创建和初始化后,该对象可以用于过滤文本。它与regulator表达式和FlashText WordProcesser.配合使用。

使用正则表达式筛选

前四个过滤器是用正则表达式实现的。更换数字是最简单的第一种更换方式:

def remove_numbers(self, text):
    return re.sub(r'\w*\d\w*', '<NUMBER>', text).strip()

此正则表达式将所有包含一个或多个数字的单词替换为标记<NUMBER>。这将替换文本中的银行账户、电话号码、身份证号码等。此过滤器是最后执行的,因此邮政编码和日期可以由其相应的标签代替,而不是一系列数字标签。

更高级的是删除邮政编码的功能。荷兰的邮政编码格式为0000AA,数字和字母之间有一个可选的空格。要替换这些,请使用以下正则表达式:

def remove_postal_codes(self, text):
  return re.sub("[0-9]{4}[ ]?[A-Z]{2}([ ,.:;])", "<POSTALCODE>\\1", text)

添加带标点符号的可选部分是为了防止单词前两个字母的四个数字序列被替换,例如,我们不想将“4000项的顺序”替换为“<POSTCODE>ems的顺序”。

由于电子邮件地址的复杂性,删除电子邮件地址变得有点棘手:

def remove_email(text):
    return re.sub("(([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\." \
                  "([a-z]{2,6}(?:\.[a-z]{2})?))(?![^<]*>)", "<EMAIL>", text)

正则表达式可以在网站上找到,99.99%的正则表达式有效。可以在那里找到各种语言的电子邮件检查器的实现。正则表达式的另一个好来源是Murani.nl.。

删除日期是不可能用一个正则表达式的,因为月份可以写成数字、缩写和全名。要删除日期,我们需要三个正则表达式:

def remove_dates(text):
    text = re.sub("\d{2}[- /.]\d{2}[- /.]\d{,4}", "<DATUM> ", text)
    text = re.sub(
        "(\d{1,2}[^\w]{,2}(januari|februari|maart|april|mei|juni|juli|augustus"\
        "|september|oktober|november|december)([- /.]{,2}(\d{4}|\d{2})){,1})"\
        "(?P<n>\D)(?![^<]*>)", "<DATE> ", text)
    text = re.sub(
        "(\d{1,2}[^\w]{,2}(jan|feb|mrt|apr|mei|jun|jul|aug|sep|okt|nov|dec)"\
        "([- /.]{,2}(\d{4}|\d{2})){,1})(?P<n>\D)(?![^<]*>)", "<DATE> ", text)
    return text

第一个正则表达式匹配以数字形式书写的日期,格式为dd-mm-yyyy。支持日期部分之间的不同分隔符。第二个和第三个匹配日期与文本中的月份名称。

使用KeyWordProcessor进行筛选

如果像以前的替换集一样构建,过滤地点、街道、名称、药物和疾病需要数千个正则表达式。即使将一系列名称组合在一个正则表达式中也是昂贵的。

为了解决这个问题,Alfred V.Aho实现了 Aho-Corasick algorithm,该算法定位存储在类似字典结构中的字符串。从所有搜索项创建一个图,并遍历该图以解析文本。

NLP

Example tree (image by author)

该图包含字符串“AB”、“ABEF”、“AC”和“BD”,因为只有蓝色节点是结束节点。当第一个字母是“AB”时,它是一个结束节点,除非后面跟着字母“C”和“E”。为了在KeywordProcessor中使用,替换标记与图中的结束节点相关联。通过这种方式,所有不同的隐私元素都可以添加到一个图中,并且仍然可以由适当的标签替换。

这个算法有几种实现,这里我们将使用Github的Flashtext实现。该算法在大规模替换和检索文档中的关键词中进行了描述。它包含一个KeywordProcessor,关键字将添加到其中并替换:KeywordProcessor.add_keyword('keyword','replacement')。端节点存储要放置的替换项。

在数据集文件夹中,有几个文件每行都有一个关键字,例如一个文件具有所有的名字,或者至少有10000个最常见的名字。我们可以使用替换标记<NAME>将该文件中的所有元素添加到图中,如下所示:

def __init__(self):
    self.keyword_processor_case_sensitive = KeywordProcessor(case_sensitive=True)

def file_to_list(filename, minimum_length=0):
    with open(filename, encoding='latin') as f:
        lst = [line.rstrip() for line in f]
    lst = list(dict.fromkeys(lst))
    if minimum_length > 0:
        lst = list(filter(lambda item: len(item) > minimum_length, lst))
    return lst

def initialize(self):
  for naam in self.file_to_list('datasets\\firstnames.csv'):
      self.keyword_processor_case_sensitive.add_keyword(naam, '<NAME>')

在构造函数中,会创建一个区分大小写的KeywordProcessor。我们使用区分大小写的处理程序,因为在荷兰语中,有几个名字也是动词。这样,我们只会在它们以输入文件中的大写字母开头时替换它们。如果您想更安全,可以使用不区分大小写的处理器。

输入文件被读取到列表中(第5行和第6行),从该列表中删除重复项(第7行),并以最小长度过滤该列表。列表中的每个项目都会添加到处理器中(从而添加到图形中),并带有相应的标记“<NAME>”。

在initialize函数中,可以为街道名称、地点、姓氏、药品等添加更多的数据文件。

class PrivacyFilter:

    def __init__(self):
        self.keyword_processor_case_sensitive = KeywordProcessor(case_sensitive=True)
        self.keyword_processor_case_insensitive = KeywordProcessor(case_sensitive=False)

    def file_to_list(self, filename, minimum_length=0, drop_first=1):
        with open(filename, encoding='latin') as f:
            lst = [line.rstrip() for line in f]
        lst = list(dict.fromkeys(lst))
        if minimum_length > 0:
            lst = list(filter(lambda item: len(item) > minimum_length, lst))
        return lst[drop_first:]

    def initialize(self):

        for naam in self.file_to_list('datasets\\streets_Nederland.csv', minimum_length=5):
            for c in ['.', ',', ' ', ':', ';', '?', '!']:
                self.keyword_processor_case_insensitive.add_keyword(naam + c, '<STREET>' + c)

        for naam in self.file_to_list('datasets\\places.csv'):
            for c in ['.', ',', ' ', ':', ';', '?', '!']:
                self.keyword_processor_case_insensitive.add_keyword(naam + c, '<PLACE>' + c)

        for naam in self.file_to_list('datasets\\firstnames.csv'):
            self.keyword_processor_case_sensitive.add_keyword(naam, '<NAME>')

        for naam in self.file_to_list('datasets\\lastnames.csv'):
            self.keyword_processor_case_sensitive.add_keyword(naam, '<NAME>')

        for naam in self.file_to_list('datasets\\aandoeningen.csv'):
            self.keyword_processor_case_insensitive.add_keyword(naam, '<DISEASE>')

        for naam in self.file_to_list('datasets\\medicijnen.csv'):
            self.keyword_processor_case_insensitive.add_keyword(naam, '<MEDICINE>')

位置名称是按大小过滤的,因为数据是从OpenStreetMap中提取的,并且在获得的数据集中有空字段、零长度字段和短缩写。最小尺寸可根据您的安全要求进行定制。

过滤文本

有了所有的函数,我们可以编写实际的过滤器方法:

def filter(self, inputtext):

    text = self.remove_dates(text)
    text = self.remove_email(text)
    text = self.remove_postal_codes(text)
    text = self.remove_numbers(text)

    text = self.keyword_processor_case_insensitive.replace_keywords(text)
    text = self.keyword_processor_case_sensitive.replace_keywords(text)

    return text.strip()

调用基于正则表达式的方法,然后调用区分大小写和不区分大小写的处理器。由于不同的数据集集成在KeywordProcessors中,因此只需要执行一次。这将产生所需的输出。

但是性能呢?更换文本部件可能会变得非常昂贵,尤其是包含大量禁止使用的单词,在这种情况下约为136.000(!!)。在我的电脑上,初始化课程需要3.1秒,但过滤前面介绍的文本只需要0.5毫秒。太快了!这足够快,可以在实际用例中使用。

最后的想法

本文为自由文本提供了一个简单但非常有效的隐私解析器。改进总是可能的,但这段代码是从文本中过滤隐私信息的最佳方法。

可以通过用标记化器替换算法来进行改进。这使得引入Levenshtein function来测量单词之间的距离成为可能,从而支持删除有打字错误的单词。

完整的代码可以在Github上找到:https://github.com/lmeulen/PrivacyFilter

标签和例句是荷兰语,但源代码可以很容易地被其他语言所采用。在存储库中还有一个程序,用于收集荷兰语的不同数据集。请注意,这些操作将第一行添加到具有数据名称的数据文件中。PrivacyFiler类在读取数据文件时过滤第一行。

本文:【隐私保护】使用Python从文本中删除个人信息 | 开发者开聊

欢迎收藏  【全球IT瞭望】,【架构师酒馆】和【开发者开聊】.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1335634.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

销售如何挖掘客户?有哪些方法?

在当今竞争激烈的市场环境中&#xff0c;客户资源的挖掘已经成为企业生存和发展的关键。销售人员需要掌握一定的技巧和方法&#xff0c;以有效地发掘潜在客户&#xff0c;提高销售业绩。以下分享一些挖掘客户的常用方法&#xff0c;帮助销售人员更好地开展业务。 一、了解客户需…

matlab附加功能管理器安装蓝牙工具箱

由于最近需要做蓝牙仿真方面的东西&#xff0c;需要用到matlab的蓝牙工具箱&#xff0c;根据官网例子输入&#xff1a; commSupportPackageCheck(BLUETOOTH);检测是否包含该工具箱&#xff0c;结果出现&#xff1a; 点击Add-On-Explorer出现&#xff1a; 网上搜索发现这是因为…

麦肯锡产品经理问题解决流程终极指南

您是否想知道世界上最成功的产品经理如何始终如一地提供不仅满足而且超出预期的解决方案&#xff1f;秘密可能就在于世界上最负盛名的咨询公司之一麦肯锡公司所磨练的方法论。本文深入探讨了麦肯锡的问题解决流程&#xff0c;该流程专为希望提升水平的产品经理量身定制。 01. 麦…

周末两个比赛3个小题

周末安洵和nctf&#xff0c;因为不是学生也没报名拿附件作了一把。 安洵/pwn/side_channel , initiate 安洵的题很好&#xff0c;唯一的问题是把几乎所有的&#xff0c;有没有必要的都放了远程&#xff0c;而且服务器很差&#xff0c;好多题不是不会而是连不上。 这个题估计…

vivado 多周期路径与时钟相移

多周期路径与时钟相移 有时&#xff0c;必须在具有相同时钟域的两个时钟域之间定义定时约束时钟周期&#xff0c;但两个时钟之间的相移。在这些情况下&#xff0c;理解正时引擎使用的默认设置和保持关系。如果没有仔细调整两个时钟之间的相移可能导致两个时钟间的逻辑约束过大…

13.TCP/IP协议

1.TCP/IP协议是什么 TCP/IP协议不仅仅指的是TCP和IP两个协议&#xff0c;二十指由FTP、SMTP、TCP、UDP、IP等等协议构成的协议簇。 TCP/IP协议是一系列规则的统称&#xff0c;他们定义了消息在网络间进行传输的规则。是供已连接互联网的设备进行通信的通信规则 2.TCP/IP协议的…

走进数字金融峰会,为金融科技数字化赋能

12月20—21日&#xff0c;FSIDigital数字金融峰会在上海圆满召开。本次峰会包含InsurDigital数字保险峰会和B&SDigital数字银行与证券峰会2场平行峰会&#xff1b;吸引了近600位来自保险、银行、证券以及金融科技等行业的领导者和专家齐聚一堂&#xff0c;共同探讨金融业数…

宝塔面板Linux服务器CentOS 7数据库mysql5.6升级至5.7版本教程

近段时间很多会员问系统更新较慢&#xff0c;也打算上几个好的系统&#xff0c;但几个系统系统只支持MYSQL5.7版本&#xff0c;服务器一直使用较低的MYSQL5.6版本&#xff0c;为了测试几个最新的系统打算让5.6和5.7并存使用&#xff0c;参考了多个文档感觉这种并存问题会很多。…

STM32 支持IAP的bootloader开发,使用串口通过Ymodem协议传输固件

资料下载: https://download.csdn.net/download/vvoennvv/88658447 一、概述 关于IAP的原理和Ymodem协议&#xff0c;本文不做任何论述&#xff0c;本文只论述bootloader如何使用串口通过Ymodem协议接收升级程序并进行IAP升级&#xff0c;以及bootloader和主程序两个工程的配置…

UGUI Panel的显示和隐藏优化

unity UI如何开启&#xff08;显示&#xff09;或者关闭&#xff08;隐藏&#xff09;Panel界面&#xff0c;相信大家都是知道的&#xff0c;但是如何做最好呢&#xff1f; 可能大家一般开启/关闭界面的方法就是直接SetActive吧。这样做通常是可以的&#xff0c;简答快速地解决…

多播ip地址配置和通信理解

经常有朋友问&#xff0c;为什么相同局域网的ip需要相同网段&#xff0c;为什么组播的网段可以不同&#xff1f; 比如&#xff1a; 在您的局域网&#xff08;192.168.1.0/24 网段&#xff09;中设置多播组时&#xff0c;您可以选择一个在本地网络范围内尚未使用的多播组地址。…

【Java中序列化的原理是什么(解析)】

&#x1f341;序列化的原理是什么&#xff1f; &#x1f341;典型-----解析&#x1f341;拓展知识仓&#x1f341;Serializable 和 Externalizable 接门有何不同? &#x1f341;如果序列化后的文件或者原始类被篡改&#xff0c;还能被反序列化吗?&#x1f341;serialVersionU…

电路设计(7)——窗口比较器的multism仿真

1.功能设计 构建一个窗口比较器的电路&#xff0c;在输入电压大于3.5v&#xff0c;小于0.8v时&#xff0c;蜂鸣器报警&#xff0c;输入电压在0.8v到3.5v之间时&#xff0c;不报警。 整体电路如下&#xff1a; 2.设计思路 在输入端&#xff0c;采取电阻分压的方式&#xff0c;输…

2024年最新Python爬虫入门『最强教程』新鲜出炉!

近年来&#xff0c;大数据成为业界与学术界最火热的话题之一&#xff0c;数据已经成为每个公司极为重要的资产。互联网大量的公开数据为个人和公司提供了以往想象不到的可以获取的数据量。而掌握网络爬虫技术可以帮助你获取这些有用的公开数据集。 爬虫能干什么呢&#xff1f;一…

11-GraalVM元原生时代的Java虚拟机

文章目录 GraalVM诞生的背景Java在微服务/云原生时代的困境事实矛盾 问题根源Java离不开虚拟机 解决方案革命派保守派 GraalVM入门GraalVM特征GraalVM下载和安装GraalVM下载win10安装及配置linux安装及配置 GraalVM初体验(Linux)多语言开发(了解即可、官网有Demo)GraalCompiler…

无人叉车驻车定位RFID传感器CNS-RFID-01|1S的CAN总线通信连接方法

无人叉车驻车定位RFID传感器CNS-RFID-01|1S支持CAN总线通信方式&#xff0c;广泛应用于智能仓库&#xff0c;AGV |RGV小车&#xff0c;无人叉车&#xff0c;搬运机器人定位&#xff0c;驻车等领域&#xff0c;本篇幅主要介绍器CNS-RFID-01|1S RFID传感器的CAN总线通信连接方法。…

“双十一、二” 业务高峰如何扛住?韵达快递选择 TDengine

小 T 导读&#xff1a; 为了有效处理每日亿级的数据量&#xff0c;早在 2021 年&#xff0c;韵达就选择用 TDengine 替代了 MySQL&#xff0c;并在三台服务器上成功部署和上线了 TDengine 2.0 集群。如今&#xff0c;随着 TDengine 3.0 版本的逐渐成熟&#xff0c;韵达决定将现…

NAT协议的实现方式

在网络通信中&#xff0c;NAT协议&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09;扮演着关键角色&#xff0c;允许内部网络与外部网络之间进行有效的通信。 实现内外网之间网络地址转换的过程中&#xff0c;NAT采用了不同的实现方式&#xff0c;…

案例分析:三一重工集团数字化转型

三一重工集团&#xff0c;作为制造业中的数字化转型佼佼者&#xff0c;荣获“全球灯塔工厂”的殊荣&#xff0c;率先采用了物联网、云计算、大数据等尖端技术手段。数字化转型让三一重工步入了全面信息化的管理时代&#xff0c;通过ERP、CRM、HRM等系统的协同运作&#xff0c;实…

高度可定制的JS电子表格组件DHTMLX Spreadsheet v5.1——拥有全新内置主题

DHTMLX Spreadsheet是用纯JavaScript编写的开源电子表格小部件&#xff0c;可让您快速在网页上添加类似于Excel的可编辑数据表。高度可定制的JavaScript电子表格组件&#xff0c;具有优雅的Material样式&#xff0c;可安全、方便地编辑和格式化数据。 近日DHTMLX Spreadsheet …