让我们一起ML吧(一)聚类分析
让我们一起ML(Make Love Machine Learning)吧!
ML.NET是微软推出的一个免费的开源跨平台机器学习框架,可用于生成自定义机器学习解决方案并将其集成到 .NET 应用程序。ML.NET当前最新版本为0.7,目前处于预览状态,本文中用到的例子来自于微软的官方教程,但随时可能更改,请注意版本变更造成的例子无法运行的状况。
准备工作
你需要一个安装了.NET Core 的VS2017 15.6或更高版本。
了解问题
在本篇中我们将对鸢尾花的数据进行聚类分析,并通过训练出来的模型来判断给出的数据是哪种鸢尾花。
此问题的本质即基于花卉特征将鸢尾花数据归入不同的组。 这些特征包括:花萼的长度和宽度以及花瓣的长度和宽度。 此教程假设每朵花的类型都是未知的。 需通过这些特征了解数据集的结构,并预测数据实例与此结构的拟合程度。
浅解算法
本例中选择K-Means算法解决问题,K-Means算法是个什么算法?不懂也没关系,简单给你介绍一下(我也是刚查的,想详细了解的自己wiki百科),K-Means算法简单来说就是给出n个数据,然后指定一个K(这个K是个大于1小于n的正整数),n个数据就被分成K堆,这个堆被称为聚类,再给出一个样例数据,用同样的方法将样例分入其中某一聚类完成聚类分析。
这K堆或者K类或者K组(K个聚类)如何分呢?假设n个数据为二维平面中的点 P1(x1,y1),P2(x2,y2),...,Pn(xn,yn) ,从n个点中随机选出K个点,这K个点被称作形心(有人也翻译成质心),然后计算其他n-K个点与这K个形心的欧氏距离(即两点之间的直线距离,欧氏即欧几里得),一个点距离哪个形心的距离最短即被分到哪个组,然后循环更换形心再次计算,直到K个组中的点都不再变化,至此n个点即被分为K组数据(K个聚类)。K-Means算法的优点是简单易行,只用指定一个参数K,难点是K值的选取。如果对算法有兴趣可以移步这里看看如何实现算法。
示例代码
本示例所有官方教程源代码都在这里,我的示例与官方示例略有不同。
- 打开VS创建一个控制台应用(.NET Core)命名为IrisClustering
- 安装Microsoft.ML Nuget包(当前最新版本为0.7)
- 在项目根路径下创建一个Data文件夹,从这里下载鸢尾花的数据保存到刚建好的Data文件夹下命名为iris_data.txt,点击iris_data.txt 将文件属性中复制到输出目录项的值改为如果较新则复制
在项目中添加实体类IrisData.cs如下:
1 using Microsoft.ML.Runtime.Api; 2 3 namespace IrisClustering 4 { 5 public class IrisData 6 { 7 [Column("0")] 8 public float SepalLength; 9 10 [Column("1")] 11 public float SepalWidth; 12 13 [Column("2")] 14 public float PetalLength; 15 16 [Column("3")] 17 public float PetalWidth; 18 } 19 20 public class ClusterPrediction 21 { 22 [ColumnName("PredictedLabel")] 23 public uint PredictedClusterId; 24 25 [ColumnName("Score")] 26 public float[] Distances; 27 } 28 }
其中IrisData
类是输入数据类,通过使用Column
属性在数据集文件中指定源列的索引。
ClusterPrediction
类表示应用到IrisData
实例的聚类分析模型的输出。通过使用ColumnName
属性将PredictedClusterId
和 Distances
字段分别绑定至PredicatedLabel
和 Score
列。
PredictedLabel
包含所预测群集的ID。Score
包含一个数组,这个数组中的数即为与群集形心之间欧氏距离的平方。这个数组的长度等于群集数(K-Means算法中的K值)。
接下来在Program.cs中添加预测模型的训练方法并通过Main方法训练预测模型并预测给出的样例属于哪种鸢尾花
1 using System; 2 using System.IO; 3 using System.Threading.Tasks; 4 using Microsoft.ML.Legacy; 5 using Microsoft.ML.Legacy.Data; 6 using Microsoft.ML.Legacy.Trainers; 7 using Microsoft.ML.Legacy.Transforms; 8 9 namespace IrisClustering 10 { 11 public static class Program 12 { 13 //数据文件路径 14 static readonly string _dataPath = Path.Combine(Environment.CurrentDirectory, "Data", "iris_data.txt"); 15 //预测模型保存路径 16 static readonly string _modelPath = Path.Combine(Environment.CurrentDirectory, "Data", "IrisClusteringModel.zip"); 17 //预测模型训练方法 18 private static PredictionModel<IrisData, ClusterPrediction> Train() 19 { 20 var pipeline = new LearningPipeline 21 { 22 new TextLoader(_dataPath).CreateFrom<IrisData>(separator: ','), //加载数据 23 new ColumnConcatenator( //指定数据列名 24 "Features", //特征 学习算法将通过ColumnConcatenator类将数据转化为特征列的值 25 "SepalLength", //花萼长度 26 "SepalWidth", //花萼宽度 27 "PetalLength", //花瓣长度 28 "PetalWidth"), //花瓣宽度 29 new KMeansPlusPlusClusterer() { K = 3 } //指定K-Means算法,这里因为数据中已经给出三个分类,所以我们指定K值为3 30 }; 31 var model = pipeline.Train<IrisData, ClusterPrediction>(); 32 return model; 33 } 34 35 //在Main方法前加async关键字是c#7.1及以后的新功能 36 //应当右键单击项目名称(IrisClustering) 属性->生成->高级->语言版本 中将语言改为c#7.1 37 private static async Task Main(string[] args) 38 { 39 PredictionModel<IrisData, ClusterPrediction> model = Train(); 40 await model.WriteAsync(_modelPath); 41 var prediction = model.Predict(TestIrisData.Setosa); 42 Console.WriteLine($"Cluster:{prediction.PredictedClusterId}"); 43 Console.WriteLine($"Distances:{string.Join(" ",prediction.Distances)}"); 44 Console.Read(); 45 } 46 } 47 }
被用于预测的样例数据如下TestIrisData.cs
1 namespace IrisClustering 2 { 3 static class TestIrisData 4 { 5 internal static readonly IrisData Setosa = new IrisData 6 { 7 SepalLength = 5.1f, 8 SepalWidth = 3.5f, 9 PetalLength = 1.4f, 10 PetalWidth = 0.2f 11 }; 12 } 13 }
程序运行结果如下:
PS:我多次运行后发现结果并不一定是同一个,如果你运行的结果与我不同也可能是正确的。另外PredictedClusterId并不是Distances数组的下标。
最后让我们看一下训练后得到的预测模型是什么东西吧
IrisClusteringModel.zip解压后得到DataLoaderModel和TrainingInfo两个文件夹,其中TrainingInfo中只有一个version.txt保存了一个版本号,而DataLoaderModel中存在数个名为model.key的二进制文件,这就是我们通过ML.NET训练出来的模型。
这样你就使用ML.NET完成了一次聚类分析。
******************************
欢迎随意打赏
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗