Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
ML.NET içeren bir SQL Server veritabanında depolanan veriler üzerinde tek değişkenli zaman serisi analizi kullanarak bisiklet kiralama hizmetine yönelik talebi tahmin etmeyi öğrenin.
Bu eğitimde şunları öğreniyorsunuz:
- Sorunu anlama
- Veritabanından veri yükleme
- Tahmin modeli oluşturma
- Tahmin modelini değerlendirme
- Tahmin modelini kaydetme
- Tahmin modeli kullanma
Önkoşullar
- Visual Studio 2022 veya daha yenisi ile .NET Masaüstü Geliştirme iş yükü yüklü.
Zaman serisi tahmin örneğine genel bakış
Bu örnek, Tekil Spektrum Analizi olarak bilinen tek değişkenli bir zaman serisi analiz algoritması kullanarak bisiklet kiralama talebini tahmin eden bir C# konsol uygulamasıdır . Bu örneğin kodu GitHub'daki dotnet/machinelearning-samples deposunda bulunabilir.
Sorunu anlama
Verimli bir işlem çalıştırmak için envanter yönetimi önemli bir rol oynar. Stokta çok fazla ürün olması, raflarda duran satılmamış ürünlerin gelir elde etmemesi anlamına gelir. Çok az ürüne sahip olmak, satışların kaybolmasına ve rakiplerden satın alınan müşterilere yol açar. Bu nedenle, sabit soru şudur: Elde tutulacak en uygun stok miktarı nedir? Zaman serisi analizi, geçmiş verilere bakarak, desenleri tanımlayarak ve gelecekte bir süre değerleri tahmin etmek için bu bilgileri kullanarak bu sorulara yanıt sağlamaya yardımcı olur.
Bu öğreticide kullanılan verileri analiz etme tekniği tek değişkenli zaman serisi analizidir. Tek değişkenli zaman serisi analizi, aylık satışlar gibi belirli aralıklarda belirli bir süre boyunca tek bir sayısal gözleme göz atar.
Bu öğreticide kullanılan algoritma Tekil Spektrum Analizi(SSA)'dır. SSA, bir zaman serisini bir dizi asıl bileşene ayırarak çalışır. Bu bileşenler bir sinyalin eğilimlere, gürültüye, mevsimselliğe ve diğer birçok faktöre karşılık gelen parçaları olarak yorumlanabilir. Ardından bu bileşenler yeniden oluşturulur ve gelecekte bir süre değerleri tahmin etmek için kullanılır.
Konsol uygulaması oluşturma
"BikeDemandForecasting" adlı bir C# Konsol Uygulaması oluşturun. İleri düğmesine tıklayın.
Kullanılacak çerçeve olarak .NET 8'i seçin. Oluştur düğmesine tıklayın.
Microsoft.ML sürüm NuGet paketini yükleme
Uyarı
Bu örnek, aksi belirtilmedikçe bahsedilen NuGet paketlerinin en son kararlı sürümünü kullanır.
- Çözüm Gezgini'nde projenize sağ tıklayın ve NuGet Paketlerini Yönet'i seçin.
- Paket kaynağı olarak "nuget.org" öğesini seçin, Gözat sekmesini seçin, Microsoft.ML arayın.
- Ön sürümü dahil et onay kutusunu işaretleyin.
- Yükle düğmesini seçin.
- Listelenen paketlerin lisans koşullarını kabul ediyorsanız, Değişiklikleri Önizle iletişim kutusunda Tamam düğmesini ve ardından Lisans Kabulü iletişim kutusunda Kabul Ediyorum düğmesini seçin.
- System.Data.SqlClient ve Microsoft.ML.TimeSeries için bu adımları yineleyin.
Verileri hazırlama ve anlama
- Data adlı bir dizin oluşturun.
- DailyDemand.mdf veritabanı dosyasını indirin ve Veri dizinine kaydedin.
Uyarı
Bu öğreticide kullanılan veriler UCI Bisiklet Paylaşım Veri Kümesi'nden gelir. Hadi Fanaee-T ve João Gama, 'Topluluk dedektörlerini ve arka plan bilgilerini birleştiren olay etiketleme', Yapay Zekada İlerleme (2013): pp. 1-15, Springer Berlin Heidelberg, Web Link.
Özgün veri kümesi mevsimsellik ve hava durumuna karşılık gelen birkaç sütun içerir. Kısa ve kısa olması için ve bu öğreticide kullanılan algoritma yalnızca tek bir sayısal sütundaki değerleri gerektirdiğinden, özgün veri kümesi yalnızca aşağıdaki sütunları içerecek şekilde daraltılmıştır:
- dteday: Gözlem tarihi.
- year: Gözlemin kodlanmış yılı (0=2011, 1=2012).
- cnt: O gün için toplam bisiklet kiralama sayısı.
Özgün veri kümesi, SQL Server veritabanında aşağıdaki şemaya sahip bir veritabanı tablosuna 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 mevcut
usingyönergeleri aşağıdakilerle değiştirin:using Microsoft.ML; using Microsoft.ML.Data; using Microsoft.ML.Transforms.TimeSeries; using System.Data.SqlClient;Sınıf oluşturma
ModelInput. 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ı aşağıdaki sütunları içerir:- RentalDate: Gözlem tarihi.
- Yıl: Gözlemin kodlanmış yılı (0=2011, 1=2012).
- TotalRentals: O güne ait toplam bisiklet kiralama sayısı.
Yeni oluşturulan
ModelOutputsı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ı aşağıdaki sütunları içerir:- ForecastedRentals: Tahmin edilen dönem için tahmin edilen değerler.
- LowerBoundRentals: Tahmin edilen dönem için tahmin edilen minimum değerler.
- UpperBoundRentals: Tahmin edilen dönem için tahmin edilen maksimum değerler.
Yolları tanımlama ve değişkenleri başlatma
Yönergelerin
usingaltında verilerinizin konumunu, bağlantı dizesini ve eğitilen modelin kaydedileceği konumu 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;";mlContextYolları tanımladıktan sonra aşağıdaki satırı ekleyerek değişkenini yeni bir örneğiyleMLContextbaş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 arasında paylaşılabilen yeni bir ML.NET ortamı oluşturur. Entity Framework'tekineDBContextbenzer, kavramsal olarak.
Verileri yükleme
türünde
DatabaseLoaderkayıtları yükleyen bir oluşturunModelInput.DatabaseLoader loader = mlContext.Data.CreateDatabaseLoader<ModelInput>();Veritabanından verileri yüklemek için 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
Singleolmasını bekler. Bu nedenle, veritabanından gelen ve türündeRealolmayan sayısal değerlerin tek duyarlıklı kayan nokta değerine dönüştürülmesiRealgerekir.YearveTotalRentalsütunlarının her ikisi de veritabanındaki tamsayı türleridir.CASTYerleşik işlevi kullanılarak her ikisi de öğesineRealatılır.Veritabanına bağlanmak ve sorguyu yürütmek için bir
DatabaseSourceoluşturun.DatabaseSource dbSource = new DatabaseSource(SqlClientFactory.Instance, connectionString, query);Verileri içine
IDataViewyükleyin.IDataView dataView = loader.Load(dbSource);Veri kümesi iki yıllık veriler içerir. Eğitim için yalnızca ilk yıla ait veriler kullanılır, ikinci yıl ise gerçek değerleri model tarafından üretilen tahminle karşılaştırmak için tutulur. Dönüştürmeyi kullanarak verileri filtreleyin
FilterRowsByColumn.IDataView firstYearData = mlContext.Data.FilterRowsByColumn(dataView, "Year", upperBound: 1); IDataView secondYearData = mlContext.Data.FilterRowsByColumn(dataView, "Year", lowerBound: 1);İlk yıl için parametre 1 olarak ayarlanarak yalnızca 1'den küçük sütundaki
YearupperBounddeğerler seçilir. Buna karşılık, ikinci yıl için parametre 1 olarak ayarlanaraklowerBound1'den büyük veya 1'e eşit değerler seçilir.
Zaman serisi çözümleme işlem hattını tanımlama
Zaman serisi veri kümesindeki değerleri tahmin etmek için SsaForecastingEstimator 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");forecastingPipelineilk yıl için 365 veri noktası alır veseriesLengthparametresi tarafından belirtilen şekilde zaman serisi veri kümesini 30 günlük (aylık) aralıklara ayırır veya örnekler alır. Bu örneklerin her biri haftalık veya 7 günlük bir süre boyunca analiz edilir. Sonraki dönemler için tahmin edilen değerin ne olduğunu belirlerken, tahminde bulunmak için önceki yedi güne ait değerler kullanılır. Model, parametresi tarafındanhorizontanımlanan yedi dönemi geleceğe tahmin etmek için ayarlanır. Tahmin, bilinçli bir tahmin olduğundan her zaman 100% doğru değildir. Bu nedenle, üst ve alt sınırlar tarafından tanımlanan en iyi ve en kötü durum senaryolarındaki değer aralığını bilmek iyidir. Bu durumda, alt ve üst sınırların güvenilirlik düzeyi 95%olarak ayarlanır. Güvenilirlik düzeyi buna göre artırılabilir veya azaltılabilir. Değer ne kadar yüksek olursa, istenen güvenilirlik düzeyini elde etmek için aralık üst ve alt sınırlar arasında o kadar geniştir.FitModeli eğitmek ve verileri önceden tanımlanmışforecastingPipelineolan öğesine sığdırmak için yöntemini kullanın.SsaForecastingTransformer forecaster = forecastingPipeline.Fit(firstYearData);
Modeli değerlendirme
Gelecek yılın verilerini tahmin ederek ve gerçek değerlerle karşılaştırarak modelin performansını değerlendirin.
Evaluatedosyasının en altında adlı 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 kullanarakTransformikinci yılın verilerini tahmin edin.IDataView predictions = model.Transform(testData);yöntemini kullanarak
CreateEnumerableverilerden gerçek değerleri alın.IEnumerable<float> actual = mlContext.Data.CreateEnumerable<ModelInput>(testData, true) .Select(observed => observed.TotalRentals);yöntemini kullanarak
CreateEnumerabletahmin değerlerini alın.IEnumerable<float> forecast = mlContext.Data.CreateEnumerable<ModelOutput>(predictions, true) .Select(prediction => prediction.ForecastedRentals[0]);Gerçek ve tahmin değerleri arasındaki farkı (genellikle hata olarak adlandırılır) hesaplayın.
var metrics = actual.Zip(forecast, (actualValue, forecastValue) => actualValue - forecastValue);Ortalama Mutlak Hata ve Kök Ortalama Kare Hatası değerlerini hesaplayarak 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çer. Bu değer 0 ile sonsuz arasında değişir. 0'a ne kadar yakın olursa, modelin kalitesi o kadar iyi olur.
- Kök Ortalama Kare Hatası: Modeldeki hatayı özetler. Bu değer 0 ile sonsuz arasında değişir. 0'a ne kadar yakın olursa, modelin kalitesi o kadar iyi olur.
Ölçümleri konsola çıktılayın.
Console.WriteLine("Evaluation Metrics"); Console.WriteLine("---------------------"); Console.WriteLine($"Mean Absolute Error: {MAE:F3}"); Console.WriteLine($"Root Mean Squared Error: {RMSE:F3}\n");EvaluateAşağıdaki yöntemi çağırarak yöntemini çağırınFit().Evaluate(secondYearData, forecaster, mlContext);
Modeli kaydetme
Modelinizden memnunsanız, daha sonra diğer uygulamalarda kullanmak üzere kaydedin.
yönteminin altında
Evaluate()birTimeSeriesPredictionEngineoluşturun.TimeSeriesPredictionEnginetek tahminler yapmak için kullanışlı bir yöntemdir.var forecastEngine = forecaster.CreateTimeSeriesEngine<ModelInput, ModelOutput>(mlContext);Modeli, önceden tanımlanmış
MLModel.zipdeğişken tarafından belirtilen adlımodelPathbir dosyaya kaydedin.CheckpointModeli kaydetmek için yöntemini kullanın.forecastEngine.CheckPoint(mlContext, modelPath);
Talebi tahmin etmek için modeli kullanma
yönteminin altında
EvaluateadlıForecastyeni bir yardımcı program yöntemi oluşturun.void Forecast(IDataView testData, int horizon, TimeSeriesPredictionEngine<ModelInput, ModelOutput> forecaster, MLContext mlContext) { }yönteminin
Forecastiçinde, sonraki yedi gün için kiralama tahmin etmek için yöntemini kullanınPredict.ModelOutput forecast = forecaster.Predict();Yedi dönem için gerçek ve tahmin değerlerini hizalayın.
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 çıktısını yineleyip konsolda görüntüleyin.
Console.WriteLine("Rental Forecast"); Console.WriteLine("---------------------"); foreach (var prediction in forecastOutput) { Console.WriteLine(prediction); }
Uygulamayı çalıştırma
Aşağıda yöntemini çağırarak
Checkpoint()yöntemini çağırınForecast.Forecast(secondYearData, 7, forecastEngine, mlContext);Uygulamayı çalıştırın. Konsolda aşağıdakine benzer bir çıktı görünmelidir. Kısalık adına çıktı kısaltıldı.
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 tahmin edilen değerlerin incelenmesi aşağıdaki ilişkileri gösterir:
Tahmin edilen değerler tam kiralama sayısını tahmin etmese de, bir işlemin kaynak kullanımını iyileştirmesine olanak tanıyan daha dar bir değer aralığı sağlar.
Tebrikler! Bisiklet kiralama talebini tahmin etmek için bir zaman serisi makine öğrenmesi modelini başarıyla oluşturdunuz.
Bu öğreticinin kaynak kodunu dotnet/machinelearning-samples deposunda bulabilirsiniz.