機械学習におけるData Augmentationのまとめ【その1】

Data Augmentationとは

一般的には,Data Augmentation(以下,DA)とは機械学習(Deep Learningなど)で性能を向上させるための技術のひとつである. 簡単な概要としては,学習用のデータに対し人工的なノイズなどを付加した画像を生成し,生成した画像を元の学習用データに追加することで性能の向上が期待される技術である.

DAを用いる方法

DAを用いる方法は2つに分類される.まず,機械学習では学習と検証という2つのフェーズを経て学習モデルが学習される.これらを踏まえ学習時に用いる方法が最も一般的なDAである.一方で学習時および検証時にもDAを用いる方法も存在し,この手法はTest Time Augmentationと呼ばれている.

Deep Learning(以下,DL)におけるDAの簡単な歴史

DLにおけるDAの歴史としては,DA関連の論文の多くでは2012年にAlexらがDAを用いたものを引用していることからAlexらの研究を基準に考えることが妥当だと考えることが出来る[1].それ以降様々なDAの種類が提案され続けている.最も一般的なDA手法はKerasなどでも実装されている手法などであるのでそれを参考していただきたい[2].著者の勝手な偏見でDAの手法のターニングポイントと考える手法は,年代順に挙げるとcutout[4]/Random Erasing[5], mixup[6], DAGANおよびshake-shake[7]の5手法であると考える.それぞれの手法についての紹介は今後行う予定である.

DAの面白い研究

DAについて面白い取組みをしている研究は,話題となったAuto Augmentであると考えている.この研究はニューラルネットのモデルを機械的に生成するための研究にインスパイヤされた研究で,機械的にDAの適用方法を最適化していく研究となっている.この研究についての詳しい内容は今後説明したいと考えている.

参考文献

  1. https://github.com/keras-team/keras-docs-ja
  2. Krizhevsky, A., Sutskever, I., Hinton, G.E.: Imagenet classification with deep convolutional neural networks. In: Proceedings of the Advances Neural Information Processing Systems 25 (NIPS), pp. 1097–1105 (2012)
  3. Devries, T. and Taylor, G. W.: Improved Regularization of Convolutional Neural Networks with cutout (2017). arXiv 1708.04552v1 1.
  4. Zhong, Z., Zheng, L., Kang, G., Li, S. and Yang, Y.: Random Erasing Data Augmentation (2017). arXiv 1708.04896. 6.Zhang, H., Cisse, M., Dauphin, Y. N. and Lopez-Paz, D.: mixup: Beyond Empirical Risk Minimization (2017). arXiv 1710.09412v1 1.
  5. Yamada, Y., Iwamura, M. and Kise, K.: ShakeDrop regularization (2018). arXiv1802.02375.

sortedでkeyにlambda使ったやり方

sortedでkeyにlambda使った物をよく見かけるのでまとめておきます

sorted((list or dict) key=lambda x: x[0])

こんなのです

で使い方としては

sorted(【リストor辞書】, key=lambda x: 【keyにしたい要素】)

こんな感じです

例としては

dictionary = [['な',3], ['か',4], ['と',1], ['お',2]]

print(dictionary) # [['な', 3], ['か', 4], ['と', 1], ['お', 2]]

sorted_dict = sorted(dictionary, key=lambda x: x[0])

# [['お', 2], ['か', 4], ['と', 1], ['な', 3]]

sorted_dict= sorted(dictionary, key=lambda x: x[1])

# [['お', 2], ['か', 4], ['と', 1], ['な', 3]]

sorted関数のkeyに「要素xを受け取り、x[1]を返す」というlambda式を指定している. 従って,sorted関数は、リストの2番目の要素をkeyとしてソートを行うようになった.

また、keyを関数として指定も可能

dictionary = [['なら',3], ['かながわ',4], ['とうきょう',1], ['おおさか',2]]

print(dictionary) # [['なら', 3], ['かながわ', 4], ['とうきょう', 1], ['おおさか', 2]]

def get_value(name_and_value):
    name, value = name_and_value
    return value

sortedDict = sorted(dictionary, key=get_value)

print(sortedDict) # [['おおさか', 2], ['かながわ', 4], ['とうきょう', 1], ['なら', 3]]

def get_name(name_and_value):
    name, value = name_and_value
    return name

sortedDict = sorted(dictionary, key=get_name)

print(sortedDict) # [['とうきょう', 1], ['おおさか', 2], ['なら', 3], ['かながわ', 4]]

その他の例1

class Hoge:
    def __init__(self, i, name):
      self.i = i
      self.name = name
    def __repr__(self):
      return "%d:%s" % (self.i, self.name)

l2 = [Hoge(2, 'c'), Hoge(3, 'a'), Hoge(1, 'b')]
print(l2) #[2:c, 3:a, 1:b]
sort_result = sorted(l2, key=lambda h: h.name)
print(sort_result) #[3:a, 1:b, 2:c]

上記の例はHogeオブジェクトのname属性を返す関数を指定したことで、name属性でソートしている

その他の例2 operatorモジュールのattrgetter関数を用いた物

特定の属性を返す関数は、operatorモジュールのattrgetter関数を使えば簡単に作成できる。

>>> import operator
>>> l2 = [Hoge(2, 'c'), Hoge(3, 'a'), Hoge(1, 'b')]
>>> sorted(l2, key=operator.attrgetter('name'))
[3:a, 1:b, 2:c]

参考

https://qiita.com/n10432/items/e0315979286ea9121d57

https://python.civic-apps.com/sort-sorted/

numpyでstart~stop区間をnum等分したデータを生成する方法

0から1までをnum等分にしたデータを生成したい場合に用いる
```python
linspace(start,stop,num=50,endpoint=True,retstop=False,dtype=None)
```

例)ある物に適用する確率を11個分,0から1までの値で生成する場合
```python
import numpy as np

prob = np.linspace(0, 1, 11)
print(prob)

#OUTOUTS
[0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. ]
```

参考
https://qiita.com/supersaiakujin/items/4410efe5dc81982ef208
[Python]Numpyでデータを生成する色々な方法(arange/linspace/logspace/zeros/ones/mgrid/ogrid) - Qiita

python 多次元配列の各要素の特定の列の値を基準にsortする

多次元配列の各要素のある列の値を参照し,sortを行う場合の方法をまとる.

from operator import itemgetter

list1 = [[1,5,3], [6,4,8], [9,11,2]]
print('ソート前:{}'.format(list1))

list1.sort(key=itemgetter(0))
print('ソート後(0番目の要素):{}'.format(list1))

list1.sort(key=itemgetter(1))
print('ソート後(1番目の要素):{}'.format(list1))

list1.sort(key=itemgetter(2))
print('ソート後(2番目の要素):{}'.format(list1))

#OUTPUTS
ソート前:[[1, 5, 3], [6, 4, 8], [9, 11, 2]]
ソート後(0番目の要素):[[1, 5, 3], [6, 4, 8], [9, 11, 2]]
ソート後(1番目の要素):[[6, 4, 8], [1, 5, 3], [9, 11, 2]]
ソート後(2番目の要素):[[9, 11, 2], [1, 5, 3], [6, 4, 8]]

参照

programming-study.com

最小二乗法で線形近似(python,numpy)

pythonのnumpyで最小二乗法で線形近似し傾き,切片,回帰式を取得したいと思います.

```python

# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt

def main():

X = [1,2,3,4,5]
Y = [1.1, 2.1, 2.8, 4.3, 5.1]

A = np.array([X,np.ones(len(X))])
A = A.T
#線形回帰(np.linalg.lstsq)を実行してa:傾き、b:切片を取得。
a,b = np.linalg.lstsq(A,Y)[0]
print("a(傾き):{}".format(a))
print("b(切片):{}".format(b))

#X,Y生データのプロット
plt.plot(X,Y,"ro")
#y=a*X;bの回帰式をプロット
plt.plot(X,(a*X+b),"g--")
plt.grid()
plt.show()


if __name__ == '__main__':
main()

```

 

出力結果

a(傾き):1.02

b(切片):0.02

f:id:kobakenkken:20181130091444p:plain

 

matplotlibでTimes New Romanを使うためのTips

理系の論文で多用される

Times New Roman

ですが(以下参照) www.panoramic-view.info

matplotlibで使うための方法をまとめておきます.

plt.rcParams['font.family'] = 'Times New Roman'

以上です.

もし,ubuntu等で findfont: Font family ['Times New Roman'] not found. Falling back to DejaVu Sans で使用できない場合は

$ sudo apt install msttcorefonts -qq
$ rm ~/.cache/matplotlib -rf

で動くと思います.

Google ColabでKaggle! 【STEP2:データ前処理とか】

前提

まず前提として言語はpythonでpandasを使用しています.

データのダウンロード

これは参加するコンペのdatasetダウンロードするだけです.

#ダウンロード可能なコンペ一覧
!kaggle competitions list
#ダウンロード
!kaggle competitions download -c titanic

データの把握

どんなデータなのかを把握することがまず第一歩です.

import pandas as pd
import numpy as np
 
train = pd.read_csv("train.csv")
test = pd.read_csv("test.csv")

print(train.head())

f:id:kobakenkken:20181117153451p:plain

次に欠損値(null)が何個あるのか,どの項目にあるのか見てみます.

## 値がnullの項目数を数える
train.isnull().sum()
###############
PassengerId      0
Survived         0
Pclass           0
Name             0
Sex              0
Age            177
SibSp            0
Parch            0
Ticket           0
Fare             0
Cabin          687
Embarked         2
dtype: int64
################

以上からデータセット内の全体を把握します.

次回は下記の内容です

データの前処理(必要な場合)

提供されているデータを取り扱うために前処理を行う必要があります。 前処理は沢山種類がありますがここでは2種類を紹介しておきます。

欠損データの補完

この欠損値をどう処理することがベターなのかを議論することはとても重要ですが簡単な方法だけとりあえずまとめます.

Ageの補完

今回のAgeはmean(平均値)とmedian(中央値)とmode(最頻値)の3つの例を示します.

#case of mean
train["Age"] = train["Age"].fillna(train["Age"].mean())
#case of median
train["Age"] = train["Age"].fillna(train["Age"].median())
#case of mode
train["Age"] = train["Age"].fillna(train["Age"].mode())

文字列データを数値データ形式へ変換

#