覚え書きブログ

Pythonによる機械学習1(Pythonの基礎 1/4)

データ解析を題材に、Pythonを用いた機械学習アルゴリズムの実装の演習を行います。本演習では、最近の機械学習ライブラリの普及によりブラックボックス化され、かえって理解が困難になった機械学習アルゴリズムの基礎的な部分の理解を深めることを目的としています。具体的には、scikit-learn、tensorflow, caffe, chanierなどの機械学習のライブラリを使わずに、教師あり学習ニューラルネットワークおよび強化学習のQ学習を、pythonの基本ライブラリのみを用いてイチから実装します。

1回目(Pythonの基礎)Pythonの環境の構築、numpyによる数値演算、matplotlib、pdbデバッグ、データ構造(リスト、タプル、辞書、numpy.array、pandas.dataframe)、リスト内包表記、関数およびオブジェクト指向などPythonスクリプトの基礎的な記述方法を学びます。


2回目(ロジスティック回帰の実装)人工知能(3セメ)で学んだニューラルネットワークの復習し、ソフトマックス、交差エントロピー最急降下法などを組み合わせて、2階層のニューラルネットワーク(ロジスティック回帰)を実装することにより、教師あり学習の基本的な実装方法を学びます。


3回目(ニューラルネットワークの実装):3階層のニューラルネットワークを学習するための勾配の導出とバックプロパゲーションの実装を通し、非線形なモデルの実装方法を学びます。


4回目(ニューラルネットワークの応用)Amazonの商品レビューの感情分類およびMNISTの手書き文字画像の分類を参考に、各グループでニューラルネットワークを応用する課題を選択し、ニューラルネットワークを応用する実践方法を学びます。

5回目(グループ発表):各グループごとに、選択した応用課題の概要、応用した結果、工夫したところ、および難しかったところを発表してもらい全体で共有します。


6回目(強化学習の基礎)強化学習の基礎(教師あり学習との違い、動物の行動学習、定式化)および実用的なQ学習法について学びます。また、ベンチマークツールのopen AI Gymのセットアップを行います。


7回目(Q学習の実装):Q学習法の実装を通し、強化学習の基本的な実装方法を学びます。また、Mountain Carタスクを用いて、実装したQ学習による強化学習の実験を行います。


8回目(強化学習の応用):Mountain Carタスクを参考に、各グループで強化学習を応用する課題を選択し、強化学習を応用する実践方法を学びます。


9回目(グループ発表):各グループごとに、選択した応用課題の概要、応用した結果、工夫したところ、および難しかったところを発表してもらい全体で共有します。



Pythonによる機械学習Pythonの基礎 1/4)の目次】



Pythonとは

Pythonは、近年、機械学習を用いたデータ解析やソフトウェアの研究開発にて、標準的に利用されているスクリプト言語で、以下の利点を持っています。

  • コンパイルを必要とせずインタラクティブに動作確認をしながら容易に実装ができる。
  • ブロック構造にカッコを用いず、インデント(スペースやタブ)を用いるため可読性が高い。
  • ライブラリが豊富なため、やりたいことが大抵はできる。

例)機械学習:scikit-learn,、数値演算:numpy、データ構造:pandas、ディープラーニングcaffe, tensorflow, chainer、画像処理cv2、グラフmatplotlib



Python環境の構築(和歌山大学向け)

ホームディレクトリの.bashrcに、以下の行を追加してください。

export PATH="/home/staff/hhachiya/anaconda3/bin:$PATH"

【既にbashを利用している方】
以下のコマンドを打って、bashを起動してください。

$ bash
bash-4.1 $

bash以外のshellを利用している方】
以下のコマンドを打って、.bashrcを読み込んでください。

bash-4.1 $ source ~/.bashrc

そして、pythonインタラクティブモードで起動します。
ちなみに、このインタラクティブモードは、読み込んで評価して表示してを繰り返すことからREPL(Read Evaluate Print Loop)とも呼ばれています。

> Python 3.6.3 |Anaconda, Inc.| (default, Oct 13 2017, 12:02:49)
[GCC 7.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

1行目のバージョン情報に、「Python 3.6.3 |Anaconda, Inc.| 」のように表示されていることを確認しましょう。



Python環境の構築(一般向け)

まず、各自、Pythonの環境を構築します。以下の手順で、最新版のPythonをインストールしてください。
1) 以下からPython3.xをダウンロードします(赤枠をクリック)。
https://www.anaconda.com/download/
f:id:hirotaka_hachiya:20171115145223p:plain:w600

Webページへのアクセスを省略したい人は、以下のようにwgetでもダウンロードできます。

> wget https://repo.continuum.io/archive/Anaconda3-5.0.1-Linux-x86_64.sh

2) ダウンロードしたshellスクリプトを実行して、Anacondaをインストールします。

> sh ./Anaconda3-5.0.1-Linux-x86_64.sh
...
Please, press ENTER to continue
>>> 

Enterを押す

...
Do you accept the license terms? [yes|no]
[no] >>>

yesと入力し、Enterを押す

...
Anaconda3 will now be installed into this location:
/home/student/xxx/anaconda3

  - Press ENTER to confirm the location
  - Press CTRL-C to abort the installation
  - Or specify a different location below
[/home/staff/hhachiya/anaconda3] >>> 

yesと入力し、Enterを押す

Do you wish the installer to prepend the Anaconda3 install location
to PATH in your /home/staff/hhachiya/.bashrc ? [yes|no]
[no] >>> 

yesと入力し、Enterを押す

3) pythonを実行する
まずは、インストールしたAnacondaに設定されたpathを読み込む

> source ~/.bashrc

※利用しているシェルがbashじゃない場合は、以下のようにbashを実行しましょう。

> bash

そして、pythonインタラクティブモードで起動します。

> Python 3.6.3 |Anaconda, Inc.| (default, Oct 13 2017, 12:02:49)
[GCC 7.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

1行目のバージョン情報に、「Python 3.6.3 |Anaconda, Inc.| 」のように表示されていることを確認しましょう。



開発環境の構築

本演習で用いるコードやデータは、gitでバージョン管理しています。リモートレポジトリは、以下のgithub上にリモートレポジトリ「intelligentSystemTraining」を作成しています。
https://github.com/hhachiya/intelligentSystemTraining

以下の手順で、開発環境(ローカルレポジトリ)を構築してください。
1) Webブラウザで「https://github.com/hhachiya/intelligentSystemTraining」をアクセスする
2) 「Clone or download」をクリックし、URLをコピーする
f:id:hirotaka_hachiya:20171204172628p:plain

3)ターミナル上で、以下のコマンドを打ちローカルレポジトリを作成する

> git clone https://github.com/hhachiya/intelligentSystemTraining.git

Cloning into 'intelligentSystemTraining'...
remote: Counting objects: 169, done.
remote: Compressing objects: 100% (116/116), done.
remote: Total 169 (delta 94), reused 120 (delta 51), pack-reused 0
Receiving objects: 100% (169/169), 239.06 KiB | 849.00 KiB/s, done.
Resolving deltas: 100% (94/94), done.

4)以下のようにintelligentSystemTrainingというフォルダが作成されていることを確認する

> ls intelligentSystemTraining/
README.md               logisticRegression_template.py  visualization
classifier_template.py  neuralNetwork_template.py
data.py                 sentiment_labelled_sentences

本演習におけるコードの作成・実行などの作業は、上記の「intelligentSystemTraining」フォルダにて行ってください。

なお、Windows上でのgit環境を構築については、以下を参照ください。
hirotaka-hachiya.hatenablog.com




Pythonにおけるデータ構造

ここから、Pythonの基礎的なコードの例を参考に演習を始めます。まずは、プログラミングで重要なデータ構造から始めます。

Pythonには、一連のデータを格納する方法が複数あります。

  • リストPython 標準):各要素をオブジェクト(数値、文字列、リスト自身など)として格納する変数。型を気にせず配列操作が簡単にできる。

以下のように、角括弧[オブジェクト1, オブジェクト2...]を用いて定義します。Pythonインタラクティブモードで実際に試しみてみましょう。

> python
>>> price = [120,180,300,150]
>>> fruit =["apple", "orange","pineapple","banana"]
>>> all = [price, fruit]
>>> all
[[120,180,300,150], ['apple', 'orange','pineapple','banana']]



  • タプル(※時間がある人のみ)Python 標準):要素の上書き、追加および削除ができないリスト。リストよりも高速にアクセスできるメリットがある。

以下のように、丸括弧(オブジェクト1, オブジェクト2...)を用いて定義します。

> python
>>> price = (120,180,300,150)
>>> price[0]
120
>>>price[0]=150
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment



  • 辞書(※時間がある人のみ)Python 標準):各要素に名前を付けられるリスト。

以下のように、中括弧{オブジェクト1の名前:オブジェクト1, オブジェクト2の名前:オブジェクト2...}を用いて定義します。

> python
>>> all=[{'price':120, 'fruit':'apple'},{'price':180, 'fruit':'orange'},{'price':300, 'fruit':'pineapple'},{'price':150, 'fruit':'banana'}]
>>> all[0]
{'price': 120, 'fruit': 'apple'}
>>> all[1]['fruit']
'orange'



  • numpy array:各要素を統一の型(float32, int, u32など)で格納する変数。厳密に型を意識して、行列やベクトルとして演算ができます。

以下のように、numpyライブラリをnpとしてインポートして、np.array(リスト)関数を用いて定義します。

>  python
>>> import numpy as np
>>> price = np.array([120,180,300,150])
>>> fruit = np.array(["apple", "orange","pineapple","banana"])
>>> all = np.array([price, fruit])

# 型の表示
>>> price.dtype
dtype('int64')
>>> fruit.dtype
dtype('<U6')
>>> all.dtype
dtype('O')

# 和の計算
>>> np.sum(value)
750



  • pandas.dataframe:データベース(またはエクセル)のテーブルのように、カラム名(列)とインデックスを割り振って各要素を格納する変数。エクセル(csv形式)のデータの読み書きが簡単にできるため、データ解析でよく使われます。

以下のように、pandasライブラリをpdとしてインポートして、Series(numpy.array, name="カラム名")を用いて定義します。

> python
>>> import pandas as pd
>>> price = pd.Series(np.array([120,180,300,150]),name="price")
>>> fruit = pd.Series(np.array(["apple","orange","pineapple","banana"]),name="fruit")
>>> pd.concat([price,fruit],axis=1)
   price      fruit
0    120      apple
1    180     orange
2    300  pineapple
3    150     banana

これは、エクセルでは以下のような表を作っていることに対応します。
f:id:hirotaka_hachiya:20181114204608p:plain

以下、リスト、numpy.arrayおよびdataframeを使ったサンプルコードです(※コードが表示されない方は、こちらを参照してください)。

上記のスクリプトをファイルlist_numpy_dataframe.pyに、文字コードUTF-8で保存し以下のように実行します。

> python list_numpy_dataframe.py
要素の追加前: ['Yamada Taro' 'Yamada Hanako'] [ 172.5  160.5]
要素の追加後: ['Yamada Taro' 'Yamada Hanako' 'Wakayama Dai'] [ 172.5  160.5  180.2]
-------

全ての要素: ['Yamada Taro' 'Yamada Hanako' 'Wakayama Dai']
0番目の要素: Yamada Taro
1番目までの要素: ['Yamada Taro' 'Yamada Hanako']
最後の要素: Wakayama Dai
0から1番目までの要素: ['Yamada Taro' 'Yamada Hanako']
170以上のインデックス: (array([0, 2], dtype=int64),)
170以上の要素: ['Yamada Taro' 'Wakayama Dai']
-------

d_dataframe:
             name  height
0    Yamada Taro   172.5
1  Yamada Hanako   160.5
2   Wakayama Dai   180.2

name列:
 0      Yamada Taro
1    Yamada Hanako
2     Wakayama Dai
Name: name, dtype: object

height列のインデックス0番: 172.

リストから、numpy arrayに変換する際に、少数の場合はfloat64、文字列の場合はUnicode(U13, U6)に自動的に設定されていることがわかります。また、numpy array(およびlist)では、appendを用いて簡単に要素を追加でき、さらに様々な要素への参照方法があることがわかります。
numpy.appendの詳細は、下記を参照してください。
https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.append.html
さらに、d_dataframeは、「name」または「height」のキーと、インデックスで各要素を参照できることがわかります。

演習1

d_dataframeに、年齢「age」の列を追加してみましょう。
以下のように、Yamada Taroさんは21歳、Yamada Hanakoさんは19歳、Wakayama Daiさんは30歳に設定してください。

d_dataframe:
             name  height  age
0    Yamada Taro   172.5   21
1  Yamada Hanako   160.5   19
3  Wakayama Dai   180.2   30

作成したスクリプトおよび出力結果を、Moodleにて提出してください。

Pythonによる機械学習1(Pythonの基礎 2/4)>>