【Python】モンテカルロ法を試してみる

【Python】モンテカルロ法を試してみる

はじめに

コジマです。

どこぞのブログで、Pythonやるのに必要な数学の知識は

  • 微分・積分
  • 線形代数
  • 確率・統計

あたりができるといいなんていう記事を見たもんで

確率・統計分野で有名なモンテカルロ法をPythonで実装してみようと思います。

モンテカルロ法

無作為にめっちゃたくさんの試行をして、その結果から未知のものを推測するやり方です。

乱数を大量に入力した結果得た出力から確率的に未知のものを予測することができます。

円周率を求めてみる

今回Pythonで組んでみたものはこれ。
モンテカルロ法と言えばこれです。

今回は一辺が2の正方形の中に半径1の円を描いたものを考えます。
(一辺2r,半径rと一般化する場合もあります。)

その正方形の上に無作為に点を打ちます。
それが円の中に入っているか調べます。
それをめっちゃたくさんやります。
円周率を調べることができます。

図と式はこんな感じです。

無作為に打った点が円の中に入っている確率は
円の面積/正方形の面積
で求められます。

n回試してm回円の中に入ったときに
円周率は上記の式で表すことができます。
一応≒としてます。

仮に1000回試して700個円の中に入った場合、
π=4*(700/1000)=2.8
となり、円周率は2.8と求まるわけです。(実際は違うけどね)

もちろん多く回数こなした方が精度が上がります。

Pythonで書いてみたよ

ソースコードはこちら

import math
import random as rd

# 座標を作るクラス
class Coordinate:
    def __init__(self):
        self.coordinate = rd.uniform(-1.0,1.0)
        
# 単位円にいればTrueを返す
def existsInCircle(x, y):
    # 三平方の定理
    r = math.sqrt(math.pow(x, 2.0) + math.pow(y, 2.0))
    # 中心(0,0)からの距離が1
    if r <= 1.0:
        return True
    else:
        return False

# 確率を求める
def getMonte(count_try, count_circle):
    return count_circle / count_try

# メイン処理
def main():
    # 試行回数
    count_try = 10000
    # 円の中に入った回数
    count_circle = 0
    
    # 試行開始
    for i in range(count_try):
        # 座標の初期化
        x = Coordinate()
        y = Coordinate()
        
        # 座標判定
        if existsInCircle(x.coordinate, y.coordinate):
            count_circle = count_circle + 1
    
    print("点が" + str(count_circle) + "回円の中に入りました。")
    
    # 円の中に入る確率を求める
    score = getMonte(count_try, count_circle)
    
    # 
    predicted_PI = 4.0 * score
    
    print("円周率の予測値【%f】" % predicted_PI)
    
    
if __name__ == '__main__':
    main()

簡単に解説

実装方針としては

  • 中心を(0,0)として乱数を取る
  • 得た座標の中心からの距離が1(半径)以下なら円の中とする
  • 円の中に入る確率を求める
  • 円周率を求める

モジュール関数は

  • 実数の乱数取るにはrandom.uniform関数
  • 累乗はmath.pow関数
  • 平方根はmath.sqrt関数

を使いました。

こんだけ!

クラスを使った実装がしたくて座標をわざわざクラス化したってことは内緒。

何回か実行してみた

実行結果はこんな感じになります。

*試行回数10000回

点が7852回円の中に入りました。
円周率の予測値【3.140800】

*試行回数100000回

点が78530回円の中に入りました。
円周率の予測値【3.141200】

*試行回数1000000回

点が785567回円の中に入りました。
円周率の予測値【3.142268】

この結果では
試行回数100000回が一番いい値が出ましたね。
ただ、これをそれぞれ複数回実行して平均値を取るとまた結果が変わってくるかもしれません。

でも今回はここまで。

さいごに

Pythonでモンテカルロ法やってみました。

試行回数が多いだけで実装自体はそんなに難しくありません。

興味ある方はこのソースコードをコピペして
試行回数を色々変えて実行してみるといいと思います。

この記事を面白いまたは役に立ったと思ってくれた方は是非私のTwitter(@kojimanotech)を
フォローしてくれたらうれしいです!

もっと学びたい人はこちら

Python、機械学習をもっと学びたいという人のためにおすすめのUdemy講座を紹介いたします!

Pythonの基本文法を押さえたい方はこちらの動画がおすすめです。
エンジニアになりたいと思って駆け出した方がPythonを選んだときはこの講座から始めるとよいと思います。
Python 3 エンジニア認定基礎試験の対策にもなります。
はじめてのPython 少しずつ丁寧に学ぶプログラミング言語Python3のエッセンス

プログラムの基礎が分かる方で機械学習に興味がある方はこちらがおすすめです。
SIGNATEという日本版Kaggleのサービスを実際に使用してハンズオン形式でデータ分析・機械学習を学ぶことができます。
もちろんこの動画だけで特級のデータサイエンティストになれるわけではないですが、機械学習の門を叩くにはとても良い講座だと思います。
【ゼロから始めるデータ分析】 ビジネスケースで学ぶPythonデータサイエンス入門

Pythonのライブラリで必ず押さえておきたいのがNumpy, Pandas, Matplotlibの3つ。
この3つを網羅的に学ぶことができる講座です。
英語の講座ですが、わかりやすい英語ですし、ソースコードメインで解説しているので
ソースコードを一緒に手を動かしながら学べば十分理解することができます。
機械学習を使わない人にもおすすめの講座です。
2021 NumPy, Pandas and Matplotlib A-Z™: for Machine Learning

気になった人はぜひ見てみてくださいね!

以上、コジマでした。


Pythonカテゴリの最新記事