Managed Service for Apache Spark ו-Apache Spark מספקים תשתית וקיבולת שמאפשרות להריץ סימולציות מונטה קרלו שכתובות ב-Java, ב-Python או ב-Scala.
שיטות מונטה קרלו יכולות לעזור לענות על מגוון רחב של שאלות בתחומי העסקים, ההנדסה, המדע, המתמטיקה ותחומים אחרים. הסימולציה משתמשת בדגימה אקראית חוזרת כדי ליצור התפלגות הסתברותית של משתנה, וכך יכולה לספק תשובות לשאלות שאחרת לא היה אפשר לענות עליהן. לדוגמה, בתחום הפיננסים, כדי לתמחר אופציה על מניות צריך לנתח את אלפי הדרכים שבהן מחיר המניה יכול להשתנות לאורך זמן. שיטות מונטה קרלו מאפשרות לדמות את השינויים האלה במחירי המניות בטווח רחב של תוצאות אפשריות, תוך שמירה על שליטה בתחום של הקלטים האפשריים לבעיה.
בעבר, הפעלת אלפי סימולציות הייתה יכולה לקחת הרבה זמן ולצבור עלויות גבוהות. בעזרת Managed Service for Apache Spark אפשר להקצות קיבולת לפי דרישה ולשלם עליה לפי דקה. Apache Spark מאפשר להשתמש באשכולות של עשרות, מאות או אלפי שרתים כדי להריץ סימולציות בצורה אינטואיטיבית, ולהתאים את קנה המידה לצרכים שלכם. זה אומר שאתם יכולים להריץ יותר סימולציות במהירות, וכך לחדש מהר יותר ולנהל סיכונים בצורה טובה יותר.
כשעובדים עם נתונים פיננסיים, האבטחה תמיד חשובה. Managed Service for Apache Spark פועל ב- Google Cloud, וכך עוזר לשמור על הנתונים שלכם בטוחים, מאובטחים ופרטיים בכמה דרכים. לדוגמה, כל הנתונים מוצפנים במהלך ההעברה וכשהם באחסון, ו Google Cloud הם תואמים לתקנים ISO 27001, SOC3 ו-PCI.
מטרות
- יצירת אשכול מנוהל של Managed Service for Apache Spark עם Apache Spark מותקן מראש.
- הפעלת סימולציית מונטה קרלו באמצעות Python, שמעריכה את הצמיחה של תיק מניות לאורך זמן.
- תריץ סימולציית מונטה קרלו באמצעות Scala כדי לדמות איך קזינו מרוויח כסף.
עלויות
במסמך הזה משתמשים ברכיבים הבאים של Google Cloud, והשימוש בהם כרוך בתשלום:
כדי ליצור הערכת עלויות בהתאם לשימוש החזוי, אתם יכולים להשתמש במחשבון התמחור.
כשמסיימים את המשימות שמתוארות במסמך הזה אפשר למחוק את המשאבים שיצרתם כדי להימנע מחיובים נוספים. מידע נוסף זמין בקטע הסרת המשאבים.
לפני שמתחילים
- הגדרת פרויקט ב- Google Cloud
- נכנסים לחשבון Google Cloud . אנחנו ממליצים למשתמשים חדשים ב- Google Cloud ליצור חשבון כדי שיוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Dataproc and Compute Engine APIs, if any are not already enabled.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.-
Install the Google Cloud CLI.
-
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
-
To initialize the gcloud CLI, run the following command:
gcloud init -
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Dataproc and Compute Engine APIs, if any are not already enabled.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.-
Install the Google Cloud CLI.
-
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
-
To initialize the gcloud CLI, run the following command:
gcloud init
יצירת אשכול Managed Service for Apache Spark
פועלים לפי השלבים כדי ליצור אשכול של Managed Service for Apache Spark ממסוף Google Cloud . הגדרות ברירת המחדל של האשכול, שכוללות שני צומתי עובדים, מספיקות למדריך הזה.
השבתת הרישום ביומן עבור אזהרות
כברירת מחדל, Apache Spark מדפיס רישום מפורט ביומן בחלון המסוף. לצורך המדריך הזה, משנים את רמת הרישום ביומן כך שרק שגיאות יירשמו ביומן. איך לעשות את זה?
משתמשים ב-ssh כדי להתחבר לצומת הראשי של האשכול ב-Managed Service for Apache Spark.
לצומת הראשי של אשכול Managed Service for Apache Spark יש את הסיומת -m בשם ה-VM שלו.
- נכנסים לדף VM instances במסוף Google Cloud .
-
ברשימת המכונות הווירטואליות, לוחצים על SSH בשורה של המכונה שרוצים להתחבר אליה.

ייפתח חלון SSH שמחובר לצומת הראשי.
Connected, host fingerprint: ssh-rsa 2048 ... ... user@clusterName-m:~$
שינוי הגדרת הרישום ביומן
בספריית הבית של הצומת הראשי, עורכים את
/etc/spark/conf/log4j.properties.sudo nano /etc/spark/conf/log4j.propertiesמגדירים את
log4j.rootCategoryלהיות שווה ל-ERROR.# Set only errors to be logged to the console log4j.rootCategory=ERROR, console log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.target=System.err log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{1}: %m%nשומרים את השינויים ויוצאים מכלי העריכה. אם רוצים להפעיל שוב רישום מפורט (verbose) ביומן, צריך לבטל את השינוי ולהחזיר את הערך של
.rootCategoryלערך המקורי (INFO).
שפות תכנות ב-Spark
ב-Spark אפשר להשתמש ב-Python, ב-Scala וב-Java כשפות תכנות לאפליקציות עצמאיות, ויש בו מפרשים אינטראקטיביים ל-Python ול-Scala. השפה שתבחרו היא עניין של העדפה אישית. במדריך הזה נעשה שימוש במפרשים אינטראקטיביים כי אפשר להתנסות בהם על ידי שינוי הקוד, ניסיון של ערכי קלט שונים ואז צפייה בתוצאות.
הערכת הצמיחה של תיק ההשקעות
בתחום הפיננסים, לפעמים משתמשים בשיטות מונטה קרלו כדי להריץ סימולציות שמנסות לחזות את הביצועים של השקעה מסוימת. סימולציית מונטה קרלו יכולה לענות על שאלות לגבי הביצועים הממוצעים של תיק השקעות או הביצועים שלו בתרחישים של המקרה הגרוע ביותר. הסימולציה מתבססת על יצירת מדגמים אקראיים של תוצאות בטווח של תנאי שוק סבירים.
כדי ליצור סימולציה שמשתמשת בשיטות מונטה קרלו כדי לנסות להעריך את הצמיחה של השקעה פיננסית על סמך כמה גורמים נפוצים בשוק:
מפעילים את מפרש Python מהצומת הראשי של Managed Service for Apache Spark.
pysparkמחכים להנחיה של Spark
>>>.מזינים את הקוד הבא. חשוב לשמור על הכניסה (indentation) בהגדרת הפונקציה.
import random import time from operator import add def grow(seed): random.seed(seed) portfolio_value = INVESTMENT_INIT for i in range(TERM): growth = random.normalvariate(MKT_AVG_RETURN, MKT_STD_DEV) portfolio_value += portfolio_value * growth + INVESTMENT_ANN return portfolio_valueלוחצים על
returnעד שרואים שוב את ההנחיה של Spark.הקוד הקודם מגדיר פונקציה שמדמה מה יכול לקרות כשמשקיע מוסיף כל שנה כסף לחשבון פנסיה קיים שמושקע בבורסה לניירות ערך. הפונקציה יוצרת החזר אקראי על ההשקעה, כאחוז, בכל שנה למשך תקופה מוגדרת. הפונקציה מקבלת ערך בסיס כפרמטר. הערך הזה משמש להגדרה מחדש של מחולל המספרים האקראיים, כדי שהפונקציה לא תקבל את אותה רשימה של מספרים אקראיים בכל פעם שהיא פועלת. הפונקציה
random.normalvariateמבטיחה שערכים אקראיים יופיעו בהתפלגות נורמלית לפי הממוצע וסטיית התקן שצוינו. הפונקציה מגדילה את הערך של תיק ההשקעות בסכום הצמיחה, שיכול להיות חיובי או שלילי, ומוסיפה סכום שנתי שמייצג השקעה נוספת.בשלב הבא תגדירו את הקבועים הנדרשים.
יוצרים הרבה ערכי seed כדי להזין אותם לפונקציה. בפרומפט של Spark, מזינים את הקוד הבא, שיוצר 10,000 זרעים:
seeds = sc.parallelize([time.time() + i for i in range(10000)])התוצאה של הפעולה
parallelizeהיא מערך נתונים מבוזר ועמיד (RDD), שהוא אוסף של רכיבים שעברו אופטימיזציה לעיבוד מקביל. במקרה הזה, ה-RDD מכיל ערכי התחלה שמבוססים על השעה הנוכחית במערכת.כשיוצרים את ה-RDD, Spark מחלק את הנתונים על סמך מספר העובדים והליבות שזמינים. במקרה הזה, Spark בוחר להשתמש בשמונה פרוסות, פרוסה אחת לכל ליבה. זה בסדר לסימולציה הזו, שיש בה 10,000 פריטי נתונים. בסימולציות גדולות יותר, כל פרוסה עשויה להיות גדולה יותר מהמגבלה שמוגדרת כברירת מחדל. במקרה כזה, ציון פרמטר שני ל-
parallelizeיכול להגדיל את מספר הפרוסות, וכך לשמור על גודל פרוסה שניתן לניהול, בזמן ש-Spark עדיין מנצל את כל שמונת הליבות.מעבירים את ה-RDD שמכיל את ה-seeds לפונקציית הצמיחה.
results = seeds.map(grow)ה-method
mapמעבירה כל seed ב-RDD לפונקציהgrowומוסיפה כל תוצאה ל-RDD חדש, שמאוחסן ב-results. שימו לב שהפעולה הזו, שמבצעת טרנספורמציה, לא מפיקה את התוצאות שלה באופן מיידי. Spark לא יבצע את העבודה הזו עד שיהיה צורך בתוצאות. ההערכה העצלה הזו היא הסיבה לכך שאפשר להזין קוד בלי להגדיר את הקבועים.מציינים כמה ערכים לפונקציה.
INVESTMENT_INIT = 100000 # starting amount INVESTMENT_ANN = 10000 # yearly new investment TERM = 30 # number of years MKT_AVG_RETURN = 0.11 # percentage MKT_STD_DEV = 0.18 # standard deviationמפעילים את הפונקציה
reduceכדי לצבור את הערכים ב-RDD. מזינים את הקוד הבא כדי לסכם את התוצאות ב-RDD:sum = results.reduce(add)הערכה והצגה של ההחזר הממוצע:
print (sum / 10000.)חשוב לכלול את תו הנקודה (
.) בסוף. הוא מציין פעולות אריתמטיות בשיטת נקודה צפה.עכשיו משנים את ההנחה ובודקים איך התוצאות משתנות. לדוגמה, אתם יכולים להזין ערך חדש להחזר הממוצע בשוק:
MKT_AVG_RETURN = 0.07מריצים את הסימולציה שוב.
print (sc.parallelize([time.time() + i for i in range(10000)]) \ .map(grow).reduce(add)/10000.)כשמסיימים את הניסוי, מקישים על
CTRL+Dכדי לצאת מהמפרש של Python.
תכנות סימולציית מונטה קרלו ב-Scala
מונטה קרלו, כמובן, מפורסמת כיעד להימורים. בקטע הזה תשתמשו ב-Scala כדי ליצור סימולציה שמדמה את היתרון המתמטי שיש לקזינו במשחק מזל. היתרון של הקזינו בבתי קזינו אמיתיים משתנה מאוד ממשחק למשחק. לדוגמה, במשחק הלוטו הוא יכול להיות מעל 20%. במדריך הזה ניצור משחק פשוט שבו לבית יש יתרון של אחוז אחד בלבד. כך המשחק פועל:
- השחקן מבצע הימור, שמורכב ממספר ז'יטונים מקרן ההימורים.
- השחקן מטיל קובייה עם 100 צדדים (איזה מגניב זה יכול להיות?).
- אם התוצאה היא מספר בין 1 ל-49, השחקן מנצח.
- אם התוצאה היא בין 50 ל-100, השחקן מפסיד בהתערבות.
אפשר לראות שהמשחק הזה יוצר חיסרון של אחוז אחד לשחקן: ב-51 מתוך 100 התוצאות האפשריות של כל הטלה, השחקן מפסיד.
כדי ליצור ולהפעיל את המשחק:
מפעילים את מפרש Scala מהצומת הראשי של Managed Service for Apache Spark.
spark-shellמעתיקים ומדביקים את הקוד הבא כדי ליצור את המשחק. ל-Scala אין את אותן דרישות כמו ל-Python בכל הנוגע להזחה, ולכן אפשר פשוט להעתיק ולהדביק את הקוד הזה בהנחיה של
scala>.val STARTING_FUND = 10 val STAKE = 1 // the amount of the bet val NUMBER_OF_GAMES = 25 def rollDie: Int = { val r = scala.util.Random r.nextInt(99) + 1 } def playGame(stake: Int): (Int) = { val faceValue = rollDie if (faceValue < 50) (2*stake) else (0) } // Function to play the game multiple times // Returns the final fund amount def playSession( startingFund: Int = STARTING_FUND, stake: Int = STAKE, numberOfGames: Int = NUMBER_OF_GAMES): (Int) = { // Initialize values var (currentFund, currentStake, currentGame) = (startingFund, 0, 1) // Keep playing until number of games is reached or funds run out while (currentGame <= numberOfGames && currentFund > 0) { // Set the current bet and deduct it from the fund currentStake = math.min(stake, currentFund) currentFund -= currentStake // Play the game val (winnings) = playGame(currentStake) // Add any winnings currentFund += winnings // Increment the loop counter currentGame += 1 } (currentFund) }מקישים על
returnעד שמופיעה ההנחיהscala>.מזינים את הקוד הבא כדי לשחק במשחק 25 פעמים, שזה ערך ברירת המחדל של
NUMBER_OF_GAMES.playSession()ההון ההתחלתי שלכם היה 10 יחידות. האם הוא גבוה או נמוך יותר עכשיו?
עכשיו נדמה 10,000 שחקנים שמבצעים הימור של 100 צ'יפים בכל משחק. לשחק ב-10,000 משחקים בהפעלה אחת. הסימולציה הזו של מונטה קרלו מחשבת את ההסתברות להפסד של כל הכסף לפני סוף הסשן. מזינים את הקוד הבא:
(sc.parallelize(1 to 10000, 500) .map(i => playSession(100000, 100, 250000)) .map(i => if (i == 0) 1 else 0) .reduce(_+_)/10000.0)שימו לב שהתחביר
.reduce(_+_)הוא קיצור דרך ב-Scala לצבירה באמצעות פונקציית סיכום. היא שוות ערך מבחינה פונקציונלית לתחביר.reduce(add)שראיתם בדוגמה של Python.הקוד שלמעלה מבצע את השלבים הבאים:
- יוצר RDD עם תוצאות הפעלת הסשן.
- מחליף את התוצאות של שחקנים שהוכרזו כפושטים רגל במספר
1ואת התוצאות שאינן אפס במספר0. - הפונקציה מחשבת את סכום מספר השחקנים שפשטו רגל.
- המדד מחושב על ידי חלוקת מספר הפעמים שהאירוע הופעל במספר השחקנים.
תוצאה טיפוסית יכולה להיות:
0.998
הסיכויים האלה מייצגים כמעט ודאות שתאבדו את כל הכסף, למרות שלקזינו היה יתרון של אחוז אחד בלבד.
הסרת המשאבים
מחיקת הפרויקט
- במסוף Google Cloud , נכנסים לדף Manage resources.
- ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
- כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.
המאמרים הבאים
- מידע נוסף על שליחת משימות Spark אל Managed Service for Apache Spark
בלי להשתמש ב-
sshכדי להתחבר לאשכול זמין במאמר Managed Service for Apache Spark – שליחת משימה