öğretici: zaman serisi analizi ve .net ML bisiklet kiralama hizmeti talebini tahmin etme
ML .net ile SQL Server veritabanında depolanan veriler üzerinde bağımsız zamanlı bir zaman serisi analizi kullanarak bir bisiklet kiralama hizmeti için talebi tahmin etme hakkında bilgi edinin.
Bu öğreticide şunların nasıl yapıldığını öğreneceksiniz:
- Sorunu anlama
- Veritabanından veri yükleme
- Tahmin modeli oluşturma
- Tahmin modelini değerlendir
- Tahmin modelini kaydetme
- Tahmin modeli kullan
Önkoşullar
- ".net masaüstü geliştirme" iş yükü yüklüyken 2022 Visual Studio .
Zaman serisi tahmin örneğine genel bakış
Bu örnek, tekil bir zaman serisi analizi analizi olarak bilinen tek değişkenli bir zaman serisi analiz algoritması kullanarak bisiklet için talebi tahmin eden bir C# .NET Core konsol uygulamasıdır . Bu örneğin kodu, GitHub üzerinde DotNet/machinöğrenim-örnekleri deposunda bulunabilir.
Sorunu anlama
Verimli bir işlem çalıştırmak için, envanter yönetimi bir anahtar rol oynar. Ücretteki bir ürünün çok fazla olması, raflardan herhangi bir gelir üretmeden satışa açık ürünler anlamına gelir. Çok az ürün, rakiplerden satın alınan satışları ve müşterileri kaybetmeyecek. Bu nedenle, sabit soru, elinizin altında tutulacak en uygun stok miktarı nedir? Zaman serisi analizi, geçmiş verileri inceleyerek, desenleri tanımlayarak ve bu bilgileri gelecekte bir süre tahmin etmek için kullanarak bu sorulara yanıt sağlanmasına yardımcı olur.
Bu öğreticide kullanılan verileri çözümlemeye yönelik teknik, zaman serisi analizinden bağımsız bir yöntemdir. Tek bir zaman serisi analizi, aylık satış gibi belirli aralıklarda tek bir sayısal izlemeye göz atacağız.
Bu öğreticide kullanılan algoritma tekil bir Spekme analizidir (SSA). SSA, bir dizi sorumlu bileşen için zaman serisini kaldırarak işe yarar. Bu bileşenler, eğilimler, gürültü, mevsimsellik ve birçok başka etkene karşılık gelen bir sinyalin parçaları olarak yorumlanamaz. Ardından, bu bileşenler yeniden yapılandırılır ve gelecekte değerleri tahmin etmek için kullanılır.
Konsol uygulaması oluşturma
"Bikeisteğtahmini" adlı bir C# konsol uygulaması oluşturun. İleri düğmesine tıklayın.
Kullanılacak çerçeve olarak .NET 6 ' yı seçin. Oluştur düğmesine tıklayın.
Microsoft. ML sürümü NuGet paketini yükler
Not
Bu örnek, aksi belirtilmediği takdirde, belirtilen NuGet paketlerinin en son kararlı sürümünü kullanır.
- Çözüm Gezgini, projenize sağ tıklayın ve NuGet paketlerini yönet' i seçin.
- Paket kaynağı olarak "nuget.org" öğesini seçin, Gözden geçirme sekmesini seçin, Microsoft. ml aratın.
- Ön sürümü dahil et onay kutusunu işaretleyin.
- Install düğmesini seçin.
- Değişiklikleri Önizle Iletişim kutusunda Tamam düğmesini seçin ve ardından listelenen paketlerin lisans koşullarını kabul ediyorsanız Lisans Kabulü iletişim kutusunda kabul ediyorum düğmesini seçin.
- System. Data. SqlClient ve Microsoft. ml için bu adımları yineleyin. TimeSeries.
Verileri hazırlama ve anlama
- Veri adlı bir dizin oluşturun.
- Dailydemand. mdf veritabanı dosyasını indirin ve veri dizinine kaydedin.
Not
Bu öğreticide kullanılan veriler, UCI bisiklet paylaşımı veri kümesindengelir. Fanaee-T, hadi ve gama, Joao, ' olay etiketleme birleştirme algılayıcıları ve arka plan bilgisi ', yapay zeka 'da Ilerleme (2013): PP. 1-15, Sprümlberg, Web bağlantısı.
Özgün veri kümesi mevsimsellik ve hava durumu ile ilgili birkaç sütun içerir. Breçekimi ve bu öğreticide kullanılan algoritma yalnızca tek bir sayısal sütundan değer gerektirdiğinden, özgün veri kümesi yalnızca aşağıdaki sütunları içerecek şekilde yoğunlaştırılmış:
- dteday: Gözlem tarihi.
- yıl: gözlemin kodlanmış yılı (0 = 2011, 1 = 2012).
- sayisi: o güne ait bisiklet salları toplam sayısı.
özgün veri kümesi, bir SQL Server veritabanında aşağıdaki şemaya sahip bir veritabanı tablosuyla eşlenir.
CREATE TABLE [Rentals] (
[RentalDate] DATE NOT NULL,
[Year] INT NOT NULL,
[TotalRentals] INT NOT NULL
);
Aşağıda, verilerin bir örneği verilmiştir:
| RentalDate | Yıl | TotalRentals |
|---|---|---|
| 1/1/2011 | 0 | 985 |
| 1/2/2011 | 0 | 801 |
| 1/3/2011 | 0 | 1349 |
Giriş ve çıkış sınıfları oluşturma
Program. cs dosyasını açın ve var olan
usingdeyimleri şu şekilde değiştirin:using System; using System.Collections.Generic; using System.Data.SqlClient; using System.IO; using System.Linq; using Microsoft.ML; using Microsoft.ML.Data; using Microsoft.ML.Transforms.TimeSeries;ModelInputsınıfını oluşturun. Sınıfının altınaProgramaşağıdaki kodu ekleyin.public class ModelInput { public DateTime RentalDate { get; set; } public float Year { get; set; } public float TotalRentals { get; set; } }ModelInputSınıfı şu sütunları içerir:- Rentaldate: Gözlem tarihi.
- Yıl: gözlemin kodlanmış yılı (0 = 2011, 1 = 2012).
- Totalrentals: Bu güne ait toplam Bisiklet randevu sayısı.
ModelOutputYeni oluşturulan sınıfın altında sınıf oluşturunModelInput.public class ModelOutput { public float[] ForecastedRentals { get; set; } public float[] LowerBoundRentals { get; set; } public float[] UpperBoundRentals { get; set; } }ModelOutputSınıfı şu sütunları içerir:- ForecastedRentals: tahmin edilen dönem için tahmin edilen değerler.
- Ials Boundrentals: tahmin edilen dönem için öngörülen minimum değerler.
- Üsteboundrentals: tahmin edilen dönem için öngörülen maksimum değer.
Yolları tanımlama ve değişkenleri başlatma
Using deyimlerinin altında, verilerinizin konumunu, Bağlantı dizenizi ve eğitilen modelin kaydedileceği yeri depolamak için değişkenler tanımlayın.
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;";mlContextMLContextYolları tanımladıktan sonra aşağıdaki satırı ekleyerek değişkeni yeni bir örneğiyle başlatın.MLContext mlContext = new MLContext();MLContextsınıfı tüm ML .net işlemleri için bir başlangıç noktasıdır ve mlcontext 'i başlatmak, model oluşturma iş akışı nesneleri genelinde paylaşılabilen yeni bir ML .net ortamı oluşturur. Entity Framework, kavramsal olarak da benzerdirDBContext.
Verileri yükleme
DatabaseLoaderBu tür kayıtları yükleyen oluşturmaModelInput.DatabaseLoader loader = mlContext.Data.CreateDatabaseLoader<ModelInput>();Veritabanından verileri yükleyecek sorguyu tanımlayın.
string query = "SELECT RentalDate, CAST(Year as REAL) as Year, CAST(TotalRentals as REAL) as TotalRentals FROM Rentals";ML .net algoritmaları verilerin türünde olmasını bekler
Single. Bu nedenle, tek duyarlıklı kayan noktalı bir değer olan, türünde olmayan veritabanından gelen sayısal değerlerinRealolarak dönüştürülmesi gerekirReal.YearVeTotalRentalsütunları, veritabanındaki tamsayı türlerdir.CASTYerleşik işlevi kullanarak, her ikisi de ' a dönüştürülürReal.DatabaseSourceVeritabanına bağlanmak ve sorguyu yürütmek için oluşturun.DatabaseSource dbSource = new DatabaseSource(SqlClientFactory.Instance, connectionString, query);Verileri bir öğesine yükleyin
IDataView.IDataView dataView = loader.Load(dbSource);Veri kümesi iki yıl değer içerir. Eğitim için yalnızca ilk yılın verileri kullanılır, ikinci yıl, gerçek değerleri model tarafından üretilen tahmine göre karşılaştırmak için tutulur. Dönüştürme kullanarak verileri filtreleyin
FilterRowsByColumn.IDataView firstYearData = mlContext.Data.FilterRowsByColumn(dataView, "Year", upperBound: 1); IDataView secondYearData = mlContext.Data.FilterRowsByColumn(dataView, "Year", lowerBound: 1);İlk yılda,
Yearparametre 1 olarak ayarlanarak yalnızca sütundaki değerler 1 ' den azupperBoundolacak şekilde seçilir. Bunun tersine, ikinci yıl için 1 ' den büyük veya eşit değerlerlowerBoundparametresi 1 olarak ayarlanarak seçilir.
Zaman serisi analizi ardışık düzenini tanımlama
Bir zaman serisi veri kümesindeki değerleri tahmin etmek için Ssaforekılaringestimator kullanan bir işlem hattı tanımlayın.
var forecastingPipeline = mlContext.Forecasting.ForecastBySsa( outputColumnName: "ForecastedRentals", inputColumnName: "TotalRentals", windowSize: 7, seriesLength: 30, trainSize: 365, horizon: 7, confidenceLevel: 0.95f, confidenceLowerBoundColumn: "LowerBoundRentals", confidenceUpperBoundColumn: "UpperBoundRentals");,
forecastingPipelineİlk yıl ve örnekler için 365 veri noktası alır ya da zaman serisi veri kümesini parametre tarafından belirtilen 30 günlük (aylık) aralıklarına bölerseriesLength. Bu örneklerin her biri haftalık veya 7 günlük bir pencere ile çözümlenir. Sonraki dönemler için tahmini değerin ne olduğu belirlenirken, tahminde etmek için önceki yedi gün içinde yer alan değerler kullanılır. Model, parametresiyle tanımlandığı şekilde yedi noktanın geleceğe doğru tahminini yapmak içinhorizonayarlanmıştır. Tahmin bilinçli bir tahmin olduğundan her zaman %100 doğru değildir. Bu nedenle, üst ve alt sınırlarla tanımlandığı gibi en iyi ve en kötü durum senaryolarında değer aralığını bilmek iyi bir fikirdir. Bu durumda, alt ve üst sınırların güven düzeyi %95 olarak ayarlanır. Güven düzeyi buna göre artırılabilir veya azaltılabilir. Değer ne kadar yüksekse, istenen güven düzeyini elde etmek için üst ve alt sınırların arasındaki aralık o kadar geniş olur.Modeli eğitmek
Fitve verileri önceden tanımlanmış olan 'a sığdırmak için yönteminiforecastingPipelinekullanın.SsaForecastingTransformer forecaster = forecastingPipeline.Fit(firstYearData);
Modeli değerlendirme
Gelecek yılın verilerini tahmin eder ve gerçek değerlerle karşılaştırarak modelin ne kadar iyi performans sergileyecezini değerlendirin.
Program.cs dosyasının en altında
Evaluateadlı yeni bir yardımcı program yöntemi oluşturun.Evaluate(IDataView testData, ITransformer model, MLContext mlContext) { }yönteminin
Evaluateiçinde, eğitilen modelle yöntemini kullanarak ikinciTransformyılın verilerini tahminde bulundurabilirsiniz.IDataView predictions = model.Transform(testData);yöntemini kullanarak verilerden gerçek değerleri
CreateEnumerableelde edersiniz.IEnumerable<float> actual = mlContext.Data.CreateEnumerable<ModelInput>(testData, true) .Select(observed => observed.TotalRentals);yöntemini kullanarak tahmin değerlerini
CreateEnumerableelde edersiniz.IEnumerable<float> forecast = mlContext.Data.CreateEnumerable<ModelOutput>(predictions, true) .Select(prediction => prediction.ForecastedRentals[0]);Genellikle hata olarak adlandırılan gerçek ve tahmin değerleri arasındaki farkı hesaplar.
var metrics = actual.Zip(forecast, (actualValue, forecastValue) => actualValue - forecastValue);Ortalama Mutlak Hata ve Kök Ortalama Hata Karesi Değerlerini hesaparak performansı ölçün.
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 ErrorPerformansı değerlendirmek için aşağıdaki ölçümler kullanılır:
- Ortalama Mutlak Hata: Tahminlerin gerçek değere ne kadar yakın olduğunu ölçür. Bu değer 0 ile sonsuz arasında aralıklara sahiptir. 0'a ne kadar yakınsa modelin kalitesi o kadar iyi olur.
- Kök Ortalama Hata Karesi: Modelde hatayı özetler. Bu değer 0 ile sonsuz arasında aralıklara sahiptir. 0'a ne kadar yakınsa modelin kalitesi o kadar iyi olur.
Ölçümleri konsola çıkış olarak kullanın.
Console.WriteLine("Evaluation Metrics"); Console.WriteLine("---------------------"); Console.WriteLine($"Mean Absolute Error: {MAE:F3}"); Console.WriteLine($"Root Mean Squared Error: {RMSE:F3}\n");yöntemini
Evaluateçağırarak aşağıdaki yönteminiFit()çağırabilirsiniz.Evaluate(secondYearData, forecaster, mlContext);
Modeli kaydetme
Modelinize memnunsanız daha sonra diğer uygulamalarda kullanmak üzere kaydedin.
yönteminin
Evalute()altında birTimeSeriesPredictionEngineoluşturun.TimeSeriesPredictionEngine, tek tahminler yapmak için kullanışlı bir yöntemdir.var forecastEngine = forecaster.CreateTimeSeriesEngine<ModelInput, ModelOutput>(mlContext);Modeli, önceden tanımlanmış değişken
MLModel.ziptarafından belirtilen adlı bir dosyayamodelPathkaydedin. ModeliCheckpointkaydetmek için yöntemini kullanın.forecastEngine.CheckPoint(mlContext, modelPath);
Talebi tahmin etmek için modeli kullanma
yönteminin
Evaluatealtında adlı yeni bir yardımcı program yöntemiForecastoluşturun.void Forecast(IDataView testData, int horizon, TimeSeriesPredictionEngine<ModelInput, ModelOutput> forecaster, MLContext mlContext) { }yönteminin
Forecastiçinde, önümüzdekiPredictyedi gün için kiralama tahmini yapmak için yöntemini kullanın.ModelOutput forecast = forecaster.Predict();Yedi dönem için gerçek ve tahmin değerlerini hizalar.
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"; });Tahmin çıkışında bir daha deneyin ve konsolda görüntüleniyor.
Console.WriteLine("Rental Forecast"); Console.WriteLine("---------------------"); foreach (var prediction in forecastOutput) { Console.WriteLine(prediction); }
Uygulamayı çalıştırma
Aşağıda yöntemini
Checkpoint()çağırma yöntemiForecastçağrılır.Forecast(secondYearData, 7, forecastEngine, mlContext);Uygulamayı çalıştırın. Konsolda aşağıdakine benzer bir çıktı görünmektedir. Daha fazla özetle, çıkış yoğun bir şekilde tamamlandı.
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
Gerçek ve tahmini değerlerin denetimi aşağıdaki ilişkileri gösterir:

Tahmin edilen değerler kiralamaların tam sayısını tahmin etmesa da, kaynakların kullanımını iyileştirmeye yönelik bir işlem sağlayan daha dar bir değer aralığı sağlar.
Tebrikler! Bisiklet kiralama talebini tahmin etmek için başarıyla bir zaman serisi makine öğrenmesi modeli tamamladın.
Bu öğreticinin kaynak kodunu dotnet/machinelearning-samples deposunda bulabilirsiniz.