PyTorch-NLPを使ってみました。
PyTorchを使って自然言語処理をするときに便利なライブラリ(※ただし、英語に限る。)
日本語を扱う場合はあまり使えないかもしれません。日本語の資料もないし…
この記事ではPyTorch-NLPで日本語を扱うために自分が学んだことなどを書いていく予定です。
github.com
docs
英語で書かれています。
Welcome to Pytorch-NLP’s documentation! — PyTorch-NLP 0.3.5 documentation
環境
※MeCabをWindowsにインストールするには
https://www.pytry3g.com/entry/2018/04/24/143934#Windows
インストール
pip install pytorch-nlp
Encode Text(テキストをTensorに変換する)
英語のテキストの場合、torchnlp.text_encodersのWhitespaceEncoderを使えばTensorに変換できます。しかし、日本語は英語と違って分かち書きされていないので、形態素解析をして分かち書きにしてからWhitespaceEncoderに渡す必要があります。
いちいち形態素解析してWhitespaceEncoderに渡すのではなく、日本語のテキストをそのまま渡してTensorに変換したいと思ったので、WhitespaceEncoderを参考にして新しくJapaneseEncoder作ってみました。
"""
japanese_encoder.py
"""
from torchnlp.text_encoders.static_tokenizer_encoder import StaticTokenizerEncoder
class JapaneseTokenizer:
def __init__(self, tagger):
self.tagger = tagger
def tokenize(self, s):
return self.tagger.parse(s).strip().split()
class JapaneseEncoder(StaticTokenizerEncoder):
""" Encodes the text written in Japanese by splitting on whitespace.
Args:
sample (list of strings): Sample of data to build dictionary on
min_occurrences (int, optional): Minimum number of occurrences for a token to
be added to dictionary.
append_eos (bool, optional): If 'True' append EOS token onto the end to the
encoded vector.
Example:
>>> encoder = JapaneseEncoder(["今日はいい天気ですね。", "そうですね。"])
>>> encoder.encode("今日はいい天気ですね。")
tensor([ 5, 6, 7, 8, 9, 10, 11])
>>> encoder.vocab
['<pad>', '<unk>', '</s>', '<s>', '<copy>', '今日', 'は', 'いい', '天気', 'です', 'ね', '。', 'そうですね']
>>> encoder.decode(encoder.encode("今日はいい天気ですね。"))
'今日はいい天気ですね。'
"""
def __init__(self, *args, **kwargs):
if 'tokenize' in kwargs:
raise TypeError('JapaneseEncoder defines a tokenize callable MeCab')
try:
import MeCab
except ImportError:
print("Please install MeCab.")
raise
self.jatokenizer = JapaneseTokenizer(MeCab.Tagger("-Owakati")).tokenize
super().__init__(*args, tokenize=self.jatokenizer, **kwargs)
@property
def word2id(self):
return self.stoi
@property
def id2word(self):
return {v: k for k, v in self.stoi.items()}
def decode(self, tensor):
tokens = [self.itos[index] for index in tensor]
return "".join(tokens)
サンプルプログラム①
新しく作ったjapanese_encoder.pyをインポートしています。
from japanese_encoder import JapaneseEncoder
sample = ["セネガルつええ、ボルト三体くらいいるわ笑笑",
"しょーみコロンビアより強い",
"それなまちがいないわ"
]
encoder = JapaneseEncoder(sample)
sentence = "ポーランド強い"
print(encoder.encode(sentence))
print(encoder.vocab)
print(encoder.decode(encoder.encode(sentence)))
<unk>は未知語を表します。
サンプルプログラム②
JapaenseEncoderに渡すオプションを少し変えています。
min_occurrencesは指定した値以上の出現する単語を辞書に加えます。
append_eosをTrueにするとテキストをTensorに変換したときに終端記号を加えるようになります。
encoder = JapaneseEncoder(sample, min_occurrences=2, append_eos=True)
sentence = "ポーランド強い"
print(encoder.encode(sentence))
print(encoder.vocab)
print(encoder.decode(encoder.encode(sentence)))
ゼロから作るDeepLearning
自然言語処理を勉強したい方へのおすすめの本です。
tensorflow, chainerやPyTorchといったフレームワークを使わずにゼロからnumpyを使ってディープラーニングの実装をしています。
扱っている内容はword2vec, RNN, GRU, seq2seqやAttentionなど、、、