応用計量分析2 (2019)
お知らせ
- 2020年1月10日は同時間に講義実施予定。ただし講義ではなくレポート課題の質問を受け付ける会にする予定なので、レポートに不安がある方はきてください。
- レポート講評
レポート課題
- 提出期限: 2020年1月17日 23:59 (JST)(遅れたレポートは受け付けません)
- 提出場所: レタス「最終レポート課題」
- 本講義の四章以降の内容で、わからなかったこと、わかりづらかったことをまとめてください
- 数学的な内容とプログラミングの内容をそれぞれ少なくとも一つあげてください
- 何が原因でわからなかったのか具体的に記述してください
- ダメな例)プログラミングのところが説明不足でわからなかった
- 「プログラミングのところ」をより具体的に
- どういう説明が足りなかったのか
- 良い例)正規分布をオブジェクト指向で書くところがわからなかった。直前にオブジェクト指向の説明や入力チェックなどの説明があったが、それらを全て使って書かれていたため理解が追いつかなかった。
- 上であげた内容について、自ら調査し理解をした上で、わかりやすい講義資料を作ってください
- 特に、上で挙げた原因を解決した講義資料としてください
- 良い例)「はじめに、入力チェックなどのない書き方で正規分布のクラスを書く。それを理解させた上で入力チェックの説明をする。」という内容の講義資料
- それぞれの内容につき3件以上の文献またはウェブページを調査した上で、それらをまとめるような資料にしてください
- 例えば数学的な内容を2つ、プログラミングの内容を3つ書く場合は、合計15件以上の文献を参照してください
- 必ず参考文献を書くこと
- 既存文献からコピーがある場合は不可とする
- 既存文献を読み込んで理解した上で、あまり既存文献を見ないで資料を作るとコピーにはならないはず…?
- その状態で資料を作れないとすると理解不足の可能性がある?
- 提出フォーマット: 以下の条件を全て守ってください
- 1番目の課題と2番目の課題の一部については Word などの文書作成ツールまたは jupyter notebook を使って、必ず以下の章立てで記述してください
- 数学的な内容
- わからなかった箇所
- わからなかった原因
- わかりやすくするための工夫
- 参考文献
- プログラミングの内容
- わからなかった箇所
- わからなかった原因
- わかりやすくするための工夫
- 参考文献
- 2番目の課題の講義資料に関しては PowerPoint などのプレゼンテーションツールを用いて、以下の順番でスライドを作ってください
- 数学的な内容に関する講義資料
- プログラミングの内容に関する講義資料
- 評価基準
- 内容の濃さ
- 内容の正しさ
- 論理的整合性(原因・解決策の整合性など)
- 講義資料のわかりやすさ
- 注意事項
- 提出いただいた講義資料を参考に来年度の講義資料を作ります
- 仮に講義資料の全てを理解できた場合でも、講義資料の中で相対的にわかりづらい箇所は必ず存在するので、その箇所に関してレポートを作成してください
- 提出いただいたものをそのまま使うことはない予定ですが、もし使いたい場合には個別に連絡します
- 他の受講者のを写す、またはWebで拾った資料を提出するなどの不正行為が判明した場合は「不可」とします
- 厳しく見るわけではないので、自分でやってみてください
講義資料
講義で使用した Jupyter notebook は ここ にあります。
以下のスライドでコードが見切れていたりする場合は上記サイトを参照ください。
第1章(自己紹介、講義の概要、Pythonの準備)
第2章(機械学習・人工知能概論)
第3章(Python の基本)
第4章(線形代数)
第5章(確率・統計)
- 途中見切れるところがあるので、その箇所はこちらを参照ください
第6章(混合分布モデル)
- 途中見切れるところがあるので、その箇所はこちらを参照ください
第7章(トピックモデル)
- 途中見切れるところがあるので、その箇所はこちらを参照ください
講義で話した内容
2019年9月13日
概要
- 自己紹介
- 講義の狙い: 数理的な基礎とそのプログラミングを通じた応用
- 基礎だけやっていても、何の役にたつかわからないとモチベーションがわかない
- 応用だけやっていても、基礎が分からなければおかしいことをやってしまいがち
- 評価方法
- 出席点はなし
- 基本的には期末レポート
- 自分で考えた(ように見える)レポートであれば基本的にはOK
- 他の人のレポートの写しやWebなどからの写しについては厳正に対処
- 機械学習の基礎知識
- 人工知能の歴史
- 教師あり学習と教師なし学習の違い
- 統計的機械学習の定式化
- 基本的には有限個のデータから、そのデータが従う確率分布を推定する問題に帰着される
- 教師あり・教師なしによって推定したい確率分布が微妙に違う(条件付き確率かどうか、など)
- 最尤推定
- 確率分布の推定は、最尤推定を用いて行うことが多い
- 大雑把には以下のプロセスで行う
- 任意のパラメタ $\theta$ に関して、手元のサンプルが得られる確率を計算する関数を作る(=尤度関数)
- 尤度関数を最大にする $\theta^\star$ を計算する
- 尤度関数の最大化の代わりに、負の対数尤度の最小化として定式化することが多い
- 得られるパラメタ $\theta^\star$ は同じ
- 計算しやすいことが多い
課題
- Anaconda を使って Python の環境を作る
2019年9月20日
概要
- 最尤推定を実際に手でやってみる
- データ: $x_1,…,x_N\in\mathbb{R}$
- モデル: 平均 $\mu\in\mathbb{R}$, 分散 $1$ の正規分布 $\mathcal{N}(\mu, 1)$
- 考え方
- とりあえず負の対数尤度 $-\sum_{n=1}^N \log p(x_n; \theta)$ を書き下したい
- とりあえず $p(x_n; \theta)$ を正規分布の式で書き換える(何も考えずに)
- 負の対数尤度を最小化しろと言われてるので、とりあえず $\mu$ に関して微分してみる(何も考えずに)
- 微分=0が $\mu$ について解析的に解けるかどうかを考える(今回は解ける)
- 解を求める
- 今後の人生を考えたとき正規分布での最尤推定くらいはできたほうがいいと思う
- 少なくともこの講義で単位を取る上で、最尤推定できないと詰む気がします
- ベイズ推定の簡単な紹介(興味ある人は講義資料追ってみてください)
課題
正規分布の最尤推定をちゃんとできるようにする
2019年9月27日
概要
- Python でプログラミングの基本
- 困ったら
print
- 四則演算ができる
- 変数には数値、文字列など、いろんなものを代入できる
x = 1
とかくと、 x
という名前の変数に 1
を代入したことになる
- その状態で
x = x + 1
と実行すると、 x
という名前の変数に x + 1
を代入することになるが、 x
には 1
が入っているので代入されるものは 1 + 1
- リストは複数のオブジェクト(数字、文字列などの総称)をひとまとめにできる
x = [1, 2, 3]
のように、大括弧で囲んでカンマで区切る
- リストの中の要素を取り出すには
x[0]
のように何番目に入っているかというインデックス(この場合 0 番目)で指定する
- 辞書も複数のオブジェクトをひとまとめにできるが、より一般的な取り出し方が可能
- 制御構文
- if 文: ある条件が満たされた時だけ実行される
- 条件:
True
もしくは False
を返すもの
x == 1
: x
が 1
と等しいならば True
, そうでないならば False
x > 1
: x
が 1
より大きいならば True
, そうでないならば False
- 文法:
if 条件:
で条件を指定し、True
の時に実行されるコードをその下に tab でインデントを下げて 記述する。例えば…
x = 0
if x == 0:
print("x is equal to zero.")
2019年10月4日
概要
- Python でプログラミングの基本
- 制御構文
- if 文、for 文、 while 文を取り扱った
- FizzBuzz ができるようになった
- 関数の定義ができるようになった
f(x)
という関数があった時、 f
は関数名をあらわし、 x
は引数に相当する
- よく使う機能は関数にしておくと簡単に使い回しできて嬉しい
2019年10月11日
概要
- Python で線形代数
numpy
というライブラリを使う
- 線形代数はベクトル・行列が出てくる
- リストを使えば良さそうだけど…?
numpy.ndarray
を使う
- オブジェクトや型の説明
- 全てのものは オブジェクト と呼ばれる
- 0, 100.0, “Hello, world” などは全てオブジェクト
- オブジェクトには 型 がある
- オブジェクトの分類を表す。同じ型のものは仲間みたいなもの。
list
, int
, float
など
type(x)
と打つと x
の型がわかる
- 型によって定義されている演算や関数が異なる
list
の足し算はリスト連結
int
の足し算は普通の数字の足し算
numpy.ndarray
という型のオブジェクトには線形代数の演算が色々定義されている
x + y
とやるとベクトル同士の足し算になったり…
- ベクトルを
list
であらわした場合は自分で演算を実行する関数を定義する必要がある
numpy.ndarray
型のオブジェクトの作り方
- ベクトル・行列を表す
list
型のオブジェクトを始めに作り、それを numpy.array
という関数で numpy.ndarray
型に変換する
- 変換後のオブジェクトは、自然に線型結合などが計算できる
- 関数の探し方
- 例えば行列の固有値を計算する関数を探したい場合は “numpy 固有値” とか “numpy eigenvalues” でググる
- 関数の引数と返り値の解釈をちゃんと理解する
- 手元で動かしてみて、理解が正しいかを確認する
2019年10月18日
概要
- 主成分分析(PCA)の説明
- 通常は分散最大化として定式化されることが多い
- オートエンコーダとしての定式化を行う(その方が個人的にはわかりやすい?)
- オートエンコーダ=エンコーダ+デコーダ
- エンコーダ: データを低次元空間に写す関数
- デコーダ: 低次元表現を元のデータ空間に写す関数
- 再構成(エンコードしたものをデコード)した時になるべく元のデータに戻るようにオートエンコーダを作りたい
- PCAはエンコーダ・デコーダを線形関数に限った場合のオートエンコーダである
- 再構成エラーをなるべく小さくするように学習すると、エンコーダ=PCA、となる
- 学習を最適化問題として定式化するが、式変形をしていくと最適解が陽に書けることを示せる
2019年10月25日
概要
2019年11月1日
概要
- 関数の書き方の復習
- 引数に相当する変数は、関数の定義範囲内のみで使える
- 引数には何が入ってくるかわからないものだが、設計時に整数が入ってくる、とか仮定して処理を書く
- 引数に変なものが入ってきたら困る場合は「例外処理」を行う
- 主成分分析の実装
- いきなり実装しろと言われてもわからないのは当たり前
- 問題の切り分け(≒何ができれば全体を実装できるかを考える)を行うことが最も重要
- 例えば $A = \sum_{n=1}^N x_n x_n^\top$ を計算するのがゴールの時は以下の三つができればゴールだと考えられる:
- 配列$X = \begin{bmatrix}x_1 & \dots & x_N \end{bmatrix}^\top$ から任意の$n=1,\dots,N$に対して $x_n$を取ってくる
- $x_n$ を用いて $x_n x_n^\top$ を計算する
- 全ての $n=1,\dots,N$ に対して $x_n x_n^\top$ を計算して和をとる
- それぞれの小ゴールをそのまま実装できれば実装すればいいし、実装できない場合はさらに小さいゴールに分ける
2019年11月8日
概要
- 確率・統計の話
- 決定的には定まらないもののモデル化に確率変数を用いる
- 例えばサイコロを $N$ 回振った時に出る目は決定的ではないので $X_1,\dots X_N$ という確率変数で表す
- これらの確率変数が従う規則(=確率分布)を推定したい
- 確率分布にどのような仮定を置くのかが大切
- $N$ 回の試行は独立なのか?
- $N$ 回の試行は同一分布に従うのか?
- 分布の形状は?
- 確率分布の仮定を決めると尤度関数を書き下せる
- $X_1,\dots,X_N$ が独立同一分布に従うと仮定すると $\ell(\theta) = \prod_{n=1}^N p(X_n ; \theta)$ と書ける
- 独立性のみの仮定だと、 $\ell(\theta) = \prod_{n=1}^N p(X_n ; \theta_n)$ のように、分布が試行ごとに異なる、ということになる
- 尤度関数を書き下せたら、最尤推定ができる(負の対数尤度を最小化する)
- オブジェクト指向の説明
- オブジェクトとクラスについて
- クラスは設計図みたいなもので、その設計図にしたがって作ったものがオブジェクト
[1, 2, 3]
も "Hello, world!"
も [1 2 3]
(numpy.ndarray
)もオブジェクトだが、違う設計図にしたがって作られている(≒型が違う)
- 逆に同じ
numpy.ndarray
型のオブジェクトは同じ設計図にしたがって作られている
- オブジェクト≒内部状態 + 専用の関数
- 内部状態: オブジェクトの持っているデータ
- 例えば
numpy.ndarray
の場合は行列やベクトルの値が内部状態に相当する
str
の場合はその文字列がオブジェクトの内部状態に相当する
- 専用の関数: 内部状態の更新や、内部状態を用いた計算に使われる
numpy.ndarray
型のオブジェクトにのみ適用できる関数が色々用意されている
ndarray
のオブジェクト x
に対して x.transpose()
は x
の転地を返す関数で、 ndarray
型のオブジェクト専用の関数(x.transpose()
は、オブジェクト x
の transpose
という関数、と読める)
a + b
を実行する際には、オブジェクト a
のクラスに定義されている __add__
という関数が呼び出される(a
のクラス専用の関数)
int
型どうしの足し算と list
どうしの足し算と numpy.ndarray
どうしの足し算がそれぞれ異なる挙動をするのは、それぞれのクラス専用の関数を使っているから
- つまり
list
クラスに実装されている __add__
という関数と numpy.ndarray
クラスに実装されている __add__
という関数は異なる
- オブジェクトを適切なクラスで定め、オブジェクトの内部状態を関数で更新していくことでプログラミングをすることが、オブジェクト指向の考え方の一部
- 大量のオブジェクトを作った場合でも、同じクラスから作っていれば使うのが簡単
- クラス間にも関係を定義すると、特殊ケースも簡単に作ることができる(継承)
- オブジェクト指向の考え方に基づいて統計モデルを定義するとどうなるか?(どのように内部状態と専用の関数を決めればいいか)
- 例えば一つの正規分布を一つのオブジェクトとして考える
- 平均 $\mu$ と共分散行列 $\Sigma$ というパラメタで正規分布は特徴付けられるため、内部状態はこの二つのパラメタとすれば良さそう
- 専用の関数は、用途によって色々設計すればいいのだが…
- 例えば内部状態を更新する関数として、最尤推定を行う関数が考えられる(サンプルを受け取って、内部状態を最尤推定量に更新する関数)
- 例えば内部状態を用いて計算する関数として、確率密度を計算する関数が考えられる(データ点を一つ受け取って、その点での確率密度を(内部状態を使って)計算して返す関数)
2019年11月15日
概要
- クラスの書き方
- オブジェクトの持っている内部状態は
self.mu
や self.sigma
のように self.[変数名]
で設定したり参照できる
self
はオブジェクト自身を指す(クラス設計時にはオブジェクトの名前は決まっていないので self
って書くしかない)
- オブジェクト専用の関数は、クラスの定義内で関数を定義することで定義できる
- 内部状態を使ったりするので、
self
を引数にとる
- 正規分布クラスを書いてみる
- まずは対数尤度を計算する関数を書いてみる
- 式を書き下す
- 全部一度にプログラミングするのはしんどいので、計算しやすい項から書いてみる
- 途中でもいいからとりあえず関数を計算してみる(エラーが出るかどうかの確認など)
- エラーが出た時は、それぞれの変数に思ったような値が入っているか調べてみる(中身を
print
してみるとか)
2019年11月22日
休み
2019年11月29日
概要
- 混合分布モデルの導入
- 混合分布モデル = 複数の分布を混ぜ合わせた分布
- $p(x) = \sum_{z=1}^K p(x \mid z) p(z)$ と書ける分布
- $x$: 観測データ
- $z$: 潜在変数(どの分布を使うのかを決める変数)
- $p(x \mid z)$: 混ぜ合わせられる分布
- $p(z)$: 混合比率
- $K$: 混合数
- 例えば、複数のガウス分布を混合すると混合ガウスモデル
- 生成モデルとしての説明
- $K$ 面サイコロを振って出た目を $z$ とする
- $z$ に対応する分布を使ってデータ$x$を生成する
- 生成モデルとしての解釈
- $x,z$ の従う同時分布は $p(x, z) = p(x \mid z) p(z)$ と書ける
- $z$ は手元にない状態での $x$ の従う分布は $p(x) = \sum_{z} p(x, z) = \sum_{z} p(x \mid z) p(z)$
- 一個のデータ点 $x$ に対して一個の $z$ が対応している
- 混合分布モデルの使い方
- より柔軟な確率分布としての利用方法
- 正規分布は単峰の分布しか表せない
- 混合ガウス分布の場合は、混合数の分の峰の分布を表せる
- ソフトクラスタリング
- 事後分布 $p(z \mid x) = p(x \mid z)p(z) / p(x)$ を見ると、データ点 $x$ がどの分布からきたのかがわかる(確率分布として)
- 同じ分布から出てきたデータ点を同じクラスタだと思うことにするとクラスタリングとして解釈できる
- cf. 普通のクラスタリングだと、データはひとつのクラスタにのみ属する(=ハードなクラスタリング)
- 混合ガウスモデルの推定
- サンプル $\mathcal{D}={x_1,\dots,x_N}$ を用いて混合ガウスモデルを推定したい
- 基本的には最尤推定をする
- $\max_{\theta\in\Theta} \prod_{n=1}^N p(x_n \mid \theta)$ を解く($\theta$はモデルパラメタ)
2019年12月6日
概要
- EM アルゴリズムの導出
- 混合分布モデルの構造
- 潜在変数 $z$ がわかればパラメタ $\theta$ の最適解が簡単に求まるし、 $\theta$ がわかれば潜在変数 $z$ の事後分布が簡単に求まる、という構造がある
- 両方ともわからない状態でパラメタを最尤推定したい場合にどうしたらいいかわからない
- 演習では実際に i) $z$ がわかっている元での $\theta$ の最尤推定と ii) $\theta$ がわかっている元での $z$ の事後分布の推定を行った
- EM アルゴリズムの目的関数
- 変分分布 $q(z)$ を導入して、対数尤度の下界を Jensen の不等式を用いて求める
- 変分分布について最適化すると、最もタイトな下界を求めることができる
- その下界をパラメタについて最大化することで対数尤度を最大化したい
- パラメタを動かすと「下界のタイトさ」がズレるので、また $q(z)$ を最適化する
- 下界を動かすとパラメタが最適ではなくなるのでまたパラメタを最適化する…というのを繰り返す
- EMアルゴリズムでは実際に対数尤度が非減少であることを示せる
2019年12月13日
概要
- レポート課題の説明(上記の説明参照)
- EM アルゴリズムの導出
- $\theta$ を固定した元での $q(z)$ の最適化
- $q(z)$ を固定した元での $\theta$ の最適化
- いずれも演習でやった式をちょっと変えればできる
- EM アルゴリズムの実装
- 最低限欲しいもの
- 内部状態 = モデルパラメタ
- データを用いて内部状態を更新する命令: 例えば最尤推定する関数
fit
- 内部状態を用いて何か計算する命令: 例えば対数尤度を計算する関数
log_pdf
- あると便利なもの(例)
- E-step を実行する関数
e_step
- M-step を実行する関数
m_step
fit
の中に全部まとめて書けるが、 e_step
, m_step
と分けておくと見やすい&便利なことも多い
2019年12月20日
概要
- トピックモデルの紹介
- トピックモデルの Inference アルゴリズムの紹介(隠れ状態の推定)
- トピックモデルの学習アルゴリズムの紹介