Chandler@Berlin -43ページ目

Chandler@Berlin

ベルリン在住

行列式についての話を続けるつもりでしたが,ちょっと寄り道して6σの話をしようと思います.

次の質問からはじめよう

あなたは 6σ の人に会ったことはあるだろうか?

6σとは

Saarbruecken に住んでいた時に,とても大きな女性がレジの係をしていた.嘘だとは思うのだが,話によると彼女は仕事で一息つこうとしたら,巨体がレジの椅子につまって出られなくなったという話である.そういう人を日本でみつけようとするとなかなか難しい.日本人の身長の分布の広がりは,ドイツよりも狭い気がするし,アメリカはとても分布が広い気がする.つまりアメリカでは太っている人はとてつもなく太っている気がする.それに比較すれば,日本人は平均に近い人が多いのではないだろうか.

統計では平均というのは大事だが,同時にこのようにどれだけ様々な人がいるかということも重要である.数学ではこのようなものを分散(σ^2),あるいはその平方根をとって,標準偏差(σ)と言う.分散,あるいは標準偏差によって標準からどれだけ離れた人がいるかということを示すことができる.アメリカ人の体重の標準偏差は多分,日本人の体重の標準偏差より大きいだろう.

図 1 に正規分布,あるいはガウス分布と呼ばれる分布のσ= 1 の場合と σ = 2 の場合を示した.σの小さい上図が日本人型,下図がアメリカ人型と言うふうに呼んでもいいかもしれないが,言葉遣いに気をつけるとそれで世界の問題が解消されると思っている Political correctnessist (今作った造語)から文句が来るだろうと思うので,やっぱりガウス分布と呼ぶことにしよう.


Chandler@Berlin-sigma=1

Chandler@Berlin-sigma=2

図では,ちょっと不正確ではあるが,X 軸がサンプルを,たとえば,体重を示しており,Y 軸の高さがどれだけの人がその体重を持っているかを示している.中央の一番高い部分が平均で,平均が高いということは,沢山の人が平均値の近くにいるということである.もし平均が 60 kg であったら,平均近くの体重60 kgを持つ可能性の人が一番高い可能性でいるという感じである

.本当は確率分布なので,積分しないといけないが,まあいいだろう.

標準偏差によってたとえば社会の中で太っている,やせている人がどんな分布かわかるのだが,もし,近似的にあるものがガウス分布に従っていれば σいくつ分の特別さがあるのか,ということを示すことができる.実際にガウス分布かどうかは注意しないといけない.わからないから何でもガウス分布にしてしまう人がいるが,それは結構危いのだ.ガウス分布は便利なので,ついつい使いたくなるということもある.

ガウス分布は平均とσさえ決まれば,どんな分布かが決まってしまう.だから,ガウス分布では平均とσを使って分布のどこにいるかということを言うことができる.これは便利なことの一つである.

次回はこの分布である人がどこにいるかということを示す話をしよう.これは時に偏差値という名前でも知られている.

Abstract

行列式(Determinant)は行列について様々な情報を持つ一つの数である.行列には多数の数が含まれているので,一目見ただけでは,それがどのような性質を持つ行列かわからないが,行列式がわかれば,どんな性質を持っている行列なのかがある程度わかる.たとえば,行列式は逆行列があるかなど,を一つの数で示すことができる.そのために行列式は線形代数で有用な概念であり,それがどんなものかを考える意味がある.


行列式(Determinant)の概要


行列式(Determinant)は行列について様々な情報を持つ一つの数,スカラ量,である.行列には多数の数が含まれているので,一目見ただけでは,それがどのような性質を持つ行列かは通常わからないが,行列式がわかれば,どんな性質を持っている行列なのかがある程度わかる.

たとえば日常生活で,ある人を紹介したい時,その人の特徴を全て挙げて説明すればその人に対して詳細な情報がわかるかもしれない: この人は何時に起床する,この人はどの電車で会社に行く,など.しかし,特に関心のある情報をかいつまんで説明する方がわかりやすいであろう.たとえば,職業は何であるとか,性格が優しいとか,お金持ちであるとか,である.これらの特徴は,その人全てを示すことはできないが,その人に関して知ろうと思った時に助けになることが多い.また,その特徴は単純かつ重要な特徴を示すものであればより有用である.

行列式は,人に対する特徴同様,重要な特徴を示すことができる.これが,一つの数字(スカラ値)であるという単純さもすばらしい.

一方で,行列式というスカラ値一つで行列を語るのはある意味無味乾燥ではある.それぞれの行列にも特徴があり,人には行列に関する好みもある.伍子胥,坂本竜馬,前田慶次郎,シーザーなどの人物を歴史小説でじっくり読むか,歴史の教科書で簡潔に知るか,という違いのようなものである.歴史小説は私の心を熱くするが,全ての人物を読むわけにはいかない.

「人物 A はどんな人だったんだ?」という問いに対して,「彼は最後は王様になったんだ.」のような簡潔で重要と思われる情報があるとその人物の概要を知るつかみとなるだろう.そういう概要を知るに重要な情報を matrix A について知りたければ,行列式(determinant)は良い指標である.

行列は多才であって,様々なことができる.次回はちょっと小難しい言葉(線形性)を使って行列について説明しよう.

(これは行列式に関する続きものです.)

Monty Hall 問題とは,アメリカの Let's make a deal というテレビ番組に由来する確率の問題である.詳しくは WikiPedia の記事に詳しいのでそちらを参照するのが良いだろう.ここでは実はこのシミュレータを作ったというのが要点なので,問題に関しては簡潔に述べよう.

---
1. 3つのドア (A, B, C) があり,(車,ヤギ,ヤギ)がランダムに入っている.
2. プレイヤーはドアを1つ選ぶ.
3. プレイヤーがどのドアを選んだかにかかわらず、ホストは残りのドアのうち1つを必ず開ける。
4. ホストは景品のあるドアを知っていて、必ずヤギの入っているドアを開ける。
もし,両方ともヤギだった場合はプレイヤーの見えないところでコインを投げて決める.
(Wikipedia の上記の記事より引用)
---

この際,プレイヤーは最初の選択を変更した方が良いかどうかというのが問題である.

回答を言ってしまえば,最初の選択ではなく,常に switch した方が景品をもらえる可能性が二倍ある.

この blog の最後に上記の問題の定義に従った Monty Hall Problem Simulator を掲載する.ruby 言語で書かれているが,簡単なので他の言語で御自分で試さるのも良いだろう.(ところで,2 に関しての実装であるが,プレイヤーは equally distributed にランダムにドアを選ぶとした.またここでの乱数の実装は rubyの組み込みのものである.)

10000回試行した結果は,

Result: switch win ratio = 0.6689, switch lose ratio = 0.3311

であり,スイッチした方がほぼ 2/3 の可能性で勝っている.(ちなみに実装では乱数の系列を常に同じに初期化しているので,このプログラムを走らせれば読者も同じ結果が得られるはずである.ruby 1.8.7)

この問題がある雑誌で解説された際には沢山のそれは間違いであるという手紙が舞い込んだという話である.そのような手紙は大学の数学教授からも届いたという話である.多分,

「スイッチした方が景品をもらえる可能性が高い」

というのが直感的にどうも変な気がする.ということ

「問題の定義に仕方によってはスイッチしてもしなくても可能性は同じ」

というふうに問題を定義できること.そして,そちらの方が直感に合っている人が問題をそのように定義したこと.

などの条件によってそのようなことになったのであろう.雑誌の記事では語られていない(常識的ではあるが)仮定があったということである.


私は独立な事象というものに関してどうも直感が働かない.たとえば,正しいサイコロの目が 5 回続けて 1 だった場合,次に 1 に賭ける気が直感的にしないのである.独立な事象であれば,どれに賭けても同じである.サイコロが前回に何が出たかを覚えているわけがないのである.

また,今回のように何か情報が与えられた場合,条件付の確率が変化することに関しても私自身の直感は怪しい.今回の場合,極端な話,もし,外れの場所ではなく,当たりがどこかという情報を教えてもらえれば,どう確率論をこねまわしたところで,可能性どうこうという問題ではなくなる.つまり情報によって勝つ可能性は変化するのは明かであり,今回の問題ではその情報がある意味与えられている.

この確率に対する自身の直感への不信のために,私はこのような小さなシミュレータをいくつも書くことになる.シミュレータを書くことで条件に何が必要なのか,ここでは rand statement を書く時に,どんな条件が必要だったのかがわかるからだ.特にこのプログラムでの 82 行目の rand と,この付近のロジックが実際のものに近いのかがどうかによってこのシミュレーションの正当性は変化する.そのあたりの面白い話が Wikipedia の記事にはあるので,御覧頂くと良いだろう.


#! /usr/bin/ruby
#
# $Id$
# Copyright (C) 2010 Hitoshi
#
# Monty Hall Problem simulator 2010-1-22(Fri)
#
# The following is the problem rule definition. It seems that Monty
# didn't clearly define the problem, so, we employ some
# assumptions. If this rule is changed, the probability will change.
#
# 1. There are three doors (A, B, C) that has (car, donkey, donkey) and
# the assign is chosen equally distributed randomness.
#
# 2. Player choose one of the door
#
# 3. Host open one of the door that is not chosen by the player
# regardless which door is chosen by the player.
#
# 4. Host knows which door has a car (Host know the information). Host
# only open the door which has a donkey. If the both doors that is not
# chosen by the Player have donkey, Host choose one of them according
# to equally distributed random number.
#
# Actually, the rule 3. and 4. are not clear (Monty didn't mention
# this definition.) The rule 1 seems satisfied, but, could be
# violated. For example, the host can move the car, or they can put
# the car after the Player choose the door. If you change these rules,
# the probability will be changed. This makes interesting
# confusion. See WikiPedia, Monty Hall Problem.
#
# http://en.wikipedia.org/wiki/Monty_Hall_problem
# http://www.youtube.com/watch?gl=US&v=mhlc7peGlGg
#
#
require "getoptlong.rb"

MONTYHALLSIM_VERSION = "0.1.0"

#------------------------------------------------------------
# help
#------------------------------------------------------------
def print_help()
$stderr.print <<"HELP"
usage: montyhallsim.rb [-h|--help] [-v|--version] number_of_trials
Monty Hall Problem simulation.
-h, --help output this help.
-V, --version show version.
number_of_trials simulation number
By Hitoshi.
HELP
end

#------------------------------------------------------------
# verbose output
#------------------------------------------------------------
def verboseprint(mes)
if $OPT_VERBOSE then
$stderr.print mes
end
end

#------------------------------------------------------------
# class montyhallsim
#------------------------------------------------------------
class MontyHallSim
# constructor
# FIXME
def initialize()
# @foo is instance variable

# winning count when switch the choise
@switch_win_count = 0
end

# one trials and keep the results in member
def one_try()
# generate the car, donkey, donkey
car_pos = rand(3)
player_choice = rand(3)

if car_pos == player_choice then
# if player's initial choise is the car, choose one of the rest
# with 1/2 possiblity
open_choise = rand(2)
open_pos = (player_choice + (open_choise + 1)) % 3
else
# if player's initial choise is not the car, choose the only one
# possible donkey
if (player_choice + 1) % 3 == car_pos then
open_pos = (player_choice + 2) % 3
else
open_pos = (player_choice + 1) % 3
end
end

# show the status
doors = ['*', '*', '*' ]
doors[player_choice] = "P"
doors[open_pos] = "H"

# player position 'P' and Host open position 'H'
print "Player-Host: ";
doors.each { |x| print x.to_s + ' ' }
print "\n";

# and the car 'C'
print "Car: ";
doors[car_pos] = "C"
doors.each { |x| print x.to_s + ' ' }

# keep the record
if player_choice != car_pos then
@switch_win_count = @switch_win_count + 1
print " ... switching win!";
end
print "\n";
end


# run simulation
# \param _number_of_trials simulation number of trials
def run(_number_of_trials)
begin
# check number of trials
raise "0 number of trials" if _number_of_trials <= 0

# init random sequence (but always the same sequence in this
# implementation)
srand(0)
i = 0;
while i < _number_of_trials do
one_try()
i = i + 1
end

# output the result
print "Result: switch win count = " + @switch_win_count.to_s + "\n"
switch_win_ratio = @switch_win_count.to_f / _number_of_trials.to_f

print "Result: switch win ratio = " + switch_win_ratio.to_s +
", non-switch win ratio = " + (1 - switch_win_ratio).to_s + "\n"

rescue
# `$!' has the last exception object
print "Error! " + $!.message + "\n"
end
end
end

#------------------------------
# command line option parsing
#------------------------------
args = GetoptLong.new();

# ['--output', '-o', GetoptLong::REQUIRED_ARGUMENT],
args.set_options(
['--help', '-h', GetoptLong::NO_ARGUMENT],
['--version', '-v', GetoptLong::NO_ARGUMENT]
);

begin
args.each_option do |name, arg|
# print(name + ", " + arg + ":\n")
eval "$OPT_#{name.sub(/^--/, '').gsub(/-/, '_').upcase} = '#{arg}'"
end
rescue
exit(1)
end

#--- help
if $OPT_HELP
print_help
exit(1)
end

#--- show version
if $OPT_VERSION
$stderr.print(MONTYHALLSIM_VERSION + "\n")
exit(1)
end

#--- dotfile only option
is_dotfileonly = false
if $OPT_DOTFILEONLY
dotfileonly = true
end

#--- get number of trials
if ARGV.length == 0 then
number_of_trials = 100
elsif ARGV.length == 1
number_of_trials = ARGV[0].to_i
else
$stderr.print("Error! illegal number of arguments.\n")
print_help
exit(1);
end

# --- backup
dback = MontyHallSim.new()
dback.run(number_of_trials)

# --- end of montyhallsim.rb