AI時代的網站與手機App建置與開發Part18 - 使用ML.NET執行客戶分群
· 摘要
將無標示(Unlabeled)的資料進行分群是一種實用的機器學習演算法, 例如利用客戶歷史交易資料, 購物喜好, 年齡層, 性別, 國籍, 或居住地將客戶分群, 以進行精準行銷與客戶經營就是分群(Clustering)演算法的典型應用場合. 透過客戶分群的幫助, 企業能夠有效地為目標客群配置行銷資源, 鞏固某種客群, 或是將特定的廣告傳送給特定的客群, 以利於業務推行.
圖: 依據身高和體重將人分類的示意圖
區分客戶族群會依據客戶的特質將客戶區分成不同的族群, 例如:
ü 喜愛高收益, 但是低風險承受的族群
ü 傾向購買某種類型商品的族群
ü 傾向訂閱某種商品的族群
ü 非營利組織的的族群
ü 分析商店的人流, 支援開店選址
ü 等等
區分客戶族群能夠得到兩種層面的效益:
1 對客戶的效益
ü 客戶認為廠商在乎他們的需求
ü 客戶認為廠商記得他們的喜好
2 對企業的效益
ü 最佳化行銷預算配置
ü 提升客戶生涯貢獻
ü 提升客戶服務和客戶體驗
ü 為不同的客戶打造最佳行銷管道
ü 改良商品功能
ü 發掘最佳貢獻客戶
· 使用K-means演算法實作客戶分群
在我們的範例中, 我們將使用K-means演算法執行客戶群的工作. 使用K-means演算法對資料進行分群的優點與缺點如下:
優點:
ü 容易實作
ü 適合處理大量資料
ü 保證收歛
缺點:
ü 必須人工設定k值(即Hyperparameter)
ü 使用不同的初始核心結果會不相同
ü 不適用大小和密度會變動的群組
ü 易受異常資料影響
ü 易受大量的資料與特徵數量影響
ü 不適合非圓形的群組(例如橢圓形或半月形的群組)
首先請到以下的網址下載欲分析的客戶資料:
ü Mall Customer Segmentation Data(下載網址: https://www.kaggle.com/datasets/shwetabh123/mall-customers
下載得到的客戶資料如圖1所示
圖1: 欲分群的客戶資料
其中的欄位說明如下:1.
CustomerID欄位 : 客戶編號
2.
Gender欄位 :
客戶性別. 1代表男性, 2代表女性
3.
Age欄位 : 客戶年齡
4.
AnnualIncome欄位 : 客戶年消費金額
5.
SpendingScore欄位 : 客戶年消費分數
· 使用k-means演算法對客戶資料進行分群
因為我們將使用OxyPlot程式庫繪出使用K-means演算法分組客戶的結果, 所以我們將會使用Visual Studio 2022建立[WPF應用程式]型態的專案, 方便顯示使用OxyPlot程式庫繪製的統計圖.
建立妥WPF應用程式專案後請定義描述欲分析的客戶資料的MallCustomerData類別:
public class MallCustomerData
{
[LoadColumn(0)]
public uint CustomerID { get; set; }
//[LoadColumn(1)]
//public string GenderText { get; set; }
[LoadColumn(2)]
public float Age { get; set; }
[LoadColumn(3)]
public float AnnualIncomeInK { get; set; }
[LoadColumn(4)]
public float SpendingScore { get; set; }
[LoadColumn(5)]
public float Gender { get; set; }
}
再定義描述分群結果的MallCustomerData類別:
public class MallCustomerPrediction
{
[KeyType(5)] // 5 is the number of clusters
[ColumnName("PredictedLabel")]
public uint PredictedClusterId;
[ColumnName("Score")]
public float[] Distances;
// Copy columns from source data (automatically bound to source data)
public uint CustomerID { get; set; }
public float Gender { get; set; }
public float Age { get; set; }
public float AnnualIncomeInK { get; set; }
public float SpendingScore { get; set; }
}
使用K-means演算法分群客戶的資料://欲分群的客戶資料
string dataPath = "mall_customers.csv";
//建立MLContext
var mlContext = new MLContext();
Trace.WriteLine("Loading data for the clustering...");
// 載入欲分析的資料
IDataView dataset = mlContext.Data.LoadFromTextFile<MallCustomerData>(dataPath, hasHeader: true, separatorChar: ',');
Trace.WriteLine("Splitting data into clusters...");
//設定k-means演算法的參數
var kmo = new KMeansTrainer.Options
{
NumberOfClusters = 3, //建立利用Elbow演算法取得
FeatureColumnName = "Features",
InitializationAlgorithm = KMeansTrainer.InitializationAlgorithm.KMeansPlusPlus,
MaximumNumberOfIterations
= 1000,
AccelerationMemoryBudgetMb
= 4096,
NumberOfThreads = null,
OptimizationTolerance
= (float)Math.Pow(10, -7),
ExampleWeightColumnName
= null
};
//建立k-means演算法模型
var trainer = mlContext.Clustering.Trainers.KMeans(kmo);
//建立訓練管線
var pipeline = mlContext.Transforms.Concatenate(
"Features", "Gender", "Age", "AnnualIncomeInK", "SpendingScore")
Append(trainer);
//執行資料轉換與訓練
IDataView transformedDataView = pipeline.Fit(dataset).Transform(dataset);
//依據K-means分群演算法的輸出結果進行GroupBy運算
var enumerable = mlContext.Data
.CreateEnumerable<MallCustomerPrediction>(transformedDataView,
reuseRowObject:
false).ToList();
var clusters = enumerable.GroupBy(r => r.PredictedClusterId);
//顯示客戶分群結果
foreach (var
cluster in
clusters)
{
Trace.WriteLine($"CustomerID,Gender,Age,Annual
Income (K), Spending Score-${cluster.Key}");
foreach (var row in cluster)
{
Trace.WriteLine($"{row.CustomerID},{row.Gender},{row.Age}, {row.AnnualIncomeInK},{row.SpendingScore}");
}
}
//利用OxyPlot程式庫繪製K-means演算法分群的客戶結果
var originalData = mlContext.Data.CreateEnumerable<MallCustomerData>(
dataset, reuseRowObject: false).ToList();
var plotModel = new PlotModel { Title = "K-Means Clustering" };
// 使用三種顏色顯示不同的客戶族群
var clusterColors = new[] { OxyColors.Red, OxyColors.Green, OxyColors.Blue };
for (int i =
0; i < clusterColors.Length; i++)
{
var clusterId = (uint)(i
+ 1); // Cluster IDs start at 1
var scatterSeries = new ScatterSeries {
MarkerType = MarkerType.Circle,
MarkerFill = clusterColors[i] };
foreach (var
(dataPoint, prediction) in
originalData.Zip(enumerable, (dp, cp) => (dp, cp)))
{
if
(prediction.PredictedClusterId == clusterId)
{
//依據客戶年消費金額和年消費分數檢視客戶的族群
scatterSeries.Points.Add(new ScatterPoint( dataPoint.SpendingScore, dataPoint.AnnualIncomeInK));
}
}
plotModel.Series.Add(scatterSeries);
}
// 將繪製的統計圖顯示到WPF應用程式
var plotView = new PlotView { Model = plotModel };
Content = plotView;
執行上述的程式, 您將會看到以下的客戶分群結果
圖2: 依據客戶年消費金額和年消費分數檢視客戶的族群
除了圖2的統計圖以外, 您也可以在Visual Studio的輸出視窗看到隷屬於各個群組的客戶清單, 如圖3所示:
圖3: 隷屬於各個群組的客戶清單
範例下載網址:




留言
張貼留言