对数据集进行k匿名(k-Anonymity)处理(python)——以adult数据集为例

这篇具有很好参考价值的文章主要介绍了对数据集进行k匿名(k-Anonymity)处理(python)——以adult数据集为例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

k匿名(k-Anonymity)

k匿名技术参考论文:L.Sweeney. Achieving k-anonymity privacy protection using generalization and suppression. International Journal on Uncertainty, Fuzziness and Knowledge-based Systems,10(5), 2002; 571-588.

其中对于k匿名的定义如下:

对数据集进行k匿名(k-Anonymity)处理(python)——以adult数据集为例

 对于一个数据集的不同属性,或者说,不同列。可以根据其作用粗略划分为三种,标识符,准标识符,与隐私数据。

标识符能够唯一确定一项数据,而不同准标识符的组合也可能可以确定一项数据。而隐私数据顾名思义,是隐私保护的对象。

标识符举例
身份证号 性别 家庭住址 所得疾病
123456789 xx市xx街道xx小区 某传染病

例如上表,身份证号即是标识符,而性别和家庭住址可以作为准标识符,他们具备一定的信息,并且组合在一起之后有可能可以确定这一条数据的所有者。而所得疾病即是我们需要保护的隐私信息。

k匿名需要满足的条件就是,对于准标识符的任意组合,搜索出来的结果都需要至少有k条。

例如,上表中以(性别,家庭住址)为准标识符,那么以(男,xx市xx街道xx小区)为条件,去数据集中搜索,最终得到至少k条数据,类似的,用其他任何可能的条件去搜索,最终得到的数据条数都大于等于k,那么就说这个数据集满足k匿名。

 精确度的计算

论文中对于精确度的定义如下:

对数据集进行k匿名(k-Anonymity)处理(python)——以adult数据集为例

 我个人认为这个公式应当翻译成:

prec=1-(各个准标识符的泛化程度(当前高度h/总泛化树高度)之和)/(准标识符个数)

adult数据集

数据集官方网址:UCI Machine Learning Repository: Adult Data Set

对于数据集的介绍引用自

云隐雾匿 的 Adult数据集分析(一)

Adult数据集(即“人口普查收入”数据集),由美国人口普查数据集库 抽取而来,其中共包含48842条记录,年收入大于50k美元的占比23.93%,年收入小于50k美元的占比76.07%,并且已经划分为训练数据32561条和测试数据16281条。 该数据集类变量为年收入是否超过50k美元,属性变量包括年龄、工种、学历、职业等 14类重要信息,其中有8类属于类别离散型变量,另外6类属于数值连续型变量。该数据集是一个分类数据集,用来预测年收入是否超过50k美元。

该数据集总共15列,包括14个属性与一个结论。

结论的取值为字符串,仅有两个:' >50K'和' <=50K'。

注意,该数据集中的每个字符串前面都有一个空格。

全部属性标签如下:

#属性标签
attributeLabels =["age",              #0年龄            int64    
                  "workclass",        #1工作类型        object   
                  "fnlwgt",           #2人口特征权重    int64    
                  "education",        #3学历            object   
                  "education_num",    #4受教育时间      int64    
                  "marital_status",   #5婚姻状态        object   
                  "occupation",       #6职业            object   
                  "relationship",     #7关系            object   
                  "race",             #8种族            object   
                  "sex",              #9性别            object   
                  "capital_gain",     #10资本收益        int64    
                  "capital_loss",     #11资本损失        int64    
                  "hours_per_week",   #12每周工作小时数  int64    
                  "native_country",   #13原籍            object   
                  "wage_class"]       #14收入类别        object    

对于第三个属性‘fnlwgt’,网上众说纷纭,有说是什么信息录入员编号的(然而实际数据长短不一,不太可能),又说代表这条数据真正的人数的(计算之后大概60多亿,也不太可能)。

感觉都不对,不过官方文档adult.names中有给出解释:

对数据集进行k匿名(k-Anonymity)处理(python)——以adult数据集为例

根据最后一段可以看出这个所谓“最终权重”应当包含了人口特征信息,具体包含哪些信息则可以参考上文给出的 3 sets of controls。

 但是最后一句话有说,这个权重数据尽在州内适用,然而这个数据集中汇聚了全部51个州的数据,所以如果我没有翻译错的话,这个人口特征权重(fnlwgt)实际上不具备参考价值。

代码实现

1.导入包与导入一些字符串配置

import numpy as np
import pandas as pd


#配置信息
#数据集文件路径
censusData_FilePath='data/adult.data'
#属性标签
attributeLabels =["age",              #0年龄            int64    
                  "workclass",        #1工作类型        object   
                  "fnlwgt",           #2人口特征权重    int64    
                  "education",        #3学历            object   
                  "education_num",    #4受教育时间      int64    
                  "marital_status",   #5婚姻状态        object   
                  "occupation",       #6职业            object   
                  "relationship",     #7关系            object   
                  "race",             #8种族            object   
                  "sex",              #9性别            object   
                  "capital_gain",     #10资本收益        int64    
                  "capital_loss",     #11资本损失        int64    
                  "hours_per_week",   #12每周工作小时数  int64    
                  "native_country",   #13原籍            object   
                  "wage_class"]       #14收入类别        object    


#准标识符
quasi_identifier_list=[]
quasi_identifier_DGH_list=[]
quasi_identifier_VGH_list=[]
quasi_identifier_height_list=[]

2.引入准标识符信息

泛化树通过父母节点表示法存储在数组中,这样就能够快速地找到每个节点的父母节点,同时为了方便计算,增加高度项,代表当前节点在泛化树中的高度。

例如,工作类型的泛化树如下:

对数据集进行k匿名(k-Anonymity)处理(python)——以adult数据集为例

 由于后续使用了replace这个函数,所以标签的字符串不能一致,加上了hx作为后缀,x为层高。

#marital-status属性标签
marital_attributeLabels=['***',                        #0抑制标签
                         'Married-h2',                 #1已婚
                         'Alone',                      #2独自一人
                         'Married-h1',                 #3已婚
                         'Single',                     #4单身 
                         'Widowhood',                  #5鳏寡
                         'Married-civ-spouse',         #已婚-公民-配偶
                         'Married-AF-spouse',          #已婚-无房-配偶
                         'Separated',                  #分居
                         'Divorced',                   #离婚
                         'Never-married',              #未婚
                         'Widowed',                    #寡居
                         'Married-spouse-absent'       #已婚-配偶-不在
                        ]
#marital-status的泛化树
vgh_marital=pd.DataFrame({'value': marital_attributeLabels,
                          'parent':[-1,0,0,1,2,2,3,3,3,4,4,5,5],
                          'height':[3,2,2,1,1,1,0,0,0,0,0,0,0]})

quasi_identifier_list.append(attributeLabels[5])        #将marital-status设置为准标识符
quasi_identifier_DGH_list.append(3)
quasi_identifier_VGH_list.append(vgh_marital)
quasi_identifier_height_list.append(0)

print(vgh_marital)

另外再加两个准标识符,种族与婚姻状况。

#race属性标签
race_attributeLabels =[ '***',                        #0抑制标签
                        'White-h1',                   #1白人
                        'Non-White',                  #2非白人
                        'White',                      #3白人
                        'Asian-Pac-Islander',         #亚洲-太平洋-伊斯兰人
                        'Amer-Indian-Eskimo',         #美洲-印第安人-爱斯基摩人
                        'Other',                      #其他
                        'Black'                       #黑人
                      ]
#workclass的泛化树
vgh_race=pd.DataFrame({'value': race_attributeLabels,
                       'parent':[-1,0,0,1,2,2,2,2],
                       'height':[2,1,1,0,0,0,0,0]})

quasi_identifier_list.append(attributeLabels[8])        #将workclass设置为准标识符
quasi_identifier_DGH_list.append(2)
quasi_identifier_VGH_list.append(vgh_race)
quasi_identifier_height_list.append(0)

print (vgh_race)
#marital-status属性标签
marital_attributeLabels=['***',                        #0抑制标签
                         'Married-h2',                 #1已婚
                         'Alone',                      #2独自一人
                         'Married-h1',                 #3已婚
                         'Single',                     #4单身 
                         'Widowhood',                  #5鳏寡
                         'Married-civ-spouse',         #已婚-公民-配偶
                         'Married-AF-spouse',          #已婚-无房-配偶
                         'Separated',                  #分居
                         'Divorced',                   #离婚
                         'Never-married',              #未婚
                         'Widowed',                    #寡居
                         'Married-spouse-absent'       #已婚-配偶-不在
                        ]
#marital-status的泛化树
vgh_marital=pd.DataFrame({'value': marital_attributeLabels,
                          'parent':[-1,0,0,1,2,2,3,3,3,4,4,5,5],
                          'height':[3,2,2,1,1,1,0,0,0,0,0,0,0]})

quasi_identifier_list.append(attributeLabels[5])        #将marital-status设置为准标识符
quasi_identifier_DGH_list.append(3)
quasi_identifier_VGH_list.append(vgh_marital)
quasi_identifier_height_list.append(0)

print(vgh_marital)

如果还要增加其他准标识符的话,以类似的格式加上就可以了。但是数值型属性需要先分段,不能直接使用。

3.导入数据集与初步处理

这个数据集有2个要处理的地方,首先是缺失值表示为‘ ?’,需要转化为NAN以便处理,然后是字符串的前端会有一个空格,需要去除。

对于有缺失值的数据,由于个数不多,大概2000+条,所以直接删去。

#导入数据集
censusData_Set=pd.read_csv(censusData_FilePath,names=attributeLabels)

# 将缺失值部分的“ ?” 置为空,即 np.NaN,便于使用pandas来处理缺失值
censusData_Set = censusData_Set.replace(" ?", np.NaN)

#类型为字符串的标签
attributeLabels_str=["workclass","education", "marital_status","occupation",
                     "relationship","race","sex","native_country","wage_class"]  
#删除数据值前的空格
for label in attributeLabels_str:
    censusData_Set[label] = censusData_Set[label].str.strip()

#删除包含缺失值的行
censusData_Set.dropna(inplace=True)
#重置索引
censusData_Set.reset_index(drop=True, inplace=True)

4.检查数据集是否满足k匿名

将所有出现过的准标识符组合存入字典并计数,最后字典中个数最小的项如果数量大于等于k,显然就满足k匿名。

#检验是否满足k匿名

#将所有准标识符的组合存入字典,值为出现次数。
def group_data(testedSet):
    quasiDict = {}
    for item in testedSet.itertuples():
        #--------------------------------------------------------------
        #将准标识符转化为字符串
        item_statement=''
        for label in quasi_identifier_list:
            item_statement=item_statement+getattr(item,label)+' '
        #--------------------------------------------------------------
        #如果该准标识符组合已经出现过了,则计数+1
        if item_statement in quasiDict.keys():
            quasiDict[item_statement] += 1
        #如果该准标识符组合没有出现过,则新建记录
        else:
            quasiDict[item_statement]=1
    #返回字典
    return quasiDict

#判断数据集testedSet是否满足k匿名,是则返回true,否则返回false
def if_k(testedSet,k):
    #对数据集进行分组,获得组合数量
    ans_dict=group_data(testedSet)
    #-----------------------------------------------------------------
    #展示准标识符组合
    print('')
    print (ans_dict)
    print('')
    #-----------------------------------------------------------------
    min_k=None
    #遍历分组字典,取出最小的重复个数,赋值给min_k
    for i in ans_dict:
        if min_k is None or ans_dict[i]<min_k :
            min_k=ans_dict[i];
    #如果字典的最小k值大于等于给定的k值,则满足k匿名
    if min_k>=k:
        return True
    else:
        return False

5.泛化

父母节点数组存储的泛化树容易得到节点的父母节点,因此泛化的代码比较容易。用节点的父母节点替换本节点即可。

#对数据集tempDataSet(dataframe)的属性列attr(String)进行泛化
#vgh(dataframe)是泛化树
def Generalization_attr(tempDataSet, attr, vgh, h):
    for index,row in vgh.iterrows():
        if row.height==h:
            tempDataSet.replace({attr:row.value},vgh.loc[row.parent].value,inplace=True)
    

6.运行主函数

输入为:数据集censusData_Set;k匿名需要满足的k值k_Anonymity;

输出为:泛化后满足k匿名的数据集censusData_Set;精确度prec;文章来源地址https://www.toymoban.com/news/detail-445805.html


#演示取值:16000;2;15;140
k_Anonymity=15

#泛化次数计数,初始化为所有准标识符泛化次数之和
gen_count=0
for index in range(len(quasi_identifier_DGH_list)):
    gen_count+=quasi_identifier_DGH_list[index]


while if_k(censusData_Set,k_Anonymity) is False:
    for index in range(len(quasi_identifier_list)):
        #如果已经到达了泛化顶点
        if quasi_identifier_height_list[index]>=quasi_identifier_DGH_list[index]:
            continue
        #-----------------------------------------------------------------
        #泛化
        Generalization_attr(censusData_Set,
                            quasi_identifier_list[index],
                            quasi_identifier_VGH_list[index],
                            quasi_identifier_height_list[index])
        #-----------------------------------------------------------------
        #泛化次数-1
        gen_count-=1
        #泛化高度+1
        quasi_identifier_height_list[index]+=1
        if if_k(censusData_Set,k_Anonymity):
            break
    print ('当前泛化高度:')
    for index in range(len(quasi_identifier_list)):
        print(quasi_identifier_list[index]+':'+str(quasi_identifier_height_list[index]))
    #直至无法泛化
    if gen_count==0:
        print('泛化失败')
        break
        
print ('当前泛化高度:')
for index in range(len(quasi_identifier_list)):
    print(quasi_identifier_list[index]+':'+str(quasi_identifier_height_list[index]))

print('当前k值为:')
print(k_Anonymity)
print ('精确度为:')
prec=0
for index in range(len(quasi_identifier_list)):
    prec+=(quasi_identifier_height_list[index])/(quasi_identifier_DGH_list[index])
prec=1-(prec/len(quasi_identifier_list))

print (prec)

到了这里,关于对数据集进行k匿名(k-Anonymity)处理(python)——以adult数据集为例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Adult数据集分析(一)

    目录 一、研究意义 二、数据集介绍         样本属性及含义 三、数据预处理  (1)模型选择 (2)数据导入 (3)数据删除与清洗 (4)数据转化 (5)重点部分 (6)划分训练集与测试集 四、两种模型对上述数据集进行预测 决策树 朴素贝叶斯 五、结果分析 如果我们知

    2023年04月08日
    浏览(27)
  • Python爬虫进阶:使用Scrapy库进行数据提取和处理

    在我们的初级教程中,我们介绍了如何使用Scrapy创建和运行一个简单的爬虫。在这篇文章中,我们将深入了解Scrapy的强大功能,学习如何使用Scrapy提取和处理数据。 在Scrapy中,提取数据主要通过Selectors来完成。Selectors基于XPath或CSS表达式的查询语言来选取HTML文档中的元素。你

    2024年02月09日
    浏览(47)
  • Python数据分析与应用 |第4章 使用pandas进行数据预处理 (实训)

    编号 性别 高血压 是否结婚 工作类型 居住类型 体重指数 吸烟史 中风 9046 男 否 是 私人 城市 36.6 以前吸烟 是 51676 女 否 是 私营企业 农村 N/A 从不吸烟 是 31112 男 否 是 私人 农村 32.5 从不吸烟 是 60182 女 否 是 私人 城市 34.4 抽烟 是 1665 女 是 是 私营企业 农村 24 从不吸烟 是

    2024年04月23日
    浏览(43)
  • OK3588运行python程序对摄像头数据进行图像处理

    把usb摄像头插入HOST的usb接口。 在串口终端运行 sudo v4l2-ctl --list-devices 如下图 当前的usb设备是 /dev/video74 远程访问开发板 用cheese打开/dev/video74 运行 cheese /dev/video74 运行结果如图 说明usb摄像头工作正常。 安装必要的软件包 sudo apt-get install python3-opencv -y sudo apt-get install python3-

    2024年02月16日
    浏览(41)
  • Python用pandas进行大数据Excel两文件比对去重300w大数据处理

    Python用pandas进行大数据Excel两文件比对去重 通俗理解有两个excel文件 分别为A和B 我要从B中去掉A中含有的数据, 数据量大约在300w左右 因为数据量较大,无论是wps还是office自带的去重都无法正常使用这样就需要用到脚本了  欢迎大家指导交流,共同学习,共同进步!

    2024年02月15日
    浏览(67)
  • 如何使用Python的Open3D开源库进行三维数据处理

    在本文中,我提供了一个关于如何使用Python的Open3D库(一个用于3D数据处理的开源库)来探索、处理和可视化3D模型的快速演练。 使用Open3D可视化的3D模型(链接https://sketchfab.com/3d-models/tesla-model-s-plaid-9de8855fae324e6cbbb83c9b5288c961处可找到原始3D模型) 如果您正在考虑处理特定任务

    2024年02月04日
    浏览(51)
  • 面向人群属性关系挖掘的数据可视化———基于美国人口adult数据集

    目录 面向人群属性关系挖掘的数据可视化 一、课程设计内容及目的 二、总体设计 (一)题目需求分析 (二)系统整体流程图或组成框图 三、详细设计 (一)读取数据并导入需要的第三方库 (二)通过判断每个属性的取值范围来估计属性及其类型 (三)除去数据值前的空

    2024年02月10日
    浏览(48)
  • 机器学习实验1——朴素贝叶斯和逻辑回归分类Adult数据集

    基于Adult数据集,完成关于收入是否大于50K的逻辑回归分类、朴素贝叶斯模型训练、测试与评估。 认识数据 14个特征变量如下 1个目标变量:Income:50K 或 50K 填充缺失值(“ ?”) 统计各类型数据缺失个数如下,这三种缺失数据类型均为离散型(discrete),因此采用众数填充较

    2024年01月23日
    浏览(48)
  • 利用Python进行数据清洗与预处理:Pandas的高级用法【第147篇—Pandas的高级用法】

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在数据科学和机器学习领域,数据清洗和预处理是至关重要的步骤。Pandas库作为Python中最受欢迎的数据处理工具之一,提供了强大的功能来处

    2024年04月09日
    浏览(105)
  • 使用比特币进行匿名交易和交易追溯

    题目:假设你是A国情报机关,需要给在J国执行任务的谍报人员提供活动经费,请问使用比特币如何操作才能躲过J国反谍机构的追查?J国反谍机构如何才能查出你的谍报人员?分别给出你的解决方案和J国反谍机构的解决方案。 比特币交易本质上是公开的,每一笔交易都在区

    2024年02月05日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包