ML.NET 示例:迴歸之銷售預測

feiyun0112發表於2018-12-09

寫在前面

準備近期將微軟的machinelearning-samples翻譯成中文,水平有限,如有錯漏,請大家多多指正。
如果有朋友對此感興趣,可以加入我:https://github.com/feiyun0112/machinelearning-samples.zh-cn

eShopDashboardML - 銷售預測

ML.NET 版本 API 型別 狀態 應用程式型別 資料型別 場景 機器學習任務 演算法
v0.7 動態 API 最新版本 ASP.NET Core Web應用程式和控制檯應用程式 SQL Server 和 .csv 檔案 銷售預測 迴歸 FastTreeTweedie 迴歸

eShopDashboardML是一個使用ML.NET 進行(每個產品和每個地區)銷售預測的Web應用程式。

概述

這個終端示例應用程式通過展現以下主題著重介紹ML.NET API的用法:

  1. 如何訓練,建立和生成ML模型
  2. 如何使用經過訓練的ML模型做下個月的銷售預測

該應用程式還使用一個SQL Server資料庫儲存常規產品目錄和訂單資訊,就像許多使用SQL Server的典型Web應用程式一樣。在本例中,由於它是一個示例,因此預設情況下使用localdb SQL資料庫,因此不需要設定真正的SQL Server。在第一次執行Web應用程式時,將建立localdb資料庫幷包含示例資料。

如果要使用真正的SQL Server或Azure SQL資料庫,只需更改應用程式中的連線字串即可。

這是Web應用程式的一個銷售預測螢幕截圖示例:

image

演練:如何設定

瞭解如何在 Visual Studio 中設定以及對程式碼的進一步說明:

演練:ML.NET程式碼實現

問題

這個問題是基於之前的銷售情況圍繞地區和產品進行銷售預測

資料集

為了解決這個問題,您建立了兩個獨立的ML模型,它們以以下資料集作為輸入:

資料集
products stats next, productId, year, month, units, avg, count, max, min, prev
country stats next, country, year, month, max, min, std, count, sales, med, prev

ML 任務 - 迴歸

這個示例的ML任務是迴歸,它是一個有監督的機器學習任務,用於從一組相關的特徵/變數中預測下一個週期的值(在本例中是銷售預測)。

解決方案

為了解決這個問題,首先我們將建立ML模型,同時根據現有資料訓練每個模型,評估其有多好,最後使用模型預測銷售。

注意,該示例實現了兩個獨立的模型:

  • 下一個週期(月)產品需求預測模型
  • 下一個週期(月)地區銷售預測模型

當然,當學習/研究此示例時,您可以只關注其中一個場景/模型。

建立 -> 訓練 -> 評估 -> 使用

1. 建立模型

您需要實現的第一步是定義要從資料集檔案載入的資料列,如下面的程式碼所示:

建立並訓練模型

var textLoader = mlContext.Data.TextReader(new TextLoader.Arguments
                        {
                            Column = new[] {
                                new TextLoader.Column("next", DataKind.R4, 0 ),
                                new TextLoader.Column("productId", DataKind.Text, 1 ),
                                new TextLoader.Column("year", DataKind.R4, 2 ),
                                new TextLoader.Column("month", DataKind.R4, 3 ),
                                new TextLoader.Column("units", DataKind.R4, 4 ),
                                new TextLoader.Column("avg", DataKind.R4, 5 ),
                                new TextLoader.Column("count", DataKind.R4, 6 ),
                                new TextLoader.Column("max", DataKind.R4, 7 ),
                                new TextLoader.Column("min", DataKind.R4, 8 ),
                                new TextLoader.Column("prev", DataKind.R4, 9 )
                            },
                            HasHeader = true,
                            Separator = ","
                        });

然後,下一步是構建轉換管道,並指定要使用什麼訓練器/演算法。
在本例中,您將進行以下轉換:

  • 連線當前特徵生成名為NumFeatures的新列
  • 使用獨熱編碼轉換productId
  • 連線所有生成的特徵生成名為'Features'的新列
  • 複製“next”列將其重新命名為“Label”
  • 指定“Fast Tree Tweedie”訓練器作為演算法應用於模型

在設計管道之後,您可以將資料集載入到DataView中,而且此步驟只是配置,DataView是延遲載入,在下一步訓練模型之前資料不會被載入。

var trainingPipeline = mlContext.Transforms.Concatenate(outputColumn: "NumFeatures", "year", "month", "units", "avg", "count", "max", "min", "prev" )
    .Append(mlContext.Transforms.Categorical.OneHotEncoding(inputColumn:"productId", outputColumn:"CatFeatures"))
    .Append(mlContext.Transforms.Concatenate(outputColumn: "Features", "NumFeatures", "CatFeatures"))
    .Append(mlContext.Transforms.CopyColumns("next", "Label"))
    .Append(trainer = mlContext.Regression.Trainers.FastTreeTweedie("Label", "Features"));

var trainingDataView = textLoader.Read(dataPath);

2. 訓練模型

在建立管道之後,我們通過使用所選演算法擬合或使用訓練資料來訓練預測模型。 在該步驟中,模型被建立,訓練並作為物件返回:

var model = trainingPipeline.Fit(trainingDataView);

3. 評估模型

在本例中,模型的評估是在使用交叉驗證方法訓練模型之前執行的,因此您將獲得指示模型準確度的指標。

var crossValidationResults = mlContext.Regression.CrossValidate(trainingDataView, trainingPipeline, numFolds: 6, labelColumn: "Label");
            
ConsoleHelper.PrintRegressionFoldsAverageMetrics(trainer.ToString(), crossValidationResults);

4. 儲存模型供終端使用者的應用程式稍後使用

一旦建立和評估了模型,就可以將它儲存到.ZIP檔案中,任何終端使用者的應用程式都可以通過以下程式碼使用它:

using (var file = File.OpenWrite(outputModelPath))
    model.SaveTo(mlContext, file);

5. 用簡單的測試預測試用模型

簡單地說,您可以從.ZIP檔案中載入模型,建立一些示例資料,建立“預測函式”,最後進行預測。

ITransformer trainedModel;
using (var stream = File.OpenRead(outputModelPath))
{
    trainedModel = mlContext.Model.Load(stream);
}

var predictionFunct = trainedModel.MakePredictionFunction<ProductData, ProductUnitPrediction>(mlContext);

Console.WriteLine("** Testing Product 1 **");

// Build sample data
ProductData dataSample = new ProductData()
{
    productId = "263",
    month = 10,
    year = 2017,
    avg = 91,
    max = 370,
    min = 1,
    count = 10,
    prev = 1675,
    units = 910
};

//model.Predict() predicts the nextperiod/month forecast to the one provided
ProductUnitPrediction prediction = predictionFunct.Predict(dataSample);
Console.WriteLine($"Product: {dataSample.productId}, month: {dataSample.month + 1}, year: {dataSample.year} - Real value (units): 551, Forecast Prediction (units): {prediction.Score}");

引用

eShopDashboardML資料集是基於UCI(http://archive.ics.uci.edu/ml/datasets/online+retail) 的一個公共線上零售資料集

Daqing Chen, Sai Liang Sain, 和 Kun Guo, 線上零售業的資料探勘: 基於RFM模型的資料探勘客戶細分案例研究, 資料庫營銷與客戶戰略管理雜誌, Vol. 19, No. 3, pp. 197–208, 2012 (印刷前線上釋出: 27 August 2012. doi: 10.1057/dbm.2012.17).

相關文章