動かして学ぶ人工知能（機械学習）の基本

# はじめに
本記事は、人工知能（機械学習）の基本についてのまとめです。
時代の流れに沿って興味を持ち学習したいと思っているが、何から始めればいいのか？
はじめて自転車に乗る場合、自転車に乗らないと始まらないように、とりあえず手を動かして色々な物を試して見るのがいいと思います。

前半は主に機械学習の基礎的なことについて、後半は人工知能を体験するための学習方法について記載しています。

GPUが搭載されたコンピュータを使用しなくても、既にローンチされたサービスや、自分で環境を作って試すことで、人工知能は誰でもすぐに使用できます。

## 人間とコンピュータの違い
人間の脳はファジー記憶と言われていて、曖昧に記憶するように都合よくできていると、昔何かの本で読みました。もし、人間の脳がファジー記憶でない場合、自分の知っている人物が昨日と違う服を着ていたら、区別がつかずにその人と認識することができません。

**人間とコンピューターの最大な違いは曖昧さです。そして、人工知能に求められるのはこの曖昧さです。**

逆説的ではありますが、コンピュータが曖昧さを克服しても、心や感情がない限り、入力に対して出力を行うという行為は、コンピュータがただ処理として行なっているにすぎません。あくまでも人間のように振舞っているだけにしか見えません。ただ今はコンピュータに感情を持たせる研究も進んでいるので、将来的にSF映画のようにコンピュータが人間のような感情を持つような時代が来るのかもしれません。

## 人工知能について考える
人工知能の研究は昔から行われていて、今は第３次ブームと言われています。
AIの民主化が進み、無料で利用できる人工知能のフレームワークやライブラリがたくさんあるので、インターネットに繋がるPCあれば誰でも利用することや開発ができます。

人工知能が仕事を奪うというネガティヴな見方をされることが多いですが、結果的に間違いではないので全ては否定できませんが、逆に新しい仕事も生まれているのでそこは前向きに考えた方がいいと思います。amazonでは工場は殆どロボットだそうですが、AIエンジニアを何千人も募集しているようです。特に、日本だと人材不足や少子高齢化の課題があるので人手不足を補うツールとして活躍が期待できると考えます。

人工知能に求めらめれることは、人間がコンピュータに求めていることが多くなっただけで、本質的に変わってないと考えます。利便性や効率性を求めて、人間だと時間がかかる作業をコンピュータに行わせることが本来のコンピュータの存在意義であり、それは昔も今も変わらないはずです。

## 人工知能概要
[人工知能（AI=artificial intelligence）](https://ja.wikipedia.org/wiki/%E4%BA%BA%E5%B7%A5%E7%9F%A5%E8%83%BD)は一般的に以下の図のように分類されます。

![AI.jpg](https://qiita-image-store.s3.amazonaws.com/0/221759/5b4ed4b4-0928-817b-83f2-b8a561ce433a.jpeg)

- **従来の人工知能**   
エキスパートシステム、事例ベース推論、ベイジアン・ネットワークなどがあり、これらは統計的機械学習と呼ばれている。
- **計算知能**  
ニュートラル・ネットワーク、ファジー制御、進化的計算などがある。

AIは特化型AIと汎用AIに大別できます。
特化型AIは特定の用途でのみ使える人工知能です。[AlphaGo](https://ja.wikipedia.org/wiki/AlphaGo)などは特化型AIです。
また、弱いAIとも呼ばれています。
汎用AIは人間に近い動きが求められる人工知能のことです。強いAIとも呼ばれます。

## 機械学習     
人工知能というと今は機械学習が主流です。ただ、機械学習に唯一の定義がないため、見方によっては相違があるかもしれません。

![Untitled Diagram.jpg](https://qiita-image-store.s3.amazonaws.com/0/221759/c8ae971f-07e2-a155-ce21-7a24432a37f5.jpeg)

機械学習は、人工知能の研究分野の一部であり、人間が行なっていた認知や判断といった比較的高度な作業をコンピュータに行わせることを目的としています。また、ビッグデータ等を利用してマーケティングに活用するなど、近年ビジネスにおいても多方面に注目されています。

機械学習で取り扱うのは、特定の問題の対して、トレーニングしてモデルを構築することです。問題特化型AIになるので人間並みの識別や予測が可能です。言い換えると100%でないため、間違えることがあります。

機械学習では様々なアルゴリズムが使用されています。

- **クラスタリング**   
近いデータをまとめること。クラスタリングはデータ集合を内的結合および外的分離が達成されるような複数の部分集合（クラスタ）に分割できる。代表的な手法としては最短距離法などの階層的手法、K-meansなどの非開層的手法がある。
- **分類**    
学習データにラベルを与えて学習を行うことで分類すること。スパム判定やニュースサイトの記事の分類、画像認識などに利用される。また、分類は教師あり学習と教師なし学習に大別できる。一概には言えないが、特微量とラベルの組み合わせで正解がハッキリしている教師あり学習の方が精度が出やすい。
- **回帰**   
売り上げや価格など連続的な量的データを予測すること。一般的には数値データ間の相関関係や因果関係を推定するのに利用される。データの組み合わせから原因と結果のモデルを導き出す。データの組み合わせによっては相関が見られないことも分かるので、データから特徴を捉えることができる。
- **ディープ・ラーニング**  
ディープ・ラーニングは自然言語処理、画像認識、音声認識に利用すると高い精度が出せる。定性的なデータの処理に向いている。また、大量のデータから特微量抽出が自動で行えるので、データから特徴を手作業で計算することなくパターンを見つけることができる。逆に、自動的に抽出された特微量を人が識別することはまだできない。ディープ・ラーニングは大量のデータ（100万〜1,000万）を扱うのに向いているため、それこそクラウドでGPUを搭載したコンピュタが必要になるので、個人で開発というよりは大規模システム開発などを行う大手企業向きである。
- **データ・マイニング**   
機械学習とデータ・マイニングは手法が同じだが目的が異なり、データ・マイニングはデータから未知の特徴を発見するのが目的である。機械学習の学習の領域ではトレーニング・データの特微量を用いて構築したモデルによって既知の特徴に基づく分類や予測を行う。データセットを作るまではデータ・マイニングで未知のデータから特徴を発見するのに利用でき、データの特徴に合わせて機械学習のアルゴリズムを選択して特微量からモデルを構築する。

**要約すると、機械学習はトレーニングモデルを構築して、訓練データから学んだ「既知」の特徴に基づく予測を行うために利用される。データマイニングの目的は、それまで「未知」だったデータの特徴を発見すること。**

**教師あり学習は既知の問題に強く、教師なし学習は未知の問題に強い。強化学習は、試行錯誤を行いながら最適だと思われる「行動の仕方」を学習する。**

以下にWeb上で簡単に試すことができる人工知能を活用したWebサービスについて記載します。

### 計算知能
- [Wolfram](http://ja.wolframalpha.com/)は数学、化学技術、社会・文化、日常生活等、様々な質問を独自のアルゴリズムで回答する知識ベース型のAIです。フォームに入力した数式やさまざまな質問に答えてくれるウェブサービスで、科学技術計算ソフト[「Mathematica」](https://ja.wikipedia.org/wiki/Mathematica)の開発元として知られる[Wolfram Research](http://www.wolfram.com/?source=nav)によって運営されています。

![スクリーンショット 2018-06-21 23.07.28.png](https://qiita-image-store.s3.amazonaws.com/0/221759/be18fc1c-219a-b76d-42f5-6b1a16814ed0.png)

### 画像認識
- [How-Old.net](https://how-old.net/)はアップロードした写真に写っている人物の年齢と性別を推定します。年齢とセットにした顔写真を大量にAIに読み込ませて学習しています。

### 画像変換
- [Waifu2x](http://waifu2x.me/index.ja.html)は小さな画像をきれいに拡大したり、ノイズを取り除いたりすることができます。ディープランニングと畳み込み演算と呼ばれる離散的な数列をなめらかにするアルゴリズムを使って、拡大した画像がギザギザにならないようにしています。

- [Colorize Photos](https://demos.algorithmia.com/colorize-photos/)は白黒写真をカラーにすることができます。大量のカラー画像と白黒画像のペアを学習させておき、白黒画像の特徴から推測してカラー化しています。

### 言語処理
- [rinna](http://www.rinna.jp/)は日本マイクロソフトが開発した会話ボットの一つです。

### 音楽
- [Amper Music](https://www.ampermusic.com/)は著作権料フリーの楽曲をAIに作曲してもらことができます。

## ライブラリ実習
人工知能を体験するための学習方法について記載します。必要なのはインターネットに繋がるPCだけです。
画像処理の例としてTensorFlowを自然言語処理の例としてword2Vecについて記載しています。

### 準備作業
人工知能の学習はコンテナを利用することで、簡単に実行環境を作ることができます。
まずはDocerをインストールしましょう。

本記事ではMiniconda3を使用しています。MinicondaはAnacondaを軽量化したものです。
まずは以下のコマンドを実行してアップデートします。

`# apt-get update`

### 画像処理
#### TensorFlow
[TensorFlow](https://www.tensorflow.org/)はオープンソースの機械学習ライブラリで、Google社の研究機関が機械学習やディープニュートラルの研究目的で開発していたが、今はオープンソース化され誰でも利用でき多くの研究機関や企業が利用しています。データフローグラフを使用した数値計算用のオープンソースのソフトウェアライブラリで、グラフのノードは数学的な演算を表し、グラフのエッジはノード間でやりとりされる多次元データ配列（テンソル）を表します。

以下に画像識別用のプログラムを実行する手順について記載します。

- tensorflowのインストール   
`# pip install tensorflow`
- 画像識別用のプログラムをダウンロード    
`# wget https://raw.githubusercontent.com/tensorflow/models/master/tutorials/image/imagenet/classify_image.py`
- 写真の識別を実行    
`# python classify_image.py --image_file ファイル名`  

下記は適当に犬の画像をwgetでダウンロードして実行した例です。この例では犬ではなく、北極キツネや白キツネで認識されています。

```python
root@87f26865e20e:/# python classify_image.py --image_file Dog+puppies.jpg 
2018-06-17 13:29:01.278582: W tensorflow/core/framework/op_def_util.cc:346] Op BatchNormWithGlobalNormalization is deprecated. It will cease to work in GraphDef version 9. Use tf.nn.batch_normalization().
2018-06-17 13:29:03.027424: W tensorflow/core/framework/allocator.cc:101] Allocation of 8257536 exceeds 10% of system memory.
2018-06-17 13:29:03.039195: W tensorflow/core/framework/allocator.cc:101] Allocation of 6193152 exceeds 10% of system memory.
2018-06-17 13:29:03.056942: W tensorflow/core/framework/allocator.cc:101] Allocation of 6193152 exceeds 10% of system memory.
2018-06-17 13:29:03.175152: W tensorflow/core/framework/allocator.cc:101] Allocation of 5760000 exceeds 10% of system memory.
Samoyed, Samoyede (score = 0.49136)
Arctic fox, white fox, Alopex lagopus (score = 0.10709)
Great Pyrenees (score = 0.07197)
kuvasz (score = 0.02922)
white wolf, Arctic wolf, Canis lupus tundrarum (score = 0.02470)
```
「w」ではじまる部分は警告メッセージであり、パソコンの性能が低いと言っています。結果は最後に出力され、左側に予測された単語が、右側にスコア（予測の確率）が表示されます。スコアが高ければ高いほどAIが自信を持っています。0.1以下は低いことを表しています。

#### OoenCV（Open Source Computer Vision Library）
[OoenCV](https://www.tensorflow.org/)はインテルが開発・公開したオープンソースのコンピュータビジョン向けライブラリで、画像処理を簡単に行うことができます。スマートフォンのアプリの開発や研究でも広く使われていて、OpenCVには画像処理に必要な様々な関数群を備えているので、画像や動画の処理、顔などの認識処理や、拡張現実（AR）の応用など幅広い用途に対応しています。

以下のコマンドでインストールできます。

`# pip install opencv-python`

### 自然言語処理
#### word2Vec
word2Vecはテキストデータを解析し、各単語の意味をベクトルで分散表現する手法です。
分散表現は、単語を数十〜数百次元のベクトルで表現します。


```python
apple 0.447528
banana 0.402594
```

コンピューターは文章を解析し、二つの単語が一緒に使われることが多いのであれば、単語同士の意味が近いと判断して、ベクトル空間上で近くに配置します。

**あくまでコンピュターは単語の意味を理解しているわけではなく、ベクトルの計算によって、導き出しています。**

マルコフ連鎖は単語をベクトルにするアルゴリズムです。word2Vec（WORD to vector）では大量の文章データを与えると、その中に含まれる単語のベクトルを生成しています。

以下に単語学習用のプログラムを実行する手順について記載します。

- work2Vecのダウンロード
`# git clone https://github.com/dav/word2vec.git`

-  コンパイル
`# cd word2vec/src`
`# make`
- データをダウンロードして学習
`# cd ../scripts/`
`# ./create-text8-vector-data.sh `
`# ./demo-word.sh `

text8.gz という圧縮ファイルが自動的にダウンロードされ、単語の学習が開始されます。
このファイルには長い英文データが格納されていいます。

```bash
root@87850df68ccd:/word2vec/scripts# ./create-text8-vector-data.sh
--2018-06-30 15:26:51--  http://mattmahoney.net/dc/text8.zip
Resolving mattmahoney.net (mattmahoney.net)... 67.195.197.75
Connecting to mattmahoney.net (mattmahoney.net)|67.195.197.75|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 31344016 (30M) [application/zip]
Saving to: ‘../data/text8.gz’

../data/text8.gz               100%[=====================================================>]  29.89M   259KB/s   in 2m 4s  s

2018-06-30 15:28:56 (247 KB/s) - ‘../data/text8.gz’ saved [31344016/31344016]

mv: cannot stat ‘text8’: No such file or directory
-----------------------------------------------------------------------------------------------------
-- Training vectors...
Starting training using file ../data/text8
Vocab size: 71291
Words in train file: 16718843
Alpha: 0.000005  Progress: 100.10%  Words/thread/sec: 46.62k  

real	47m3.404s
user	88m43.110s
sys	1m33.530s
```

入力を促すメッセージが表示されたら、単語を小文字で入力します。

```bash
root@87850df68ccd:/word2vec/scripts# ./demo-word.sh
/word2vec/src /word2vec/scripts
gcc word2vec.c -o ../bin/word2vec -lm -pthread -O3 -march=native -Wall -funroll-loops -Wno-unused-result
gcc word2phrase.c -o ../bin/word2phrase -lm -pthread -O3 -march=native -Wall -funroll-loops -Wno-unused-result
gcc distance.c -o ../bin/distance -lm -pthread -O3 -march=native -Wall -funroll-loops -Wno-unused-result
distance.c: In function ‘main’:
distance.c:33:8: warning: unused variable ‘ch’ [-Wunused-variable]
   char ch;
        ^
gcc word-analogy.c -o ../bin/word-analogy -lm -pthread -O3 -march=native -Wall -funroll-loops -Wno-unused-result
word-analogy.c: In function ‘main’:
word-analogy.c:33:8: warning: unused variable ‘ch’ [-Wunused-variable]
   char ch;
        ^
gcc compute-accuracy.c -o ../bin/compute-accuracy -lm -pthread -O3 -march=native -Wall -funroll-loops -Wno-unused-result
compute-accuracy.c: In function ‘main’:
compute-accuracy.c:31:109: warning: unused variable ‘ch’ [-Wunused-variable]
   char st1[max_size], st2[max_size], st3[max_size], st4[max_size], bestw[N][max_size], file_name[max_size], ch;
                                                                                                             ^
chmod +x ../scripts/*.sh
/word2vec/scripts
+ ../bin/distance ../data/text8-vector.bin
Enter word or sentence (EXIT to break): 
```

右側の数字は単語の距離を表し、数値が大きいほど関連が近いことを示します。
下記はsoccerと入力し、一番footballと関連が近いことが分かります。

```bash
Enter word or sentence (EXIT to break): soccer

Word: soccer  Position in vocabulary: 5231

                                              Word       Cosine distance
------------------------------------------------------------------------
                                          football		0.654716
                                        volleyball		0.612472
                                        basketball		0.570732
                                             sport		0.558216
                                            chivas		0.553757
                                            sports		0.549288
                                            hockey		0.537989
                                          handball		0.530699
                                         deportivo		0.521572
                                         badminton		0.514515
                                        midfielder		0.508851
                                             clube		0.508278
                                              tbol		0.503981
                                            futsal		0.503467
                                              liga		0.498593
                                            rowing		0.497187
                                           netball		0.495673
                                          softball		0.490544
                                          lacrosse		0.488564
                                              alai		0.483350
                                            shinty		0.480412
                                           hurling		0.475455
                                             jongg		0.474539
                                   interuniversity		0.471783
                                              hagi		0.469208
                                          korfball		0.465063
                                         pengrowth		0.464865
                                             rugby		0.464188
                                             bocce		0.462394
                                       footballers		0.455753
                                         feyenoord		0.447820
                                               psv		0.447072
                                        saddledome		0.443745
                                         sportsmen		0.441408
                                    mountaineering		0.440455
                                         sportsman		0.440277
                                              fiba		0.438473
                                             teams		0.437966
                                            calcio		0.435269
                                               cfl		0.433307
```

関連語の検索を終了するには、プロンプト上で「EXIT」と入力して、「Enter」を押します。

- 単語の関係性を演算    
`./demo-analogy.sh `

```bash
root@87850df68ccd:/word2vec/scripts# ./demo-analogy.sh
/word2vec/src /word2vec/scripts
gcc word2vec.c -o ../bin/word2vec -lm -pthread -O3 -march=native -Wall -funroll-loops -Wno-unused-result
gcc word2phrase.c -o ../bin/word2phrase -lm -pthread -O3 -march=native -Wall -funroll-loops -Wno-unused-result

gcc distance.c -o ../bin/distance -lm -pthread -O3 -march=native -Wall -funroll-loops -Wno-unused-result
distance.c: In function ‘main’:
distance.c:33:8: warning: unused variable ‘ch’ [-Wunused-variable]
   char ch;
        ^
gcc word-analogy.c -o ../bin/word-analogy -lm -pthread -O3 -march=native -Wall -funroll-loops -Wno-unused-result
word-analogy.c: In function ‘main’:
word-analogy.c:33:8: warning: unused variable ‘ch’ [-Wunused-variable]
   char ch;
        ^
gcc compute-accuracy.c -o ../bin/compute-accuracy -lm -pthread -O3 -march=native -Wall -funroll-loops -Wno-unused-result
compute-accuracy.c: In function ‘main’:
compute-accuracy.c:31:109: warning: unused variable ‘ch’ [-Wunused-variable]
   char st1[max_size], st2[max_size], st3[max_size], st4[max_size], bestw[N][max_size], file_name[max_size], ch;
                                                                                                             ^
chmod +x ../scripts/*.sh
/word2vec/scripts
-----------------------------------------------------------------------------------------------------
Note that for the word analogy to perform well, the models should be trained on much larger data sets
Example input: paris france berlin
-----------------------------------------------------------------------------------------------------
+ ../bin/word-analogy ../data/text8-vector.bin
Enter three words (EXIT to break): Only 1 words were entered.. three words are needed at the input to perform the calculation
Enter three words (EXIT to break): 
```

AとBの関係はCに対して何であるかを出力します。
下記はsoccer、baseball、ballと入力した例。

```bash
Enter three words (EXIT to break): soccer baseball ball

Word: soccer  Position in vocabulary: 5231

Word: baseball  Position in vocabulary: 940

Word: ball  Position in vocabulary: 797

                                              Word              Distance
------------------------------------------------------------------------
                                            batter		0.519509
                                             balls		0.514528
                                           pitcher		0.511606
                                            batted		0.484992
                                        baserunner		0.481012
                                            hitter		0.472762
                                         infielder		0.468838
                                          pitchers		0.467682
                                         strikeout		0.459293
                                       baserunners		0.454910
                                            fumble		0.451071
                                               rbi		0.446237
                                             pitch		0.443997
                                         backwards		0.442098
                                             throw		0.441679
                                           catcher		0.438472
                                             fouls		0.436955
                                          unearned		0.436265
                                           batters		0.434271
                                           hitters		0.429963
                                               cue		0.425643
                                           cueball		0.422985
                                            homers		0.421095
                                           infield		0.419438
                                           batting		0.414544
                                              bunt		0.414514
                                           hitting		0.414235
                                          outfield		0.413629
                                          fastball		0.413180
                                        outfielder		0.411428
                                       outfielders		0.410298
                                          slugging		0.409602
                                               mlb		0.405875
                                           baseman		0.405671
                                             flick		0.404992
                                               hbp		0.404542
                                           fielder		0.401474
                                          inbounds		0.397781
                                          pitching		0.397073
                                            inning		0.395184
```


**work2Vecではコンピュータはただ演算をしているだけで、それを理解しているわけではない。**

AIがやっていることは[「中国語の部屋」](https://ja.wikipedia.org/wiki/%E4%B8%AD%E5%9B%BD%E8%AA%9E%E3%81%AE%E9%83%A8%E5%B1%8B)の小部屋の中の人がやっていることと同じです。

## 大事なこと
人工知能を学習するにあたり、忘れてはいけない技術に対する考え方を纏めます。

### 低レイヤの技術

「Binary Hacks ―ハッカー秘伝のテクニック100選」の冒頭に記述してある一節ですが、この記述は本が出てから10年たった今でも響きます。
>現代のプログラマは、最初から強力な道具をふんだんに使える。アイディアさえあれば、軽量スクリプト言語、出来合いのライブラリ、ネットワーク上の各種サービスを組み合わせて、気の利いたサービスを素早くローンチすることができる。
（中略）
>道具の力とは、抽象化の力だ。泥臭い現実を特定の切り口で簡略化することで、本質に関係のない膨大な雑事を気にせずに、考えたい問題のみに集中できる。

**大事なことは既に洗練されたライブラリを使用して、大抵のやりたいことは何でもできると思うが、ライブラリが動く下には、先人達が積み上げた低レイヤの技術が地層のように積み重なっているということ。**

>ソフトウェアの世界は抽象化の積み重ねによって進歩してきました。アセンプラはマシン語に対する抽象化であり、C言語はアセンブラに対する抽象化です。そして、C言語の上にはさらに、Cで実装された各種のスクリプト言語が存在します。抽象化は低レイヤの複雑な部分を隠蔽し、より生産性、安全性の高い方法でプログラミングする手段を開発者に提供します。
（中略）
たとえば、RubyやPelのスクリプトがセグメンテーションフォルトで異常終了する問題が発生したら、Cのレベルまで下りて原因を探る必要があります。ときには、特殊な問題のために「実行中に自分自身のマシン語のコードを書き換える」といったトリッキーなテクニックが必要になることもあります。低レイヤの技術を知らなければ、このような問題を解決することはできないでしょう。

**今に置き換えると、pythonのライブラリを実行して、何かエラーが起きた場合はOSやC言語等のレベルまで掘り下げて原因を探る必要がある。**

出典：高林哲、鵜飼文敏、佐藤祐介、浜地慎一郎、首藤一幸著「Binary Hacks」（オライリー・ジャパン）

### TCP/IP
AIが進化しても変わらない技術があります。それはTCP/IPです。
デバイス数が世界の人工を上回り、IPV4も枯渇化が進み、ビッグデータという言葉が生まれてインターネットのトラフィック量が爆発的に増えることが予想されますが、インターネットにおける通信プロトコルのデファクトスタンダードとしてTCP/IPはまだまだ使われるでしょう。Webサービスを提供するならTCP/IPのスキルは必須です。

### オープンソース
オープンソースは動いて当たり前ですが、ライブラリの依存関係やそこに係る人々を抽象化しています。

[TechCrunchのオープンソースの持続可能性](https://jp.techcrunch.com/2018/06/27/2018-06-23-open-source-sustainability/)より

>Eghbalは、OpenSSLを例とした挙げた。これはWeb上の暗号化された通信の大部分を担うライブラリだ。Heartbleedセキュリティバグが公表されたときに、人びとはOpenSSLプロジェクトが非常に小さな個人のチームの仕事であり、そのうちの1人だけがフルタイムで働いていることを知って驚いた（そのフルタイム作業者も、業界基準に比べれば非常に少ない給与で働いていたのだ）。

Pythonでは便利なライブラリがたくさんがありますが、それらはエコシステムによって支えられています。先人達に感謝しましよう。

## さいごに
自分で導き出した人工知能を学習するためのメソッドです。

1. 人工知能でできること、できないことなどを整理し、やりたいことに対する自分のスタンスを決める。
2. やりたいことを実現させるための最適なアルゴリズムを見つける。
3. Pythonや必要なライブラリの使い方を覚える。

人工知能の学習に数学は必要？

**やみくもに数学を勉強する必要はなく、アルゴリズムのチューニングなど必要に応じて最短距離で勉強すればいい。**