単語N-gram の基礎理解【Pythonによる自然言語処理超入門】

Python

 

 

こんにちは!monachan_papaです。
Pythonによる自然言語処理超入門、久々の投稿です。今回は単語N-gramについて紹介したいと思います。
そもそも単語N-gramとは何か。一言であらわすならば、いわゆる単語分割の手法のひとつです。以降で簡単な例文を使って、単語N-gramの解説と実装までやっていきます!

uni-gram と bi-gram

さっそくですが、「男は黙ってサッポロビール」を、わかち書き してみましょう!

import MeCab

t = MeCab.Tagger('-Owakati')
datas = t.parse('男は黙ってサッポロビール')
print(datas)
男 は 黙っ て サッポロビール

簡単にできました。意図的にスラッシュをつけて分かりやすく図字するとこんな感じです。

男 / は / 黙っ / て / サッポロビール

では、連続する2単語を繋げて、あたかも1つの単語のように扱ってみると、どうなるでしょうか?さきほどと同様、スラッシュをつけて図字してみます。

男は / は黙っ / 黙って / てサッポロビール

ご覧のように、2単語で1つ扱い。こういった扱いをすることを 単語bi-gram(バイグラム) と呼びます。
一方、一番初めに図字した例は、1単語で1つ扱いで uni-gram(ユニグラム) と呼びます。

つまりは、単語N-gramN部分は何単語で分割するか、ということなります。いくつで分けてもよいですが、1単語、2単語、3単語までは特別な名前がついています。

  • 1単語: 単語uni-gram(ユニグラム)
  • 2単語: 単語bi-gram(バイグラム)
  • 3単語: 単語tri-gram(トライグラム)

以上のように、非常にシンプルな構造です!

bi-gram の実装

構造が分かったところで早速、実装してみましょう。
ライブラリを使わない方法と、使う方法の2通り示します。

普通に実装する

import MeCab

t = MeCab.Tagger('-Owakati')
datas = t.parse('男は黙ってサッポロビール')

datas = datas.split()
[(datas[i], datas[i+1]) for i in range(len(datas)-1)]
[('男', 'は'), ('は', '黙っ'), ('黙っ', 'て'), ('て', 'サッポロビール')]

わかち書き結果はスペース区切りになっているので、まずはsplit関数で分割してリスト化します。
その後、内包表記でサクッといけます!

ライブラリを使って実装する

import MeCab
from nltk import ngrams

t = MeCab.Tagger('-Owakati')
datas = t.parse('男は黙ってサッポロビール')

datas = datas.split()
list(ngrams(datas, 2))
[('男', 'は'), ('は', '黙っ'), ('黙っ', 'て'), ('て', 'サッポロビール')]

from nltk import ngrams でライブラリをインポートします。
そして、重要なところは ngrams(datas, 2) の部分です。

 

ngrams(シーケンス, N)

第1引数にはリストなどのシーケンスを指定します。第2引数には何gramsにしたいか数値指定します。
結果はジェネレータで返って来るので、list関数を使ってリスト化しています。

N-gram の利点

N-gramについて、基本的なことはつかめました。では、N-gramって、何がイイのか?!
今回は良いところをひとつ挙げてみます。

bi-gram 以上にすることで、単語の繋がりがよく分かる!

「この店のラーメンは、あの店のラーメンよりスープが濃厚で美味い。」という文で検証してみます。

Nに3を指定した場合

import MeCab
from nltk import ngrams

t = MeCab.Tagger('-Owakati')
datas = t.parse('この店のラーメンは、あの店のラーメンよりスープが濃厚で美味い。')

datas = datas.split()
list(ngrams(datas, 3))
[('この', '店', 'の'),
 ('店', 'の', 'ラーメン'),
 ('の', 'ラーメン', 'は'),
 ('ラーメン', 'は', '、'),
 ('は', '、', 'あの'),
 ('、', 'あの', '店'),
 ('あの', '店', 'の'),
 ('店', 'の', 'ラーメン'),
 ('の', 'ラーメン', 'より'),
 ('ラーメン', 'より', 'スープ'),
 ('より', 'スープ', 'が'),
 ('スープ', 'が', '濃厚'),
 ('が', '濃厚', 'で'),
 ('濃厚', 'で', '美味い'),
 ('で', '美味い', '。')]

Nに1を指定した場合

import MeCab
from nltk import ngrams

t = MeCab.Tagger('-Owakati')
datas = t.parse('この店のラーメンは、あの店のラーメンよりスープが濃厚で美味い。')

datas = datas.split()
list(ngrams(datas, 1))
[('この',),
 ('店',),
 ('の',),
 ('ラーメン',),
 ('は',),
 ('、',),
 ('あの',),
 ('店',),
 ('の',),
 ('ラーメン',),
 ('より',),
 ('スープ',),
 ('が',),
 ('濃厚',),
 ('で',),
 ('美味い',),
 ('。',)]

Nが3の場合の方が、繋がりが非常によく分かりますね!


 

以上、単語N-gram についての超基本的な紹介でした。

この仕組みは、マルコフ連鎖で自動文章生成をする【Pythonによる自然言語処理超入門】で使用します。しっかり押さえてステップアップを目指していきましょう。

 

 

 

また、爆速で 自然言語処理 を学びたい御方にはプログラミングスクールを考えるのも、ひとつの手です。独学よりも効果が出やすいですが、いかんせん投資がけっこうかかります。しかし、techgymというスクールは通うか通わないかは別として、無料のサンプルテキスト&解説動画がもらえます。これをとりあえず getしてまずは試しに体験学習するのもありでしょう。

コメント

タイトルとURLをコピーしました