专栏首页微卡智享C#开源跨平台机器学习框架ML.NET----结合SqlSugar进行多类分类

C#开源跨平台机器学习框架ML.NET----结合SqlSugar进行多类分类

前一篇文章《C#开源跨平台机器学习框架ML.NET----二元分类情绪分析》我们做了ML.NET中二元分类任务的一个小Demo,今天我们来试一下多类分类的Demo。

说明

由于前面我们刚刚学习了SqlSugar的框架,检验学习效果的其中一个方法就是输出,所以这次我们的多类分类里面就把训练数据改为数据库中的数据。

视频演示

实现目标

我们数据库中存在商品信息(tbSpXinXi)和品类信息(tbSpPLXinXi)两个表,商品信息中有一个品类编码(stype)的字段,通过对商品信息的对应的品类码进行训练,实现我们输一个商品名称后系统自动预测出输入的商品属于什么品类的效果。

数据源

品类信息表

上面红框中我们只用到三位数级别的,商品信息中因为是5位的最小级别,我们这里只取到三位对应

商品信息表

商品信息表中字段较多,我们只查询出编码incode,品名fname和品类stype三个字段使用

创建项目

我们用VS2017创建了一个名称为MLSqlSugar的项目,在Nuget安装包中安装上Microsoft.ML和SqlSugar。

SqlSugar

在sqlsugar文件夹下,我们建了一个DBConnect的类,另一个是SqlSugar我们说过的二级缓存的类,详细可以看我以前的文章

窗体布局

  • 窗体布局中我们加入一个ToolStrip里面写了多级分类,主要是以后的分类也在这个Demo中加入,所以用的这个
  • 主界面上加入一个输入文本框,一个按钮和下部的显示文本框

定义类

Goods类

定义的Goods类,对应的就是我们的商品信息类里面就是incode,fname,stype三项,分别是编码,品名和品类码

ResGoods类

ResGoods类为我们预测后的返回类,其中stype就是预测后的结果,Probability为概率,Score为得到的分数。

多类分类实现

流程

进行多类分析的实现顺序

  1. 从数据库获取训练数据
  2. 训练数据并将训练模型存入本地
  3. 输入要预测的数据
  4. 加载训练模型进行数据预测

01

创建训练模型

点击初始化数据按钮

上面是点击初始化数据按钮,实现在提取数据及训练数据并保存到本地

训练

采集数据库数据

获取数据

从数据库中获取商品信息并存入List<Good>集合中,我们把品类stype只取到前三位,通过Order by newid()全部打乱顺序再输出,后面有个分页为取了1200条,这里最后我们说原因

训练

训练并保存数据模型

1

2

3

4

5

02

预测数据

按钮事件

加载模型并预测数据

MLMultiApi代码

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.ML;

namespace MLSqlSugar.Multiclass
{
    /// <summary>
    /// 多类分类训练API
    /// </summary>
    public class MLMultiApi
    {
        //训练数据存档位置
        private string _modelpath = Path.Combine(
            Environment.CurrentDirectory, "stypemodel.zip");
        //定义ML的基本参数
        private MLContext _ml;
        private DataOperationsCatalog.TrainTestData _dataView;
        private IDataView _tranDataView;
        private ITransformer _trainedModel, _testModel;
        private PredictionEngine<Goods, ResGoods> _predEngine;

        /// <summary>
        /// 初始化数据
        /// </summary>
        /// <param name="list"></param>
        public void InitData(IEnumerable<Goods> list)
        {
            //加载数据
            LoadData(list);
            //训练数据
            var pipe = TrainData();
            BuildAndTrainModel(_tranDataView, pipe);
            //测试并保存训练数据
            EvaluateAndSaveModel();
        }

        /// <summary>
        /// 加载数据
        /// </summary>
        /// <param name="list"></param>
        private void LoadData(IEnumerable<Goods> list)
        {
            _ml = new MLContext(0);
            //加载数据
            _tranDataView = _ml.Data.LoadFromEnumerable(list);
            //拆分数据集进行模拟训练和测试
            _dataView = _ml.Data.TrainTestSplit(_tranDataView, 0.2);
        }

        /// <summary>
        /// 训练数据
        /// </summary>
        /// <returns></returns>
        private IEstimator<ITransformer> TrainData()
        {
            //将stype转换为数字键类型Label(分类算法所接受的格式)
            //并将其添加为新的数据集列
            var pipeline = _ml.Transforms.Conversion
                .MapValueToKey(inputColumnName: "stype"
                    , outputColumnName: "Label")
            //将fname转换为名为fnameFeaturized的值的数字向量,
            //并将特征化附加到管道
            .Append(_ml.Transforms.Text
                    .FeaturizeText(inputColumnName: "fname"
                        , outputColumnName: "fnameFeaturized"))
                //                .Append(_ml.Transforms.Text
                //                .FeaturizeText(inputColumnName: "incode"
                //                    , outputColumnName: "incodeFeaturized"))
                //Concatenate() 方法将所有特征合并到“特征”列 。
                //默认情况下,学习算法仅处理“特征”列的特征 
                .Append(_ml.Transforms.Concatenate(
                    "Features", "fnameFeaturized"));

            return pipeline;
        }

        /// <summary>
        /// 训练数据
        /// </summary>
        /// <param name="data"></param>
        /// <param name="pipeline"></param>
        /// <returns></returns>
        private IEstimator<ITransformer> BuildAndTrainModel(
            IDataView data, IEstimator<ITransformer> pipeline)
        {
            //SdcaMaximumEntropy 即多类分类训练算法
            var trainingPipeline = pipeline.Append(_ml.MulticlassClassification
                    .Trainers.SdcaMaximumEntropy("Label", "Features"))
                .Append(_ml.Transforms.Conversion.MapKeyToValue("PredictedLabel"));
            //定型模型
            _trainedModel = trainingPipeline.Fit(data);
            //定义训练的模型进行预测
            _predEngine = _ml.Model.CreatePredictionEngine
                <Goods, ResGoods>(_trainedModel);

            Goods good=new Goods();
            good.incode = "00090";
            good.fname = "神行鞋垫";

            var prediction = _predEngine.Predict(good);
            Console.WriteLine("stype:" + prediction.stype + " percent:"+ prediction.Percent + " score:"+ prediction.Score[0] + "," + prediction.Score[1]);

            return trainingPipeline;
        }

        /// <summary>
        /// 评估模型
        /// </summary>
        public void EvaluateAndSaveModel()
        {
            //用测试数据进行预测
            var testMetrics = _ml.MulticlassClassification
                .Evaluate(_trainedModel.Transform(_dataView.TestSet));
            Console.WriteLine($"Metrics for Multi-class Classification model - Test Data     ");
            Console.WriteLine($"MicroAccuracy:    {testMetrics.MicroAccuracy:0.###}");
            Console.WriteLine($"MacroAccuracy:    {testMetrics.MacroAccuracy:0.###}");
            Console.WriteLine($"LogLoss:          {testMetrics.LogLoss:#.###}");
            Console.WriteLine($"LogLossReduction: {testMetrics.LogLossReduction:#.###}");
            //保存模型
            _ml.Model.Save(_trainedModel, _dataView.TrainSet.Schema, _modelpath);
        }

        /// <summary>
        /// 初始化并加载保存的模型
        /// </summary>
        public void InitFinalModel()
        {
            _ml = new MLContext(0);
            _testModel = _ml.Model.Load(_modelpath, out var modelInputSchema);
        }

        /// <summary>
        /// 进行预测
        /// </summary>
        /// <param name="good"></param>
        /// <returns></returns>
        public ResGoods Predict(Goods good)
        {
            _predEngine = _ml.Model.CreatePredictionEngine
                <Goods, ResGoods>(_testModel);

            return _predEngine.Predict(good);
        }
    }
}

运行效果

划重点

多类分类做的时候遇到的几个问题

上图中我们获取数据训练时分页数据用的是1200条,我这里试过,只要写到1300或再大的,就直接没有训练成功,怀疑过是有个临界点超过后需要训练时间非常长?所以花了9个半小时晚上训练20000条还是没有结果,这里有知道什么原因的小伙伴可以留言告诉我,我也非常困惑。

GitHub代码地址

https://github.com/Vaccae/MLSqlSugar.git

-END-

本文分享自微信公众号 - 微卡智享(VaccaeShare),作者:Vaccae

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-09-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • C++ OpenCV模版匹配

    模板匹配(TemplateMatching)就是在一幅图像中寻找和模板图像(template)最相似的区域,该方法原理简单计算速度快,能够应用于目标识别,目标...

    Vaccae
  • 学习|Unity3d的导航实现循环线路移动

    前阵子用Unity3d做的那个模拟收费的动画,主要是模拟了一个项目中的场景,让人看到更直观一些,最主要的目的还是最近在学习Unity3d,直接以实际项目应用的方...

    Vaccae
  • LeetCode|560. 和为K的子数组--C++题解

    本题原本按我最喜欢的暴力破解提交的,结果到最后几个大数据的时候提示超时了,最后也是看了官方的思路,了解了动态规划的思路去解的这个题,所以本篇写了两个实现的方法。...

    Vaccae
  • Java 操作 HBase 教程

    在上一篇文章 HBase 基础入门 中,我们已经介绍了 HBase 的一些基本概念,以及如何安装使用的方法。那么,作为一名 Javaer,自然是希望用 Java...

    美码师
  • D-News | 百度开放自动驾驶训练数据 Google加大AR/VR推广力度

    大数据文摘
  • 大数据技术学习路线

    加米谷大数据
  • 2019精炼的大数据技术学习路线

    近年来大数据BigData、人工智能AI、物联网Iot等行业发展迅猛,很多人都想要从事大数据技术开发工作,但是,请问要怎么做,路线是什么?从哪里开始学?学哪些?...

    用户2292346
  • 分布式深度学习算法产品及在蚂蚁金服中的应用(附33页PDF下载)

    大数据文摘
  • Streaming-大数据的未来

    分享一篇关于实时流式计算的经典文章,这篇文章名为Streaming 101: The world beyond batch

    用户6070864
  • Streaming-大数据的未来

    分享一篇关于实时流式计算的经典文章,这篇文章名为Streaming 101: The world beyond batch

    实时计算

扫码关注云+社区

领取腾讯云代金券