Penyetelan performa dan pengoptimalan data untuk R

Berlaku untuk: SQL Server 2016 (13.x) dan versi yang lebih baru

Artikel ini membahas pengoptimalan performa untuk skrip R atau Python yang berjalan di SQL Server. Anda dapat menggunakan metode ini untuk memperbarui kode R Anda, baik untuk meningkatkan performa maupun untuk menghindari masalah yang diketahui.

Memilih konteks komputasi

Dalam SQL Server, Anda dapat menggunakan konteks komputasi lokal atau SQL saat menjalankan skrip R atau Python.

Saat menggunakan konteks komputasi lokal , analisis dilakukan pada komputer Anda dan bukan pada server. Oleh karena itu, jika Anda mendapatkan data dari SQL Server untuk digunakan dalam kode Anda, data harus diambil melalui jaringan. Performa yang terjadi untuk transfer jaringan ini tergantung pada ukuran data yang ditransfer, kecepatan jaringan, dan transfer jaringan lainnya yang terjadi pada saat yang sama.

Saat menggunakan konteks komputasi SQL Server, kode dijalankan di server. Jika Anda mendapatkan data dari SQL Server, data harus lokal ke server yang menjalankan analisis, dan oleh karena itu tidak ada overhead jaringan yang diperkenalkan. Jika Anda perlu mengimpor data dari sumber lain, pertimbangkan untuk mengatur ETL sebelumnya.

Saat bekerja dengan himpunan data besar, Anda harus selalu menggunakan konteks komputasi SQL.

Faktor

Bahasa R memiliki konsep faktor, yang merupakan variabel khusus untuk data kategoris. Ilmuwan data sering menggunakan variabel faktor dalam rumusnya, karena menangani variabel kategoris sebagai faktor memastikan bahwa data diproses dengan benar oleh fungsi pembelajaran mesin.

Secara desain, variabel faktor dapat dikonversi dari string ke bilangan bulat dan kembali lagi untuk penyimpanan atau pemrosesan. Fungsi R data.frame menangani semua string sebagai variabel faktor, kecuali string argumenAsFactors diatur ke False. Artinya, string secara otomatis dikonversi ke bilangan bulat untuk diproses, lalu dipetakan kembali ke string asli.

Jika data sumber untuk faktor disimpan sebagai bilangan bulat, performa dapat menderita, karena R mengonversi bilangan bulat faktor menjadi string pada durasi, lalu melakukan konversi string-ke-bilangan bulat internalnya sendiri.

Untuk menghindari konversi run-time tersebut, pertimbangkan untuk menyimpan nilai sebagai bilangan bulat dalam tabel SQL Server, dan menggunakan argumen colInfo untuk menentukan tingkat kolom yang digunakan sebagai faktor. Sebagian besar objek sumber data di RevoScaleR mengambil parameter colInfo. Anda menggunakan parameter ini untuk memberi nama variabel yang digunakan oleh sumber data, menentukan jenisnya, dan menentukan tingkat variabel atau transformasi pada nilai kolom.

Misalnya, panggilan fungsi R berikut mendapatkan bilangan bulat 1, 2, dan 3 dari tabel, tetapi memetakan nilai ke faktor dengan tingkat "apel", "oranye", dan "pisang".

c("fruit" = c(type = "factor", levels=as.character(c(1:3)), newLevels=c("apple", "orange", "banana")))

Ketika kolom sumber berisi string, selalu lebih efisien untuk menentukan tingkat sebelumnya menggunakan parameter colInfo . Misalnya, kode R berikut memperlakukan string sebagai faktor saat dibaca.

c("fruit" = c(type = "factor", levels= c("apple", "orange", "banana")))

Jika tidak ada perbedaan semantik dalam pembuatan model, maka pendekatan terakhir dapat menyebabkan performa yang lebih baik.

Transformasi data

Ilmuwan data sering menggunakan fungsi transformasi yang ditulis dalam R sebagai bagian dari analisis. Fungsi transformasi diterapkan ke setiap baris yang diambil dari tabel. Dalam SQL Server, transformasi tersebut diterapkan ke semua baris yang diambil dalam batch, yang memerlukan komunikasi antara penerjemah R dan mesin analitik. Untuk melakukan transformasi, data berpindah dari SQL ke mesin analitik lalu ke proses penerjemah R dan kembali.

Untuk alasan ini, menggunakan transformasi sebagai bagian dari kode R Anda dapat memiliki efek buruk yang signifikan pada performa algoritma, tergantung pada jumlah data yang terlibat.

Lebih efisien untuk memiliki semua kolom yang diperlukan dalam tabel atau tampilan sebelum melakukan analisis, dan menghindari transformasi selama komputasi. Jika tidak dimungkinkan untuk menambahkan kolom tambahan ke tabel yang sudah ada, pertimbangkan untuk membuat tabel atau tampilan lain dengan kolom yang ditransformasi dan menggunakan kueri yang sesuai untuk mengambil data.

Pembacaan baris batch

Jika Anda menggunakan sumber data SQL Server (RxSqlServerData) dalam kode Anda, kami sarankan Anda mencoba menggunakan parameter rowsPerRead untuk menentukan ukuran batch. Parameter ini menentukan jumlah baris yang dikueri lalu dikirim ke skrip eksternal untuk diproses. Pada durasi, algoritma hanya melihat jumlah baris yang ditentukan di setiap batch.

Kemampuan untuk mengontrol jumlah data yang diproses pada satu waktu dapat membantu Anda menyelesaikan atau menghindari masalah. Misalnya, jika himpunan data input Anda sangat luas (memiliki banyak kolom), atau jika himpunan data memiliki beberapa kolom besar (seperti teks gratis), Anda dapat mengurangi ukuran batch untuk menghindari data halaman kehabisan memori.

Secara default, nilai parameter ini diatur ke 50000, untuk memastikan performa yang layak bahkan pada komputer dengan memori rendah. Jika server memiliki cukup memori yang tersedia, meningkatkan nilai ini menjadi 500.000 atau bahkan satu juta dapat menghasilkan performa yang lebih baik, terutama untuk tabel besar.

Manfaat meningkatkan ukuran batch menjadi jelas pada himpunan data besar, dan dalam tugas yang dapat berjalan pada beberapa proses. Namun, meningkatkan nilai ini tidak selalu menghasilkan hasil terbaik. Kami menyarankan agar Anda bereksperimen dengan data dan algoritma Anda untuk menentukan nilai optimal.

Pemrosesan paralel

Untuk meningkatkan performa fungsi analitik rx, Anda dapat memanfaatkan kemampuan SQL Server untuk menjalankan tugas secara paralel menggunakan inti yang tersedia di komputer server.

Ada dua cara untuk mencapai paralelisasi dengan R dalam SQL Server:

  • Gunakan @parallel. Saat menggunakan prosedur tersimpan sp_execute_external_script untuk menjalankan skrip R, atur parameter ke @parallel1. Ini adalah metode terbaik jika skrip R Anda tidak menggunakan fungsi RevoScaleR, yang memiliki mekanisme lain untuk diproses. Jika skrip Anda menggunakan fungsi RevoScaleR (umumnya diawali dengan "rx"), pemrosesan paralel dilakukan secara otomatis dan Anda tidak perlu secara eksplisit mengatur @parallel ke 1.

    Jika skrip R dapat diparalelkan, dan jika kueri SQL dapat diparalelkan, mesin database membuat beberapa proses paralel. Jumlah maksimum proses yang dapat dibuat sama dengan pengaturan tingkat paralelisme maksimum (MAXDOP) untuk instans. Semua proses kemudian menjalankan skrip yang sama, tetapi hanya menerima sebagian data.

    Dengan demikian, metode ini tidak berguna dengan skrip yang harus melihat semua data, seperti saat melatih model. Namun, ini berguna saat melakukan tugas seperti prediksi batch secara paralel. Untuk informasi selengkapnya tentang menggunakan paralelisme dengan sp_execute_external_script, lihat bagian Tips tingkat lanjut: pemrosesan paraleldari Menggunakan Kode R di Transact-SQL.

  • Gunakan numTasks =1. Saat menggunakan fungsi rx dalam konteks komputasi SQL Server, atur nilai parameter numTasks ke jumlah proses yang ingin Anda buat. Jumlah proses yang dibuat tidak pernah bisa lebih dari MAXDOP; namun, jumlah aktual proses yang dibuat ditentukan oleh mesin database dan mungkin kurang dari yang Anda minta.

    Jika skrip R dapat diparalelkan, dan jika kueri SQL dapat diparalelkan, maka SQL Server membuat beberapa proses paralel saat menjalankan fungsi rx. Jumlah proses aktual yang dibuat tergantung pada berbagai faktor. Ini termasuk tata kelola sumber daya, penggunaan sumber daya saat ini, sesi lain, dan rencana eksekusi kueri untuk kueri yang digunakan dengan skrip R.

Paralelisasi kueri

Di Microsoft R, Anda dapat bekerja dengan SQL Server sumber data dengan menentukan data Anda sebagai objek sumber data RxSqlServerData.

Membuat sumber data berdasarkan seluruh tabel atau tampilan:

RxSqlServerData(table= "airline", connectionString = sqlConnString)

Membuat sumber data berdasarkan kueri SQL:

RxSqlServerData(sqlQuery= "SELECT [ArrDelay],[CRSDepTime],[DayOfWeek] FROM  airlineWithIndex WHERE rowNum <= 100000", connectionString = sqlConnString)

Catatan

Jika tabel ditentukan dalam sumber data alih-alih kueri, R Services menggunakan heuristik internal untuk menentukan kolom yang diperlukan untuk diambil dari tabel; namun, pendekatan ini tidak mungkin menghasilkan eksekusi paralel.

Untuk memastikan bahwa data dapat dianalisis secara paralel, kueri yang digunakan untuk mengambil data harus dibingkai sedih sehingga mesin database dapat membuat rencana kueri paralel. Jika kode atau algoritma menggunakan data dalam volume besar, pastikan kueri yang diberikan untuk RxSqlServerData dioptimalkan untuk eksekusi paralel. Kueri yang tidak menghasilkan rencana eksekusi paralel dapat menghasilkan satu proses untuk komputasi.

Jika Anda perlu bekerja dengan himpunan data besar, gunakan Management Studio atau penganalisis kueri SQL lain sebelum Anda menjalankan kode R, untuk menganalisis rencana eksekusi. Kemudian, ambil langkah-langkah yang direkomendasikan untuk meningkatkan performa kueri. Misalnya, indeks yang hilang pada tabel dapat memengaruhi waktu yang diperlukan untuk menjalankan kueri. Untuk informasi selengkapnya, lihat Memantau dan Menyelaraskan Performa.

Kesalahan umum lain yang dapat memengaruhi performa adalah bahwa kueri mengambil lebih banyak kolom daripada yang diperlukan. Misalnya, jika rumus hanya didasarkan pada tiga kolom, tetapi tabel sumber Anda memiliki 30 kolom, Anda memindahkan data yang tidak perlu.

  • Hindari menggunakan SELECT *!
  • Luangkan waktu untuk meninjau kolom dalam himpunan data dan mengidentifikasi hanya kolom yang diperlukan untuk analisis
  • Hapus dari kueri Anda kolom apa pun yang berisi jenis data yang tidak kompatibel dengan kode R, seperti GUIDS dan rowguids
  • Periksa format tanggal dan waktu yang tidak didukung
  • Daripada memuat tabel, buat tampilan yang memilih nilai tertentu atau melemparkan kolom untuk menghindari kesalahan konversi

Mengoptimalkan algoritma pembelajaran mesin

Bagian ini menyediakan berbagai tips dan sumber daya yang khusus untuk RevoScaleR dan opsi lain di Microsoft R.

Tip

Diskusi umum pengoptimalan R berada di luar cakupan artikel ini. Namun, jika Anda perlu membuat kode Anda lebih cepat, kami merekomendasikan artikel populer, The R Inferno. Ini mencakup konstruksi pemrograman di R dan jebakan umum dalam bahasa dan detail yang jelas, dan memberikan banyak contoh spesifik teknik pemrograman R.

Pengoptimalan untuk RevoScaleR

Banyak algoritma RevoScaleR mendukung parameter untuk mengontrol bagaimana model terlatih dihasilkan. Meskipun akurasi dan kebenaran model penting, performa algoritma mungkin sama pentingnya. Untuk mendapatkan keseimbangan yang tepat antara akurasi dan waktu pelatihan, Anda dapat memodifikasi parameter untuk meningkatkan kecepatan komputasi, dan dalam banyak kasus, meningkatkan performa tanpa mengurangi akurasi atau kebenaran.

  • rxDTree

    rxDTreemaxDepth mendukung parameter , yang mengontrol kedalaman pohon keputusan. Seperti maxDepth yang ditingkatkan, performa dapat mengalami penurunan, jadi penting untuk menganalisis manfaat meningkatkan kedalaman vs. performa yang menyakitkan.

    Anda juga dapat mengontrol keseimbangan antara kompleksitas waktu dan akurasi prediksi dengan menyesuaikan parameter seperti maxNumBins, , maxDepthmaxComplete, dan maxSurrogate. Meningkatkan kedalaman hingga lebih dari 10 atau 15 dapat membuat komputasi sangat mahal.

  • rxLinMod

    Coba gunakan cube argumen jika variabel dependen pertama dalam rumus adalah variabel faktor.

    Ketika cube diatur ke TRUE, regresi dilakukan menggunakan inversi yang dipartisi, yang mungkin lebih cepat dan menggunakan lebih sedikit memori daripada komputasi regresi standar. Jika rumus memiliki sejumlah besar variabel, perolehan performa bisa signifikan.

  • rxLogit

    cube Gunakan argumen jika variabel dependen pertama adalah variabel faktor.

    Ketika cube diatur ke TRUE, algoritma menggunakan inversi yang dipartisi, yang mungkin lebih cepat dan menggunakan lebih sedikit memori. Jika rumus memiliki sejumlah besar variabel, perolehan performa bisa signifikan.

Untuk informasi selengkapnya tentang pengoptimalan RevoScaleR, lihat artikel berikut ini:

Menggunakan MicrosoftML

Kami juga menyarankan agar Anda melihat paket MicrosoftML baru, yang menyediakan algoritma pembelajaran mesin yang dapat diskalakan yang dapat menggunakan konteks komputasi dan transformasi yang disediakan oleh RevoScaleR.

Langkah berikutnya