(1) 今回やりたいこと(概要)
個人情報(名前・住所など)をバリバリに含むテキストデータを、クラウドAIサービスに投げる前に、ローカル環境で個人情報をマスキングして隠す処理を施す。
利用客の山田太郎様が世田谷区から来られて、一泊二日されました。
↓
利用客の●●●●様が●●から来られて、一泊二日されました。
(2) 経緯
ChatGPT、便利ですよね。
LLM系に限らず、世の中便利なAIサービスが多数出てきているので、色々なデータを喰わせてみて、どのような活用ができるか探るのはとても楽しいことです。
でも、手元のデータに個人情報が含まれる場合は、気の赴くまま気軽にやっちゃいけません。うっかりすると個人情報保護違反になる恐れが。
信頼できるAIサービス業者に委ねればいい。そういう考え方もありますね。
例えばChatGPT系だと、本家OpenAI社やAzure経由でサービス提供しているMicrosoft社は、ユーザから受け取ったデータをAI学習に利用しない(=外部に漏洩させない)というオプション規約を用意しています。注意してデータを委ねれば、データの安全性は守られると見込まれます。
しかし絶対安全安心ではありません。先方のプログラムのバグや、設定ミスや、悪意ある内部犯によって、預けたサービスが外部に流出してしまう可能性は、常に考えておくべきです。
実際に、一部の企業や行政がChatGPTの活用に当たって業務機密や個人情報を含むデータでの利用を禁止するルールを定めていますが、そういうことだと思います。
ということで、ローカル環境で一旦データを処理して、危ないデータを消す方法になります。
組織が保有する個人情報データについては、当該組織の然るべき部署に事前に相談をした上で、慎重に行いましょう。
100%完全完璧な個人情報除去ができるものではありません。処理の抜け漏れが無いか、自分の目で最終チェックする必要があります。
個人情報を全部マスキングしても、文脈でどこの誰についての情報か推測できることもあるので、そういうのも気をつけて下さい。
(3)動作環境
- 簡単な python プログラムです(ChatGPT 4 さんが主に作ってくれました)
- 入力されたテキストファイルを形態素解析して、個人情報と思われる種別の単語をマスキングして、出力します
- 日本語の形態素解析に、GiNZA を利用します(https://megagonlabs.github.io/ginza/)
- linux、もしくは、windows の WSL 環境で動きます
(4)環境設定
以下コマンドで、必要なモジュールをインストールします。
(pythonの環境構築と、windows の WSL 環境構築については、別途調べてください)
pip install ginza
pip install spacy
pip install -U ginza ja-ginza
(5)プログラム
1ファイルです。適当なフォルダに、配置して下さい。
import spacy
import argparse
'''
#要件
・テキストに含まれる個人情報を伏せ字に置き換えて、個人情報を含まないテキストとしてクリーニングする
# 動作
1.指定されたテキストファイルを読み込む
2.テキストファイルの文面に含まれる個人情報(名前・住所、等)を検出して、マスキングする
3.マスキングされた処理済みテキストを、テキストファイルとして保存する
# モジュールインストール
pip install ginza
pip install spacy
pip install -U ginza ja-ginza
# コマンド例
python3 mask_personal_info.py input.txt output.txt --entities "名詞-固有名詞-人名-姓", "名詞-固有名詞-人名-名","名詞-固有名詞-地名-一般"
'''
def read_input_file(input_file):
with open(input_file, "r", encoding="utf-8") as f:
return f.read()
def write_output_file(output_file, processed_text):
with open(output_file, "w", encoding="utf-8") as f:
f.write(processed_text)
# text の中の個人情報をマスキングする
# entity_types には、マスキングするエンティティのタイプを指定する
def mask_personal_info(text, entity_types):
nlp = spacy.load("ja_ginza")
doc = nlp(text)
masked_text = ""
for sent in doc.sents:
for token in sent:
if token.tag_ in entity_types:
masked_text += '●●' # token.orth_ をマスキングする
else:
masked_text += token.orth_
return masked_text
def main():
parser = argparse.ArgumentParser(description="Mask personal information in a text file.")
parser.add_argument("input_file", help="Path to the input text file.")
parser.add_argument("output_file", help="Path to the output text file.")
parser.add_argument("--entities", nargs="+", default=["名詞-固有名詞-人名-姓", "名詞-固有名詞-人名-名", "名詞-固有名詞-地名-一般"], help="List of entity types to mask (default: Name Address)")
args = parser.parse_args()
text = read_input_file(args.input_file)
masked_text = mask_personal_info(text, args.entities)
write_output_file(args.output_file, masked_text)
if __name__ == "__main__":
main()
(6)実行のさせかた
-
個人情報マスキングしたいテキストファイルを、プログラムファイルと同じフォルダに、"input.txt" というファイル名で保存します。
-
以下のコマンドで、プログラムを動作させます。
python3 mask_personal_info.py input.txt output.txt --entities "名詞-固有名詞-人名-姓", "名詞-固有名詞-人名-名","名詞-固有名詞-地名-一般"
- 処理結果は、同じフォルダに "output.txt" として保存されます。
(デフォルトでは、【人名】【地名】の2種類をマスキング対象としていますが、対象データに合わせて他種別の単語もマスキング可能です。--entities の項目を調整してみて下さい)
(クレジットカード番号や顧客IDみたいなのは、別途、正規表現パターンでも使ってマスキングするのが良いかと思います)
(7)注意
組織が保有する個人情報データについては、当該組織の然るべき部署に事前に相談をした上で、慎重に行いましょう。
100%完全完璧な個人情報除去ができるものではありません。処理の抜け漏れが無いか、自分の目で最終チェックする必要があります。
個人情報を全部マスキングしても、文脈でどこの誰についての情報か推測できることもあるので、そういうのも気をつけて下さい。