Dataproc y Apache Spark proporcionan la infraestructura y la capacidad que puedes usar para ejecutar simulaciones de Montecarlo escritas en Java, Python o Scala.
Los métodos de Monte Carlo pueden ayudar a responder a una amplia gama de preguntas en los ámbitos de los negocios, la ingeniería, la ciencia, las matemáticas y otros. Al usar un muestreo aleatorio repetido para crear una distribución de probabilidad de una variable, una simulación de Monte Carlo puede proporcionar respuestas a preguntas que, de otro modo, serían imposibles de responder. En finanzas, por ejemplo, para fijar el precio de una opción sobre acciones, es necesario analizar las miles de formas en las que el precio de las acciones podría cambiar con el tiempo. Los métodos de Monte Carlo permiten simular esos cambios en el precio de las acciones en una amplia gama de resultados posibles, al tiempo que se mantiene el control sobre el dominio de las entradas posibles del problema.
Antes, ejecutar miles de simulaciones podía llevar mucho tiempo y generar costes elevados. Dataproc te permite aprovisionar capacidad bajo demanda y pagar por ella por minutos. Apache Spark te permite usar clústeres de decenas, cientos o miles de servidores para ejecutar simulaciones de forma intuitiva y escalable para satisfacer tus necesidades. Esto significa que puedes realizar más simulaciones más rápido, lo que puede ayudar a tu empresa a innovar más rápido y a gestionar mejor los riesgos.
La seguridad es siempre importante cuando se trabaja con datos financieros. Dataproc se ejecuta en Google Cloud, lo que ayuda a mantener tus datos seguros, protegidos y privados de varias formas. Por ejemplo, todos los datos se cifran durante la transmisión y cuando están en reposo, y Google Cloud cumple las normas ISO 27001, SOC3 y PCI.
Objetivos
- Crea un clúster de Dataproc gestionado con Apache Spark preinstalado.
- Ejecuta una simulación de Monte Carlo con Python que estime el crecimiento de una cartera de acciones a lo largo del tiempo.
- Ejecuta una simulación de Montecarlo con Scala que simule cómo gana dinero un casino.
Costes
En este documento, se utilizan los siguientes componentes facturables de Google Cloud:
Para generar una estimación de costes basada en el uso previsto,
utiliza la calculadora de precios.
Cuando termines las tareas que se describen en este documento, puedes evitar que se te siga facturando eliminando los recursos que has creado. Para obtener más información, consulta la sección Limpiar.
Antes de empezar
- Configurar un Google Cloud proyecto
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
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
(
roles/resourcemanager.projectCreator
), which contains theresourcemanager.projects.create
permission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
Enable the Dataproc and Compute Engine APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin
), which contains theserviceusage.services.enable
permission. Learn how to grant roles. -
Install the Google Cloud CLI.
-
Si utilizas un proveedor de identidades (IdP) externo, primero debes iniciar sesión en la CLI de gcloud con tu identidad federada.
-
Para inicializar gcloud CLI, ejecuta el siguiente comando:
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
(
roles/resourcemanager.projectCreator
), which contains theresourcemanager.projects.create
permission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
Enable the Dataproc and Compute Engine APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin
), which contains theserviceusage.services.enable
permission. Learn how to grant roles. -
Install the Google Cloud CLI.
-
Si utilizas un proveedor de identidades (IdP) externo, primero debes iniciar sesión en la CLI de gcloud con tu identidad federada.
-
Para inicializar gcloud CLI, ejecuta el siguiente comando:
gcloud init
- In the Google Cloud console, go to the VM instances page.
-
In the list of virtual machine instances, click SSH in the row of
the instance that you want to connect to.
En el directorio principal del nodo principal, edita
/etc/spark/conf/log4j.properties
.sudo nano /etc/spark/conf/log4j.properties
Asigna el valor
ERROR
alog4j.rootCategory
.# 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
Guarda los cambios y cierra el editor. Si quieres volver a habilitar el registro detallado, revierte el cambio restaurando el valor de
.rootCategory
a su valor original (INFO
).Inicia el intérprete de Python desde el nodo principal de Dataproc.
pyspark
Espera a que aparezca la petición de Spark
>>>
.Introduce el siguiente código. Asegúrate de mantener la sangría en la definición de la función.
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
Pulsa
return
hasta que vuelva a aparecer la petición de Spark.El código anterior define una función que modeliza lo que podría ocurrir cuando un inversor tiene una cuenta de jubilación invertida en el mercado de valores a la que añade dinero cada año. La función genera un rendimiento aleatorio de la inversión, expresado como porcentaje, cada año durante el plazo especificado. La función toma un valor de inicialización como parámetro. Este valor se usa para reinicializar el generador de números aleatorios, lo que asegura que la función no obtenga la misma lista de números aleatorios cada vez que se ejecute. La función
random.normalvariate
asegura que los valores aleatorios se produzcan en una distribución normal para la media y la desviación estándar especificadas. La función aumenta el valor de la cartera en la cantidad de crecimiento, que puede ser positiva o negativa, y añade una suma anual que representa una inversión adicional.Definirás las constantes necesarias en un paso posterior.
Crea muchas semillas para introducir en la función. En la petición de Spark, introduce el siguiente código, que genera 10.000 semillas:
seeds = sc.parallelize([time.time() + i for i in range(10000)])
El resultado de la operación
parallelize
es un conjunto de datos distribuidos resiliente (RDD), que es una colección de elementos optimizados para el procesamiento paralelo. En este caso, el RDD contiene semillas basadas en la hora del sistema actual.Al crear el RDD, Spark divide los datos en función del número de trabajadores y de los núcleos disponibles. En este caso, Spark elige usar ocho segmentos, uno por cada núcleo. Esto es suficiente para esta simulación, que tiene 10.000 elementos de datos. En simulaciones más grandes, cada segmento puede ser mayor que el límite predeterminado. En ese caso, especificar un segundo parámetro en
parallelize
puede aumentar el número de particiones, lo que puede ayudar a que el tamaño de cada partición sea manejable, mientras que Spark sigue aprovechando los ocho núcleos.Introduce el RDD que contiene las semillas en la función de crecimiento.
results = seeds.map(grow)
El método
map
transfiere cada valor inicial del RDD a la funcióngrow
y añade cada resultado a un nuevo RDD, que se almacena enresults
. Ten en cuenta que esta operación, que realiza una transformación, no produce resultados de inmediato. Spark no realizará este trabajo hasta que se necesiten los resultados. Esta evaluación diferida es el motivo por el que puedes introducir código sin que se definan las constantes.Especifica algunos valores para la función.
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
Llama a
reduce
para agregar los valores del RDD. Introduce el siguiente código para sumar los resultados del RDD:sum = results.reduce(add)
Estima y muestra la rentabilidad media:
print (sum / 10000.)
Asegúrate de incluir el carácter de punto (
.
) al final. Significa aritmética de punto flotante.Ahora, cambia una suposición y observa cómo cambian los resultados. Por ejemplo, puede introducir un nuevo valor para el retorno medio del mercado:
MKT_AVG_RETURN = 0.07
Vuelve a ejecutar la simulación.
print (sc.parallelize([time.time() + i for i in range(10000)]) \ .map(grow).reduce(add)/10000.)
Cuando hayas terminado de experimentar, pulsa
CTRL+D
para salir del intérprete de Python.- El jugador hace una apuesta, que consiste en un número de fichas de un fondo de banca.
- El jugador tira un dado de 100 caras (¿no sería genial?).
- Si el resultado de la tirada es un número del 1 al 49, el jugador gana.
- Si el resultado es de 50 a 100, el jugador pierde la apuesta.
Inicia el intérprete de Scala desde el nodo principal de Dataproc.
spark-shell
Copia y pega el siguiente código para crear el juego. Scala no tiene los mismos requisitos que Python en lo que respecta a la sangría, por lo que puedes copiar y pegar este código en la petición de
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) }
Pulsa
return
hasta que veas la peticiónscala>
.Introduce el siguiente código para jugar 25 veces, que es el valor predeterminado de
NUMBER_OF_GAMES
.playSession()
Tu saldo inicial era de 10 unidades. ¿Es más alta o más baja ahora?
Ahora,simula que 10.000 jugadores apuestan 100 fichas por partida. Juega 10.000 partidas en una sesión. Esta simulación de Monte Carlo calcula la probabilidad de perder todo tu dinero antes de que finalice la sesión. Introduce el siguiente código:
(sc.parallelize(1 to 10000, 500) .map(i => playSession(100000, 100, 250000)) .map(i => if (i == 0) 1 else 0) .reduce(_+_)/10000.0)
Ten en cuenta que la sintaxis
.reduce(_+_)
es una abreviatura en Scala para agregar datos mediante una función de suma. Es funcionalmente equivalente a la sintaxis.reduce(add)
que has visto en el ejemplo de Python.El código anterior realiza los siguientes pasos:
- Crea un RDD con los resultados de la reproducción de la sesión.
- Sustituye los resultados de los jugadores en bancarrota por el número
1
y los resultados distintos de cero por el número0
. - Suma el número de jugadores en bancarrota.
- Divide el recuento entre el número de jugadores.
Un resultado habitual podría ser el siguiente:
0.998
Lo que representa una garantía casi total de perder todo tu dinero, aunque el casino solo tuviera una ventaja del uno por ciento.
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
- Para obtener más información sobre cómo enviar tareas de Spark a Dataproc sin tener que usar
ssh
para conectarte al clúster, consulta Dataproc: enviar una tarea.
Crear una agrupación Dataproc
Sigue los pasos para crear un clúster de Dataproc desde la consola de Google Cloud . Los ajustes predeterminados del clúster, que incluyen dos nodos de trabajo, son suficientes para este tutorial.
Inhabilitar el registro de advertencias
De forma predeterminada, Apache Spark imprime registros detallados en la ventana de la consola. En este tutorial, cambia el nivel de registro para que solo se registren los errores. Sigue estos pasos:
Usa
ssh
para conectarte al nodo principal del clúster de DataprocEl nodo principal del clúster de Dataproc tiene el sufijo
-m
en el nombre de su VM.Se abrirá una ventana de SSH conectada al nodo principal.
Connected, host fingerprint: ssh-rsa 2048 ... ... user@clusterName-m:~$
Cambiar el ajuste de registro
Lenguajes de programación de Spark
Spark admite Python, Scala y Java como lenguajes de programación para aplicaciones independientes y proporciona intérpretes interactivos para Python y Scala. El idioma que elijas es una cuestión de preferencia personal. En este tutorial se usan intérpretes interactivos porque puedes experimentar cambiando el código, probando diferentes valores de entrada y viendo los resultados.
Estimar el crecimiento de la cartera
En el ámbito de las finanzas, los métodos de Monte Carlo se usan a veces para realizar simulaciones que intentan predecir el rendimiento de una inversión. Al generar muestras aleatorias de resultados en una serie de condiciones de mercado probables, una simulación de Montecarlo puede responder a preguntas sobre el rendimiento medio de una cartera o en el peor de los casos.
Sigue estos pasos para crear una simulación que use métodos de Monte Carlo para intentar estimar el crecimiento de una inversión financiera en función de algunos factores comunes del mercado.
Programar una simulación de Monte Carlo en Scala
Montecarlo, por supuesto, es famosa por sus casinos. En esta sección, usarás Scala para crear una simulación que modele la ventaja matemática que tiene un casino en un juego de azar. La "ventaja de la casa" en un casino real varía mucho de un juego a otro. Por ejemplo, puede superar el 20% en el keno. En este tutorial se crea un juego sencillo en el que la casa tiene solo un 1 % de ventaja. Así es como funciona el juego:
Como puedes ver, este juego crea una desventaja del 1 % para el jugador: en 51 de los 100 resultados posibles de cada tirada, el jugador pierde.
Sigue estos pasos para crear y ejecutar el juego:
Limpieza
Eliminar el proyecto
Siguientes pasos