אינטגרציית מונטה קרלו

מתוך testwiki
קפיצה לניווט קפיצה לחיפוש
אנימציה של אינטגרציית מונטה קרלו של הפולינום x36x2+9x+1 בתחום [0,4]. הקווים הנוספים מסמלים את כיסוי התנהגות הפונקציה ע״י הוספת נקודות דגימה נוספות. בכותרת מוצגת השגיאה היחסית שקטנה ככל שמספר נקודות הדגימה עולה.

אינטגרציית מונטה קרלו היא שיטת אינטגרציה נומרית מבוססת דגימה אקראית של נקודות בתחום האינטגרל, והיא מקרה פרטי של שיטת מונטה קרלו. השיטה שימושית במיוחד לחישוב אינטגרלים רב ממדיים מאחר שאינה מחלקת את תחום האינטגרל לרשת בדידה שגדלה בצורה מעריכית כתלות בממד.

שיטה זאת זוכה לשימושים נרחבים במתמטיקה פיננסית[1][2], פיזיקה סטטיסטית[3], גרפיקה ממוחשבת[4][5] ובעוד תחומים רבים.

רקע

נניח כי ברצוננו לחשב את האינטגרל המסוים I של פונקציה חד או רב ממדית g(𝐱) על התחום Ωn כאשר Ω היא קבוצה סופית.

I=Ωg(𝐱)d𝐱נניח כי Ω בעלת נפח סופי V=Ωd𝐱.

נגדיר משתנה מקרי XUnif(Ω) שמתפלג בצורה אחידה על Ω ונשים לב כי פונקציית הצפיפות f של X תוגדר להיותf(x)={p=1/VxΩ0otherwise

נשים לב כי, התוחלת של X כאשר עליו מופעלת הפונקציה g היא

𝔼[g(X)]=Ω¯g(𝐱)f(𝐱)d𝐱=Ω¯g(𝐱)p d𝐱=pI=I/V

מאידך, עבור N דגימות מהמ״מ X, 𝐱1,𝐱2,,𝐱NΩ¯ נשערך את 𝔼[g(X)] ע״י

𝔼[g(X)]1Ni=1Ng(𝐱i)ולבסוף נקבל

I=V𝔼[g(X)]QNVNi=1Ng(𝐱i)

מחוק המספרים הגדולים נקבל

limNQN=V𝔼[g(X)]=I

הערכת השגיאה

ראשית, נשים לב כי QN משערך חסר הטיה תבנית:אנ

𝔼[QN]=𝔼[VNi=1Ng(𝐱i)]=VNi=1N𝔼[g(𝐱i)]=V𝔼[g(X)]=I

נחשב את המשערך חסר ההטייה σ^N2 של השונות[6] 𝕍[g(X)]

σ^N21N1i=1N(g(𝐱i)I)2
שגיאה יחסית של אינטגרציית מונטה קרלו כתלות במספר הדגימות N שדועכת בקצב התכנסות 1/N

והשונות של המשערך

QN

𝕍[QN]=𝕍[VNi=1Ng(𝐱i)]=V2N2i=1N𝕍[g(𝐱i)]=V2N𝕍[g(X)]V2σ^N2N

ולבסוף נקבל, כי שורש השגיאה הריבועית ממוצעת, ע״פ משפט 6.9 של[7] והיעדר ההטייה של QN הוא

RMSE(QN)=𝕍[QN]+bias(QN)=𝕍[QN]VσN2N

דוגמה: שערוך הערך π ע״י חישוב שטח מעגל היחידה

אנימציה של שערוך הערך π ע״י דגימת נקודות

הדגמה נפוצה של השיטה היא שערוך הערך π ע״י חישוב שטח מעגל היחידה 𝕊1. על אף שזו אינה דרך יעילה לחשיוב הערך של π, היא מדגימה את השיטה.

בשביל לחשב את π ניתן לחשב אינטגרל על התחום [1,1]×[1,1] של פונקציית האינדיקטור של מעגל היחידה 𝟏S1 המוגדרת להיות

𝟏S1(x,y)={1if x2+y210elseומכך מקבלים:

π=area(S1)=S1d𝐱=[1,1]2𝟏S1d𝐱

והמשערך יהיה

QN(π)=VNi=1Ng(𝐱i)=vol([1,1]2)Ni=1N𝟏S1=4#{samples in S1}#{total samples}

כלומר למעשה, החישוב נעשה ע״י דגימת נקודות בריבוע היחידה [1,1]2, ספירה של הנקודות שנופלות בתוך מעגל היחידה, חלוקה במספר נקודות הדגימה הכולל (תחולת האינטגרנד) והכפלה בנפח ריבוע היחידה.

מימוש ההדגמה בשפת פייתון:

import numpy as np

### parameters
# number of samples
N = 1e6

# generate N uniform random points inside the unit cube [-1, 1] x [-1, 1]
X = np.random.uniform(low=-1, high=1, size=(int(N), 2))
domain_volume = 4  # unit cube area.

# mask for points inside the unit circle - equivalent to applying the indicator function of the unit circle.
distance = np.sqrt(X[:, 0] ** 2 + X[:, 1] ** 2)
inside_mask = distance <= 1  # array of booleans.

# compute the mean of the indicator function over the domain and multiply by the domain volume to get the integral value.
indicator_mean = np.sum(inside_mask) / N
integral_value = indicator_mean * domain_volume

ניתן כמובן לשערך את הערך

π

בעזרת חישוב שטחם של מעגלים בעלי רדיוס שונה מ-1

יתרונות וחסרונות

תבנית:תמונות מרובות יתרונות

  • פשטות - להבנה ומימוש - השיטה אינטואיטיבית ודי פשוטה למימוש כפי שניתן לראות בקוד לעיל.
  • היעדר תלות בממד[8]תבנית:הערה - שיטות אינטגרציה נומרית אחרות (תרבוע גאוסיאני ושיטת סימפסוןתבנית:אנ לדוגמה) מחלקות את תחום האינטגרציה לרשת בדידה בעלת N נקודות, בהן הפונקציה מופעלת. כאשר ממד האינטגרל גדול מאחד d1 אנו מקבלים גידול אקספוננציאלי במספר הנקודות מאחר שעלינו לחלק את התחום לרשת בדידה בכל ממד כלומר - Nd נקודות. שיטת מונטה לעומת זאת, דוגמת N נקודות במרחב הרב ממדי כולו ולכן אינה סובלת מ״קללת הממד״תבנית:אנ

חסרונות

  • התכנסות איטית - כאמור, השגיאה הריבועית ממוצעת דועכת בקצב O(1N) כתלות במספר הדגימות N.
  • אינה דטרמיניסטית - בעלת מרכיב אקראי (דגימת הנקודות) - בשונה משיטות אינטגרציה נומרית רשתיות כגון שיטת הטרפזתבנית:אנ שמחלקות את תחום האינטגרציה לרשת בדידה דטרמיניסטית, שיטת מונטה קרלו דוגמת אקראית נקודות בתחום האינטגרציה. צורת הדגימה של הנקודות חשובה מאוד. לדוגמה, לא נרצה לקבל מעיין ״גוש״ נקודות קרובות אחת לשנייה (איור 1), אלא דגימה אחידה במרחב ע״מ לקבל כיסוי מספיק של התנהגות הפונקציה בתחום. נוסף על כך, אקראיות השיטה תאלץ אותנו לחזור על חישובנו מספר רב של פעמים על מנת ליצור סטטיסטיקה מספקת על התוצאות ולהשתמש ברווח בר-סמך ו/או מבחנים סטטיסטים.

וריאציות

דגימת שכבות רקורסיבית

תבנית:הפניה לערך מורחב

הכללה של אינטגרציה מסתגלתתבנית:אנ לשיטת מונטה קרלו. כאשר בכל חזרור, אם הדיוק המתקבל אינו עומד בדיוק הרצוי, תחום האינטגרציה מחולק ל-2 תתי תחומים, אשר עליהם נעשית האינטגרציה, בצורה איטרטיבית. החלוקה תעשה לתחומים בהם שונות הפונקציה היא הגדולה ביותר על מנת להביא לכיסוי טוב יותר של התחום באזורים חשובים אלה.

כאשר האינטגרל הוא רב ממדי, חלוקה של כל ממד ל-2 תגדיל את מספר הנקודות בצורה מעריכית, לכן החלוקה תעשה בממד בו חלוקה נוספת תביא להקטנת השגיאה המשמעותית ביותר.

ניתן להרחיב על דגימת שכבות רקורסיבית ואלגוריתם MISERתבנית:אנ המממש אותה.

דגימת חשיבות

שגיאה יחסית של חישוב ערך האינטגרל של פעמון גאוסיאני סטנדרטי בתחום האינטגרציה [50,50] כתלות במספר הדגימות N. מדגיש את עליונות אלגוריתם וגאס תבנית:אנ אשר דוגם פחות נקודות בקצוות התחום (מאחר שחשיבותן נמוכה מאוד) לעומת דגימה אחידה על התחום האינטגרציה.

בדומה לאלגוריתמים דטרמיניסטים כגון שיטת סימפסוןתבנית:אנ, נקודות בעלות ערך שונה בהרבה מסביבתן, אשר משפיעות על הערך הסופי של האינטגרל, עלולות ״להתפספס״ כנקודות דגימה ולהשפיע לרעה על התוצאה הסופית. לכן ישנה חשיבות רבה על נקודות הדגימה עצמן, הדרך בהן הן נבחרות.

השיטה ״הנאבית״ פשוטה להבנה ומימוש, הנקודות נבחרות בצורה שרירותית ע״י דגימה אחידה על תחום האינטגרציה, ללא התייחסות לחשיבותן בתוצאה הסופית. וריאציות של השיטה מסוג "דגימת חשיבות" מציעות צורת דגימה אחרת.

דוגמה טובה לכך היא חישוב האינטגרל המסוים של פעמון גאוסיאני סטנדרטי בעל תוחלת μ=0 וסטיית תקן σ=1 על התחום [50,50]. כאשר נשתמש בשיטה הנאיבית, מאחר שהדגימה אחידה על התחום, יתקבלו נקודות דגימה רחוקות ממרכז הפעמון (0) למרות היותן בעלות חשיבות נמוכה עד זניחה עבור חישוב האינטגרל שהרי עבור |x|3 (3 סטיות תקן) ערך הפונקציה קטן מ- 5103. אי לכך, רצוי להתמקד בדגימה באזורים בהם הנקודות בעלות חשיבות גבוהה (סביב מרכז הפעמון בדוגמה לעיל). רעיון זה ממומש, לדוגמה, באלגוריתם וגאס [9] [10] [11]תבנית:אנ.

מימוש בקוד

קוד פייתון כללי כאשר הפונקציה ותחום האינטגרציה ידועים, והתחום הוא מלבן רב ממדי:

import numpy as np
from typing import Callable


def monte_carlo_integration(
    domain: np.ndarray, N: int, f: Callable[[np.ndarray], float]
) -> float:
    """monte_carlo_integration

    Args:
        domain (np.ndarray): d-dimensional domain - [a_i, b_i] x ... x [a_d, b_d] - represented as a 2 x d numpy array.
        N (int): number of random points to generate.
        f (Callable[[np.ndarray], float]): function to integrate that receives a d-dimensional point and returns a float.

    Returns:
        float: integral value of f over the domain.
    """

    # generate N uniform random points - a random matrix of size N x d with each row representing a random point.
    # first column of the domain holds the lower bounds and the second column holds the upper bounds.
    X = np.random.uniform(
        low=domain[:, 0], high=domain[:, 1], size=(N, domain.shape[1])
    )

    # evaluate the function at the random points
    f_values = np.apply_along_axis(func1d=f, axis=1, arr=X)

    # compute the domain volume and final integral
    domain_volume = np.prod(domain[:, 1] - domain[:, 0])
    integral_value = np.mean(f_values) * domain_volume

    return integral_value


# Example usage with unit circle
domain = np.array([[-1, 1], [-1, 1]])
N = 1e6
f = lambda arr: np.where(np.linalg.norm(arr) <= 1, 1, 0)
integral_value = monte_carlo_integration(domain, N, f)

בנוסף, קיימות דוגמאותתבנית:הערה וספריות [12] פייתון שממשות גרסאות שונות של האלגוריתם.

קישורים חיצוניים

הערות שוליים

תבנית:הערות שוליים