Metode Monte Carlo menggunakan Apache Spark

Managed Service untuk Apache Spark dan Apache Spark menyediakan infrastruktur dan kapasitas yang dapat Anda gunakan untuk menjalankan simulasi Monte Carlo yang ditulis dalam Java, Python, atau Scala.

Metode Monte Carlo dapat membantu menjawab berbagai pertanyaan dalam bisnis, teknik, sains, matematika, dan bidang lainnya. Dengan menggunakan sampling acak berulang untuk membuat distribusi probabilitas untuk variabel, simulasi Monte Carlo dapat memberikan jawaban atas pertanyaan yang mungkin tidak dapat dijawab. Dalam keuangan, misalnya, penetapan harga opsi ekuitas memerlukan analisis ribuan cara harga saham dapat berubah dari waktu ke waktu. Metode Monte Carlo menyediakan cara untuk menyimulasikan perubahan harga saham tersebut dalam berbagai kemungkinan hasil, sekaligus mempertahankan kontrol atas domain kemungkinan input ke masalah tersebut.

Dahulu, menjalankan ribuan simulasi dapat memerlukan waktu yang sangat lama dan menimbulkan biaya yang tinggi. Managed Service untuk Apache Spark memungkinkan Anda menyediakan kapasitas sesuai permintaan dan membayarnya per menit. Apache Spark memungkinkan Anda menggunakan cluster yang terdiri dari puluhan, ratusan, atau ribuan server untuk menjalankan simulasi dengan cara yang intuitif dan dapat diskalakan untuk memenuhi kebutuhan Anda. Artinya, Anda dapat menjalankan lebih banyak simulasi dengan lebih cepat, yang dapat membantu bisnis Anda berinovasi lebih cepat dan mengelola risiko dengan lebih baik.

Keamanan selalu penting saat bekerja dengan data keuangan. Managed Service untuk Apache Spark berjalan di Google Cloud, yang membantu menjaga keamanan, keamanan, dan privasi data Anda dalam beberapa cara. Misalnya, semua data dienkripsi selama transmisi dan saat tidak aktif, dan Google Cloud mematuhi ISO 27001, SOC3, dan PCI.

Tujuan

  • Membuat cluster Managed Service untuk Apache Spark terkelola dengan Apache Spark bawaan.
  • Menjalankan simulasi Monte Carlo menggunakan Python yang memperkirakan pertumbuhan portofolio saham dari waktu ke waktu.
  • Menjalankan simulasi Monte Carlo menggunakan Scala yang menyimulasikan cara kasino menghasilkan uang.

Biaya

Dalam dokumen ini, Anda akan menggunakan komponen yang dapat ditagih berikut Google Cloud:

Untuk membuat perkiraan biaya berdasarkan proyeksi penggunaan Anda, gunakan kalkulator harga.

Pengguna baru mungkin memenuhi syarat untuk mendapatkan uji coba gratis. Google Cloud

Setelah menyelesaikan tugas yang dijelaskan dalam dokumen ini, Anda dapat menghindari penagihan berkelanjutan dengan menghapus resource yang Anda buat. Untuk mengetahui informasi selengkapnya, baca bagian Pembersihan.

Sebelum memulai

  • Menyiapkan Google Cloud project
    1. Login keakun Anda. Google Cloud Jika Anda baru menggunakan Google Cloud, buat akun untuk mengevaluasi performa produk kami dalam skenario dunia nyata. Pelanggan baru juga mendapatkan kredit gratis senilai $300 untuk menjalankan, menguji, dan men-deploy workload.
    2. 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 the resourcemanager.projects.create permission. Learn how to grant roles.

      Go to project selector

    3. Verify that billing is enabled for your Google Cloud project.

    4. 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 the serviceusage.services.enable permission. Learn how to grant roles.

      Enable the APIs

    5. Instal Google Cloud CLI.

    6. Jika Anda menggunakan penyedia identitas (IdP) eksternal, Anda harus login ke gcloud CLI dengan identitas gabungan Anda terlebih dahulu.

    7. Untuk melakukan inisialisasi gcloud CLI, jalankan perintah berikut:

      gcloud init
    8. 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 the resourcemanager.projects.create permission. Learn how to grant roles.

      Go to project selector

    9. Verify that billing is enabled for your Google Cloud project.

    10. 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 the serviceusage.services.enable permission. Learn how to grant roles.

      Enable the APIs

    11. Instal Google Cloud CLI.

    12. Jika Anda menggunakan penyedia identitas (IdP) eksternal, Anda harus login ke gcloud CLI dengan identitas gabungan Anda terlebih dahulu.

    13. Untuk melakukan inisialisasi gcloud CLI, jalankan perintah berikut:

      gcloud init

Membuat cluster Managed Service untuk Apache Spark

Ikuti langkah-langkah untuk membuat cluster Managed Service untuk Apache Spark dari konsol. Google Cloud Setelan cluster default, yang mencakup dua node pekerja, sudah cukup untuk tutorial ini.

Menonaktifkan logging untuk peringatan

Secara default, Apache Spark mencetak logging panjang di jendela konsol. Untuk tujuan tutorial ini, ubah tingkat logging agar hanya mencatat error. Ikuti langkah-langkah berikut:

Menggunakan ssh untuk terhubung ke node utama cluster Managed Service untuk Apache Spark

Node utama cluster Managed Service untuk Apache Spark memiliki akhiran -m pada nama VM-nya.

  1. Di Google Cloud konsol, buka halaman VM instances.

    Buka instance VM

  2. Di daftar instance virtual machine, klik SSH di baris instance yang ingin Anda hubungkan.

    Tombol SSH di samping nama instance.

Jendela SSH akan terbuka dan terhubung ke node utama.

Connected, host fingerprint: ssh-rsa 2048 ...
...
user@clusterName-m:~$

Mengubah setelan logging

  1. Dari direktori beranda node utama, edit /etc/spark/conf/log4j.properties.

    sudo nano /etc/spark/conf/log4j.properties
    
  2. Tetapkan log4j.rootCategory sama dengan 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
    
  3. Simpan perubahan dan keluar dari editor. Jika ingin mengaktifkan logging panjang lagi, batalkan perubahan dengan memulihkan nilai untuk .rootCategory ke nilai aslinya (INFO).

Bahasa pemrograman Spark

Spark mendukung Python, Scala, dan Java sebagai bahasa pemrograman untuk aplikasi mandiri, serta menyediakan interpreter interaktif untuk Python dan Scala. Bahasa yang Anda pilih adalah masalah preferensi pribadi. Tutorial ini menggunakan interpreter interaktif karena Anda dapat bereksperimen dengan mengubah kode, mencoba nilai input yang berbeda, lalu melihat hasilnya.

Memperkirakan pertumbuhan portofolio

Dalam keuangan, metode Monte Carlo terkadang digunakan untuk menjalankan simulasi yang mencoba memprediksi performa investasi. Dengan menghasilkan sampel hasil acak dalam berbagai kondisi pasar yang mungkin, simulasi Monte Carlo dapat menjawab pertanyaan tentang performa portofolio secara rata-rata atau dalam skenario terburuk.

Ikuti langkah-langkah berikut untuk membuat simulasi yang menggunakan metode Monte Carlo untuk mencoba memperkirakan pertumbuhan investasi keuangan berdasarkan beberapa faktor pasar umum.

  1. Mulai interpreter Python dari node utama Managed Service untuk Apache Spark.

    pyspark
    

    Tunggu perintah Spark >>>.

  2. Masukkan kode berikut. Pastikan Anda mempertahankan indentasi dalam definisi fungsi.

    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
    
  3. Tekan return hingga Anda melihat perintah Spark lagi.

    Kode sebelumnya menentukan fungsi yang memodelkan apa yang mungkin terjadi saat investor memiliki akun pensiun yang ada yang diinvestasikan di pasar saham, yang ditambahkan uang tambahan setiap tahun. Fungsi ini menghasilkan pengembalian acak atas investasi, sebagai persentase, setiap tahun selama jangka waktu yang ditentukan. Fungsi ini mengambil nilai awal sebagai parameter. Nilai ini digunakan untuk mengulang inisialisasi generator angka acak, yang memastikan bahwa fungsi tidak mendapatkan daftar angka acak yang sama setiap kali dijalankan. Fungsi random.normalvariate memastikan bahwa nilai acak terjadi di seluruh distribusi normal untuk rata-rata dan simpangan baku yang ditentukan. Fungsi ini meningkatkan nilai portofolio berdasarkan jumlah pertumbuhan, yang bisa positif atau negatif, dan menambahkan jumlah tahunan yang mewakili investasi lebih lanjut.

    Anda akan menentukan konstanta yang diperlukan pada langkah mendatang.

  4. Buat banyak nilai awal untuk dimasukkan ke fungsi. Pada perintah Spark, masukkan kode berikut, yang menghasilkan 10.000 nilai awal:

    seeds = sc.parallelize([time.time() + i for i in range(10000)])
    

    Hasil operasi parallelize adalah kumpulan data terdistribusi yang tangguh (RDD), yang merupakan kumpulan elemen yang dioptimalkan untuk pemrosesan paralel. Dalam hal ini, RDD berisi nilai awal yang didasarkan pada waktu sistem saat ini.

    Saat membuat RDD, Spark membagi data berdasarkan jumlah pekerja dan core yang tersedia. Dalam hal ini, Spark memilih untuk menggunakan delapan bagian, satu bagian untuk setiap core. Hal ini tidak masalah untuk simulasi ini, yang memiliki 10.000 item data. Untuk simulasi yang lebih besar, setiap bagian mungkin lebih besar dari batas default. Dalam hal ini, menentukan parameter kedua ke parallelize dapat meningkatkan jumlah bagian, yang dapat membantu menjaga ukuran setiap bagian tetap dapat dikelola, sementara Spark masih memanfaatkan semua delapan core.

  5. Masukkan RDD yang berisi nilai awal ke fungsi pertumbuhan.

    results = seeds.map(grow)
    

    Metode map meneruskan setiap nilai awal dalam RDD ke fungsi grow dan menambahkan setiap hasil ke RDD baru, yang disimpan di results. Perhatikan bahwa operasi ini, yang melakukan transformasi, tidak langsung menghasilkan hasilnya. Spark tidak akan melakukan pekerjaan ini hingga hasilnya diperlukan. Evaluasi lambat inilah yang membuat Anda dapat memasukkan kode tanpa konstanta yang ditentukan.

  6. Tentukan beberapa nilai untuk fungsi.

    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
    
  7. Panggil reduce untuk menggabungkan nilai dalam RDD. Masukkan kode berikut untuk menjumlahkan hasil dalam RDD:

    sum = results.reduce(add)
    
  8. Perkirakan dan tampilkan pengembalian rata-rata:

    print (sum / 10000.)
    

    Pastikan untuk menyertakan karakter titik (.) di akhir. Ini menandakan aritmetika floating point.

  9. Sekarang ubah asumsi dan lihat bagaimana hasilnya berubah. Misalnya, Anda dapat memasukkan nilai baru untuk pengembalian rata-rata pasar:

    MKT_AVG_RETURN = 0.07
    
  10. Jalankan simulasi lagi.

    print (sc.parallelize([time.time() + i for i in range(10000)]) \
            .map(grow).reduce(add)/10000.)
    
  11. Setelah selesai bereksperimen, tekan CTRL+D untuk keluar dari interpreter Python.

Memprogram simulasi Monte Carlo di Scala

Monte Carlo, tentu saja, terkenal sebagai tujuan perjudian. Di bagian ini, Anda akan menggunakan Scala untuk membuat simulasi yang memodelkan keuntungan matematika yang dinikmati kasino dalam permainan peluang. "Keunggulan kasino" di kasino sungguhan sangat bervariasi dari game ke game; misalnya, bisa lebih dari 20% di keno. Tutorial ini membuat game sederhana yang hanya memiliki keunggulan satu persen. Berikut cara kerja game ini:

  • Pemain memasang taruhan, yang terdiri dari sejumlah chip dari dana bankroll.
  • Pemain melempar dadu 100 sisi (keren, bukan?).
  • Jika hasil lemparan adalah angka dari 1 hingga 49, pemain akan menang.
  • Untuk hasil 50 hingga 100, pemain akan kalah taruhan.

Anda dapat melihat bahwa game ini menciptakan kerugian satu persen bagi pemain: dalam 51 dari 100 kemungkinan hasil untuk setiap lemparan, pemain akan kalah.

Ikuti langkah-langkah berikut untuk membuat dan menjalankan game:

  1. Mulai interpreter Scala dari node utama Managed Service untuk Apache Spark.

    spark-shell
    
  2. Salin dan tempel kode berikut untuk membuat game. Scala tidak memiliki persyaratan yang sama dengan Python terkait indentasi, sehingga Anda dapat menyalin dan menempel kode ini di perintah 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)
    }
    
  3. Tekan return hingga Anda melihat perintah scala>.

  4. Masukkan kode berikut untuk memainkan game 25 kali, yang merupakan nilai default untuk NUMBER_OF_GAMES.

    playSession()
    

    Bankroll Anda dimulai dengan nilai 10 unit. Apakah sekarang lebih tinggi atau lebih rendah?

  5. Sekarang simulasikan 10.000 pemain yang bertaruh 100 chip per game. Mainkan 10.000 game dalam satu sesi. Simulasi Monte Carlo ini menghitung probabilitas kehilangan semua uang Anda sebelum akhir sesi. Masukkan kode berikut:

    (sc.parallelize(1 to 10000, 500)
      .map(i => playSession(100000, 100, 250000))
      .map(i => if (i == 0) 1 else 0)
      .reduce(_+_)/10000.0)
    

    Perhatikan bahwa sintaksis .reduce(_+_) adalah singkatan di Scala untuk menggabungkan menggunakan fungsi penjumlahan. Secara fungsional, sintaksis ini setara dengan sintaksis .reduce(add) yang Anda lihat dalam contoh Python.

    Kode sebelumnya melakukan langkah-langkah berikut:

    • Membuat RDD dengan hasil bermain sesi.
    • Mengganti hasil pemain yang bangkrut dengan angka 1 dan hasil bukan nol dengan angka 0.
    • Menjumlahkan jumlah pemain yang bangkrut.
    • Membagi jumlah dengan jumlah pemain.

    Hasil umumnya mungkin:

    0.998
    

    Yang mewakili jaminan hampir pasti kehilangan semua uang Anda, meskipun kasino hanya memiliki keunggulan satu persen.

Pembersihan

Menghapus project

  1. Di Google Cloud konsol, buka halaman Manage resources.

    Buka Kelola resource

  2. Pada daftar project, pilih project yang Anda ingin Anda hapus, lalu klik Delete.
  3. Pada dialog, ketik project ID, lalu klik Shut down untuk menghapus project.

Langkah berikutnya