【HuggingFace】基于检索策略的隐私政策标注应用

数据源:https://github.com/EnlightenedAI/CAPP-130
注意在数据源的链接中原作者自己也训练了一个用以标注隐私政策信息的模型,有兴趣可以去看一下。
hugging-face上的Space:https://huggingface.co/spaces/ThornRugal/ChinesePrivacyPolicyMark

注意由于我没有花钱租GPU,hugging-face上的这个应用使用的CPU版本的,跑起来很慢,尽量不要输入整个隐私政策文档。有条件的可以直接clone到本地使用GPU跑。

现在注册网站都需要同意隐私政策才可以注册,然而隐私政策条文过于复杂冗余让人难以阅读而且用户急于进入应用,因此有很多人都是直接勾选“已经阅读并同意xx政策”。然而这一之前也有迪士尼在合同中暗藏“不允许以任何理由在法律上控告迪士尼公司”的“霸王条款”。虽然不是隐私政策条款,但是也侧面证明了,在注册账号前详细查看各个条款是有必要的。在这一数据集中,包含130个来自流行应用的中文隐私政策,这些政策由法律专家进行标注,甚至还有许多的重写句子。该数据集旨在帮助用户理解和总结隐私政策,以保护个人隐私信息。本次的任务,就是利用数据集做一个自动标注隐私数据的应用。

问题分析

在数据集中,标注者将以下多个标签打入隐私政策的句子中:

'使用','停止运营','共享、委托、转让、公开(披露)','存储方式','安全措施','摘要','数据、权限管理','数据收集','权限获取','潜在风险','特殊人群','联系方式','隐私政策的授权、修改与变更'

每句句子可能不包含任何标签,也可能包含多个标签。诚然,我们可以将它作为一个分类问题,一共13个子问题(是否有“使用”标签,是否有“停止运营”标签……),如果将他们使用一个单独的分类模型需要做13个输出,且会面临模型过于复杂、数据失衡、决策边界模糊等问题;而如果对13个子问题分别建模,则又会大大增加模型的维护成本。(数据源的提供者训练了一个可以用以检测“潜在风险”的二分类模型。)因此,笔者使用了一个更为简易的策略:直接将所有标注好的数据序列化后保存,有新数据时将其与保存的数据进行对比,将与它最接近的标签拿出作为预测结果。这样的策略尽管可能准确率上比作为分类任务时来的要差,但是胜在简单快捷,连fine-tune都不需要,速度与能耗上更为优秀。

标注策略

零、模型流程

我们集合所有标签非空的句子,将它们作为字典存储,对于每个键(句子),使用特征筛选模型将其序列化,变为多个向量。当有新的句子进来后,使用特征筛选模型序列化句子得到一个新的向量,筛选出离新最近的那n个向量获得n条备选句子。之后将新句子与n条备选句子输入句子相似度模型进行对比,再精筛出m条句子,将它们对应的标签融合作为输入语句的标签。

一、数据准备

首先我们将jsonl格式的语句转化为pandas.DataFrame格式

import pandas as pd
import os

data = pd.DataFrame(columns=["task","id","text","label","rewrite"])
file_dir = "./CAPP_130_Corpus/Annotation/Annotation/"
for file in os.listdir(file_dir):
    pth = file_dir+file
    tmp = pd.read_json(pth,lines=True)
    data = pd.concat([data,tmp],axis=0).reset_index(drop=True)

data.to_excel("data_Excel_format.xlsx",index=None)

我们读取保存好的Excel文件,并筛选其中的一部分作为验证集。注意保存为Excel文件后list对象会被当做字符串,需要手动将其转化回来。将训练集以及总体数据的分别筛选标签非空的部分保存备用。

import warnings
warnings.filterwarnings("ignore")

import pandas as pd
from sklearn.model_selection import train_test_split
import numpy as np
from itertools import islice
import faiss
import os
import ast
import json

data_all = pd.read_excel("data_Excel_format.xlsx")
def get_not_empty_data(df,x_column="text",y_column="label"):
    df = df[df[y_column] != "[]"].reset_index(drop=True)
    res_dict = {}
    for idx in df.index:
        if df.loc[idx,x_column] not in res_dict:
            res_dict[df.loc[idx,x_column]] = ast.literal_eval(df.loc[idx,y_column])
        else:
            res_dict[df.loc[idx,x_column]] += ast.literal_eval(df.loc[idx,y_column])
    res_dict = {k:list(set(v)) for k,v in res_dict.items()}
    df_dict = pd.DataFrame({"x":res_dict.keys(),"y":res_dict.values()})
    return df_dict

df_dict_all = get_not_empty_data(data_all)
df_dict_all.to_excel("data_not_empty.xlsx",index=None)
train_tasks = {f"rw_{i+1}.jsonl" for i in range(int(data_all["task"].nunique()*0.8))}
x_train = data_all[data_all["task"].isin(train_tasks)]["text"].values
y_train = data_all[data_all["task"].isin(train_tasks)]["label"].values

x_valid = data_all[~data_all["task"].isin(train_tasks)]["text"].values
y_valid = data_all[~data_all["task"].isin(train_tasks)]["label"].values

df_train = pd.DataFrame({"x":x_train,"y":y_train})
df_valid = pd.DataFrame({"x":x_valid,"y":y_valid})
df_dict_train = get_not_empty_data(df_train,x_column="
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值