上一篇博文我们介绍了ML.NET 的入门:

ML.NET技术研究系列1-入门篇

本文我们继续,研究分享一下聚类算法k-means.

一、k-means算法简介

k-means算法是一种聚类算法,所谓聚类,即根据相似性原则,将具有较高相似度的数据对象划分至同一类簇,将具有较高相异度的数据对象划分至不同类簇。

1. k-means算法的原理是什么样的?参考:https://baijiahao.baidu.com/s?id=1622412414004300046&wfr=spider&for=pc

k-means算法中的k代表类簇个数,means代表类簇内数据对象的均值(这种均值是一种对类簇中心的描述),因此,k-means算法又称为k-均值算法。

k-means算法是一种基于划分的聚类算法,以距离作为数据对象间相似性度量的标准,即数据对象间的距离越小,则它们的相似性越高,则它们越有可能在同一个类簇。

数据对象间距离的计算有很多种,k-means算法通常采用欧氏距离来计算数据对象间的距离。算法详细的流程描述如下:

   2. k-means算法的优缺点:

优点: 算法简单易实现;

缺点: 需要用户事先指定类簇个数; 聚类结果对初始类簇中心的选取较为敏感; 容易陷入局部最优; 只能发现球形类簇;

接下来我们说一下k-means算法的经典应用场景:鸢尾花

二、鸢尾花

首先,鸢尾花是一种植物,有四个典型的属性:

  • 花瓣长度
  • 花瓣宽度
  • 花萼长度
  • 花萼宽度

鸢尾花有三大品种setosa、versicolor 或 virginica ,每个品种对应的以上四个属性各不相同。

鸢尾花数据集中一共包含了150条记录,每个样本的包含它的萼片长度和宽度,花瓣的长度和宽度以及这个样本所属的具体品种。每个品种的样本量为50条。

鸢尾花样本数据格式:

5.2,3.4,1.4,0.2,Iris-setosa
4.7,3.2,1.6,0.2,Iris-setosa
4.8,3.1,1.6,0.2,Iris-setosa
6.0,2.2,4.0,1.0,Iris-versicolor
6.1,2.9,4.7,1.4,Iris-versicolor
5.6,2.9,3.6,1.3,Iris-versicolor
5.7,2.5,5.0,2.0,Iris-virginica
5.8,2.8,5.1,2.4,Iris-virginica
6.4,3.2,5.3,2.3,Iris-virginica

 上述数据中,第一列是鸢尾花花萼长度,第二列是鸢尾花花萼宽度,第三列是鸢尾花花瓣长度,第四列是鸢尾花花瓣宽度。

基于上述数据做机器学习、训练,形成一个模型。

三、ML.NET k-means

基于上述的场景,我们先准备样本数据,https://github.com/dotnet/machinelearning/blob/master/test/data/iris.data

另存为iris.data文件,每个属性逗号间隔。

然后,大致梳理了一下实现步骤:

  1. 新建一个.Net  Core Console Project
  2. 添加Microsoft.ML nuget 1.2.0版本
  3. 添加鸢尾花数据、预测类实体类IrisData、ClusterPrediction
  4. 构造MLContext、从iris.data构造IDataView,采用Trainers.KMeans进行模型训练,形成模型文件:IrisClusteringModel.zip
  5. 输入一个测试数据,进行预测。

好,让我们开始搞吧:

   1. 新建一个.Net  Core Console Project

先看下用的VS的版本:

新建一个.Net Core Console的Project KMeansDemo

   2. 添加Microsoft.ML nuget 1.2.0版本

将iris.data文件放到Project下的Data目录中,同时右键iris.data,设置为:始终复制

 3. 添加鸢尾花数据、预测类实体类IrisData、ClusterPrediction

using System;
using System.Collections.Generic;
using System.Text; namespace KMeansDemo
{
using Microsoft.ML.Data; /// <summary>
/// 鸢尾花数据
/// </summary>
class IrisData
{
/// <summary>
/// 鸢尾花花萼长度
/// </summary>
[LoadColumn(0)]
public float SepalLength; /// <summary>
/// 鸢尾花花萼宽度
/// </summary>
[LoadColumn(1)]
public float SepalWidth; /// <summary>
/// 鸢尾花花瓣长度
/// </summary>
[LoadColumn(2)]
public float PetalLength; /// <summary>
/// 鸢尾花花瓣宽度
/// </summary>
[LoadColumn(3)]
public float PetalWidth;
}
}
using System;
using System.Collections.Generic;
using System.Text; namespace KMeansDemo
{
using Microsoft.ML.Data; public class ClusterPrediction
{
/// <summary>
/// 预测的族群
/// </summary>
[ColumnName("PredictedLabel")]
public uint PredictedClusterId; [ColumnName("Score")]
public float[] Distances;
}
}

4.  构造MLContext、从iris.data构造IDataView,采用Trainers.KMeans进行模型训练,形成模型文件:IrisClusteringModel.zip

在Main函数中,开始编码 ,首先添加引用

using Microsoft.ML;

声明样本数据文件和模型文件的文件路径

static readonly string _dataPath = Path.Combine(Environment.CurrentDirectory, "Data", "iris.data");
static readonly string _modelPath = Path.Combine(Environment.CurrentDirectory, "Data", "IrisClusteringModel.zip");

构造MLContext、IDataView,采用Trainer.KMeans进行模型训练,形成模型文件:IrisClusteringModel.zip

var mlContext = new MLContext(seed: 0);
IDataView dataView = mlContext.Data.LoadFromTextFile<IrisData>(_dataPath, hasHeader: false, separatorChar: ',');
string featuresColumnName = "Features";
var pipeline = mlContext.Transforms
.Concatenate(featuresColumnName, "SepalLength", "SepalWidth", "PetalLength", "PetalWidth")
.Append(mlContext.Clustering.Trainers.KMeans(featuresColumnName, numberOfClusters: 3));
var model = pipeline.Fit(dataView);
using (var fileStream = new FileStream(_modelPath, FileMode.Create, FileAccess.Write, FileShare.Write))
{
mlContext.Model.Save(model, dataView.Schema, fileStream);
}
Console.WriteLine("完成模型训练!");
Console.WriteLine("模型文件:"+ _modelPath);

5.  输入一个测试数据,进行预测。

输入一个测试数据,使用生成的模型,进行预测:

var predictor = mlContext.Model.CreatePredictionEngine<IrisData, ClusterPrediction>(model);
var Setosa = new IrisData
{
SepalLength = 5.1f,
SepalWidth = 3.5f,
PetalLength = 1.4f,
PetalWidth = 0.2f
}; var prediction = predictor.Predict(Setosa);
Console.WriteLine($"Cluster: {prediction.PredictedClusterId}");
Console.WriteLine($"Distances: {string.Join(" ", prediction.Distances)}");
Console.WriteLine("Press any key!");

 全部的代码:

 using Microsoft.ML;
using System;
using System.IO; namespace KMeansDemo
{
class Program
{
static readonly string _dataPath = Path.Combine(Environment.CurrentDirectory, "Data", "iris.data");
static readonly string _modelPath = Path.Combine(Environment.CurrentDirectory, "Data", "IrisClusteringModel.zip"); static void Main(string[] args)
{
var mlContext = new MLContext(seed: );
IDataView dataView = mlContext.Data.LoadFromTextFile<IrisData>(_dataPath, hasHeader: false, separatorChar: ',');
string featuresColumnName = "Features";
var pipeline = mlContext.Transforms
.Concatenate(featuresColumnName, "SepalLength", "SepalWidth", "PetalLength", "PetalWidth")
.Append(mlContext.Clustering.Trainers.KMeans(featuresColumnName, numberOfClusters: ));
var model = pipeline.Fit(dataView);
using (var fileStream = new FileStream(_modelPath, FileMode.Create, FileAccess.Write, FileShare.Write))
{
mlContext.Model.Save(model, dataView.Schema, fileStream);
}
Console.WriteLine("完成模型训练!");
Console.WriteLine("模型文件:"+ _modelPath); //预测
var predictor = mlContext.Model.CreatePredictionEngine<IrisData, ClusterPrediction>(model); var Setosa = new IrisData
{
SepalLength = 5.1f,
SepalWidth = 3.5f,
PetalLength = 1.4f,
PetalWidth = 0.2f
}; var prediction = predictor.Predict(Setosa);
Console.WriteLine($"Cluster: {prediction.PredictedClusterId}");
Console.WriteLine($"Distances: {string.Join(" ", prediction.Distances)}");
Console.WriteLine("Press any key!");
}
}
}

Run,看一下输出:

以上就是通过ML.NET 的KMeans算法,实现聚类。

上面的数据是一个监督学习的样本,同时是一个数值类型的数据,比较好奇的是,能不能对文本数据+值数据进行聚类,下一篇,我们将继续完成文本数据+值数据的聚类分析。

以上,分享给大家。

周国庆

2019/7/14

ML.NET技术研究系列-2聚类算法KMeans的更多相关文章

  1. ML.NET技术研究系列1-入门篇

    近期团队在研究机器学习,希望通过机器学习实现补丁发布评估,系统异常检测.业务场景归纳一下: 收集整理数据(发布相关的异常日志.告警数据),标识出补丁发布情况(成功.失败) 选择一个机器学习的Model ...

  2. Nginx技术研究系列5-动态路由升级版

    前几篇文章我们介绍了Nginx的配置.OpenResty安装配置.基于Redis的动态路由以及Nginx的监控. Nginx-OpenResty安装配置 Nginx配置详解 Nginx技术研究系列1- ...

  3. Azure IoT 技术研究系列2-起步示例之设备注册到Azure IoT Hub

    上篇博文中,我们主要介绍了Azure IoT Hub的基本概念.架构.特性: Azure IoT 技术研究系列1-入门篇 本文中,我们继续深入研究,做一个起步示例程序:模拟设备注册到Azure IoT ...

  4. Azure IoT 技术研究系列3-设备到云、云到设备通信

    上篇博文中我们将模拟设备注册到Azure IoT Hub中:我们得到了设备的唯一标识. Azure IoT 技术研究系列2-设备注册到Azure IoT Hub 本文中我们继续深入研究,设备到云.云到 ...

  5. Azure IoT 技术研究系列4-Azure IoT Hub的配额及缩放级别

    上两篇博文中,我们介绍了将设备注册到Azure IoT Hub,设备到云.云到设备之间的通信: Azure IoT 技术研究系列2-设备注册到Azure IoT Hub Azure IoT 技术研究系 ...

  6. Azure IoT 技术研究系列5-Azure IoT Hub与Event Hub比较

    上篇博文中,我们介绍了Azure IoT Hub的使用配额和缩放级别: Azure IoT 技术研究系列4-Azure IoT Hub的配额及缩放级别 本文中,我们比较一下Azure IoT Hub和 ...

  7. Azure Event Hub 技术研究系列2-发送事件到Event Hub

    上篇博文中,我们介绍了Azure Event Hub的一些基本概念和架构: Azure Event Hub 技术研究系列1-Event Hub入门篇 本篇文章中,我们继续深入研究,了解Azure Ev ...

  8. Azure Event Hub 技术研究系列3-Event Hub接收事件

    上篇博文中,我们通过编程的方式介绍了如何将事件消息发送到Azure Event Hub: Azure Event Hub 技术研究系列2-发送事件到Event Hub 本篇文章中,我们继续:从Even ...

  9. Ngnix技术研究系列2-基于Redis实现动态路由

    上篇博文我们写了个引子: Ngnix技术研究系列1-通过应用场景看Nginx的反向代理 发现了新大陆,OpenResty OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台 ...

随机推荐

  1. Bootstrap 缩略图 警告框

    @{    Layout = null;}<!DOCTYPE html><html><head>    <meta name="viewport&q ...

  2. IOS开发之把 Array 和 Dictionaries 序列化成 JSON 对象

    1 前言通过 NSJSONSerialization 这个类的 dataWithJSONObject:options:error:方法来实现,Array 和 dictionary 序列化成 JSON ...

  3. Qt浮动按钮的实现(使用窗口背景透明、实现只显示浮动按钮的目的)

    Qt浮动按钮的实现 效果如下: 图3 估计很多做Qt有一定经验的朋友会觉得这个效果不难,但是这是一个需求奇葩的实际业务中做出的效果.笔者会想讲下客户的需求和整体框架的矛盾. 整个项目主要是由Qt搭建的 ...

  4. Expression Blend学习二UI布局

    什么是布局? · Panels控件(其实就是容器控件) · 对内部的子控件提供了自动布局功能 · 可以在容器控件内继续添加容器控件(一个复杂的界面往往是多种容器控件嵌套而组成的) · 一些界面器控件也 ...

  5. 微信小程序把玩(六)模块化

    原文:微信小程序把玩(六)模块化 模块化也就是将一些通用的东西抽出来放到一个文件中,通过module.exports去暴露接口.我们在最初新建项目时就有个util.js文件就是被模块化处理时间的 /* ...

  6. Elevate Web Builder for Web Developers(类似于unigui的东西)

    推荐一款pascal 语言的web 开发工具 这几天仔细研究了一款使用Pascal 语言开发web 的工具 具体介绍可以参照这里. 先上几张他开发的页面照.

  7. C# ACCESS 修改表记录提示"UPDATE 语句语法错"问题

    错误的sql 语句如下: sqlStr =  "update tb_userInfo set passWord='" + pw + "' where userName=' ...

  8. delphi中pos和Ansipos函数的区别

    POS和ANSIPOS的主要区别在于,POS参数多用于是一个字符,而ANSIPOS多用于是多个字符: 例如:i:=pos('a','sssssas'); i:=ansipos('abc','sdabc ...

  9. 基于ASP.NET的新闻管理系统(一)

    1. 项目简介 1.1设计内容 (1)可以在首页查看各类新闻,可以点击新闻查看具体内容:可以查看不同类型的新闻,并了解热点新闻,可以在搜索框里输入要查找的内容. (2)在后台界面中,管理员可以修改密码 ...

  10. postman --- 如何在用户登陆和CSRF验证的场景下使用

    一.前提 安装postman和Postman Interceptor postman应用放到桌面: 二.用户登陆 这种场景很简单,只要开启Interceptor,然后先请求登陆地址,再继续请求其他地址 ...