見出し画像

SentencePiece 入門

「Google Colab」で「SentencePiece」を試してみました。

1. SentencePiece

SentencePiece」は、テキストを「サブワード」に分割するツールです。

自然言語処理」の深層学習を行うには、テキストを何かしらの「トークン」に分割し、それを「ベクトル表現」に変換する必要があります。

以前は、「MeCab」の形態素解析を使ってテキストを「単語」に分割するのが一般的でした。しかし「単語」を使うのは実用上の問題点があります。語彙数が膨大になり、高頻度語彙のみに限定したとしても、低頻度語彙が捨てられ未知語として扱われることになります。

SentencePiece」では「サブワード」を使ってこの問題を解決しています。はじめに、テキストを単語に分割し、各単語の頻度を求めます。次に、高頻度単語は1語彙として扱い、低頻度単語はより短い語彙に分割します。そして、語彙数が事前に指定した数になるまで、分割を繰り返します。これによって、語彙数を小さくしつつ、未知語をなくすことを可能にしています。

2. SentencePieceのインストール

SentencePieceのインストール方法は、次のとおりです。

# SentencePieceのインストール
!pip install sentencepiece

3. Google Driveのマウント

「Google Drive」にマウントします。

# Google Driveのマウント
from google.colab import drive
drive.mount('/content/drive')

そして、「Google Drive」の「Colab Notebooks」フォルダに移動します。

# Google DriveのColab Notebooksフォルダへの移動
%cd "drive/My Drive/Colab Notebooks"

4. SentencePieceの学習

「SentencePiece」はニューラルネットワークベースで、サブワード分割を行うには、事前に大量のテキストデータでの「教師なし学習」が必要になります。これによって、サブワードとなる「語彙テーブル」を学習します。

5. テキストデータの準備

今回は、Wikipediaの小説家の記事を使います。

import codecs
import re
import requests
from bs4 import BeautifulSoup

# URLとキーワードリスト
url = "https://ja.wikipedia.org/wiki/"
keyword_list = [
    "中島敦", "太宰治", "国木田独歩",
    "江戸川乱歩", "谷崎潤一郎", "宮沢賢治",
    "与謝野晶子", "芥川龍之介", "樋口一葉",
    "中原中也", "尾崎紅葉", "梶井基次郎",
    "夢野久作", "森鷗外", "織田作之助"   
]

# Wikipediaの小説家の記事のダウンロード
corpus = []
for keyword in keyword_list:
    response = requests.get(url + keyword)
   
    soup = BeautifulSoup(response.text, 'lxml')
    for p_tag in soup.find_all('p'):
        # 空白の削除
        text = "".join(p_tag.text.strip().split(" "))

        # 空行は無処理
        if len(text) == 0:
            continue

        # 注釈の削除 (例: [注釈1], [注釈1], [1])
        text = re.sub(r"\[注釈[0-9]+\]", "", text)
        text = re.sub(r"\[注[0-9]+\]", "", text)
        text = re.sub(r"\[[0-9]+\]", "", text)

        # 行の追加
        corpus.append(text)

# ファイルの保存       
print(*corpus, sep="\n", file=codecs.open("wiki.txt", "w", "utf-8"))

「Colab Notebooks」フォルダに「wiki.txt」が生成されます。

中島敦(なかじまあつし、1909年(明治42年)5月5日-1942年(昭和17年)12月4日)は、日本の小説家。代表作は『山月記』『光と風と夢』『弟子』『李陵』など。第一高等学校、東京帝国大学を卒業後、横浜高等女学校の教員勤務のかたわら小説執筆を続け、パラオ南洋庁の官吏(教科書編修書記)を経て専業作家になるも、同年中に持病の喘息悪化のため33歳で病没。死後に出版された全集は毎日出版文化賞を受賞した。
その短い生涯に残した著作は、中国古典の歴史世界を題材にした作品や、南島から材を得た作品、古代伝説の体裁をとった奇譚・寓意物、自身の身辺を題材にした私小説的なものなど、未完作も含めわずか20篇たらずであったが、漢文調に基づいた硬質な文章の中に美しく響く叙情詩的な一節が印象的で、冷厳な自己解析や存在の哲学的な懐疑に裏打ちされた芸術性の高い作品として評価されている。
特に遺作となった『李陵』の評価は高く、死後に名声を上げた作品のひとつとして知られている。また、『山月記』は雑誌『文學界』に掲載されたことで中島敦の名を初めて世間に知らしめた作品であり、のちに新制高等学校の国語教科書に広く掲載され、多くの人々に読み継がれている。なお、自筆資料や遺品は神奈川近代文学館の「中島敦文庫」に所蔵されている。
    :

6. 学習の実行

学習の実行のコードは、次のとおりです。

import sentencepiece as spm

# 学習の実行
spm.SentencePieceTrainer.Train(
   '--input=wiki.txt --model_prefix=sentencepiece --vocab_size=8000 --character_coverage=0.9995'
)

モデル」(sentencepiece.model)と「語彙テーブル」(sentencepiece.vocab)が生成されます。

<unk>	0
<s>	0
</s>	0
<pad>	0
、	-2.94898
の	-3.01888
。	-3.42797
に	-4.18738
を	-4.30927
    :

学習のパラメータは、次のとおりです。

・--input : テキストデータのパス(1文が1行)
--model_prefix : 出力ファイル名。
--vocab_size : 語彙数。小規模は数千から10k、超大規模は32k程度。
--character_coverage : モデルがカバーする語彙割合。1.0で100%カバー。日本語は0.9995推奨。
--model_type : モデル種別 (unigram(デフォルト), bpe)

7. テキストの分割

◎ モデルの作成
モデルを作成します。

import sentencepiece as spm

# モデルの作成
sp = spm.SentencePieceProcessor()
sp.Load("sentencepiece.model")

◎ テキストを語彙に分割

# テキストを語彙列に分割
print(corpus[0])
print(sp.EncodeAsPieces(corpus[0]))
中島敦(なかじまあつし、1909年(明治42年)55-1942年(昭和17年)124日)は、日本の小説家。代表作は『山月記』『光と風と夢』『弟子』『李陵』など。第一高等学校、東京帝国大学を卒業後、横浜高等女学校の教員勤務のかたわら小説執筆を続け、パラオ南洋庁の官吏(教科書編修書記)を経て専業作家になるも、同年中に持病の喘息悪化のため33歳で病没。死後に出版された全集は毎日出版文化賞を受賞した。
['▁', '中島敦', '(', 'なか', 'じ', 'ま', 'あ', 'つ', 'し', '、190', '9', '年', '(', '明治', '4', '2', '年', ')', '5', '月', '5', '日', '-194', '2', '年', '(', '昭和', '17', '年', ')', '12', '月', '4', '日', ')', 'は', '、', '日本の小説家', '。', '代表作', 'は', '『', '山月記', '』『', '光と風と夢', '』『', '弟子', '』『', '李陵', '』', 'など', '。', '第一高等学校', '、', '東京帝国大学', 'を', '卒業後', '、', '横浜高等女学校', 'の', '教員', '勤務', 'の', 'かたわら', '小説', '執筆', 'を続け', '、', 'パラオ南洋庁', 'の', '官', '吏', '(', '教科書', '編修書記', ')', 'を経て', '専業作家', 'になる', 'も', '、', '同年', '中', 'に持病の', '喘息悪化', 'のため', '33', '歳で病没', '。', '死後', 'に', '出版された', '全集', 'は', '毎日出版文化賞を受賞し', 'た', '。']

◎ テキストを語彙IDに分割

# テキストを語彙IDに分割
print(corpus[0])
print(sp.EncodeAsIds(corpus[0]))
中島敦(なかじまあつし、1909年(明治42年)5月5日-1942年(昭和17年)12月4日)は、日本の小説家。代表作は『山月記』『光と風と夢』『弟子』『李陵』など。第一高等学校、東京帝国大学を卒業後、横浜高等女学校の教員勤務のかたわら小説執筆を続け、パラオ南洋庁の官吏(教科書編修書記)を経て専業作家になるも、同年中に持病の喘息悪化のため33歳で病没。死後に出版された全集は毎日出版文化賞を受賞した。
[22, 343, 11, 989, 218, 340, 202, 119, 27, 650, 52, 10, 11, 51, 36, 30, 10, 13, 41, 21, 41, 29, 2678, 30, 10, 11, 54, 196, 10, 13, 72, 21, 36, 29, 13, 12, 4, 1212, 6, 963, 12, 16, 400, 110, 694, 110, 539, 110, 702, 15, 40, 6, 1644, 4, 1937, 8, 1240, 4, 3888, 5, 2277, 656, 5, 1886, 79, 634, 2185, 4, 5353, 5, 267, 7811, 11, 1009, 6005, 13, 1070, 6418, 635, 23, 4, 283, 71, 5423, 5452, 280, 1255, 6168, 6, 993, 7, 3490, 268, 12, 5022, 24, 6]

◎ 語彙列をテキストに変換

# 語彙列をテキストに変換
tokens = ['▁', '中島敦', '(', 'なか', 'じ', 'ま', 'あ', 'つ', 'し', '、190', '9', '年', '(', '明治', '4', '2', '年', ')', '5', '月', '5', '日', '-194', '2', '年', '(', '昭和', '17', '年', ')', '12', '月', '4', '日', ')', 'は', '、', '日本の小説家', '。', '代表作', 'は', '『', '山月記', '』『', '光と風と夢', '』『', '弟子', '』『', '李陵', '』', 'など', '。', '第一高等学校', '、', '東京帝国大学', 'を', '卒業後', '、', '横浜高等女学校', 'の', '教員', '勤務', 'の', 'かたわら', '小説', '執筆', 'を続け', '、', 'パラオ南洋庁', 'の', '官', '吏', '(', '教科書', '編修書記', ')', 'を経て', '専業作家', 'になる', 'も', '、', '同年', '中', 'に持病の', '喘息悪化', 'のため', '33', '歳で病没', '。', '死後', 'に', '出版された', '全集', 'は', '毎日出版文化賞を受賞し', 'た', '。']
print(sp.DecodePieces(tokens))
中島敦(なかじまあつし、1909年(明治42年)5月5日-1942年(昭和17年)12月4日)は、日本の小説家。代表作は『山月記』『光と風と夢』『弟子』『李陵』など。第一高等学校、東京帝国大学を卒業後、横浜高等女学校の教員勤務のかたわら小説執筆を続け、パラオ南洋庁の官吏(教科書編修書記)を経て専業作家になるも、同年中に持病の喘息悪化のため33歳で病没。死後に出版された全集は毎日出版文化賞を受賞した。

◎ 語彙ID列をテキストに変換

# 語彙ID列をテキストに変換
ids = [22, 343, 11, 989, 218, 340, 202, 119, 27, 650, 52, 10, 11, 51, 36, 30, 10, 13, 41, 21, 41, 29, 2678, 30, 10, 11, 54, 196, 10, 13, 72, 21, 36, 29, 13, 12, 4, 1212, 6, 963, 12, 16, 400, 110, 694, 110, 539, 110, 702, 15, 40, 6, 1644, 4, 1937, 8, 1240, 4, 3888, 5, 2277, 656, 5, 1886, 79, 634, 2185, 4, 5353, 5, 267, 7811, 11, 1009, 6005, 13, 1070, 6418, 635, 23, 4, 283, 71, 5423, 5452, 280, 1255, 6168, 6, 993, 7, 3490, 268, 12, 5022, 24, 6]
print(sp.DecodeIds(ids))
中島敦(なかじまあつし、1909年(明治42年)5月5日-1942年(昭和17年)12月4日)は、日本の小説家。代表作は『山月記』『光と風と夢』『弟子』『李陵』など。第一高等学校、東京帝国大学を卒業後、横浜高等女学校の教員勤務のかたわら小説執筆を続け、パラオ南洋庁の官吏(教科書編修書記)を経て専業作家になるも、同年中に持病の喘息悪化のため33歳で病没。死後に出版された全集は毎日出版文化賞を受賞した。

◎ 語彙数の取得

# 語彙数の取得
print(sp.GetPieceSize())
8000

◎ 語彙を語彙IDに変換

# トークンをトークンIDに変換 (どちらでも)
print(sp.PieceToId('</s>')) 
print(sp['</s>'])
2
2

◎ 語彙IDを語彙に変換

print(sp.IdToPiece(2))
</s>



この記事が気に入ったらサポートをしてみませんか?