Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Pelajari cara memperkirakan permintaan untuk layanan penyewaan sepeda menggunakan analisis rangkaian waktu univariat pada data yang disimpan dalam database SQL Server dengan ML.NET.
Dalam tutorial ini, Anda mempelajari cara:
- Memahami masalahnya
- Memuat data dari database
- Membuat model prakiraan
- Mengevaluasi model prakiraan
- Menyimpan model prakiraan
- Menggunakan model prakiraan
Prasyarat
- Visual Studio 2022 atau yang lebih baru dengan beban kerja Pengembangan Desktop .NET terinstal.
Gambaran umum sampel prakiraan rangkaian waktu
Sampel ini adalah aplikasi konsol C# yang memperkirakan permintaan penyewaan sepeda menggunakan algoritma analisis rangkaian waktu univariat yang dikenal sebagai Analisis Spektrum Singular. Kode untuk sampel ini dapat ditemukan di dotnet/machinelearning-samples repositori di GitHub.
Memahami masalahnya
Untuk menjalankan operasi yang efisien, manajemen inventaris memainkan peran kunci. Memiliki terlalu banyak produk dalam stok berarti produk yang tidak terjual duduk di rak tidak menghasilkan pendapatan apa pun. Memiliki terlalu sedikit produk menyebabkan penjualan hilang dan pelanggan membeli dari pesaing. Oleh karena itu, pertanyaan konstan adalah, berapa jumlah inventaris optimal yang harus ditangani? Analisis rangkaian waktu membantu memberikan jawaban atas pertanyaan-pertanyaan ini dengan melihat data historis, mengidentifikasi pola, dan menggunakan informasi ini untuk memperkirakan nilai beberapa waktu di masa mendatang.
Teknik untuk menganalisis data yang digunakan dalam tutorial ini adalah analisis rangkaian waktu univariat. Analisis rangkaian waktu Univariat melihat satu pengamatan numerik selama periode waktu tertentu pada interval tertentu seperti penjualan bulanan.
Algoritma yang digunakan dalam tutorial ini adalah Singular Spectrum Analysis (SSA). SSA bekerja dengan menguraikan rangkaian waktu menjadi satu set komponen utama. Komponen-komponen ini dapat ditafsirkan sebagai bagian dari sinyal yang sesuai dengan tren, kebisingan, musiman, dan banyak faktor lainnya. Kemudian, komponen-komponen ini direkonstruksi dan digunakan untuk memperkirakan nilai beberapa waktu di masa depan.
Membuat aplikasi konsol
Buat Aplikasi Konsol C#
dengan nama "BikeDemandForecasting". Klik tombol Berikutnya. Pilih .NET 8 sebagai kerangka kerja yang akan digunakan. Klik tombol Buat.
Menginstal paket NuGet versi Microsoft.ML
Nota
Sampel ini menggunakan versi stabil terbaru dari paket NuGet yang disebutkan kecuali dinyatakan lain.
- Di Penjelajah Solusi, klik kanan proyek Anda dan pilih Kelola Paket NuGet.
- Pilih "nuget.org" sebagai sumber paket, pilih tab Telusuri, lalu cari Microsoft.ML.
- Centang kotak centang Sertakan prarilis.
- Pilih tombol Instal.
- Pilih tombol
OK pada dialog Perubahan Pratinjaulalu pilih tombol Saya Terima pada dialog Penerimaan Lisensi jika Anda setuju dengan ketentuan lisensi untuk paket yang tercantum. - Ulangi langkah-langkah ini untuk System.Data.SqlClient dan Microsoft.ML.TimeSeries.
Menyiapkan dan memahami data
- Buat direktori yang disebut Data.
- Unduh file database
dan simpan ke direktori DataDailyDemand.mdf .
Nota
Data yang digunakan dalam tutorial ini berasal dari Himpunan Data Berbagi Sepeda UCI. Hadi Fanaee-T dan João Gama, 'Pelabelan peristiwa menggabungkan detektor ansambel dan pengetahuan latar belakang', Kemajuan kecerdasan buatan (2013): pp. 1-15, Springer Berlin Heidelberg, Web Link.
Himpunan data asli berisi beberapa kolom yang sesuai dengan musiman dan cuaca. Untuk brevity dan karena algoritma yang digunakan dalam tutorial ini hanya memerlukan nilai dari satu kolom numerik, himpunan data asli telah dikondensasikan untuk hanya menyertakan kolom berikut:
- dteday: Tanggal pengamatan.
- tahun: Tahun pengamatan yang dikodekan (0=2011, 1=2012).
- cnt: Jumlah total penyewaan sepeda untuk hari itu.
Himpunan data asli dipetakan ke tabel database dengan skema berikut dalam database SQL Server.
CREATE TABLE [Rentals] (
[RentalDate] DATE NOT NULL,
[Year] INT NOT NULL,
[TotalRentals] INT NOT NULL
);
Berikut ini adalah sampel data:
| TanggalSewa | Tahun | TotalRentals |
|---|---|---|
| 1/1/2011 | 0 | 985 |
| 1/2/2011 | 0 | 801 |
| 1/3/2011 | 0 | 1349 |
Membuat kelas input dan output
Buka file Program.cs dan ganti arahan
usingyang ada dengan yang berikut ini:using Microsoft.ML; using Microsoft.ML.Data; using Microsoft.ML.Transforms.TimeSeries; using System.Data.SqlClient;Buat kelas
ModelInput. Di bawah kelasProgram, tambahkan kode berikut.public class ModelInput { public DateTime RentalDate { get; set; } public float Year { get; set; } public float TotalRentals { get; set; } }Kelas
ModelInputberisi kolom berikut:- RentalDate: Tanggal pengamatan.
- Tahun: Tahun pengamatan yang dikodekan (0=2011, 1=2012).
- TotalRentals: Jumlah total penyewaan sepeda untuk hari itu.
Buat kelas
ModelOutputdi bawah kelasModelInputyang baru dibuat.public class ModelOutput { public float[] ForecastedRentals { get; set; } public float[] LowerBoundRentals { get; set; } public float[] UpperBoundRentals { get; set; } }Kelas
ModelOutputberisi kolom berikut:- ForecastedRentals: Nilai yang diprediksi untuk periode yang diramalkan.
- LowerBoundRentals: Nilai minimum yang diprediksi untuk jangka waktu yang diperkirakan.
- UpperBoundRentals: Nilai maksimum yang diprediksi untuk periode yang diperkirakan.
Menentukan jalur dan menginisialisasi variabel
Di bawah ini, direktif
usingmendefinisikan variabel untuk menyimpan lokasi data, string koneksi, serta tempat menyimpan model yang terlatih.string rootDir = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../../../")); string dbFilePath = Path.Combine(rootDir, "Data", "DailyDemand.mdf"); string modelPath = Path.Combine(rootDir, "MLModel.zip"); var connectionString = $"Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename={dbFilePath};Integrated Security=True;Connect Timeout=30;";Inisialisasi variabel
mlContextdengan instans baruMLContextdengan menambahkan baris berikut setelah menentukan jalur.MLContext mlContext = new MLContext();Kelas
MLContextadalah titik awal untuk semua operasi ML.NET, dan menginisialisasi mlContext membuat lingkungan ML.NET baru yang dapat dibagikan di seluruh objek alur kerja pembuatan model. Ini mirip, secara konseptual, untukDBContextdalam Entity Framework.
Memuat data
Buat
DatabaseLoaderyang memuat rekaman jenisModelInput.DatabaseLoader loader = mlContext.Data.CreateDatabaseLoader<ModelInput>();Tentukan kueri untuk memuat data dari database.
string query = "SELECT RentalDate, CAST(Year as REAL) as Year, CAST(TotalRentals as REAL) as TotalRentals FROM Rentals";algoritma ML.NET mengharapkan data berjenis
Single. Oleh karena itu, nilai numerik yang berasal dari database yang bukan tipeReal, nilai floating-point presisi tunggal, harus dikonversi keReal.Kolom
YeardanTotalRentaladalah jenis bilangan bulat dalam database. Menggunakan fungsi bawaanCAST, keduanya diubah keReal.Buat
DatabaseSourceuntuk menyambungkan ke database dan menjalankan kueri.DatabaseSource dbSource = new DatabaseSource(SqlClientFactory.Instance, connectionString, query);Muat data ke dalam
IDataView.IDataView dataView = loader.Load(dbSource);Himpunan data berisi data senilai dua tahun. Hanya data dari tahun pertama yang digunakan untuk pelatihan, tahun kedua diadakan untuk membandingkan nilai aktual dengan perkiraan yang dihasilkan oleh model. Filter data menggunakan transformasi
FilterRowsByColumn.IDataView firstYearData = mlContext.Data.FilterRowsByColumn(dataView, "Year", upperBound: 1); IDataView secondYearData = mlContext.Data.FilterRowsByColumn(dataView, "Year", lowerBound: 1);Untuk tahun pertama, hanya nilai di kolom
Yearkurang dari 1 yang dipilih dengan mengatur parameterupperBoundke 1. Sebaliknya, untuk tahun kedua, nilai yang lebih besar dari atau sama dengan 1 dipilih dengan mengatur parameterlowerBoundke 1.
Menentukan alur analisis rangkaian waktu
Tentukan alur yang menggunakan SsaForecastingEstimator untuk memperkirakan nilai dalam himpunan data rangkaian waktu.
var forecastingPipeline = mlContext.Forecasting.ForecastBySsa( outputColumnName: "ForecastedRentals", inputColumnName: "TotalRentals", windowSize: 7, seriesLength: 30, trainSize: 365, horizon: 7, confidenceLevel: 0.95f, confidenceLowerBoundColumn: "LowerBoundRentals", confidenceUpperBoundColumn: "UpperBoundRentals");forecastingPipelinemengambil 365 poin data untuk tahun pertama dan sampel atau membagi himpunan data rangkaian waktu menjadi interval 30 hari (bulanan) seperti yang ditentukan oleh parameterseriesLength. Masing-masing sampel ini dianalisis melalui jendela mingguan atau 7 hari. Saat menentukan nilai yang diperkirakan untuk periode berikutnya, nilai dari tujuh hari sebelumnya digunakan untuk membuat prediksi. Model diatur untuk memperkirakan tujuh periode ke masa depan seperti yang didefinisikan oleh parameterhorizon. Karena perkiraan adalah tebakan berdasarkan informasi, itu tidak selalu 100% akurat. Oleh karena itu, ada baiknya untuk mengetahui rentang nilai dalam skenario terbaik dan terburuk seperti yang didefinisikan oleh batas atas dan bawah. Dalam hal ini, tingkat keyakinan untuk batas bawah dan atas ditetapkan pada 95%. Tingkat keyakinan dapat ditingkatkan atau menurun sesuai. Semakin tinggi nilainya, semakin luas rentangnya antara batas atas dan bawah untuk mencapai tingkat keyakinan yang diinginkan.Gunakan metode
Fituntuk melatih model dan menyesuaikan data denganforecastingPipelineyang ditentukan sebelumnya.SsaForecastingTransformer forecaster = forecastingPipeline.Fit(firstYearData);
Evaluasi model
Evaluasi seberapa baik performa model dengan memperkirakan data tahun depan dan membandingkannya dengan nilai aktual.
Buat metode utilitas baru yang disebut
Evaluatedi bagian bawah file Program.cs.Evaluate(IDataView testData, ITransformer model, MLContext mlContext) { }Di dalam metode
Evaluate, perkirakan data tahun kedua dengan menggunakan metodeTransformdengan model terlatih.IDataView predictions = model.Transform(testData);Dapatkan nilai aktual dari data dengan menggunakan metode
CreateEnumerable.IEnumerable<float> actual = mlContext.Data.CreateEnumerable<ModelInput>(testData, true) .Select(observed => observed.TotalRentals);Dapatkan nilai prakiraan dengan menggunakan metode
CreateEnumerable.IEnumerable<float> forecast = mlContext.Data.CreateEnumerable<ModelOutput>(predictions, true) .Select(prediction => prediction.ForecastedRentals[0]);Hitung perbedaan antara nilai aktual dan prakiraan, yang biasa disebut sebagai kesalahan.
var metrics = actual.Zip(forecast, (actualValue, forecastValue) => actualValue - forecastValue);Ukur performa dengan menghitung nilai Kesalahan Absolut Rata-Rata dan Kesalahan Rata-Rata Kuadrat Akar.
var MAE = metrics.Average(error => Math.Abs(error)); // Mean Absolute Error var RMSE = Math.Sqrt(metrics.Average(error => Math.Pow(error, 2))); // Root Mean Squared ErrorUntuk mengevaluasi performa, metrik berikut digunakan:
- Kesalahan Absolut Rata-rata: Mengukur seberapa dekat prediksi dengan nilai sesungguhnya. Nilai ini berkisar antara 0 dan tak terbatas. Semakin dekat ke 0, semakin baik kualitas model.
- Kesalahan Kuadrat Rata-Rata Akar: Merangkum kesalahan dalam model. Nilai ini berkisar antara 0 dan tak terbatas. Semakin dekat ke 0, semakin baik kualitas model.
Keluarkan metrik ke konsol.
Console.WriteLine("Evaluation Metrics"); Console.WriteLine("---------------------"); Console.WriteLine($"Mean Absolute Error: {MAE:F3}"); Console.WriteLine($"Root Mean Squared Error: {RMSE:F3}\n");Panggil metode
Evaluatedi bawah ini dengan memanggil metodeFit().Evaluate(secondYearData, forecaster, mlContext);
Simpan model
Jika Anda puas dengan model Anda, simpan untuk digunakan nanti di aplikasi lain.
Di bawah metode
Evaluate()buatTimeSeriesPredictionEngine.TimeSeriesPredictionEngineadalah metode yang praktis untuk membuat prediksi tunggal.var forecastEngine = forecaster.CreateTimeSeriesEngine<ModelInput, ModelOutput>(mlContext);Simpan model ke file yang disebut
MLModel.zipseperti yang ditentukan oleh variabelmodelPathyang ditentukan sebelumnya. Gunakan metodeCheckpointuntuk menyimpan model.forecastEngine.CheckPoint(mlContext, modelPath);
Menggunakan model untuk memperkirakan permintaan
Di bawah metode
Evaluate, buat metode utilitas baru yang disebutForecast.void Forecast(IDataView testData, int horizon, TimeSeriesPredictionEngine<ModelInput, ModelOutput> forecaster, MLContext mlContext) { }Di dalam metode
Forecast, gunakan metodePredictuntuk memperkirakan penyewaan selama tujuh hari ke depan.ModelOutput forecast = forecaster.Predict();Ratakan nilai aktual dan prakiraan selama tujuh periode.
IEnumerable<string> forecastOutput = mlContext.Data.CreateEnumerable<ModelInput>(testData, reuseRowObject: false) .Take(horizon) .Select((ModelInput rental, int index) => { string rentalDate = rental.RentalDate.ToShortDateString(); float actualRentals = rental.TotalRentals; float lowerEstimate = Math.Max(0, forecast.LowerBoundRentals[index]); float estimate = forecast.ForecastedRentals[index]; float upperEstimate = forecast.UpperBoundRentals[index]; return $"Date: {rentalDate}\n" + $"Actual Rentals: {actualRentals}\n" + $"Lower Estimate: {lowerEstimate}\n" + $"Forecast: {estimate}\n" + $"Upper Estimate: {upperEstimate}\n"; });Telusuri output prakiraan dan tampilkan di konsol.
Console.WriteLine("Rental Forecast"); Console.WriteLine("---------------------"); foreach (var prediction in forecastOutput) { Console.WriteLine(prediction); }
Jalankan aplikasi
Di bawah ini, setelah memanggil metode
Checkpoint(), selanjutnya panggil metodeForecast.Forecast(secondYearData, 7, forecastEngine, mlContext);Jalankan aplikasi. Keluaran yang mirip dengan yang di bawah ini akan muncul pada konsol. Untuk kejelasan, output telah dipadatkan.
Evaluation Metrics --------------------- Mean Absolute Error: 726.416 Root Mean Squared Error: 987.658 Rental Forecast --------------------- Date: 1/1/2012 Actual Rentals: 2294 Lower Estimate: 1197.842 Forecast: 2334.443 Upper Estimate: 3471.044 Date: 1/2/2012 Actual Rentals: 1951 Lower Estimate: 1148.412 Forecast: 2360.861 Upper Estimate: 3573.309
Inspeksi nilai aktual dan prakiraan menunjukkan hubungan berikut:
Perbandingan Aktual vs Prakiraan
Meskipun nilai yang diperkirakan tidak memprediksi jumlah penyewaan yang tepat, nilai tersebut memberikan rentang nilai yang lebih sempit yang memungkinkan operasi untuk mengoptimalkan penggunaan sumber daya mereka.
Selamat! Anda sekarang telah berhasil membangun model pembelajaran mesin rangkaian waktu untuk memperkirakan permintaan penyewaan sepeda.
Anda dapat menemukan kode sumber untuk tutorial ini di dotnet/machinelearning-samples repositori.