機械学習の本のメモ

http://cl.sd.tmu.ac.jp/prospective/readings
をながめていたら、自分のメモも残しておきたくなった。

[教科書]
パターン認識機械学習PRML
定本。昔輪講で使った
自然言語処理のための機械学習入門
自然言語処理にかぎらず入門として良かった。ベイズの解説が丁寧だった記憶がある。

[概要の復習/俯瞰に使える本]
フリーソフトでつくる音声認識システム ~パターン認識機械学習の初歩から対話システムまで
概要を眺めるのに良い。この本を見ながらパーセプトロン最急降下法を実装した。
メルケプストラム係数の説明がよかった
フリーソフトではじめる機械学習入門
全体像を俯瞰するのに良い。上の音声認識システムと類書?
・はじめてのパターン認識
フリーソフトではじめる〜の内容をもう少しだけ掘り下げて知りたいときに便利。
・ITエンジニアのための機械学習入門
EMアルゴリズムをつかってMNISTデータを分類するところが参考になった

[確率統計の復習]
・完全独習統計学入門
・完全独習ベイズ統計学入門
シンプルな記述でわかりやすかった
・入門 統計学 検定から多変量解析・実験計画法まで
記述が詳しくて良かった

[言語処理]
自然言語処理入門(オライリー
NLTKの使い方をこれで覚えた。分厚いが、入門としては良い本ではないらしい?
・言語と計算 (4) 確率的言語モデル | 北 研二, 辻井 潤一
よく覚えていないが、参考になる箇所があって、何回も読み返した記憶がある。

[実装に関する本]
集合知プログラミング
NMF(非負値行列因子分解)をこの本で知った。サンプルコードを写経した記憶がある。
機械学習入門(ML for Hackers)
Rの使い方をこれで覚えた
・実践機械学習システム
今見返したら、後半のスペクトログラム、次元削減、画像認識のところがすぐに参考になりそう
Pythonによるデータ分析入門
PythonでもPandasを使えばRみたいにできるんだ、と感心しただけで終わっていたが、今見ると時系列解析の手法など、参考になりそうな部分がある。
・RとRubyによるデータ解析入門
トイレがどうとか、という例題があったのを覚えている。検定の話が出ていた記憶がある。

[深層学習の実装に使える本]
・ゼロから作るDeep Learning
Clojureで実装し直していたが、途中であきらめた。もう一度読む。
・TensorFlowで学ぶディープラーニング
まだ読んでないが、公式のチュートリアルやるよりも、本でやったほうが良さそう

[数学の復習に使える本]
・これなら分かる応用数学教室
最小二乗法→直交関数展開→フーリエ変換、という解説の流れが神がかっている
・これなら分かる最適化数学
SVMの実装をしていて、2次計画法(非線形計画法)の理論を知りたくて読んだ。動的計画法の記述もある。

[プログラミング一般]
プログラミングコンテストチャレンジブック
後回しになってしまって読んでいないが、あとで読む

[読書メモ]
・わかりやすいパターン認識
この分量でSVMが無いのが謎
・続・わかりやすいパターン認識教師なし学習
EMアルゴリズムの説明に特徴があるらしいので興味あり
Python機械学習プログラミング
→とてもおすすめらしい

t分布、カイ2乗分布、F分布

Γ=ガンマ関数、γ=不完全ガンマ関数、B=不完全ベータ関数、I=正規化不完全ベータ関数

t分布

確率密度関数

積分布関数

import numpy as np
from pylab import *
import math

vs = [1.0,2.0,5.0,100.0]
colors = ['b','g','r','c']
xs = np.linspace(-5,5,100)
counter = 0
for v in vs:
    print counter
    fs = []
    c = colors[counter]
    for x in xs:
        fs.append(math.gamma((v+1)/2)/(math.sqrt(v*math.pi)*math.gamma(v/2))*((1+x**2/v)**(-(v+1)/2)))
    plot(xs,fs,color=c)
    counter = counter+1

stringArray = []
for v in vs:
    stringArray.append('v={0}'.format(v))
legend(stringArray)
title('Student\'s t distribution')
show()


カイ2乗分布

確率密度関数

積分布関数

import numpy as np
from pylab import *
import math

ks = [1.0,2.0,3.0,4.0,5.0]
colors = ['b','g','r','c','m']
xs = np.linspace(0,8,50)
counter = 0
for k in ks:
    print counter
    fs = []
    c = colors[counter]
    for x in xs:
        f = ((0.5)**(k/2))/(math.gamma(k/2))*x**(k/2-1)*math.e**(-x/2)
        fs.append(f)
    plot(xs,fs,color=c)
    counter = counter+1

stringArray = []
for k in ks:
    stringArray.append('k={0}'.format(k))
legend(stringArray)
title('Chi-squared distribution')
show()

F分布

確率密度関数

積分布関数

import numpy as np
from pylab import *
import math

def beta(a,b):
    beta = math.gamma(a)*math.gamma(b)/math.gamma(a+b)
    return beta

ds = [(1.0,4.0),(6.0,28.0),(28.0,6.0)]
colors = ['b','g','r']
xs = np.linspace(0,4,50)
counter = 0
for d in ds:
    print counter
    fs = []
    c = colors[counter]
    for x in xs:
        d1 = d[0]
        d2 = d[1]
        f = 1/(beta(d1/2,d2/2))*(d1*x/(d1*x+d2))**(d1/2)*(1-(d1*x/(d1*x+d2)))**(d2/2)*(x**(-1))
        fs.append(f)
    plot(xs,fs,color=c)
    counter = counter+1

stringArray = []
for d in ds:
    stringArray.append('(d1,d2)={0}'.format(d))
legend(stringArray)
title('F distribution')
show()

PYNQにOpenCVを入れてWebカメラの映像を入力する

apt-get して入れた?opencvではWebカメラが認識されなかったのでソースからビルドする

http://stackoverflow.com/questions/14424325/opencv-cannot-acces-my-webcam

cd opencv
mkdir build 
cd build
cmake -D CMAKE_BULD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_PYTHON_SUPPORT=ON USE_V4L=ON WITH_TBB=ON -D BUILD_NEW_PYTHON_SUPPORT=ON USE_GStreamer=ON ..
make 
sudo make install

FFTとIFFTでローパスフィルタ

# -*- coding: utf-8 -*-
from pylab import *
import numpy as np
import pdb

fin = open("3_3.csv","r").readlines()
xs = []
ys = []
for line in fin:
    x  = float(line.rstrip().split(',')[0])
    y = float(line.rstrip().split(',')[1])
    xs.append(x)
    ys.append(y)

xs = xs[2:-1]
ys = ys[2:-1]

ave = sum(ys)/len(ys)
aves = [ave for i in range(len(ys))]
subplot(221)
plot(xs,ys,'b-')
plot(xs,aves,'r-',linewidth=3.0)
l = ['raw','average']
legend(l)
title(u'原波形')

Fk = np.fft.fft(ys)
P = Fk*np.conj(Fk)
subplot(222)
semilogy(P)
title(u'パワースペクトル')

subplot(223)
fs = 20
for i in range(len(P)):
    if i>fs:
        P[i]=0
        Fk[i]=0

semilogy(P)
ylim([10**3,10**14])
title(u'フィルタ後パワースペクトル\n第20高調波以上を阻止')

subplot(224)
f = np.fft.ifft(Fk)
plot(f)
title(u'ローパスフィルタをかけた信号波形')

show()

アヤメデータをベイズ識別器で分類する

尤度関数を多次元正規分布で仮定する(アヤメデータの場合、d=4(Sepal.Length, Sepal.Width, Petal.Length, Petal.Width))
 p(x|C_i) = \frac{1}{(2 \pi)^{d/2} det{\Sigma_i}^{1/2}} {\rm exp} (-\frac{1}{2}(x-\mu_i)^T \Sigma_i^{-1} (x-\mu_i))

識別関数はベイズの定理を使い、上の尤度関数の対数をとって用い、-1を両辺にかけることで
 g_i(x) = (x-\mu_i)^T \Sigma_i^{-1} (x-\mu_i)+ ln det{\Sigma_i} -2 ln P(C_i)

識別規則は、
  C_i = \underset{i}{\arg\min}  g_i(x)

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
import math
from numpy import dot
import pdb

iris = datasets.load_iris()
data = iris.data
target = iris.target

Pc1 = 1/3.0 # a priori probability
Pc2 = 1/3.0
Pc3 = 1/3.0

c1_indices = np.where(target==0)[0].tolist()
c2_indices = np.where(target==1)[0].tolist()
c3_indices = np.where(target==2)[0].tolist()

c1=[]
c2=[]
c3=[]
for idx in c1_indices:
    c1.append(data[idx])
for idx in c2_indices:
    c2.append(data[idx])
for idx in c3_indices:
    c3.append(data[idx])

c1a = np.array(c1)
c2a = np.array(c2)
c3a = np.array(c3)

mu1 = sum(c1) /len(c1)
mu2 = sum(c2) /len(c2)
mu3 = sum(c3) /len(c3)
mu1s = mu1*np.ones((len(c1a),1))
mu2s = mu2*np.ones((len(c2a),1))
mu3s = mu3*np.ones((len(c3a),1))

S1 = np.zeros((4,4))
for i in range(4):
    for j in range(4):
        s = sum((c1a[:,i] - mu1s[:,i])*(c1a[:,j]-mu1s[:,j]))
        cov = s/len(data)
        S1[i,j] = cov 

S2 = np.zeros((4,4))
for i in range(4):
    for j in range(4):
        s = sum((c2a[:,i] - mu2s[:,i])*(c2a[:,j]-mu2s[:,j]))
        cov = s/len(data)
        S2[i,j] = cov 

S3 = np.zeros((4,4))
for i in range(4):
    for j in range(4):
        s = sum((c3a[:,i] - mu3s[:,i])*(c3a[:,j]-mu3s[:,j]))
        cov = s/len(data)
        S3[i,j] = cov 

def g1(x):
    A=np.matrix(x).T-np.matrix(mu1).T
    B=np.linalg.inv(S1)
    C=A.T
    detS1 = np.linalg.det(S1) 
    result = dot(dot(C,B),A) + np.log(detS1) - 2*math.log(Pc1)
    return result.item()
def g2(x):
    A=np.matrix(x).T-np.matrix(mu2).T
    B=np.linalg.inv(S2)
    C=A.T
    detS2 = np.linalg.det(S2) 
    result = dot(dot(C,B),A) + np.log(detS2) - 2*math.log(Pc2)
    return result.item()
def g3(x):
    A=np.matrix(x).T-np.matrix(mu3).T
    B=np.linalg.inv(S3)
    C=A.T
    detS3 = np.linalg.det(S3) 
    result = dot(dot(C,B),A) + np.log(detS3) - 2*math.log(Pc3)
    return result.item()

def classify(x):
    map1inv = g1(x)
    map2inv = g2(x)
    map3inv = g3(x)
    mapinvs = np.array([map1inv,map2inv,map3inv])
    result = np.where(mapinvs==min(mapinvs))[0].tolist()[0]
    return result

results = []
for d in data:
    res = classify(d)
    results.append(res) 

def makeColor(labels):
    colors=[]
    for l in labels:
        if l==0:
            colors.append('r')
        elif l==1:
            colors.append('g')
        elif l==2:
            colors.append('b')
    return colors

def calcPrecision(target,results):
    success = 0
    fail = 0
    for i in range(len(target)):
        if target[i]==results[i]:
            success = success + 1
        else:
            fail = fail+1
    return success/float(success+fail)*100

precision = calcPrecision(target,results)
print 'success rate: ',precision,'%'

plt.subplot(121)
xs = data[:,0]
ys = data[:,2]
s = [30 for i in range(len(xs))]
colors = makeColor(target)
plt.scatter(xs,ys,s,colors)
plt.title('original data')

plt.subplot(122)
colors = makeColor(results)
plt.scatter(xs,ys,s,colors)
plt.title('Bayes classifier with normal distribution')


plt.show()

実行結果

success rate:  98.6666666667 %