Machine Morning

機械学習やWebについて学んだことを記録しています。

Pythonのif __name__ == "__main__":とは

if __name__ == "__main__":

__name__はモジュールの名前が入っている特殊な変数で、通常import hogeをしてモジュールを取り込むと、そのモジュールの__name__hogeとなる。

例えば、

import numpy as np

print(np.__name__)

>>> numpy

しかし、python hoge.pyを実行した場合、hoge.pyの中での__name____main__となる。 したがって、

if __name__ == "__main__":

は、モジュールとして取り込んだ場合、__name__はモージュル名となり、直接スクリプトファイルをpython hoge.pyとして実行した場合は、__name____main__:となる。if __name__ == "__main__":Trueなら直接python hoge.pyの形で実行され、Falseならモジュールとして読み込まれたことを判定している。

なぜ、いつ使うのか

Pythonはモジュールとして読み込んだファイルは1行目から最後の行まで実行される。実用例としてモジュールのテストコードを if __name__ == "__main__":の中に書いておけば、python hoge.pyと直接実行すればテストが走り、モジュールとして利用されたときにテストが行われなくて済む。

最小公倍数と最大公約数を求めるアルゴリズム

最小公倍数は最大公約数を使って簡単に求めることができるので、まず最大公約数を求める。

最大公約数

最大公約数を求める最も有名なアルゴリズムユークリッドの互除法である。

wikipediaから引用すると、

2つの自然数a, b (a >= b)について、aのbによる剰余をrとるすと、aとbとの最大公約数はbとrとの最大公約数に等しい。この操作を剰余が0になるまで繰り返し行い、剰余が0になったときの序数がaとbとの最大公約数となる。

例: 1071と1029の最大公約数を求める。 * 1071を1029で割った余りは42 * 1029を42で割った余りは21 * 42を21で割った余りは0 よって、1071と1029の最大公約数は21である。

これをPythonで実装すると

nums = list(map(int, input().split()))
a, b = max(nums), min(nums)

def GCD(a, b):
    while a % b != 0:
        r = a % b
        a, b = b, r
    return b

print("The GCD of {} and {} is {}.".format(a, b, GCD(a, b)))

最小公倍数

最小公倍数は  \dfrac {a\cdot b} {GCD}で求めることができる。 Pythonで書くと

def LCM(a, b):
    return int((a * b) / GCM(a, b))

print("The LCM of {} and {} is {}.".format(a, b, LCM(a, b)))

Pythonで変数を動的に生成する

使う機会があるのかわからないが、変数を動的に生成する方法を紹介する。 基本的に辞書、または変数名が数字でいい場合は配列の方が使い勝手はよい。

for i in range(5):
    exec("var_{} = {}".format(i, i))

print(var_0)
=> 0
print(var_1)
=> 1
print(var_2)
=> 2
print(var_3)
=> 3
print(var_4)
=> 4

気持ち悪い。やはり辞書を使うのが良い。

R studioでファイルを読み込む際の文字コードエラー

MacのRStudioでcsvファイルを読み込もうとすると以下のようにinvalid multibyte stringというエラーが出てくる。

> df <- read.csv("filename.csv", header=T, sep=",")
Error in make.names(col.names, unique = TRUE) : 
  invalid multibyte string at '<94>N<8c><8e>'

これは文字コードのエラーであるが、MacのRStudioでは読み込むデフォルトの文字コードUTF-8になっている。実際にRStudio上で対象のファイルを開いてみると、文字化けしていることがわかる。デフォルトの文字コードを変更することによる解決策が見つからなかったので、ここではファイルの文字コードを直接変更して対処する。

nkfで対象のファイルの文字コードを確認する。

$ nkf --guess [filename]
Shift_JIS (CRLF)

今回はShift-JIS(CRLF)であったので、MacのRStudioで読み込めるように、nkfでファイルをUTF-8に変換する。

$ nkf -w before_file.csv > after_file.csv

オプションの-wUTF-8に変換するもので、windowsの標準文字コードであるShift-JISに変換する場合は-sオプションと使う。

変換後のファイルはread.csv()で読み込むことができる。

標準誤差とは

今回は標準誤差について取り上げる。標準偏差との違いがいまいちわからないという人もいると思うが、これらはまったくの別物であり、推定や検定を理解する上で非常に大切なものである。ただし、ここで扱う標準誤差とはSEM(standard error of the mean)、すなわち標本平均の標準偏差のことである。ある統計量を指して標準誤差ということもあるので一応断っておく。

以前標本平均の分散はなぜサンプルサイズnで割るのか - Machine Morningという記事で標本平均について確認した。今回はその標本平均の標準偏差(=標準誤差)の求め方を紹介する。といっても以前の記事で標本平均の分散まで求めているので、そこまで理解していれば標準誤差を求めるのは簡単である。

標準誤差とは、標本平均の標準偏差である。標本平均は、サンプリングを繰り返し行った標本の平均だ。一度のサンプリングで得た標本の平均ではなく、繰り返しサンプリングを行い、何度も得た標本の平均を求めたものの平均である。

標準誤差の求め方は、以前求めた標本平均の分散の平方根を取ったものである。

 SE=\sqrt {\dfrac {\sigma ^{2}}{n}}=\dfrac{\sigma}{\sqrt{n}}

標準誤差の \dfrac{\sigma}{\sqrt{n}}だけ見ると、なぜ標準偏差 \sigma {\sqrt{n}}で割っているのかと疑問に思うかもしれないが、標本平均の分散の平方根を取ったものと理解していれば納得できるはずである。

信頼区間の幅は標本の数が大きくなるに連れて幅が小さくなり、 \dfrac{1}{\sqrt{n}}のオーダーで0に収束する。

サンプルサイズが100あれば \dfrac{1}{\sqrt{100}}=\dfrac{1}{10}、100,000,000あれば \dfrac{1}{\sqrt{100,000,000}}=\dfrac{1}{10,000}で標準誤差は小さくなる。

標準偏差との違いは、標準偏差は単にデータのばらつきを示すものだが、標準誤差は母集団から得られた標本から推定した推定量のばらつきを示すものだ。したがって標準誤差は母集団の真のパラメータを推定する際に用いられるため、区間推定や検定をする際に重要なものである。

テイラー展開からオイラーの等式を導く

世界一美しい等式として有名なオイラーの等式 e^{i\pi }+1=0を導出する。

導出の手順は以下の通りである。

  1.  e^{x} \cos{x} \sin{x}多項式近似をテイラー展開で求める。

  2.  \cos{x} \sin{x}を足す。

  3. 虚数 iを指数に導入する。

  4.  x \piを代入する。

まず初めに、 e^{x} \cos{x} \sin{x}多項式近似をテイラー展開で求めると以下のようになる。

 e^{x}=1+\dfrac {x}{1!}+\dfrac {x^{2}}{2!}+\dfrac {x^{3}}{3!}+\dfrac {x^{4}}{4!}+\dfrac {x^{5}}{5!}+\dfrac {x^{6}}{6!}+\dfrac {x^{7}}{7!}+\dfrac {x^{8}}{8!}+\ldots

 \cos x=1-\dfrac {x^{2}}{2!}+\dfrac {x^{4}}{4!}-\dfrac {x^{6}}{6!}+\dfrac {x^{8}}{8!}-\ldots

 \sin x=\dfrac {x}{1!}-\dfrac {x^{3}}{3!}+\dfrac {x^{5}}{5!}-\dfrac {x^{7}}{7!}+\ldots

これらは見ての通りよく似ており xが奇数のときは \sin{x}、偶数のときでは \cos{x}となっているように見える。そこで、多項式近似した \cos{x} \sin{x}を足し、 \cos{x} + \sin{x}を求める。

 \cos x+\sin x=1+\dfrac {x}{1!}-\dfrac {x^{2}}{2!}-\dfrac {x^{3}}{3!}+\dfrac {x^{4}}{4!}+\dfrac {x^{5}}{5!}-\dfrac {x^{6}}{6!}-\dfrac {x^{7}}{7!}+\dfrac {x^{8}}{8!}+\ldots

すると、各項の符号が前から順にプラス(+)、プラス(+)、マイナス(-)、マイナス(-)となっていることがわかる。ここで、各項にこの順番で符号を与えるために、虚数単位 iを導入する。 iは以下に示す通すり、累乗ごとに符号が、プラス(+)、プラス(+)、マイナス(-)、マイナス(-)と循環する。

 i^{0} = 1

 i^{1} = i

 i^{2} = -1

 i^{3} = -i

 i^{4} = 1

 i^{5} = i

 i^{6} = -1

 i^{7} = -i

 i^{8} = 1

次に e^{x} ixを代入すると、

 e^{ix}=1+\dfrac {ix}{1!}+\dfrac {i^{2}x^{2}}{2!}+\dfrac {i^{3}x^{3}}{3!}+\dfrac {i^{4}x^{4}}{4!}+\dfrac {i^{5}x^{5}}{5!}+\dfrac {i^{6}x^{6}}{6!}+\dfrac {i^{7}x^{7}}{7!}+\dfrac {i^{8}x^{8}}{8!}+\ldots

となり、式変形すると以下のようになる。

 e^{ix}=1+\dfrac {ix}{1!}-\dfrac {x^{2}}{2!}+\dfrac {ix^{3}}{3!}-\dfrac {x^{4}}{4!}+\dfrac {ix^{5}}{5!}-\dfrac {x^{6}}{6!}+\dfrac {ix^{7}}{7!}-\dfrac {x^{8}}{8!}+\ldots

これを実部(前半のカッコ内)と虚部(後半のカッコ内)に分けると、

 e^{ix}=\left( 1-\dfrac {x^{2}}{2!}+\dfrac {x^{4}}{4!}-\dfrac {x^{6}}{6!}+\dfrac {x^{8}}{8!}-...\right) +i\left( \dfrac {x}{1!}-\dfrac {x^{3}}{3!}+\dfrac {x^{5}}{5!}-\dfrac {x^{7}}{7!}+\ldots \right)

となる。なんだか見覚えのある並びが出てきたのではないだろうか。実部が \cos{x}、虚部が \sin{x}となっている。

 e^{ix} = \cos{x} + i\sin{x}

最後に、 x \piを代入すると、

 \cos{\pi} = -1

 \sin{\pi} = 0

のため、

 e^{i\pi }+1=0

この通りオイラーの等式が導かれる。

誤解されがちな信頼区間

学部3年時に取った授業内で、「信頼区間(CI: Confidence Interval)の意味理解してる?」という話になり、当時自分も含め大勢の理解がいい加減だったことを思い出したので、今回はこの話題を取り上げる。ちなみにこの話題を振ってくださったのはダートマス大学で計量政治をやっている教授で、アカデミアの人間でも結構誤解している人が多いという話だったので今でも強烈に記憶に残っている。確かに実際に統計の解説記事を読むと、誤解して書かれている記事が多い。

まずよくありがちな誤解として、「95%信頼区間は95%の確率で母集団のパラメータが信頼区間に含まれるんだよね?」というものである。確か自分もこんな理解をしていた気がする。今振り返ると、誤解の原因は当時ベイズ統計学を勉強していなかったことで、母集団のパラメータのあり方について意識することがなかったからだと思う。検定をやることを目的に頻度論の初歩にしか触れていない人間には、誤解されやすいのかもしれない。

信頼区間について正しい理解をするために、まず意識しなくてはいけないことは、頻度論の枠組みでの統計学では、母集団のパラメータは真の値(唯一決まったもの)が存在し、確率変数ではないということである。このことを理解していれば、母集団のパラメータに対して確率を与えている上記の誤解がおかしいことはすぐにわかる。

95%信頼区間についての本来の正しい意味は 「繰り返し母集団から標本を抽出し信頼区間を求めると、95%の信頼区間が母集団の真のパラメータを含む」である。ここで注目すべきポイントは、確率変数は信頼区間の方であることだ。

信頼区間
出典: https://support.minitab.com/en-us/minitab/18/help-and-how-to/statistics/basic-statistics/supporting-topics/basics/what-is-a-confidence-interval/

上図は母集団から20回サンプリングし、繰り返し信頼区間を求めると、19回は信頼区間が母集団の真の平均 \muを含み、1回は含まれないことを表している。すなわち95%信頼区間だ。

信頼区間の幅はサンプルサイズを増やせば増やすほど狭まる。これが意味するところは、母集団の真のパラメータをより精確に推定できるということだ。

ちなみにベイズ統計学では母集団のパラメータについてCredible Interval(※日本語では、信用区間や確信区間と呼ばれる)というものがあるが、上述した頻度論でのよくある誤解がCredible Intervalの正しい解釈である。ベイズ統計学では 、母集団のパラメータは事前分布に従う確率変数で真の値は存在しないと考えるからである。