「プログラミングのための確率統計」を読む : 2章 #2

2.2 同時確率と周辺確率

確率変数 X , Yがある場合、 - X=a、Y=bになる確率をP(X=a,Y=b)とする。同時にX=a、Y=bが成り立つ確率 = 同時確率。その分布を同時分布 - P(X=a)、P(Y=b)になる確率は周辺確率。その分布を周辺分布

  • サイコロXとYをふたつ投げて、X6の場合つまり、P(X = 6)の場合は、
  • P(X = 6,Y = 1) + P(X = 6,Y = 2) + P(X = 6,Y = 3) + P(X = 6,Y = 4) + P(X = 6,Y = 5)+ P(X = 6,Y = 6) = P(X = 6)
  • つまり、同時確率を足し合わせると、周辺確率が求まる。逆は無理。

確率変数が3つ以上の場合も同じ

2.3 条件付き確率

2.3.1 条件付き確率とは

神様視点的には領域限定

♦️J ♦️Q ♦️K ♥J ♥Q ♥K ♥1 ♥2 ♠️K ♠️1 ♠️2 ♥3 ♠️3 ♠️4 ♠️5 ♠️6

  • 赤い札は9枚
  • 黒い札は7枚
  • 数字は9枚
  • 絵札は7枚
  • 赤くて数字は3枚
  • 赤くて絵札は6枚
  • 黒くて数字は6枚
  • 黒くて絵札は1枚

赤い札に限定すると、

  • 赤い札の世界は、 9/16 の世界
  • この世界の絵札の割合が、「赤いという条件のもとでの絵札の確率」条件付き確率
  • (6/16) / (9/16) = 6/9 = 2/3

A県における工場の面積の割合は、A県の工場の面積をA県の面積でわればいい。

P(Y = b| X = a) = P(X = a, Y = b)/ P(X = a)

2.3.1 同時分布・周辺分布・条件付き分布の関係

ジョーカーを除いた52枚のトランプから1枚引き、さらにもう一枚引く。 両方同じ色の確率は?

  • 両方赤の場合。
    • 1枚目が赤の確率は、26/52 = 1/2
    • 1枚目が赤でかつ2枚目も赤の確率は、1/2 * 25/51
  • 黒の場合も同じなので、(1/2 * 25/51) * 2 = 25/51
    • 25/51は実はP( Y= 赤| X = 赤) = 25/51
    • 1枚目が赤ということは、赤は残り25枚、全部で残り、51枚だから。

2.3.4 3つ以上の確率変数

2つの時と同じ、例えば、

P(X = a, Y = b, Z =c) を考える。

  • P(X = a)とP(Y = b)とP(Z = c)の同時確率。
  • P(図柄 = 絵札, タイプ =♦️,色 = 赤) = P(図柄 = 絵札|タイプ =♦️,色 = 赤) * P(タイプ =♦️,色 = 赤)
  • P(図柄 = 絵札|タイプ =♦️,色 = 赤) = 赤で♦️という世界に限定した上で、図柄が絵札ということ。(3/52) / (1/4)
  • P(タイプ =♦️,色 = 赤) = P(タイプ =♦️|色 = 赤) * P(色 = 赤)
  • P(タイプ =♦️|色 = 赤) = 赤いという世界に限定した上で、♦️であるということ (1/4) / (1/2)
  • P(色 = 赤) = 1/2
  • P(図柄 = 絵札, タイプ =♦️,色 = 赤) = (3/52) / (1/4) * (1/4) / (1/2) * 1/2 = 3/52

P(◯◯ , ×× | △△) = P(◯◯ , ×× , △△) / P(△△) P(◯◯ , ×× , △△) = P(◯◯ | ×× , △△) P( ×× | △△) P(△△) P(◯◯ , ×× | △△) = P(◯◯ | ×× , △△) P( ×× | △△)

「プログラミングのための確率統計」を読む : 2章

複数の確率変数のからみあい

  • 現実では複数の確率変数の関わりあいを解析する。
  • 絡まり合いを調べる必要がある。

からまりあいを理解するには、神様視点を使って

  • 同時確率、周辺確率、条件付き確率の3点セットを抑える
  • Bayesの公式も3点セットの応用
  • 独立性という概念もしっかりと。

2.1 各県の土地利用

2.1.1 県別、用途別の集計(同時確率と周辺確率)

神様視点なので、確率を面積として扱う。

f:id:stokutake:20150918223930p:plain

  • 全体の面積は1
  • A県とB県とC県がある
  • 住宅と栗林と工場ががある
  • P(A) + P(B) + P(C) = 1
  • P(住宅) + P(栗林) + P(工場) = 1
  • A県の住宅の面積は、P(A,住宅)とかく
2.1.2 県内、用途内の割合(条件付き確率の練習)

どの県が、工場を重視しているのかを考える。

  • 単純にP(A,工場)、P(B,工場)、P(C,工場)を比べるのはバッドアイディア。
  • 県の面積が違うのだから。
  • 各県の面積に占める工場の割合を比べればいい。
    • A県に占める工場の割合 = A県内の工場の面積 / A県の面積 = P(工場 | A)   
    • B県に占める工場の割合 = B県内の工場の面積 / B県の面積 = P(工場 | B)   
    • C県に占める工場の割合 = C県内の工場の面積 / C県の面積 = P(工場 | C)
2.1.3 割合を逆算するには (Bayesの公式の練習)

P(県)とP(用途|県)の一覧から、P(県 | 用途)を計算する。

  • P(A県|栗林)は、国全体の栗林のうち、A県が占める割合。つまり P(A,栗林)/ P(栗林)
  • P(A,栗林)とP(栗林)がわかれば、P(A県|栗林)がわかる。
  • P(A,栗林)は、A県の栗林の面積。国全体に占めるA県の面積のうちの栗林の割合と同値。
    • 国全体に占めるA県の面積はP(A)
    • A県の面積のうちの栗林の割合はP(栗林|A)
    • 国全体に占めるA県の面積のうちの栗林の割合はP(A)✖P(栗林|A)
    • A県の面積が0.2でそのうち60%が栗林だったら、0.2 ✖ 0.6
  • これで、P(A,栗林)がわかった。
  • P(栗林)は個別に集計するしかない。P(A,栗林) + P(B,栗林) + P(C,栗林) = P(栗林)
    • B県の面積が0.32でそのうち、25%が栗林だったら、P(B,栗林) = 0.32 ✖ 0.25
    • C県の面積が0.48でそのうち、25%が栗林だったら、P(C,栗林) = 0.48 ✖ 0.25
    • P(A,栗林) + P(B,栗林) + P(C,栗林) = 0.2 ✖ 0.6 + 0.32 ✖ 0.25 + 0.48 ✖ 0.25 = P(栗林)
  • P(A,栗林)/ P(栗林) = 0.2 ✖ 0.6 / (0.2 ✖ 0.6 + 0.32 ✖ 0.25 + 0.48 ✖ 0.25 ) = 0.375
2.1.4 割合が画一的な場合 (独立性の練習)

どの県でも、住宅が30%、栗林が20%、工場が50%だとすると、 - P(住宅|A) = P(住宅|B) = P(住宅|C) = 0.3 = P(住宅) - つまり、P(用途|県) = P(用途)P(県) -ということは、P(A|住宅) = P(B|住宅) = P(C|住宅)

「プログラミングのための確率統計」を読む : 1章 モンティホール問題のシュミレーション

Pythonでシュミレーション

回答者が選びなおさない場合
from numpy import *

ok = 0
ng = 0

for num in range(1, 10000):

    door = ["a", "b", "c"]

    answer = random.choice(door)
    choice = random.choice(door)

    if answer == choice:
        ok += 1
    else:
        ng += 1

print "ok = " + str(ok)
print "ng = " + str(ng)

結果は、

ok = 3393
ng = 6606
回答者が選びなおさない場合
from numpy import *

ok = 0
ng = 0

for num in range(1, 10000):

    door = ["a", "b", "c"]

    answer = random.choice(door)
    choice = random.choice(door)

    incorrectanswer = ""

    # 回答者が正解だった場合は、不正解の選択肢しかのこらない
    if answer == choice:
        door.remove(choice)

        # 選択されなかった扉から司会者が不正解の扉をひとつ選ぶ
        incorrectanswer = random.choice(door)
    # 回答者が不正解だった場合は、正解の選択肢しかのこらない
    else:
        door.remove(choice)
        door.remove(answer)

        # 選択されなかった扉から司会者が不正解の扉をひとつ選ぶ。    
        incorrectanswer = random.choice(door)
        door.append(answer)

    # 司会者が不正解の扉を開く。回答者が最初の選択で不正解だった場合は、この時点で正解の選択肢しかのこらない
    door.remove(incorrectanswer)

    choice = random.choice(door)

    if answer == choice:
        ok += 1
    else:
        ng += 1


print "ok = " + str(ok)
print "ng = " + str(ng)

結果は、

ok = 6639
ng = 3360

「プログラミングのための確率統計」を読む : 1章

プログラミングのための確率統計

プログラミングのための確率統計

第1章 確率とは

1.1 数学の立場

この章の目的は、「確率」のぼんやりとしたイメージと、その抽象的な定義を結びつけることにある。

1.2 三つの扉(モンティホール問題) - 飛行機視点

1.2.1 モンティホール問題
  • 3つの扉がある
  • そのうちひとつは開けると高級車がある
  • 残りふたつは開けるとやぎ
  • 挑戦者はひとつの扉を選ぶ
  • 司会者は選ばれなかったふたつのうち、不正解の扉を開き、挑戦者に「選び直してもいいですよ」
  • 挑戦者は選び直したほうがいいのか?そのままでいいのか?どちらでも同じか

モンティ・ホール問題 - Wikipedia

1.2.2 正しい答えとよくある勘違い

正しい答えは、選び直すほうが得。 しかし、 選び直しても、正解の確率は1/2になるだけなので、得にはならない、と思える。

1.2.3 飛行機視点への翻訳
  • 360の会場でモンティホール問題を出題。Aが正解の会場=120会場,Bが正解の会場=120会場,Cが正解の会場=120会場
  • 120会場のうち、挑戦者がAを選ぶ=40会場、挑戦者がBを選ぶ=40会場、挑戦者がCを選ぶ=40会場

f:id:stokutake:20150905112437p:plain

正解がBの場合も、正解がCの場合も同様に、

  • 選び直した場合は、80会場で車ゲット。
  • 選び直さなかった場合は、40会場で車ゲット。

合計すると、

  • 選び直した場合は、240会場で車ゲット。240/360=2/3で車ゲット。
  • 選び直さなかった場合は、120会場で車ゲット。120/360=1/3で車ゲット。

なので、選び直したほうがお得。

1.3 三つ組(Ω、F、P) ー 神様視点

神様から見れば、

  • さまざまな世界がある。
  • しかし、それぞれの世界にはシナリオが配られており、起きることが決まっている。すべて確定的。
  • ex ) すでに結果が決まっているモンティホールゲームをする会場が360ある = 360の世界がある。
  • 確率的なことはなにもない。

しかし、人間からみると、

  • 自分がどの世界に住んでるのかわからない。
  • 360の会場のうち、どの会場を観覧しているのかわからない。だから、ゲームの結果もわからない。
  • 不確実さがある。

会場の数=世界の数を数えることができたら、不確実さを論じることができる。 しかし、人間にはできない。

そこで、人間は面積をはかる。

  • Ω = パラレルワールド全体 = 面積1
  • P(x) = 面積をはかる関数
  • ω = パラレルワールドの中の世界のひとつ。1以下の面積を占める。すべてのωの面積を足すと1になる。
  • ω' = コインを投げて表が出る世界 = 面積0.5 = P (ω)
  • ω'' = コインを投げて裏が出る世界 = 面積0.5 = P (ω')

パラレルワールド全体の集合ΩとΩ内の面積を計測する関数Pがあれば、確率の話ができる。

1.4 確率変数

確率的な量を確率変数という。運次第で揺らぐ不確定な量。

神様視点で言えば、確率変数とは、ただの関数 f(ω) 。神様はパラメータωがどのパラレルワールドかわかっているから。 人間視点でいうと、f(ω)は不確定。ωがわからないから。

  • X(u,v)は、uとvの値に応じて、あたりかはずれになる。
  • 0 < u < 1 かつ 0 < v < 1
  • この場合は、あたり、はずれ、が確率変数

実数値の確率変数なら、例えば、

  • Z(u,v) = 20(u - v)
  • 0 < u < 1 かつ 0 < v < 1 なら 取りうる値は -20から20までの間
  • 0 < Z(u,v) < 10 となる確率は?
    • 20(u - v)が0になるのは(u=0,v=0) (u=1,v=1)
    • 20(u - v)が10になるのは(u=0.5,v=0) (u=1,v=0.5)
    • (u=0,v=0) (u=1,v=1) (u=0.5,v=0) (u=1,v=0.5) の4つの点に囲まれた部分の面積が答え。

1.5 確率分布

  • 確率変数はある世界ωをパラメータにした場合のf(ω) 。どの世界でどんな値がでるかを特定。
  • 確率分布はωを意識しない。出る値とその面積 = 確率を意識する。

サイコロの目

サイコロの目 その目がでる確率
1 0.4
2 0.1
3 0.1
4 0,1
5 0.1
6 0.2

ざっくり言えばどの確率=面積でどの値がでるかの一覧表。

確率変数が与えられたら確率分布が作れる。 上の例であれば、1,2,3,4,5,6という確率変数とそのf(ω)である0.4,0.1,0.1,0.1,0.1,0.2が決まっていれば、確率分布は作れる。 しかし、f(ω)である0.4,0.1,0.1,0.1,0.1,0.2だけでは、確率変数はわからない。

1.6 現場流の略記法

1.7 Ωは裏方

Ωは円でもいいし立体でもいい。

念押し

  • 確率は面積だからマイナスにならない。
  • 全体の面積は1を越えない。
  • ⚪️⚪️な確率と⚪️⚪️でない確率を足せば、1

Gulp 入門

始めに

Pluralsightで、Gulpについて勉強しました。

www.pluralsight.com

コースはこちら

http://www.pluralsight.com/courses/javascript-build-automation-gulpjs

Gulpの基本的な部分を紹介したいと思います。

Gulp とは何か

GulpのGithubの説明によれば、

gulp is a toolkit that will help you automate painful or time-consuming tasks in your development workflow.

だそうです。 つまり、時間がかかる作業や何度も繰り返す作業を自動化するためのツールということのようです。 Pluralsightでは、タスクランナーとして紹介されています。 特に、フロントエンド周りの開発、例えば、

など、必須の細かなタスクの実行で威力を発揮するようです。 たしかにこのようなタスクを手動でやるのは、苦痛ですね。。。

The streaming build system

GulpのGithubには、「The streaming build system」と書いてあります。 これは、Gulpのコンセプトを一言で表しています。

http://i.imgur.com/B0B77QN.png

Gulpは、

  • ファイルを読み、
  • なんらかの変換をして、
  • 書き出す

というシンプルな仕組みを提供します。

Gulpをインストールする

まず、node.jsが必要ですので、node.jsをインストールします。

Node.js

インストーラからnode.jsをインストールすれば、npmも使えるはずですので、npmを使ってGulpをインストールします。 ※パッケージ管理システムを使った場合はnpmは一緒に入らないかもしれません。Macportsで入れたのですが、一緒に入りませんでした。

sudo npm install-g gulp

そして、特定のプロジェクトフォルダで、ローカルインストールをする必要があります。 gulpを使うフォルダで、

sudo npm install gulp

これでインストールは終了です。

Gulpの4つのAPI

Gulpの良い点はたった4つのAPIを学べば使いこなせるということだと思います。

  • gulp.task
  • gulp.src
  • gulp.dest
  • gulp.watch

gulp.task(name,[,dep],fn)

gulp.taskは文字通り、gulpのタスクを定義します。

  • 最初の引数nameはタスクの名前です。
  • 2つめの引数depはオプションです。これは、依存するタスク名を書きます。ここに書かれたタスクの後に、このタスクが実行されるようになります。ただし、引数depに書かれたタスクはパラレルで実行されるので注意が必要です。
  • 3つめの引数fnは実行される処理をfunctionとして書きます。

実際にタスクを作成し、実行してみます。 プロジェクトフォルダに以下の内容のgulpfile.jsというファイルを作成します。

var gulp = require('gulp');

gulp.task('hello-world',function(){
  console.log('Hello world gulp');
});

このタスクを実行するには、コマンドからタスク名を指定して実行します。

gulp hello-world

すると結果は、

[10:31:18] Using gulpfile ~/Documents/workspace/auto-glup/gulpfile.js
[10:31:18] Starting 'hello-world'...
Hello world gulp
[10:31:18] Finished 'hello-world' after 102 μs

と、Hello world gulpが出力されているのがわかります。

では次に、オプション引数のdepをつけてみます。

var gulp = require('gulp');

gulp.task('hello-world',['wakeup-gulp','good-morning-gulp'],function(){ 
  console.log('Hello world gulp');
});

gulp.task('good-morning-gulp',function(){
  console.log('good morning gulp');
});

gulp.task('wakeup-gulp',function(){
  console.log('wakeup gulp');
});

ふたつのタスクを追加しました。good-morning-gulpとwakeup-gulpです。 そして、hello-worldのタスクの依存タスクとして、このふたつを登録しました。['wakeup-gulp','good-morning-gulp']です。

さきほどと同じように、hello-worldを実行してみます。

gulp hello-world

結果は以下の通り。

[11:09:22] Using gulpfile ~/Documents/workspace/auto-glup/gulpfile.js
[11:09:22] Starting 'wakeup-gulp'...
wakeup gulp
[11:09:22] Finished 'wakeup-gulp' after 116 μs
[11:09:22] Starting 'good-morning-gulp'...
good morning gulp
[11:09:22] Finished 'good-morning-gulp' after 46 μs
[11:09:22] Starting 'hello-world'...
Hello world gulp
[11:09:22] Finished 'hello-world' after 32 μs

Hello world gulpが出力される前に、wakeup gulpとgood morning gulpが出力されているのがわかります。

gulp.srcとgulp.dest

gulp.srcはファイルを読み込みます。ストリームの始点です。 gulp.destはファイルを書き出します。ストリームの終点です。 ストリームはpipeを使って、処理を挟むことができます。

実際に、 - jsを読み込む - 空白を取り除いて最小化する=minifyする - minifyしたjsを書き出す ということをやってみます。

まず、minifyのためのgulpのプラグインをインストールします。

npm install --save-dev gulp-uglify

そして、gulpfile.jsにタスクを定義します。

var gulp = require('gulp');
var uglify = require('gulp-uglify');

gulp.task('compress', function() {
  return gulp.src('./lib/*.js')
    .pipe(uglify())
    .pipe(gulp.dest('dist'));
});

gulp.src('./lib/*.js')で拡張子がjsのファイルをすべてストリームとして読み込んでいます。 .pipe(uglify())はストリームに対して、uglify()という処理を適用しています。uglify()が最小化をしています。 .pipe(gulp.dest('dist'))はストリームに対して、gulp.dest('dist')という処理を適用しています。gulp.dest('dist')はストリームをdistに保存しています。

libの中に、jquery.jsとangular.jsの最小化していないバージョンを入れて、実際に実行してみます。

gulp compress

すると、distというフォルダが作られ、jquery.jsとangular.jsの最小化されたバージョンが出力されました。

gulp.watch

gulp.watchはファイルやフォルダを監視し、変更があったらなんらかのタスクを実行します。 例えば、sassのコンパイルなど、編集を検知して、リアルタイムで、出力したい場合に有用です。

ここでは、

  • sassフォルダを監視する
  • 変更があったら、cssコンパイルして出力する

というのをやってみます。

まず、sassのプラグインをインストールします。

npm install --save-dev gulp-sass

そして、sassのコンパイルをするタスクを定義します。

var gulp = require('gulp');
var sass = require('gulp-sass');

gulp.task('sass', function () {
  gulp.src('./sass/*.scss')
    .pipe(sass())
    .pipe(gulp.dest('./css'));
});

gulp.src('./sass/*.scss')で拡張子がscssのファイルをすべてストリームとして読み込んでいます。 .pipe(sass())はストリームに対して、sass()という処理を適用しています。sass()がsassコンパイルを実行します。 .pipe(gulp.dest('./css'))はストリームに対して、gulp.dest('./css')という処理を適用しています。gulp.dest('./css')はストリームをcssに保存しています。

実行してみます。

gulp sass

cssフォルダが作成され、cssファイルが生成されました。

さらに、./sass/*.scssに更新(追加、変更、削除)があったら、タスクsassを実行するようにgulp.watchを使ってみます。

var gulp = require('gulp');
var sass = require('gulp-sass');

gulp.task('sass', function () {
  gulp.src('./sass/*.scss')
    .pipe(sass())
    .pipe(gulp.dest('./css'));
});

gulp.task('sass-watch', function () {
  gulp.watch('./sass/*.scss',['sass']);
});

sass-watchというタスクを定義します。 gulp.watch('./sass/.scss',['sass'])は、./sass/.scssを監視し、更新があったらタスクsassを実行します。タスクは2番目の引数に配列で複数設定することができます。

実行してみます。

gulp sass-watch

監視タスクなので、コンソールは帰ってきません。 実際に./sass/*.scssのscssファイルを更新して確かめてみると、cssフォルダにコンパイルされた結果のcssが出力されました。

まとめ

4つのAPIというシンプルな構成で、それを組み合わせることで、幅広いタスクを自動化できるというのが魅力的なツールという感じがします。

特に基本がシンプルなので、導入のハードルが低いです。

以下の参考情報を見ながらやれば、短い間にかなり複雑なことまでできるようになると思います。

参考

github.com

https://raw.githubusercontent.com/osscafe/gulp-cheatsheet/master/images/ja-js-p1.png

https://raw.githubusercontent.com/osscafe/gulp-cheatsheet/master/images/ja-js-p2.png

  • 開発者によるプレゼン。モチベーションなどよくわかる。

slides.com