zoukankan      html  css  js  c++  java
  • ML.NET机器学习、API容器化与Azure DevOps实践(二):案例

    在上文中,我简单地介绍了机器学习以及ML.NET的相关知识,从本讲开始,我会基于一个简单的案例:学生成绩预测,来介绍使用ML.NET进行机器学习以及API部署的基本过程。

    学生成绩预测案例

    本案例的数据来源为加州大学尔湾分校的机器学习公开样本数据集,数据介绍页面和下载地址为:https://archive.ics.uci.edu/ml/datasets/Student+Performance。该数据集包含了来自两所学校的学生的问卷调查结果,以及每位学生的综合成绩。数据集为CSV格式,每个字段的含义在官网上都有详细介绍,因此,在这里就不再赘述了。

    确定问题类型

    我们的任务很简单,就是基于这套已有的学生问卷调查结果以及综合成绩,进行机器学习模型训练,然后,再根据一套给定的学生情况信息,来预测该名学生的综合成绩。不难发现,我们需要使用监督学习中的回归算法来进行模型训练,因为我们需要得到一个连续的预测值,而不是离散的二元或者多元值。在确定了我们的任务之后,就可以对得到的数据集进行一些预处理,以便机器学习的过程能够顺利进行。

    数据预处理与数据分析

    在得到训练数据集之后,通常不能直接拿来进行机器学习,需要对数据进行一些处理。数据预处理任务大致有:
    • 数据格式规整化:对每一列的数据进行类型和单位统一,比如,“浓度”字段有些行使用的是ug/mL,有些行使用的是g/L,需要对单位进行统一,并将“浓度”字段的值转换为数值类型,以便进行统计
    • 特殊值处理:有些样本数据的取值比较异常,超出正常范围很多,对于这样的数据,可以直接丢弃,也可以通过一些统计学算法对其进行修正
    • 空值、无效值处理:有些样本数据的取值为空(或者对于数值型的数据,取值为0,并且不合理),对于这样的数据,也需要进行修正或者舍弃
    • 数据一致性校验:对数据一致性进行校验
    • 识别特征属性与目标属性:分析训练数据中,哪些属性会对预测目标造成影响,哪些属性不会影响预测结果
    例如,基于本案例中的学生问卷调查结果,我们可以看到,有些学生的综合成绩为0,在本案例中,我们可以选择舍弃这些数据: image 再比如,通过下面的热图我们可以了解到,平时学习时间相对较长,外出时间较短,并且有意向继续深造的学生,综合成绩也会相对越好。因此,学习时间、外出时间以及是否有意向继续深造,都有可能是影响综合成绩的因素。在进行模型训练时,就有可能需要将这些因素考虑进去。 image 在实际应用中,数据对于机器学习而言尤为重要,数据清洗的任务相当繁重。据我所知,某国际知名制药公司正在将人工智能应用在新药研发中,但由于数据清洗任务巨大,根本没有足够的标准化、规整化数据来支持各种机器学习任务,因此,在新药研发领域,人工智能的应用进展缓慢。 回到我们的案例,在完成了数据清洗任务和特征属性、目标属性的识别之后,就可以使用ML.NET进行编程,实现学生学习成绩的预测。

    基于ML.NET的模型训练

    注:本案例代码已开源。地址是:https://github.com/daxnet/mlnet-trainer。 通过上面的分析不难得出,我们的应用场景属于监督学习中的回归(Regression)预测,因此,我们可以选择使用ML.NET中所提供的回归算法,使用样本数据逐一完成模型训练,然后,使用测试数据对每个模型的预测结果进行评估,以选择合适的预测算法。为了对所有ML.NET默认支持的回归算法进行预测评估,在程序中使用如下数据结构来保存这些算法的实例,以便之后进行模型训练的时候,可以逐一对这些算法进行训练和评估:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var trainers = new List<ITrainerEstimator<ISingleFeaturePredictionTransformer<ModelParametersBase<float>>, ModelParametersBase<float>>>()
    {
        mlContext.Regression.Trainers.FastTree(),
        mlContext.Regression.Trainers.FastForest(),
        mlContext.Regression.Trainers.FastTreeTweedie(),
        mlContext.Regression.Trainers.GeneralizedAdditiveModels(),
        mlContext.Regression.Trainers.OnlineGradientDescent(),
        mlContext.Regression.Trainers.PoissonRegression(),
        mlContext.Regression.Trainers.StochasticDualCoordinateAscent()
    };
    首先,我们将原始样本数据分成两份,一份用来训练,另一份用来测试,将两份数据读入ML.NET的DataView,使用训练数据集进行模型训练,并使用测试数据集对模型进行评估,代码如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    public IEnumerable<KeyValuePair<string, RegressionMetrics>> TrainAndEvaluate(IDataView trainingDataView, IDataView testDataView)
    {
        var metrics = new Dictionary<string, RegressionMetrics>();
        foreach(var trainer in this.trainers)
        {
            var pipeline = mlContext.Transforms.CopyColumns(inputColumnName: "G3", outputColumnName: "Label")
                .Append(mlContext.Transforms.Categorical.OneHotEncoding("School"))
                .Append(mlContext.Transforms.Categorical.OneHotEncoding("Sex"))
                .Append(mlContext.Transforms.Categorical.OneHotEncoding("Age"))
                .Append(mlContext.Transforms.Categorical.OneHotEncoding("Famsize"))
                .Append(mlContext.Transforms.Categorical.OneHotEncoding("Guardian"))
                .Append(mlContext.Transforms.Categorical.OneHotEncoding("Traveltime"))
                .Append(mlContext.Transforms.Categorical.OneHotEncoding("Studytime"))
                .Append(mlContext.Transforms.Categorical.OneHotEncoding("Failures"))
                .Append(mlContext.Transforms.Categorical.OneHotEncoding("Paid"))
                .Append(mlContext.Transforms.Categorical.OneHotEncoding("Higher"))
                .Append(mlContext.Transforms.Categorical.OneHotEncoding("Famrel"))
                .Append(mlContext.Transforms.Categorical.OneHotEncoding("Absences"))
                .Append(mlContext.Transforms.Concatenate("Features",
                    "School",
                    "Sex",
                    "Age",
                    "Famsize",
                    "Guardian",
                    "Traveltime",
                    "Studytime",
                    "Failures",
                    "Paid",
                    "Higher",
                    "Famrel",
                    "Absences"))
                .AppendCacheCheckpoint(mlContext)
                .Append(trainer);
     
            var trainedModel = pipeline.Fit(trainingDataView);
            trainedModels.Add(trainer.GetType().Name, trainedModel);
     
            var predictionModel = trainedModel.Transform(testDataView);
            var regMetrics = mlContext.Regression.Evaluate(predictionModel);
            metrics.Add(trainer.GetType().Name, regMetrics);
        }
     
        return metrics;
    }
    上面代码中所出现的列名(比如School、Sex、Age等)均来自于学生问卷调查原始数据,此处并没有包含原始数据中的所有字段,因为仅有上述这些字段会对综合成绩产生影响,所以并不需要将所有字段列出。接下来,就是针对各个算法的评估结果,找出合适的算法,然后将模型保存下来以便后续使用:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // 基于训练数据集进行训练,并基于测试数据集进行评估,然后输出评估结果
    var regressionMetrics = session.TrainAndEvaluate(trainingDataView, testingDataView);
    foreach (var item in regressionMetrics)
    {
        LearningSession.OutputRegressionMetrics(item.Key, item.Value);
    }
     
    // 找到RMS最小的算法,作为最优算法
    var winnerAlgorithmName = regressionMetrics.OrderBy(x => x.Value.Rms).First().Key;
    Console.WriteLine($"最优算法为:{winnerAlgorithmName}");
    Console.WriteLine();
    var winnerModel = session.GetTrainedModel(winnerAlgorithmName);
    using (var fileStream = new FileStream(ModelFileName, FileMode.Create, FileAccess.Write))
    {
        mlContext.Model.Save(winnerModel, fileStream);
    }
    此处,使用Root Mean Squared Error的评估值作为参考,得出Rms取值最小的回归算法作为最优算法。保存的模型为一个ZIP文件,在后续的API构建部分,会使用这个ZIP文件保存的训练模型,来构建RESTful API。上述代码就不详细分析了,Github上有完整的源代码。

    总结

    本文简要介绍了基于学生成绩预测的机器学习案例,并介绍了数据分析与清洗工作的一些思路,之后,大致介绍了一下基于ML.NET进行模型训练、算法评估和模型保存的过程。在下文中,我会介绍如何基于产生的模型,构建RESTful API。
  • 相关阅读:
    腾讯2014年实习生招聘笔试面试经历
    Unity MVC框架 StrangeIoC
    Android入门第八篇之GridView(九宫图)
    拓扑排序
    C:打印菱形(自己的方法)
    JSP中Session的使用
    继承Application实现Android数据共享
    使用Java高速实现进度条
    首次启动优美新手指引tip
    递归算法
  • 原文地址:https://www.cnblogs.com/daxnet/p/12941764.html
Copyright © 2011-2022 走看看