2018/7/17【25日目】Pythonでn-gramを実装していく
今日は自然言語処理のテキストに良く出てくるn-gramについて実装していきたいと思います。
n-gramとは
大学受験の時に、『英単語ピーナッツほど美味しいものはない』という単語帳がありましたが、「形容詞+名詞」や「動詞+名詞」をひたすらノートに書いていくというものでした。まさにあれがn-gramというものらしいです。
例をあげると「know」と「how」だけですと、「知る」と「どのように」という意味ですが、「know how」になると「やり方」になるように、2つ以上の単語で置き換えができない組み合わせをコロケーションというらしいです。
n-gramはこれらのコロケーションを見つけるために、2文字ずつ(バイグラム)、3文字ずつ(スリーグラム)、4文字ずつ(フォーグラム)といったぐらいに言葉を集めることだそうです。
物は試しにとりあえず実装していきます。
実装
とりあえず、ライブラリでpython-ngramというのがあり、一番簡単そうなので、まずはこれを使ってみます。
tweet = "SHOWROOM「こみの部屋」ありがとうございました〜??チームKについてたくさんお話できたかな!舞台、プロレスと今年も一緒に夏を過ごしそうです??? https://t.co/qxc047jzLg" import ngram index = ngram.NGram(N=2) for two_gram in index.ngrams(index.pad(tweet)): print(two_gram)
実行結果
$S SH HO OW WR RO OO OM M「 「こ こみ みの の部 (省略)
それぽいのができました。ただ、これだとKnow howというようなコロケーションは一生作れなさそうですね。 できれば単語ごとに分けていきたいような気がします。
ちょっと調べてみましたが、いいライブラリがなさそうなので自分で実装してみます。 まずは単語にばらして配列に代入。
import MeCab tagger = MeCab.Tagger ("") kaisekiyou = tweet.split('¥n') string = ' '.join(kaisekiyou) mecab = tagger.parse(string) kaigyou = mecab.splitlines() word = [] for tango_list in kaigyou: tab = tango_list.split('\t') words = tab[0] word.append(words) print(word)
実行結果。
['SHOWROOM', '「', 'こみの部屋', '」', 'ありがとう', 'ござい', 'まし', 'た', '〜', '??', 'チームK', 'について', 'たくさん', 'お話', 'でき', 'た', 'か', 'な', '!', '舞台', '、', 'プロレス', 'と', '今年', 'も', '一緒', 'に', '夏', 'を', '過ごし', 'そう', 'です', '???', 'https', '://', 't', '.', 'co', '/', 'qxc', '047', 'jzLg', 'EOS']
とりあえず単語ごとに配列に代入しました。 これを1個ずつスライドして新しい配列にすれば良さそうです。 配列に2つずつ追加するには、数字でfor文を回して、2つずつappedすれば良さそうです。
bigram_list = [] for i in range(len(word)-1): bigram_list.append((word[i], word[i+1]))
実行結果
[('SHOWROOM', '「'), ('「', 'こみの部屋'), ('こみの部屋', '」'), ('」', 'ありがとう'), ('ありがとう', 'ござい'), ('ござい', 'まし'), ('まし', 'た'), ('た', '〜'), ('〜', '??'), ('??', 'チームK'), ('チームK', 'について'), ('について', 'たくさん'), ('たくさん', 'お話'), ('お話', 'でき'), ('でき', 'た'), ('た', 'か'), ('か', 'な'), ('な', '!'), ('!', '舞台'), ('舞台', '、'), ('、', 'プロレス'), ('プロレス', 'と'), ('と', '今年'), ('今年', 'も'), ('も', '一緒'), ('一緒', 'に'), ('に', '夏'), ('夏', 'を'), ('を', '過ごし'), ('過ごし', 'そう'), ('そう', 'です'), ('です', '???'), ('???', 'https'), ('https', '://'), ('://', 't'), ('t', '.'), ('.', 'co'), ('co', '/'), ('/', 'qxc'), ('qxc', '047'), ('047', 'jzLg'), ('jzLg', 'EOS')]
お、良さそうにできています。 明日はこれを使って何か分析ぽいことをしたいと思います。
ちなみに3グラムの時はこんな感じですね。
three_list = [] for i in range(len(word)-2): three_list.append((word[i], word[i+1], word[i+2]))
今日の結果
本日のAKBメンバーによる呟きは45件でした。 久しぶりに画像を作ってみます。
{'あおい': 13, '楽しい': 11, '嬉しい': 8, '暑い': 5, 'すごい': 3, '可愛い': 2, '優しい': 2, '凄い': 2, '面白い': 2, '少ない': 1, '黒い': 1, 'ない': 1, 'すっごい': 1, '暖かい': 1, 'うれしい': 1, 'たのしい': 1, '大きい': 1}) '公演': 27, '今日': 17, 'さん': 16, 'あおい': 13, '楽しい': 11, '嬉しい': 8, '暑い': 5, '笑': 5, '皆さん': 5, 'ん': 5, 'みんな': 4, '出演': 4, '福岡': 4, '日': 4, '私': 4, 'みなさん': 4, 'たくさん': 4, 'ちゃん': 4, '公演': 27, 'する': 27, '今日': 17, 'さん': 16, 'あおい': 13, '楽しい': 11, '嬉しい': 8, 'なる': 6, '暑い': 5, '笑': 5, '皆さん': 5, 'ん': 5, 'せる': 5, '頑張る': 5, 'くださる': 5, 'ゆう': 5,
こんな感じでした。