R で日本語テキストに word2vec


# R で日本語テキストに word2vec

## word2vec

word2vec は単語列をベクトルで表現する手法ですが、応用することで意味構造を可視化できる手法です。ググれば解説は無数に出てきます。

さて、本稿ではRを使って日本語テキストにword2vecを適用する方法を概観します。 ここでは **WordVectors** パッケージの利用方法を説明します。
日本語テキストの処理

**wordVectors** パッケージで日本語テキストを処理するためには、あらかじめ単語ごとに分ち書き(つまり単語を分割し、単語間に半角スペースを挿入)しておきます。形態素解析については『[Rによるテキストマイニング入門](https://www.amazon.co.jp/dp/4627848420?tag=motohiro-22&camp=243&creative=1615&linkCode=as1&creativeASIN=4627848420&adid=0V0QZEH10YEC1N66GQFN&)』を参照してください。


## テキストの準備

宮沢賢治 『銀河鉄道の夜』を青空文庫からダウンロードし、ルビなどのメタ情報を削除

```{r}
## テキストのダウンロードと前処理
source("http://rmecab.jp/R/Aozora.R")
kenji <- Aozora(url = "http://www.aozora.gr.jp/cards/000081/files/43737_ruby_19028.zip") 

## 分かち書き処理の用意
library(RMeCab)
library(dplyr)
library(purrr)

## 一時ファイルを用意
tf <- tempfile()
RMeCabText(kenji) %>% map(function(x) 
  ifelse( (x[[2]] %in% c("名詞", "形容詞", "動詞"))  && 
            (!x[[3]] %in% c("数", "非自立", "代名詞","接尾") ) && (x[[8]] != "*"), 
          x[[8]],  ""))  %>%  paste(" ", collapse = "") %>%
  write(file = tf, append = TRUE) 

## 生成されたファイルを確認するには
## file.show(tf)
```


## モデル構築

wordVectorssに読み込ませるファイルは用意できたので、あとは wordVectors のビネットなどを参照しつつ、単語間の相関や、あるいはword2vecの売りである単語どうしの演算などを試行。

```
## text2vecを実行するパッケージをインストール
# devtools::install_github("bmschmidt/wordVectors") 
library(wordVectors)

## 学習
model <- train_word2vec(tf,"tf.bin", min_count = 2)
```

## 学習されたモデル

```
model

## A VectorSpaceModel object of  889  words and  100  vectors
##                  [,1]         [,2]         [,3]         [,4]         [,5]
## 
      0.004002686  0.004419403 -0.003830261 -0.003278046  0.001366577
## する     -0.081605606 -0.276083529  0.053755093 -0.215761125 -0.015686007
## なる      0.139376521 -0.311665773  0.109456837 -0.084202334  0.279922992
## 見る     -0.050623279 -0.074353449  0.020936850 -0.165816724  0.145149201
## 言う     -0.063046515 -0.171760380  0.093058035 -0.019183068  0.037652198
## いる      0.423858851 -0.030605637  0.320812494 -0.131878242  0.240542665
## 見える    0.133048505 -0.440167218  0.166549504 -0.334573805  0.222126007
## 行く      0.024968117 -0.322981983 -0.049303867  0.024144927 -0.022971302
## ほんとう -0.054643303 -0.624526739 -0.060474392 -0.195618823 -0.013863897
## 思う     -0.220538810 -0.089468285  0.125748336 -0.211816043  0.128125787
##                  [,6]
## 
      0.003021088
## する     -0.196594119
## なる     -0.103877820
## 見る     -0.094995320
## 言う      0.022074323
## いる      0.130194664
## 見える   -0.219103903
## 行く      0.029321071
## ほんとう -0.002299511
## 思う     -0.289635211
## attr(,".cache")
## <environment: 0x4fa5d28>
```

### 意味の類似

```
## 「銀河」と意味的に近い語
> model %>% closest_to("銀河")
     word similarity to "銀河"
1    銀河            1.0000000
2    水素            0.7862936
3    水銀            0.7749105
4    硫黄            0.7735890
5    写る            0.7564250
6    泳ぐ            0.7479894
7  ひたる            0.7469686
8    一斉            0.7463763
9    浮く            0.7102072
10 きもの            0.7075043
###
model %>%  nearest_to(vector = model[["銀河"]], n = 20) %>% round(2) 
##         銀河 ステーション         そん         時間         手首 
##         0.00         0.11         0.15         0.16         0.16 
##         流れ         地球           粒           球         太陽 
##         0.16         0.17         0.18         0.18         0.19 
##         速い       ガラス         厚い         指す       レンズ 
##         0.19         0.20         0.20         0.21         0.21 
##           上           図         工兵         つぶ         水素 
##         0.22         0.22         0.23         0.23         0.23
##     0.27     0.27     0.27     0.27

```

### アナロジーを見る

「銀河」と「ガラス」の加算

```
model %>% nearest_to(model[["銀河"]] + model[["ガラス"]])

##       銀河       そん     ガラス       手首       地球         粒 
## 0.04055901 0.05939323 0.06295547 0.06668550 0.07197342 0.08290203 
##       流れ       太陽       厚い       速い 
## 0.08995927 0.09296061 0.09544364 0.09921091
```

「銀河」と「天の川」の減算

```
model %>% nearest_to(model[["銀河"]] - model[["天の川"]])

##      銀河        家    くじら      学校      祭り    くるみ      活版 
## 0.5495010 0.6355500 0.6548515 0.6910687 0.6916897 0.6935851 0.7051282 
##      さき        実      今日 
## 0.7145932 0.7169427 0.7193023
```

### ポリセミー

「銀河」と「レンズ」の意味的近さを、他の単語を意味空間から削除して調べる。ここでは意味的近さの算出に `cosineSimilarity()` を利用。

```
model[["銀河"]] %>% cosineSimilarity(model[["レンズ"]]) 

##           [,1]
## [1,] 0.7924778
```

空間から「工兵」を削除して再計算

```
model[["銀河"]] %>% reject(model[["工兵"]]) %>% cosineSimilarity(model[["レンズ"]]) 

##           [,1]
## [1,] 0.3605714
```

```
## 一時ファイルを削除
unlink("tf.bin")
unlink(tf)
```

## doc2vec

次はRで日本語テキストに doc2vec を適用する方法を紹介します。**text2vec** の解析関数として **RMeCab** の関数へのラッパーを渡します。