fastTextの言語獲得①

# fastTextを使って言語を獲得する

# はじめに
こんにちは。お久しぶりです。記事にできるようなことは色々やっていたのですが、忙しくて書けませんでした。これではダメだと思い、小出しにはなってしまいますが、記事を書いていこう思います。合計でいくつの記事になるかわかりませんが、基本はキリの良いところで分割しようと持っているので、読みやすいようにはなっているはずだと思います。

前回の記事の「[アイドルのコンセプトは歌詞にも現れているのか？](https://qiita.com/NeoSoleil/items/23589d83900266b1f824)」という記事が結構な人数の方に読んでいただけているようで、とてもうれしいです。この場を借りて感謝を伝えさせてください。ありがとうございます。qiitaでほかの方の記事を読むときに自分の記事のviewを見るのが少し楽しみになりました。

さて、今回の記事はfastTextを用いて、ニューラルネットワークを学習させて、ニューラルネットワークに言語を獲得させるという記事です。前提知識は多少必要かもしれませんが、のんびりと分かりやすく書いていくつもりです。よろしくお願いします。


# 今回の概要の説明

 ::: note info
今回行いたいこと
 
fastTextから生成されるベクトルを用いて、全結合のニューラルネットワーク（MLP）の学習を行い、MLPから生成されるベクトルがfastTextから生成されるベクトルと同じにしたい。

:::
もし、fastTextからの出力とMLPからの出力が同じになればfastTextと同じベクトル空間の言語を獲得したことと同義となる考えられるからです。（簡単に言えばマッピングするということです）

どういうことなのかを身近な例で表現します。

日本語しか知らない人が英語の勉強をする時は日本語の「りんご」という単語が英語では「Apple」という単語と対応させて勉強しますよね。
そんな感じで、MLPに擬似的な言語を入力し、fastTextからの出力(覚えさせたい言語)を対応させて学習させます。
学習させることで擬似的な言語からもう一つの言語を習得することができると考えました。


今回は単語を学習させると大変なので、五十音を学習させてみます。
「あ」は「a」、「い」は「i」...といった感じです。
日本語をローマ字にしたものです。

MLPへの入力は五十音をone hotベクトルにしたものを擬似的な言語として使用します。
あまり複雑なものをMLPの入力とすると学習しにくのではないかと考えたからです。
入力はシンプルに出力は複雑なものにする方がイイ！

# 処理の順番を番号で示す
①五十音をonehotベクトルにする
②MLP学習時の正解のfastTextの生成
③MLPの生成
④MLPの学習
⑤MLPの精度の確認

次のセクションからそれぞれについて詳しく解説していきます。

# ①五十音をonehotベクトルにする
### onehotベクトルとは？
まずはonehotベクトルについて知る必要があります。(知ってる方は②へgo)

 ::: note info
onehotベクトルとは？

onehotベクトルとは、データをベクトルとして表現する際に、1つの要素だけが1で、それ以外の要素がすべて0である形式のベクトルを指す。
onehotベクトルは、主にカテゴリデータを数値データに変換するために使用される。
ベクトルの長さはカテゴリの総数と同じとなる。

:::

具体例を用いると
犬、猿、雉の３つを単語をカテゴリーデータとした場合、
ベクトルの次元数は１であり、ベクトルの長さは３のonehotベクトルを生成することができます。
```ruby:犬、猿、雉の３つを単語をカテゴリーデータとした場合のonehotベクトル
"犬"=[1,0,0]
"猿"=[0,1,0]
"雉"=[0,0,1]
```
[1,0,0]というベクトルは犬を示します。


仮に犬、猿、雉の３つのカテゴリーに桃太郎が増えた場合は以下のようになります。
```ruby:犬、猿、雉、桃太郎の４つを単語をカテゴリーデータとした場合のonehotベクトル
"犬"=[1,0,0,0]
"猿"=[0,1,0,0]
"雉"=[0,0,1,0]
"桃太郎"=[0,0,0,1]
```
[1,0,0,0]というベクトルは犬を示します。

このようにカテゴリーデータが増えるとベクトルの長さが増えるといった特徴があります。

### 五十音のonehotベクトルを取得するためのコード

```ruby:onehotベクトルの取得
import numpy as np

# 五十音のリスト
gojyuon = [
    'あ', 'い', 'う', 'え', 'お',
    'か', 'き', 'く', 'け', 'こ',
    'さ', 'し', 'す', 'せ', 'そ',
    'た', 'ち', 'つ', 'て', 'と',
    'な', 'に', 'ぬ', 'ね', 'の',
    'は', 'ひ', 'ふ', 'へ', 'ほ',
    'ま', 'み', 'む', 'め', 'も',
    'や', 'ゆ', 'よ',
    'ら', 'り', 'る', 'れ', 'ろ',
    'わ', 'を', 'ん'
]

# 辞書を用いて、文字とインデックスの対応を作成
char_to_index = {char: i for i, char in enumerate(gojyuon)}

# onehotベクトルを生成する関数
def make_one_hot_vector(char, char_to_index):
    # ベクトルの初期化（すべて0のベクトル）
    vector = np.zeros(len(char_to_index))
    # 対応するインデックスに1を設定
    if char in char_to_index:
        vector[char_to_index[char]] = 1
    return torch.tensor(vector)

# 五十音の文字ごとにOne-Hotベクトルを生成
dict_one_hot_vectors = {char: make_one_hot_vector(char, char_to_index) for char in gojyuon}
one_hot_vectors=[]
for i in range(len(dict_one_hot_vectors)):
    one_hot_vectors.append(dict_one_hot_vectors[gojyuon[i]])


print(one_hot_vectors)

```

上記のコードにより、gojyuonに含まれている五十音の文字を用いたonehotベクトルを生成します。
one_hot_vectorsという変数に五十音のonehotベクトルが入っています。


# おわりに

今回の記事はここで一旦休憩しようと思います。
まだ全体の少ししか終わってませんが、ここから先の処理について詳しく書くとかなりに時間かかってしまうので、次の記事に書きます。
なるべく早く書き上げるので、ぜひまた見てください。

分かりにくいところや疑問点があれば、気軽にコメントなどで教えてください。
そこについて詳しい説明などをしたいと思います。

ここまで読んでいただきありがとうございます。
また書こうと思います。
また逢う日まで。