mathhunの日記

Haskellと機械学習の勉強日記。PRML読みます。

PythonでPerceptronを実装してみた

PRML 4.1.7 にあるパーセプトロンを実装した。勉強のため。
いまのところPython(numpy, pandas)の知識がなさすぎて時間がかかる。
パーセプトロンは単純だし他にわかりやすい説明がいろいろあるし特に書くこともないかな。
こんなに単純なのにちゃんと学習できる事はちょっとおもしろい。

f:id:mathhun:20140109072724p:plain

コードは適当

Python Pandasメモ

Rを先に覚えたので、Rだと簡単に書けるようになったもののそれと同じ事をPython(numpy+pandas)でやりたいときに良いやり方が思いつかない AND ググっても時間がかかる AND 多分すぐ忘れる。
ので特にはまったのをメモしておく。

DataFrame ある条件を満たす行の、あるカラムの値を書き換えたい

Rだと

> df <- data.frame(x=1:5, t=sample(0:1, size=5, replace=T))
> df
  x t
1 1 0
2 2 0
3 3 0
4 4 1
5 5 0

# t==0 の行だけ t=-1 にしたい

> df[df['t']==0, ]$t = -1
> df
  x  t
1 1 -1
2 2 -1
3 3 -1
4 4  1
5 5 -1

PandasのDataFrameでは

df['t'] = df.apply(lambda row: (1 if row['t']==1 else -1), axis=1)

とりあえずやりたいことはできた

「基礎線形代数と固有値問題」読んだ

科学者・技術者のための 基礎線形代数と固有値問題

科学者・技術者のための 基礎線形代数と固有値問題

正月休みに読んだ。1日1章ずつで読める範囲で、ざっと内容を把握出来る程度に読んだだけ。細かい計算は追ってないし飛ばしたところも結構ある。また固有値問題などでひっかかったら復習する予定。

  • 対角化重要
  • 機械学習に関連しそうなもの (ここで詰まったら復習する)
    • ラグランジュの未定乗数法
    • 主成分分析
    • 遷移確率行列・マルコフ過程
    • 半正定値性 (機械学習ではおなじみらしいけどよく知らない)
    • SVD(特異値分解) (見たことあるような無いような)
  • 固有値問題に必要最小限の定理のみに絞って書いてある印象
    • より厳密な数学書を読むときに、実用に直結する定理と基礎・土台としての定理の区別がしやすくなる(といいな)

線型代数は次線型代数入門 (基礎数学1)を読みたい。

StackOverflowの質問数で見るプログラミング言語

API経由でStackOverflowの質問数を取得してグラフ化してみた。

f:id:mathhun:20140101125225p:plain

雑感
  • 最近はScalaが伸びてるんじゃないかなと予想していたがそうでもなかった。
  • PythonAPIはまだAPI V1.x系を使用しているようだが、V2.x系が出てるのでそっちを使えという事らしい。(http://api.stackexchange.com/)
    • 単純なAPIだし認証もほとんど要らないのでcurl等で直接叩いてもいいかもしれない。
  • 全体的に右上がりなのはStackOverflow自体の人気の上昇か
課題
  • 質問数以外の数値・テキストも使ってみる
  • Perlの人気を日本と海外で比較してみたいので次はQiitaあたりでもやってみたい。
コード

とりあえず時間をかけずに動かすことにしたのでコードは糞

GoogleのDeep Learning論文読んだ

Representation Learning: A Review and New Perspectives を読んだ。

どこまで理解出来てるかいまいちだがメモとしてAbstractの要約をまとめとく。読んだことメモってことで。

  • 高レベルの特徴抽出器(教師なし)を構築した (high-level, class-specific feature detectors)
  • 9-layered locally connected sparse autoencoder
  • 使用したデータセットは、1,000,000の画像(200x200px)
  • 使用したコンピューターは1,000台(コア数で言うと16,000コア)
  • 学習期間3日
  • (直感には難しそうな)ラベル無し(=教師無し)画像のみから顔認識器(face detector)が構築できる事を示すことができた。
  • 他には猫の顔や人影も識別できる。
  • (deep learningによって学習した)特徴を用いた識別により、過去の研究を上回る制度を達成できた。

本文も一応読んだけどAbstract以上に理解が深まった感じはしない。
アルゴリズムの解説とかではなく、大規模計算リソース+大規模データぶん回したら教師なしでここまでできたよーっていう紹介なんだと思う。

Deep Learning 資料まとめのまとめ

Yet Another まとめのまとめ。資料ありすぎて混乱してきたので自分用メモということで。

まとめ系


使ってみる系


Googleの猫なやつ


読みたい論文

正規分布 vs t分布 - 外れ値に影響されやすい度グラフ化してみた

PRML 図2.16を再現してみた。

まずはグラフから
f:id:mathhun:20131129080215p:plain:w300
f:id:mathhun:20131129080218p:plain:w300

上は外れ値なし、下はあり。赤が正規分布で青はt分布。

外れ値なしでは2つのグラフはほぼ重なる。このグラフは乱数を何度か取り直してあえて重なりが少なくなるものを選んだが、たいていはほぼ完全に一致する。

Rコード
data <- rnorm(50, -1, 1.2)
noise <- rnorm(5, 10, 1) # 外れ値なしの場合は第一引数を0にする
data <- c(data, noise)

# norm
log.likelihood.norm <- function(x) {
	return(function(par) {
		mu <- par[1]
		sigma2 <- par[2]
		- length(x) / 2 * log(sigma2) - 1 / 2 * sum((x - mu)^2) / sigma2
	})
}

my.dt <- function(x, mu, lambda, v) {
	gamma(v/2 + 1/2) / gamma(v/2) * (lambda/pi/v)^(1/2) * (1 + lambda*(x - mu)^2 / v)^(-v/2 -1/2)
}
my.dt.log <- function(x, mu, lambda, v) {
	log(gamma(v/2 + 1/2)) - log(gamma(v/2)) + (1/2)*log(lambda/pi/v) + (-(v/2) - (1/2)) * log(1 + lambda*(x - mu)^2 / v)
}

# t
likelihood.t <- function(x) {
	return(function(par) {
		mu <- par[1]
		lam <- par[2]
		v <- par[3]
		
		sum(my.dt.log(x, mu, lam, v))
	})
}


# 解析的に求められる式で計算
mu <- mean(data)
sigma2 <- sum((data - mu)^2) / length(data)

# 数値的に求めた結果
# norm
opt <- optim(par=c(0,1), fn=log.likelihood.norm(data), control=list(fnscale=-1))
mu.guess <- opt$par[1]
sigma2.guess <- opt$par[2]

print(list(
  title="norm",
  mu=mu,
  sigma=sigma2,
  mu.guess=mu.guess,
  sigma2.guess=sigma2.guess
))

# t
opt <- optim(par=c(0,1,1), fn=likelihood.t(data), control=list(fnscale=-1))
mu.t.guess <- opt$par[1]
lambda.guess <- opt$par[2]
v.guess <- opt$par[3]

print(list(
  title="t",
  mu=mu.t.guess,
  lambda=lambda.guess,
  v=v.guess
))


# ---
# visualization
# ---

x.max <- 15
x.min <- -5
y.max <- 0.5

# raw data
hist(data, xlim=c(x.min, x.max), ylim=c(0, y.max), breaks=seq(x.min, x.max, 1), freq=F)
par(new=T)

# norm
f <- function(x) dnorm(x, mean=mu.guess, sd=sqrt(sigma2.guess))
curve(f, xlab='', ylab='', xlim=c(x.min, x.max), ylim=c(0, y.max), col="red")
par(new=T)

# t
f2 <- function(x) my.dt(x, mu.t.guess, lambda.guess, v.guess)
curve(f2, xlab='', ylab='', xlim=c(x.min, x.max), ylim=c(0, y.max), col="blue")
数式

t分布
本に載ってる定義
St(x | \mu, \lambda, \nu)=\frac{\Gamma(\nu/2 + 1/2)}{\Gamma(\nu/2)} \biggl(\frac{\lambda}{\pi \nu} \biggr)^{1/2} \biggl[ 1 + \frac{\lambda(x - \mu)^2}{\nu} \biggr]  ^{-\nu/2 - 1/2}

はまったところ

この程度のグラフは簡単に描けると思ったがかなり苦戦した。t分布のパラメータ推定でいろいろ苦労したので書いておく。

  • t分布というと、「正規分布のパラメータ推定の時に脇役的に登場するあのヒトね」という感じだが、t分布自体のデータへの当てはめというのは知らなかった。ググっても情報少なめ。
    • そもそも普通t分布のパラメータは1つ。正規分布のように平均などを指定できないの?と思った。
    • よく見るとPRMLに載ってる式にはパラメータが3つあり、正規分布の2つのパラメータに対応するものがある。
  • 推定値の計算
    • 解析的に求める式が本に載っていないし自力で計算できるかも謎。Rのoptim関数というものがあることを知ったのでそれを使ってみることに。
    • 最終推定でlogとらないバージョンで結果を求めると推定値が求まらない。(初期値として与えたのとほぼ同じ値が返ってくる)
    • 調べてみると絶対値の小さな値を多量に掛け算しているので結果が0になっている(アンダーフロー)
    • t分布の関数logバージョンで再度optimに掛けてそれらしき値が得られる
おまけ

せっかくコード書いたのでいろいろ遊んでいたら発見したこと
データ数の1/4が「外れ値」でもt分布はぶれない!ここまで来るともはや鈍感としか
f:id:mathhun:20131130141850p:plain:w300