"Jalan panjang sedang menunggu Anda ..." atau menyelesaikan masalah perkiraan di C # menggunakan Ml.NET (DataScience)

Baru-baru ini, saya menemukan lebih banyak informasi tentang kerangka pembelajaran mesin Ml.NET . Jumlah referensi untuk itu tumbuh menjadi kualitas, dan saya memutuskan untuk melihat sekilas dengan satu mengintip jenis hewan apa itu.

Sebelumnya kami mencoba untuk memecahkan masalah prediksi paling sederhana menggunakan regresi linier dalam ekosistem .NET. Untuk ini, kami menggunakan Accord.NET Framework. Untuk tujuan ini, satu set data kecil disiapkan dari data terbuka tentang banding warga negara ke otoritas eksekutif dan secara pribadi ke walikota Moskow .

Setelah beberapa tahun pada dataset yang diperbarui, kami akan mencoba menyelesaikan masalah yang paling sederhana . Menggunakan model regresi dalam Kerangka Ml.NET, kami memperkirakan berapa banyak permintaan per bulan mendapatkan solusi positif. Sepanjang jalan, kita akan membandingkan Ml.NET dengan Accord. Perpustakaan NET dan Python.

Apakah Anda ingin menguasai kekuatan dan kekuatan sang prediktor? Maka Anda dipersilakan di bawah kucing.



PS Biarkan S.S. Sobyanin, artikel itu tidak akan mengatakan sepatah kata pun tentang politik.


Konten:

Bagian I: pengantar dan sedikit tentang data
Bagian II: menulis kode C #
Bagian III: Kesimpulan

Saya pikir perlu untuk segera memperingatkan Anda bahwa saya bukan pro dalam analisis data dan pemrograman secara umum, saya juga tidak terlibat dengan Balai Kota Moskow. Oleh karena itu, artikel ini lebih cenderung dari pemula ke pemula. Namun terlepas dari pengetahuan saya yang terbatas, saya harap artikel ini akan bermanfaat bagi Anda.

Orang-orang yang sudah terbiasa dengan artikel-artikel sebelumnya dari siklus mungkin ingat bahwa kami telah mencoba memecahkan masalah memprediksi jumlah masalah yang diselesaikan secara positif dari permohonan warga yang ditujukan kepada cabang eksekutif Moskow. Untuk ini, kami menggunakan Kerangka Python dan Accord.Net .



Bagaimanapun, tidak akan berlebihan untuk mengurai set data yang digunakan lagi.

Semua materi artikel, termasuk kode dan kumpulan data, tersedia secara bebas di GitHub .

Data pada GitHub disajikan dalam format csv, berisi 44 entri dan, pada prinsipnya, mereka dapat (dan harus) digunakan tidak hanya untuk analisis contoh.

Kolom data berarti yang berikut:

  • num - rekam indeks
  • tahun - tahun rekor
  • bulan - bulan rekaman
  • total_appeals - jumlah total klik per bulan
  • appeals_to_mayor - jumlah total banding ke Walikota
  • res_positive- jumlah keputusan positif
  • res_explained - jumlah panggilan untuk klarifikasi
  • res_negative - jumlah panggilan dengan keputusan negatif
  • El_form_to_mayor - jumlah banding ke Walikota dalam bentuk elektronik
  • Pap_form_to_mayor - jumlah banding ke Walikota di atas kertas to_10K_total_VAO ... to_10K_total_YUZAO - jumlah banding per 10.000 populasi di berbagai distrik di Moskow
  • to_10K_mayor_VAO ... to_10K_mayor_YUZAO– jumlah banding yang ditujukan kepada Walikota dan pemerintah Moskow per 10.000 penduduk di berbagai distrik di kota tersebut

Saya tidak menemukan cara untuk mengotomatiskan proses pengumpulan data dan mengumpulkannya secara manual, jadi saya bisa sedikit keliru. Jika tidak, keandalan data akan diserahkan kepada hati nurani penulis.

Saat ini, data di situs web pemerintah di Moskow disajikan secara lengkap dari Januari 2016 hingga Agustus 2019 (beberapa data hilang pada bulan September). Dengan demikian, kami akan memiliki 44 entri. Sedikit, tentu saja, tetapi untuk demonstrasi kepada kami ini sudah cukup.

Sebelum Anda mulai, hanya beberapa kata tentang pahlawan artikel kami.
ML.NET Framework - Pengembangan sumber terbuka Microsoft. Menurut iklan media sosial, ini adalah jawaban mereka untuk perpustakaan pembelajaran mesin Python. Kerangka kerja ini adalah lintas platform dan memungkinkan Anda untuk menyelesaikan berbagai tugas mulai dari regresi sederhana dan klasifikasi hingga pembelajaran mendalam. Pada Habr kawan sudah melakukan analisis ML.NET dan perpustakaan di Python. Siapa peduli, ini tautannya .

Saya tidak akan memberikan panduan terperinci untuk menginstal dan menggunakan Ml.NET karena, pada intinya, semuanya ditipu "diadaptasi" berdasarkan buku teks dari situs web resmi Microsoft . Di sana, masalah dengan harga perjalanan dengan taksi diselesaikan, dan jujur, ada lebih banyak manfaat dari itu

Tapi saya pikir penjelasan kecilnya tidak akan berlebihan.

Saya menggunakan Visual Studio 2017 dengan pembaruan terbaru.
Proyek ini didasarkan pada templat aplikasi konsol .NET Core (versi 2.1).
Proyek harus menginstal paket NuGet Microsoft.ML, Microsoft.ML.FastTree. Faktanya, itu adalah seluruh persiapan.


Kami melanjutkan langsung ke kode.

Pertama, saya membuat kelas MayorAppel, di mana saya menjelaskan dalam urutan kolom dengan data dari file csv.
Bagaimana tidak susah menebak [LoadColumn (0)]
- Memberitahu kami kolom mana dari file csv yang kami ambil.
Selanjutnya, mengikuti tutorial, saya membuat kelas MayorAppelPrediction - untuk hasil prediksi

Terlepas dari kenyataan bahwa hampir semua kolom dalam set data memiliki nilai integer, untuk menghindari kesalahan pada tahap menempelkan data dalam pipa, saya harus menetapkannya tipe float (sehingga semua tipe data sama).
Daftarnya cukup besar, jadi letakkan di bawah spoiler.

Kode kelas untuk deskripsi data
using Microsoft.ML.Data; namespace app_to_mayor_mlnet { class MayorAppel { [LoadColumn(0)] public float Year; [LoadColumn(1)] public string Month; [LoadColumn(2)] public float TotalAppeals; [LoadColumn(3)] public float AppealsToMayor; [LoadColumn(4)] public float ResPositive; [LoadColumn(5)] public float ResExplained; [LoadColumn(6)] public float ResNegative; [LoadColumn(7)] public float ElFormToMayor; [LoadColumn(8)] public float PapFormToMayor; [LoadColumn(9)] public float To10KTotalVAO; [LoadColumn(10)] public float To10KMayorVAO; [LoadColumn(11)] public float To10KTotalZAO; [LoadColumn(12)] public float To10KMayorZAO; [LoadColumn(13)] public float To10KTotalZelAO; [LoadColumn(14)] public float To10KMayorZelAO; [LoadColumn(6)] public float To10KTotalSAO; [LoadColumn(15)] public float To10KMayorSAO; [LoadColumn(16)] public float To10KTotalSVAO; [LoadColumn(17)] public float To10KMayorSVAO; [LoadColumn(18)] public float To10KTotalSZAO; [LoadColumn(19)] public float To10KMayorSZAO; [LoadColumn(20)] public float To10KTotalTiNAO; [LoadColumn(21)] public float To10KMayorTiNAO; [LoadColumn(22)] public float To10KTotalCAO; [LoadColumn(23)] public float To10KMayorCAO; [LoadColumn(24)] public float To10KTotalYUAO; [LoadColumn(25)] public float To10KMayorYUAO; [LoadColumn(26)] public float To10KTotalYUVAO; [LoadColumn(27)] public float To10KMayorYUVAO; [LoadColumn(28)] public float To10KTotalYUZAO; [LoadColumn(29)] public float To10KMayorYUZAO; } public class MayorAppelPrediction { [ColumnName("Score")] public float ResPositive; } } 


Mari kita beralih ke kode program utama.
Jangan lupa untuk menambahkan di awal:

 using System.IO; using Microsoft.ML; 


Berikut ini adalah deskripsi bidang data.

 namespace app_to_mayor_mlnet { class Program { static readonly string _trainDataPath = Path.Combine(Environment.CurrentDirectory, "Data", "train_data.csv"); static readonly string _testDataPath = Path.Combine(Environment.CurrentDirectory, "Data", "test_data.csv"); static readonly string _modelPath = Path.Combine(Environment.CurrentDirectory, "Data", "Model.zip"); 


Dalam bidang ini, pada kenyataannya, jalur ke file data disimpan, kali ini saya memutuskan untuk memisahkannya terlebih dahulu (tidak seperti halnya dengan Accord.NET)

By the way, jika Anda melakukan proyek Anda, jangan lupa untuk mengatur opsi "Salin versi nanti" di properti file data untuk menghindari kesalahan karena kurangnya file perakitan.

Berikutnya adalah tantangan metode yang membentuk model, lakukan penilaian dan beri kami prediksi.

  static void Main(string[] args) { MLContext mlContext = new MLContext(seed: 0); var model = Train(mlContext, _trainDataPath); Evaluate(mlContext, model); TestSinglePrediction(mlContext, model); } 


Mari kita mulai

Metode Kereta diperlukan untuk melatih model.

 public static ITransformer Train(MLContext mlContext, string dataPath) { IDataView dataView = mlContext.Data.LoadFromTextFile<MayorAppel>(dataPath, hasHeader: true, separatorChar: ','); var pipeline = mlContext.Transforms.CopyColumns(outputColumnName: "Label", inputColumnName: "ResPositive") .Append(mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "MonthEncoded", inputColumnName: "Month")) .Append(mlContext.Transforms.Concatenate("Features", "Year", "MonthEncoded", "TotalAppeals", "AppealsToMayor", "ResExplained", "ResNegative", "ElFormToMayor", "PapFormToMayor", "To10KTotalVAO", "To10KMayorVAO", "To10KTotalZAO", "To10KMayorZAO", "To10KTotalZelAO", "To10KMayorZelAO", "To10KTotalSAO", "To10KMayorSAO" , "To10KTotalSVAO", "To10KMayorSVAO", "To10KTotalSZAO", "To10KMayorSZAO", "To10KTotalTiNAO", "To10KMayorTiNAO" , "To10KTotalCAO", "To10KMayorCAO", "To10KTotalYUAO", "To10KMayorYUAO", "To10KTotalYUVAO", "To10KMayorYUVAO" , "To10KTotalYUZAO", "To10KMayorYUZAO")).Append(mlContext.Regression.Trainers.FastTree()); var model = pipeline.Fit(dataView); return model; } 


Pada awalnya kami membaca data dari sampel pelatihan. Kemudian dalam rantai kita menentukan parameter yang akan diprediksi (label).

Dalam kasus kami, ini adalah jumlah masalah yang berhasil diselesaikan tentang permohonan warga per bulan.
Karena dalam kasus ini model meningkatkan pohon keputusan berdasarkan regresi digunakan, kita perlu membawa semua tanda ke nilai numerik.
Berbeda dengan halnya dengan Accord.NET, solusi OneHotEncoding yang sudah jadi segera disajikan di sini dalam dokumentasi.

Setelah itu tetap membentuk kolom, seperti yang saya katakan di atas, mereka semua harus dari tipe data yang sama, dalam hal ini, pelampung.

Sebagai kesimpulan, kami membentuk dan mengembalikan model yang sudah jadi.

Selanjutnya, kami mengevaluasi kualitas prediksi oleh model kami.

  private static void Evaluate(MLContext mlContext, ITransformer model) { IDataView dataView = mlContext.Data.LoadFromTextFile<MayorAppel>(_testDataPath, hasHeader: true, separatorChar: ','); var predictions = model.Transform(dataView); var metrics = mlContext.Regression.Evaluate(predictions, "Label", "Score"); Console.WriteLine(); Console.WriteLine($"*************************************************"); Console.WriteLine($"* Model quality metrics evaluation "); Console.WriteLine($"*------------------------------------------------"); Console.WriteLine($"* RSquared Score: {metrics.RSquared:0.##}"); Console.WriteLine($"* Root Mean Squared Error: {metrics.RootMeanSquaredError:#.##}"); } 

Kami memuat sampel uji kami (4 bulan terakhir dari set), kami memperoleh prediksi data uji kami pada model yang terlatih menggunakan metode Transform (). Lalu kami menghitung metrik dan mencetaknya. Dalam hal ini, itu adalah koefisien determinasi dan standar deviasi. Idealnya yang pertama seharusnya cenderung ke 1, dan yang kedua pada dasarnya ke nol.

Pada prinsipnya, untuk membuat prediksi kami tidak memerlukan metode ini, tetapi senang memahami betapa buruknya model kami memprediksi sesuatu.

Metode terakhir tetap - prediksi itu sendiri.
Kami juga akan menyembunyikannya di bawah spoiler.

metode prediksi dan data
 private static void TestSinglePrediction(MLContext mlContext, ITransformer model) { var predictionFunction = mlContext.Model.CreatePredictionEngine<MayorAppel, MayorAppelPrediction>(model); var MayorAppelSampleMinData = new MayorAppel() { Year = 2019, Month = "August", ResPositive = 0 }; var MayorAppelSampleMediumData = new MayorAppel() { Year = 2019, Month = "August", TotalAppeals = 111340, AppealsToMayor = 17932, ResExplained = 66858, ResNegative = 8945, ElFormToMayor = 14931, PapFormToMayor = 2967, ResPositive = 0 }; var MayorAppelSampleMaxData = new MayorAppel() { Year = 2019, Month = "August", TotalAppeals = 111340, AppealsToMayor = 17932, ResExplained = 66858, ResNegative = 8945, ElFormToMayor = 14931, PapFormToMayor = 2967, To10KTotalVAO = 67, To10KMayorVAO = 13, To10KTotalZAO = 57, To10KMayorZAO = 13, To10KTotalZelAO = 49, To10KMayorZelAO = 9, To10KTotalSAO = 71, To10KMayorSAO = 14, To10KTotalSVAO = 86, To10KMayorSVAO = 27, To10KTotalSZAO = 68, To10KMayorSZAO = 12, To10KTotalTiNAO = 93, To10KMayorTiNAO = 36, To10KTotalCAO = 104, To10KMayorCAO = 24, To10KTotalYUAO = 56, To10KMayorYUAO = 12, To10KTotalYUVAO = 59, To10KMayorYUVAO = 13, To10KTotalYUZAO = 78, To10KMayorYUZAO = 23, ResPositive = 0 }; var predictionMin = predictionFunction.Predict(MayorAppelSampleMinData); var predictionMed = predictionFunction.Predict(MayorAppelSampleMediumData); var predictionMax = predictionFunction.Predict(MayorAppelSampleMaxData); Console.WriteLine($"**********************************************************************"); Console.WriteLine($"Prediction for August 2019"); Console.WriteLine($"Predicted Positive decisions (Minimum Features): {predictionMin.ResPositive:0.####}, actual res_positive : 22313"); Console.WriteLine($"Predicted Positive decisions (Medium Features: {predictionMed.ResPositive:0.####}, actual res_positive : 22313"); Console.WriteLine($"Predicted Positive decisions (Maximum Features): {predictionMax.ResPositive:0.####}, actual res_positive : 22313"); Console.WriteLine($"**********************************************************************"); } 



Dalam contoh tersebut, kami menggunakan kelas PredictionEngine, yang memungkinkan kami memperoleh prediksi tunggal berdasarkan model yang terlatih dan kumpulan data uji.

Kami akan membuat tiga "probe" dengan data untuk prediksi.
Yang pertama dengan set data minimum (hanya satu bulan dan satu tahun), yang kedua dengan rata-rata dan yang ketiga dengan set lengkap atribut - masing-masing.

Kami mendapatkan tiga prediksi berbeda dan mencetaknya.

Seperti yang dapat Anda lihat di tangkapan layar (Windows 10 x64), menambahkan data pada jumlah panggilan per 10.000 penduduk di distrik, dalam hal ini, hanya merusak segalanya, tetapi menambahkan data lainnya memberikan sedikit peningkatan keakuratan prediksi.



Di Linux, Mint 19 juga mengkompilasi luar biasa di Mono.
Ternyata kerangka kerjanya cukup lintas platform.




Kesimpulannya, seperti yang dijanjikan, saya akan memberikan sedikit analisis komparatif subjektif dari ML.NET dengan perpustakaan pembelajaran mesin Accord.NET dan Python.

1. Dirasakan bahwa para pengembang berusaha untuk mematuhi tren di bidang pembelajaran mesin. Tentu saja, dalam Python dengan banyak perpustakaan yang diinstal di Anaconda, tugas ini dapat diselesaikan dengan lebih kompak dan menghabiskan lebih sedikit waktu untuk pengembangan. Namun secara umum, menurut saya pendekatan untuk memecahkan masalah dengan ML.NET ramah bagi orang-orang yang terbiasa memecahkan masalah pembelajaran mesin menggunakan Python.

2. Dibandingkan dengan Framework Accord.NET , ML.NET terlihat lebih nyaman dan menjanjikan bagi orang yang telah mencoba pembelajaran mesin dengan Python. Saya ingat ketika saya mencoba menulis sesuatu di Accord.NET dua tahun lalu, saya sangat kurang penjelasan dan contoh untuk beberapa kelas dan metode. Dalam hal ini, Ml.NET dengan dokumentasi melakukan sedikit lebih baik, terlepas dari kenyataan bahwa kerangka kerja ini jauh lebih muda daripada Accord.NET. Faktor penting lainnya adalah bahwa ML.NET, dilihat dari aktivitasnya di GitHub, berkembang jauh lebih intensif daripada Accord.NET dan memiliki lebih banyak materi pelatihan berbahasa Rusia.

Akibatnya, pada pandangan pertama, ML.NET terlihat seperti alat yang nyaman yang melengkapi gudang senjata Anda jika tidak mungkin menggunakan Python atau R (misalnya, ketika bekerja dengan API CAD yang dieksekusi di .NET).
Semoga minggu kerja Anda menyenangkan!

Source: https://habr.com/ru/post/id473342/


All Articles