Pythonで機械学習するのに勉強したことまとめ

#概要
何を隠そう食べごろうは，機械学習を扱う研究室に所属するにもかかわらず，"Pythonに初めて触れたのが学部3年" && "記憶力がべらぼうに悪い"という最悪の条件が整った人材である．
一度調べたこともすぐに忘れてしまうので，手だけでも動かす＋後々見返しやすくするためにこの記事を書いていく．

#本編

##リスト・配列操作
基礎で困りがち．

###初期化

```python:List
#単純なリストの宣言．何もインポートせずに使える．異なる型の要素を持つこともできる
list = [1,2]

#多次元配列も宣言可能
list_2D = [['a','b'], ['c','d']]     
```

```python:array
import array

#arrayモジュールをインポートして作る．第一引数で型コードを宣言し，第二引数の配列の要素の型はそれに合わせる必要がある．
array_int = array.array('i', [0,1,2])
```

```python:ndarray
import numpy as np

#numpyモジュールインポートして作る．配列の要素の型は合わせる必要がある（Object型を使うことで例外的に操作することは可能っぽい）
np_array = np.array([1,2,3])

#多次元配列も宣言可能
np_array_2D = np.array([[1,2,3],[4,5,6]])
```


###配列要素へのアクセス
後で．

##pandasモジュール
データを`Series`または`DataFrame`型としてを天才的に扱いやすくするモジュール．csvファイル使う操作とかには必須か．使用時には`numpy`も同時にインポートした方がいい．

###read_csvメソッド
csvファイルから`DataFrame`オブジェクトを作れる．

```python:pandas.read_csv
#例
import pandas as pd
import numpy as np

inputs = pd.read_csv('dir1/input.csv', index_col=0)
```

上の例では`inputs`をカレントディレクトリからの相対パスが`dir1/input.csv`であるファイルを，0列目をインデックスとしてDataFrame型に変換したものにしている．
この場合，ヘッダーはデフォルトで0行目が指定されている．

###applyメソッド
DataFrame型の各行・列，またはSeries型の各要素に関数を適用するメソッド．（デフォルトでは列だが，引数に`axis=1`を加えると行に適用される）

```python:apply
#例
df = pd.DataFrame([[0,1,2],[3,4,5],[6,7,8],[9,10,11]], columns=['A','B','C'], index=['a','b','c','d'])
#    A  B  C
# a  0  1  2
# b  3  4  5
# c  6  7  8
# d  9  10 11

f = lambda x: max(x) - min(x)

print(df.apply(f))
#    A  B  C
#    9  9  9
```
※追記
`df.swifter.apply()`とすると高速化できるらしい．`swifter`が早く処理してくれる方法を自走で選んでくれるとかなんとか．

###DataFrameからの行・列の取り出し
`df`は適当なDataFrame型の変数とする．

**行**

* `df.head(5)`：先頭の5行を表示する．
* `df[:5]`：先頭の5行を表示する．（スライスを使ったやり方）
* `df.[-5:]`：最後から5行を表示する．（負の数は，データの最後から遡った数を指定することになる）
* `df.iloc[0]`：（headerを含めない）0行目を表示する．
* `df.loc[0]`：（headerを含めない）0行目を表示する．

**列**

* `df['index1']`：インデックス名が`index1`の列を表示
* `df[['index1', 'index3']]`：インデックス名が`index1`の列と`index3`の列を表示
* `df.iloc[:, 0:2]`：（indexを含めない）0~1列目を表示
* `df.loc[:, ['index1', 'index3']]`：インデックス名が`index1`の列と`index3`の列を表示

**要素・部分**

* `df.iloc[0:5, 0:2]`：（headerを含めない）0~4行目の，（indexを含めない）0~1列目を表示
* `df.loc[1:3, ['index1', 'index3']]`：（headerを含めない）1~3行目の，インデックス名が`index1`の列と`index3`の列を表示

##Kerasモジュール
機械学習で避けて通れないぽいモジュール．

###Keras.layers
多分ニューラルネットワークモデルの層を作るのにお役立ち．
###Keras.layers.Input
ニューラルネットワークモデルの入力層を宣言する．

```python:Keras.layers.Input
#例
from keras.layers import Input
inputs = Input(shape=(5,))
```

上の例では`inputs`を5次元の入力として宣言する．


###Keras.layers.Dense
ニューラルネットワークモデルの隠れ層を宣言する．

```python:Keras.layers.Dense
#Documentation
keras.layers.Dense(units, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)

#例
from keras.layers import Dense
x = Dense(20,activation='tanh')(inputs)
```

上の例では`x`を，ノード数が20で，入力が`inputs`であるような層として宣言する

###Keras.layers.Dropout
ニューラルネットワークモデルの隠れ層におけるドロップアウト（＝ランダムにニューロンを消去しながら学習を行う手法．過学習の抑制などの目的）を行う．

```python:Keras.layers.Dropout
#Documentation
keras.layers.Dropout(rate, noise_shape=None, seed=None)

#例
from keras.layers import Dropout
y = Dropout(0.3)(x)
```

上の例では`y`を，入力が`x`で，0.3の割合でドロップアウトさせる層として宣言している．

##Keras.models
多分モデルを動かすのにお役立ち．
###Keras.models.Model
モデルの入力と出力の層を指定できる．

```python:Keras.models.Model
#例
from keras.models import Model
from keras.layers import Input, Dense

a = Input(shape=(32,))
b = Dense(32)(a)
model = Model(inputs=a, outputs=b)
```
上の例では`model`を，入力層が`x`で，出力層が`b`のモデルとして宣言している．

####compileメソッド
学習モデルの設定．詳しくは[公式ドキュメント](https://keras.io/ja/models/model/)で

```Model.compile
# Documentation
compile(optimizer, loss=None, metrics=None, loss_weights=None, sample_weight_mode=None, weighted_metrics=None, target_tensors=None)
```

##argparseモジュール
pythonの実行時にコマンドライン引数を取りたい時におすすめなモジュール．
公式ドキュメントは[こちら](https://docs.python.org/ja/3/library/argparse.html)．
###argparse.ArgumentParser
Parserの宣言・初期化に必要っぽい．Parserは多分，コマンドライン引数をちゃんと分割して，それぞれの引数の意味を解析してくれるやつ．

```python:argparse.ArgumentParser
#Documentation
class argparse.ArgumentParser(prog=None, usage=None, description=None, epilog=None, parents=[], formatter_class=argparse.HelpFormatter, prefix_chars='-', fromfile_prefix_chars=None, argument_default=None, conflict_handler='error', add_help=True, allow_abbrev=True, exit_on_error=True)

#例
import argparse

parser = argparse.ArgumentParser(description='お試し')
```

上の例では`parser`を，このインスタンスの説明文を'お試し'として宣言している．

####add_argumentメソッド
作ったParserに，受け取る引数を追加するメソッド．

```python:ArgumentParser.add_argument
#Documentation
ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])

#例
#parserは上の例で作ったものとする
parser.add_argument('arg1', help='第一引数')
parser.add_argument('-c', '--config', type=int, default=None, help='オプション引数')
```

上の例は，`parser`に第一引数`arg1`と，オプション引数`config`を許容している．

####parse_argsメソッド
実際にコマンドライン引数をパースするメソッド．

```python:ArgumentParser.parse_args
#Documentation
ArgumentParser.parse_args(args=None, namespace=None)

#例
#parserは上の例で作ったものとする
#コマンドラインは　$python sample.py input.txt -c 50000　とする
args = parser.parse_args()
```

上の例では，`args.arg1`に`input.txt`が，`args.config`に`50000`が入る事になる．