LoginSignup
0

posted at

updated at

自然言語処理の前処理 ベクトル化について

はじめに

自然言語処理では単語をアルゴリズムで扱える数字に変換する前処理が必要です。
ここでは、単語のベクトル化と称します。
単語のベクトルにも主に2つのアプローチがあります。

ここではそれらのアプローチの概要と軽く実装を紹介しようと思います。
以下の自然言語処理処理の流れの中でベクトル化についての話です。

  1. 前処理
    1. 形態素解析
    2. ベクトル化
  2. アルゴリズム
  3. 後処理して出力

ベクトル化のアプローチ

ワンホットベクトル

単語をベクトルで表現する方法として、簡単に思いつく方法は、01のみのエンコードするケースです.
例とえば、文字0~9を表現する場合は、次元数は10の以下のようなベクトルで表現できます.

010000000

ただし、この方法にはいろいろな課題があります.

  • 単語同士の計算ができない
  • 単語間の関連性がわからない
  • 次元数が単語数に比例する
    • 例えば広辞苑にある24万語を表現すると24万の次元数になる
    • データ量が非常に多くなってしまう

分散ベクトル

分散ベクトルとは、単語の意味をベクトルで表現したものです.
ベクトルで表現することで単語同士の演算ができ、類似度を測れたりと色々とメリットがあります.

例えば以下みたいな表現にすれば単語同士で計算でき、関連性が測れたりするのでは?

0.443 0.854 0.133, ...

分散表現がわかると、色々な嬉しいことがあります.

分散ベクトルのアルゴリズム

Word2Vec

  • Word2Vecは、単語の分散表現を得るためほ手法(2013年 トマス・ミコロフらによる)
  • 分散表現を得る際にニューラルネットを使用
  • 飛躍的な精度向上
  • 分布仮説をもとにしている

Word2Vecの手法

以下2つの方法があります。

Skip-gram

  • 中心の単語から周辺語を予測する

CBOW

  • 周辺語から中心の単語を予測する

分布仮説とは

単語の意味は周辺の単語によって決まるとい分布仮説というものがあります.
単語の分散表現を得る手法はWord2Vec以外にもありますが、基本がこの仮説をもとにしています.

例) eatとくれば大体次は食べ物の単語がくることが予想できます.

I eat 食べ物の単語.

genismで分散ベクトルを取得

genismを用いて単語の分散ベクトルを取得してみます。
genismはLDA(トピック分析)で使われるものですが、今回はLDAについては割愛します。
ベクトル化のAPIを使ってちょっと遊んでみます。
Gensim: topic modelling for humans

学習済の単語ベクトルを取得

import gensim.downloader as api
wv = api.load('word2vec-google-news-300')

出力してみる

wv["Tokyo"]
array([-2.16064453e-02,  1.79687500e-01,  1.98242188e-01, -1.62109375e-01,
       -1.34765625e-01,  1.25732422e-02, -1.99218750e-01, -2.68554688e-02,
       -3.78417969e-02,  1.66992188e-01, -3.26171875e-01,  4.66796875e-01,
        8.74023438e-02, -2.63671875e-01, -8.69140625e-02, -2.55859375e-01,
        1.67846680e-03,  2.61718750e-01, -3.58886719e-02, -4.83398438e-02,
        6.17675781e-02, -1.97265625e-01, -8.30078125e-02, -6.49414062e-02,
       -2.35595703e-02,  2.47070312e-01, -1.05468750e-01,  3.36914062e-02,
       ...

単語の次元数は300でした

wv["Toyko"].shape
(300,)

色々計算してみます。

ロンドン - イギリス + 日本 =東京

wv.similar_by_vector(wv["London"] - wv["England"] + wv["Japan"], 1)
[('Tokyo', 0.7490742206573486)]

東京 - 日本 + イギリス =ロンドン

wv.similar_by_vector(wv["Tokyo"] - wv["Japan"] + wv["England"] , 1)
[('England', 0.708386242389679)]

なるほど。。

おわりに

自然言語処理の単語のベクトル化について軽くまとめてみました。
ベクトル化をどう応用して実際の課題とアルゴリズムに適用するかはまた後ほど。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0