keisukeのブログ

***乱雑です!自分用のメモです!*** 統計や機械学習の勉強と、読み物を書く練習と、備忘録用のブログ

ベイズ推定(ベイズ予測分布)

訓練標本を{\begin{align*}\mathcal{X}:=\{\boldsymbol{x}_i\}_{i=1}^n\end{align*}}とする.
{\begin{align*}p(\boldsymbol{\theta},\mathcal{X})\end{align*}}{\begin{align*}\boldsymbol{\theta},\mathcal{X}\end{align*}}同時確率
{\begin{align*}p(\boldsymbol{\theta}|\mathcal{X})\end{align*}}{\begin{align*}\boldsymbol{\theta}\end{align*}}事後確率
{\begin{align*}p(\boldsymbol{\theta})\end{align*}}{\begin{align*}\boldsymbol{\theta}\end{align*}}事前確率
{\begin{align*}p(\mathcal{X}|\boldsymbol{\theta}) = \prod_{i=1}^nq(\boldsymbol{x}_i|\boldsymbol{\theta})\end{align*}}{\begin{align*}\boldsymbol{\theta}\end{align*}}尤度である.
ベイズ推定では{\begin{align*}\boldsymbol{\theta}\end{align*}}は確率変数なのでモデルも条件付き確率{\begin{align*}q(\boldsymbol{x}_i|\boldsymbol{\theta})\end{align*}}で表される.


{\begin{align*}p(\boldsymbol{\theta},\mathcal{X})=p(\mathcal{X}|\boldsymbol{\theta})p(\boldsymbol{\theta})\end{align*}}{\begin{align*}\int p(\boldsymbol{\theta},\mathcal{X})d\boldsymbol{\theta}=p(\mathcal{X})\end{align*}}から
{\begin{align*}p(\mathcal{X})=\int\prod_{i=1}^nq(\boldsymbol{x}_i|\boldsymbol{\theta})p(\boldsymbol{\theta})d\boldsymbol{\theta}\end{align*}}が得られる.
よって{\begin{align*}p(\boldsymbol{\theta}|\mathcal{X}) = \frac{p(\mathcal{X}|\boldsymbol{\theta})p(\boldsymbol{\theta})}{p(\mathcal{X})} = \frac{\prod_{i=1}^nq(\boldsymbol{x}_i|\boldsymbol{\theta})p(\boldsymbol{\theta})}{\int\prod_{i=1}^nq(\boldsymbol{x}_i|\boldsymbol{\theta})p(\boldsymbol{\theta})d\boldsymbol{\theta}}\end{align*}}であるから,ベイズ予測分布は
{\begin{align*}\widehat{p}_{\text{Bayes}}(\boldsymbol{x}) := \int q(\boldsymbol{x}|\boldsymbol{\theta})p(\boldsymbol{\theta}|\mathcal{X})d\boldsymbol{\theta} = \frac{\int q(\boldsymbol{x}|\boldsymbol{\theta})\prod_{i=1}^nq(\boldsymbol{x}_i|\boldsymbol{\theta})p(\boldsymbol{\theta})d\boldsymbol{\theta}}{\int\prod_{i=1}^nq(\boldsymbol{x}_i|\boldsymbol{\theta})p(\boldsymbol{\theta})d\boldsymbol{\theta}} \end{align*}}
となる.


{\begin{align*}\widehat{p}_{\text{Bayes}}(\boldsymbol{x}) := \int q(\boldsymbol{x}|\boldsymbol{\theta})p(\boldsymbol{\theta}|\mathcal{X})d\boldsymbol{\theta}\end{align*}}は,
モデル{\begin{align*} q(\boldsymbol{x}|\boldsymbol{\theta})\end{align*}}{\begin{align*} \boldsymbol{\theta}\end{align*}}の事後確率{\begin{align*} p(\boldsymbol{\theta}|\mathcal{X})\end{align*}}で重みをつけて平均したものと解釈できる.
最尤推定は尤度の最も高くなるパラメータ{\begin{align*} \boldsymbol{\theta}\end{align*}}を選ぶが,ベイズ推定では事後確率の高いものを優先しつつ,低いものもある程度考慮にいれる.

selfってなんじゃ

Pythonでclassを定義する時、methodの引数やメンバ変数などに出現するself。
あれはそのクラスのオブジェクトを指している。

obj = Cls(x, y)

などとオブジェクトobjを生成すると、クラスClsのselfにobjが使われる。
実のところ、

obj.method(z)

は、

Cls.method(obj, z)

の糖衣構文にすぎない。もっとも、後者は使う機会がないけれど・・・

【Firefoxアドオン】DictionaryTooltip+Stylishでポップアップ英辞郎

2015/04/15追記:
英辞郎 on the WEB (Space ALC) のサイトデザインが更新されました。
Stylishのスタイルは次のようにするとよいです:

@namespace url(http://www.w3.org/1999/xhtml);

@-moz-document domain("eowf.alc.co.jp") {
/* common settings */
  #logo {display: none !important;}
  
/* for small window mode   */
  #search {display: none}
  .paging_left_small {display: none !important;}
  .paging_small {display: none !important;}
  #small_title {margin-top: 0px !important;
                border-top: 0px !important;}
  #content {padding: 0px !important;}
  #desc {padding-top: 0px !important;
         padding-bottom: 0px !important;}
  #resultlist {padding-top: 0px !important;}
  .desc {padding-bottom: 1px !important;}

/* for normal mode   */
  .inner {display: block !important;}
  #leftbar {display: none !important;}
  .adSuperBanner {display: none !important;}
  #pr {display: none !important;}
  #common_wrap_limit {display: none !important;}
  .cartoon {display: none !important;}
}

追記終わり

2015/02/24追記:
英辞郎 on the WEB (SPACE ALC) に、Proの体験版が無期限で試用できるようになりました。
2015年4月からは、従来の(Proではない)バージョンだと、検索結果に例文が含まれなくなります。
これを踏まえての追記です。

まず、例文が検索されないのは問題外なので、Pro体験版に登録しましょう。無期限で無料です。

登録したら、FirefoxのアドオンStylishの「新しいスタイルを書く→白紙のスタイル」を選んで、出てきたウィンドウに次のように入力してください:

@namespace url(http://www.w3.org/1999/xhtml);

@-moz-document domain("eowf.alc.co.jp") {
/* for small window mode   */
  #logo {display: none !important;}
  .slogansmall {display: none !important;}
  #title {display: none !important;}
  .smallpage {background: none !important;}
  #content {padding-top: 0 !important;}
  .desc {padding-bottom: 0 !important;}
  div.desc ol {margin-bottom: 0 !important;}

/* for normal mode   */
  /*   #topmenu > div:nth-child(3) {display: true !important;} */
  .result_page {background: none !important;}
  #cartoon {display: none !important;}
  #common_wrap_limit {display: none !important;}
  .slogan {display: none !important;}
  #result_search {margin-bottom: 0 !important;}
}

これは、英辞郎 on the WEB の表示からいらないものを取るさるためのものです。
具体的には、画面上部のロゴやテキストをカット、検索結果のリストの間隔を詰める、などです。
名前を適当に(例えば「minieijiro」など)をつけて、保存ボタンを押してください。

これが終わったら、次はFirefoxのアドオン Dictionay Tooltip の設定です。
Preference(設定画面)を開いて、「Add/Edit Custom Sites」タブに移り、「Add new site」をクリック、
「Site」に「ALC」、「Site URL」に「http://eowf.alc.co.jp/small/search?q=$$」と入力してSaveボタンを押してください。

あとは、Dictionary Tooltip をポップアップウィンドウから先ほど設定した「ALC」を選べば完了です。

追記終わり





Firefox前提で話を進めますが、おそらくChromeにも同等のプラグインや機能が存在すると思います。
Chrome使用者の方は適宜読み替えたり調べたりしたら同じことができると思います。

DictionaryTooltip

Dictionary Tooltipの、右の方にあるオレンジ色の「Download」ボタンからインストールできます。
このDictionaryTooltipというアドオン、ちょっと触ってみればわかりますが、非常に強力です。
DictionaryTooltipの設定からダブルクリックで検索を有効にすると、意味を知りたい単語をダブルクリックすればポップアップで辞書が出現します。
しかし、デフォルトではオンラインの英英辞書や英独辞書などのみが表示可能です。
SPACE ALC提供の英辞郎 on the WEBを追加しましょう。*1

まずはDictionaryTooltipの設定画面を開きます。下半分の「Add/Edit custom sites」タブへ移動し、Add new site → Site name:ALC、 Site url:http://eow.alc.co.jp/search?q=$$ と入力しましょう。
ここまででDictionaryTooltipの設定は終わりです。
英単語をダブルクリックするとDictionaryTooltipのポップアップ画面があらわれるので、
ポップアップ画面下の「show dictionary」から先ほど作成した「ALC」を選びましょう。
一度選択すれば次回からは記憶されます。

ところで

ここから先は、英辞郎 on the WEB Pro(有料会員)になれば必要ない作業です。
ただひとつだけする作業は、先ほどのSite urlをPro用、http://eowp.alc.co.jp/search?q=$$へと変更するだけです(「p」が増えています)
有料会員になることを強く推奨します。

Stylish

DictionaryTooltipに英辞郎 on the WEBを導入するだけでもかなり便利ですが、さらに英辞郎 on the WEBをカスタマイズして見やすくしましょう。
導入するアドオンはStylishです。
Stylish :: Add-ons for Firefox
インストールしたら、Stylishによって追加された「S」マークのボタンから、「新しいスタイルを書く」→「白紙のスタイル」としましょう。
「名前」に「simplify ALC」などと入力し、下の大きなテキストエリアに次をコピペして保存ボタンを押したら終了です。

@namespace url(http://www.w3.org/1999/xhtml);

@-moz-document domain("eow.alc.co.jp") {
  #AreaHeaderLeft {display:none !important;}
  #searchHeader {display:none !important;}
  .pr_text {display:none !important;}
  #sw {display:none !important;}
/*   #navigation {padding:0 0 0 0 !important;} */
/*   #navigation {display:none !important;} */
  .sas {margin:0 !important; font-size:12px !important;}
  #eijiro_img {display:none !important;}
/*   .clearfix navif {display:1 !important;} */
/*   #paging {margin-top: 0px font-size: 1 !important;} */
/*   #smallredfont {display:none !important;} */
  #introduceEowp {display:none !important;}
  #AreaUpperRight {display:none !important;}
  .sns {display:none !important;}
  #AreaFooter {display:none !important;}
  .eijiro_tit {display:none !important;}
  .search_area_left {width:450px !important;}
  .search_box {width:450px !important;}
  .s_txt1 {width: 300px !important;}
  #AreaUpperLeftContainer {margin-right: 0px !important;}
  #resultsArea > div:nth-child(2) {display:none !important}
  #AreaUpperLeftInner > div:nth-child(11) {display:none !important}
}

英辞郎 on the WEBへ行ってみてください。
なんか色々消えてると思います。
ついでに、DictionaryTooltipによる英辞郎ポップアップも見やすくなります。(というかこっちが主目的です)
ちなみこの設定だと、ナビゲーションバー(ページ移動用!)もろとも消し去るので相当不便です。
復活させたい人はさっきのコピペの
#navigation {display:none !important;}
を消去してください。
(2014-10-24追記:下部の広告を削除,下部のナビゲーションバーを復活させました.上部のナビゲーションバーは邪魔なので消したままです.)

おわりに

しばらくこれで使ってみて、便利だったら有料会員になりましょう。
無料版はいつ仕様がかわったりするか謎です。
この記事も怒られそうです。

ちなみにHTMLもCSSもよくわからないので、上のコードはやばいくらいめちゃくちゃだと思います。誰かちゃんと書き直して

*1:ALC利用規約を読むと、おそらくここまではセーフです。ポップアップでALCのウェブサイトを表示しているだけですので

matplotlibのplotの種類

pyplot — Matplotlib 1.4.0 documentation

plt.plotの引数である,linestyleとcolor,markerの実際のプロット例.
plt.plot(x, y, linestyle='-', color='b', marker='.')などと指定する.
plt.plot(x, y, 'b.-')などと同時に指定もできる.

f:id:kaisk:20141016154312p:plainf:id:kaisk:20141016154315p:plain

import numpy as np
import matplotlib.pyplot as plt


linestyles = ['-', '--', '-.', ':']
markers = ['.', ',', 'o', 'v', '^', '<', '>', '1', '2', '3', '4', '8', 's', 'p', '*', 'h', 'H', '+', 'x', 'D', 'd', '|', '_', r'$\alpha$']
colors = ['b', 'g', 'r', 'c', 'm', 'y', 'k', 'w']


def plot_plots():
    x = np.linspace(-10,10)
    data = np.sin(x)

    nof_l = len(linestyles)
    nof_m = len(markers)
    nof_c = len(colors)

    f=plt.figure()
    f.add_subplot(1,1,1, axisbg='#999999')
    plt.hold(True)
    for i in range(nof_c):
        plt.plot(x+0.5*i, data, linestyle=linestyles[i%nof_l], color=colors[i], label=colors[i]+linestyles[i%nof_l])
    legend = plt.legend(loc='best')
    legend.get_frame().set_facecolor('#999999')
    plt.savefig('plot_plots.png')
    plt.clf()

    plt.figure()
    x = np.arange(0,11,1)
    for i in range(nof_m):
        plt.plot(x, i*np.ones(len(x)), color='b', marker=markers[i], label=markers[i])
    plt.legend(loc='best', ncol=2)
    plt.ylim([-1,24])
    plt.savefig('plot_plots2.png')
    plt.clf()


if __name__ == '__main__':
    plot_plots()

decorator

http://www.jeffknupp.com/blog/2013/11/29/improve-your-python-decorators-explained/

@currency
def price_with_tax(price, tax_rate_percentage):
    return price * (1 + tax_rate_percentage)

では、currencyがdecorator.
currencyは

def currency(f):
    def wrapper(*args, **kwargs):
        return '$' + str(f(*args, **kwargs))

    return wrapper

のように定義される。
decoratorとは、関数を返す関数。
デコレート*された*関数、この場合price_with_taxは、decoratorの引数fに代入されるように振る舞う。
price_with_taxをcurrencyでデコレーションすることによって、

price_with_tax = currency(price_with_tax)

のように代入されるイメージ。

currencyは関数を返す関数なので、price_with_taxは代入された後も関数のまま。
ただし、その機能はcurrencyによって上書きされている。

yield

Improve Your Python: 'yield' and Generators Explained
yield文はgenerator functionを作るために必要。
yield文をひとつでも持つ関数はgenerator functionと呼ばれる。
また、generator fucntionのインスタンスクロージャ?(gen = gen_func()のgenみたいなやつ)は単にgeneratorと呼ばれる。
yieldはreturnのように働き、generatorがyield文に出会うとそこでその関数を抜ける。
ただし、yieldはreturnと違い、どこで抜けたかを覚えていて、次にその関数が呼ばれるときはその抜けた次の行から再開する。
局所変数なども同時に冷凍してある。

generatorは__next__()で次の呼び出しができるのでforループに用いることができる。

基本的にはyield文は__next__()の返り値で欲しい値を吐くために使う。

numpyの1d-arrayを2d-arrayに変換

超基本的だけど毎回微妙にむかつくので整理するためにメモ.

numpyはベクトルと行列を分けているので*1,ベクトルの転置が取れなくて困る.
n次元ベクトルxは,numpyでは行ベクトルでも列ベクトルでもない.単にn次元ベクトル.
だからx.transpose()してもなにも起きない.ベクトルにtranspose()したらエラー投げて欲しい.

明示的に行ベクトルや列ベクトルにするときは,行ベクトルなら1xn行列,列ベクトルならnx1行列を作る必要がある.
n次元ベクトルxから行ベクトル(横ベクトル)を作るときは,x.reshape(1, n).
列ベクトル(縦ベクトル)を作るときは,x.reshape(n, 1).

x.reshape(-1, n)でも問題ない.reshapeではtupleの要素にひとつだけ-1を指定できる.-1を指定された次元は,他の明示的に指定した次元と元のベクトルの長さから自動的に決定される.

x[:, np.newaxis]とx[np.newaxis, :]という書き方もあるけど,「:」の意味がわかりづらくなる書き方だからあまり好きじゃない.xはベクトルなのに,np.newaxisをいいことに第二次元にアクセスしてるみたいで気持ち悪い.

ちなみに,列ベクトル(縦ベクトル)を作りたいときに限って,np.vstack(x)でも可.
ただしnp.hstack(x)では行ベクトルを作ってくれないので使わないほうがいいかも.
ただ,vstackではベクトルの長さnを取ってこなくても良いので,便利そう.
reshapeを使うと,x.reshape(x.shape[0], 1)とかx.reshape(len(x),1)みたいなことになるから・・・

numpyにarray.h()とarray.v()ってメソッド追加してくれないかなぁ

2014/10/31追記:
numpy.c_[x]でnx1に変換できるらしい。一番シンプル。
しかし、関数ではない(丸括弧じゃなくてカギ括弧!)だったり、c_に対応するr_を使って、array型のxをr_[x]としても1xnにはならなかったり、細かいところが微妙。
やっぱりarray.h()とarray.v()が欲しい

*1:matlaboctaveではベクトルは1xn行列という扱い