用于机器学习的.NET交互式笔记本

135 阅读8分钟

几个月前,微软发布了将Jupyter Notebooks整合到Visual Studio Code中。这对我来说是件大事,因为VS Code是我最喜欢的IDE,而且我经常在Jupyter笔记本中进行数据科学实验。 机器学习和数据科学实验,并在Jupyter笔记本中使用Python。这样我就可以利用VS Code的全部功能,并且仍然拥有Jupyter Notebooks的灵活性和交互性(我不确定这是否是真正的词:)。

此外,微软还将.NET交互式集成到这整个画面中。现在,对我来说,似乎是一个游戏规则的改变。虽然 .NET是一个了不起的工具,但当它涉及到快速做事时,特别是当它涉及到执行一些数据科学实验时,它仍然远远落后于Python等语言。在我看来,这正在缩小差距,使用*.NET* 交互式笔记本是使用这种技术的一种令人耳目一新的方式。在这篇文章中,我们探讨的就是这个问题--我们如何以一种新的方式使用各种*.Net*技术。此外,我们还探讨了如何将这些笔记本用于机器学习与 ML.NET.

在这篇文章中,我们将探讨:

1.安装

2.在Jupyter Notebooks中使用.Net Interactive

3.用.NET交互式笔记本进行数据可视化

4.用ML.NET和.NET交互式笔记本进行机器学习

1.安装

要使用*.NET交互式笔记本*,你需要安装 Visual Studio代码.此外,你还需要安装*.NET交互式笔记本*的扩展。

.NET Interactive Notebooks Extension

这些笔记本支持几种语言。C#、F#、PowerShell、JavaScript、HTML、SQL等。正如你所看到的,这是一个非常广泛的语言范围,从技术上讲,你可以用它们做很多事情。在这篇文章中,我们主要讨论C#ML.NET。

我们在本文中使用的数据是来自 PalmerPenguins数据集.这个数据集最近被介绍为著名的Iris数据集的替代品。它是由Kristen Gorman博士和南极洲LTER的Palmer站创建的。你可以获得这个数据集 这里,或通过Kaggle。

这个数据集基本上由两个数据集组成,每个数据集都包含344只企鹅的数据。就像在Iris数据集中,有3个不同种类的企鹅来自帕尔默群岛的3个岛屿。此外,这些数据集还包含每个物种的culmen尺寸。喙是鸟类喙的上脊。在简化的企鹅数据中, culmen的长度和深度被重新命名为culmen_length_mmculmen_depth_mm两个变量。

2.使用.Net交互式笔记本

.NET交互式笔记本就像Jupyter笔记本一样,只是在其中你可以运行C#、F#等的代码*。它们甚至有相同的扩展名--.ipynb。* 然而,为了运行它们,你需要选择适当的内核,即*.NET交互式内核* 。你可以这样做。

.Net Interactive Notebooks Select Kernel

就像Jupyter笔记本 一样*,.NET交互式笔记本* 将代码与其他丰富的媒体结合起来,如叙述性文本、图像、数学公式等等。从本质上讲,它是一个单一的文件,可以容纳你所需要的所有信息,如对你的项目的完整解释,以及必要的图像和方程式,并带有互动代码,你可以立即运行并看到结果。

笔记本是由单元格和内核组成的。有两种类型的单元格:

  • Markdown单元包含使用Markdown格式的文本。这些单元格包含文本、图像和我们谈到的方程式。这是Jupyter笔记本的 "文档部分"。
  • 一个代码单元包含由内核执行的代码。一旦代码被运行,笔记本就会在产生它的代码单元下面显示输出。

这里是你如何创建一个标记单元。

.NET Interactive Notebooks: Markdown cell

这些单元格可以包含关于你的项目的所有有用的信息。另一方面,代码单元可以针对选定的内核运行。

.NET Interactive Notebooks: Code cell

在开始时以这种类似脚本的方式使用C#,这可能是反直觉的,也是不寻常的。然而,你会发现它非常有用,用于快速检查。正如你所看到的,变量在单元之间是共享的。

3.用.NET交互式笔记本实现数据可视化

好了,现在我们知道如何在*.NET交互式笔记本中运行非常简单的代码让我们看看如何使用这些笔记本进行数据可视化。为了这个目的,我们可以使用 Microsoft SandDance,它是Extension Labs NuGet*包的一部分。

为了做到这一点,我们需要做两件事:下载PalmerPenguins数据集并将penguins_size.csv文件放到根目录下,同时安装Extension LabsNuGet包。要安装任何NuGet包,你需要有一个代码单元,它以关键字*#r* 开头*,* 后面是NuGet包的名称和版本*。*在这种情况下。

#r "nuget:Microsoft.DotNet.Interactive.ExtensionLab,*-*"

一旦你运行了这个,你就可以用usings创建一个单元。

var data = DataFrame.LoadCsv("penguins_size.csv");
data.ExploreWithSandDance().Display();

最后,你可以加载数据并运行Sand Dance。

var data = DataFrame.LoadCsv("penguins_size.csv");
data.ExploreWithSandDance().Display();

总的来说,那输出看起来是这样的,从这一点上,你可以使用各种Sand Dance选项。

.NET Interactive Notebooks: Data Visualization

4.用ML.NET和.NET交互式笔记本进行机器学习

最后,让我们看看如何将 .NET交互式 笔记本ML.NET 一起使用本教程的目标是创建ML.NET机器学习模型,它能够对 PalmerPenguin数据进行分类。这个模型根据其余的数据来预测企鹅的类别。首先,我们需要安装所有必要的 NuGet包。

#r "nuget:Microsoft.Data.Analysis,*-*"
#r "nuget:Microsoft.ML,*-*"
#r "nuget:Microsoft.DotNet.Interactive.ExtensionLab,*-*"

然后我们需要添加使用。

using Microsoft.Data.Analysis;
using Microsoft.ML;
using Microsoft.ML.Data;

using System.IO;
using System.Text;

4.1 数据模型

好了,现在我们可以把ML.NET代码装进去了。为了从数据集中加载数据并将其用于 ML.NET 算法,我们需要实现 对 这些数据进行建模的 类 。因此,我们创建一个单元格,实现两个类。PalmerPenguinDataPricePalmerPenguinPredictions。这些类为输入和输出数据建模。输出是企鹅的类,而其他的数据是输入。

public class PalmerPenguinsData
{
    [LoadColumn(0)]
        public string Label { get; set; }

    [LoadColumn(1)]
    public string Island { get; set; }

    [LoadColumn(2)]
    public float CulmenLength { get; set; }

    [LoadColumn(3)]
    public float CulmenDepth { get; set; }

    [LoadColumn(4)]
    public float FliperLength { get; set; }

    [LoadColumn(5)]
    public float BodyMass { get; set; }

    [LoadColumn(6)]
    public string Sex { get; set; }
}

public class PalmerPenguinsPrediction
{
    [ColumnName("PredictedLabel")]
    public string PredictedLabel { get; set; }
}

Programming Visual

4.2 加载数据

一旦数据模型类创建完毕,我们就可以用它们来加载数据。要做到这一点,我们创建一个新的单元。

var mlContext = new MLContext();

var trainingDataView = mlContext.Data.LoadFromTextFile<PalmerPenguinsData>("penguins_size.csv", hasHeader: true, separatorChar: ',');

var dataSplit = mlContext.Data.TrainTestSplit(trainingDataView, testFraction: 0.3);

在这个单元中,我们所做的不仅仅是数据加载,实际上我们通过创建一个MlContext对象来初始化一个完整的ML.NET 功能。ML.NET 的核心 可以在两个类中找到 ,MLContextDataView. MLContext 类是一个单子类,它的对象提供了对大多数 ML.NET 功能的 访问 ,比如各种机器学习算法,这些算法 在 ML.NET 的背景下 被 称为 训练器

dataSplit 字段包含加载的数据。数据 在这个结构中 被 分割 成训练和测试数据集。我们可以通过以下单元格实际看到这些数据的样子。

var mlContext = new MLContext();

var trainingDataView = mlContext.Data.LoadFromTextFile<PalmerPenguinsData>("penguins_size.csv", hasHeader: true, separatorChar: ',');

var dataSplit = mlContext.Data.TrainTestSplit(trainingDataView, testFraction: 0.3);

.NET Interactive Table

现在,在这里你可以看到*.NET交互式笔记本*的好处。这是在 C# 变量中实际看到数据的一种简单方法。这真是太酷了!

4.3 初始化和训练机器学习ML.NET模型

现在到了重要和有趣的部分。我们要初始化和训练模型。事实上,我们要创建一个完整的训练管道,预先处理数据,训练模型并保存模型。下面是我们如何做的。

var model = mlContext.MulticlassClassification.Trainers.SdcaNonCalibrated(labelColumnName: "Label", featureColumnName: "Features");

var pipeline = mlContext.Transforms.Conversion.MapValueToKey(inputColumnName: nameof(PalmerPenguinsData.Label), outputColumnName: "Label")
                .Append(mlContext.Transforms.Text.FeaturizeText(inputColumnName: "Sex", outputColumnName: "SexFeaturized"))
                .Append(mlContext.Transforms.Text.FeaturizeText(inputColumnName: "Island", outputColumnName: "IslandFeaturized"))
                .Append(mlContext.Transforms.Concatenate("Features",
                                               "IslandFeaturized",
                                               nameof(PalmerPenguinsData.CulmenLength),
                                               nameof(PalmerPenguinsData.CulmenDepth),
                                               nameof(PalmerPenguinsData.BodyMass),
                                               nameof(PalmerPenguinsData.FliperLength),
                                               "SexFeaturized"
                                               ))
               .Append(mlContext.Transforms.NormalizeMinMax("Features", "Features"))
               .Append(model)
               .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));;

var trainedModel = pipeline.Fit(dataSplit.TrainSet);

mlContext.Model.Save(trainedModel, dataSplit.TrainSet.Schema, "model.mdl");

首先,我们创建一个SdcaNonCalibrated 类的对象。这个对象是我们用于这个问题的机器学习算法。本质上是 基于随机双坐标上升法(SDCA) 的 逻辑回归 的一个变体 。该算法可以被扩展,因为它是一种流式训练算法,正如 KDD最佳论文中所描述的

然后我们创建一个训练管道。这个管道首先对数据进行一些预处理,然后利用提到的机器学习模型。然后我们在这个管道上调用Fit方法。这样,我们就启动了训练过程。最后,我们将模型保存到model.mdl文件中。

Programming Visual

4.4 评估模型

为了评估模型,我们使用测试数据的Evaluate 方法。

var testSetTransform = trainedModel.Transform(dataSplit.TestSet);
var metrics = mlContext.MulticlassClassification.Evaluate(testSetTransform);

输出是度量变量,它包含关于我们模型的一些有用信息。例如,我们可以打印出Macro Accuracy。

metrics.MacroAccuracy
0.991869918699187

4.5 使用模型进行预测

下面是我们如何使用保存在文件中的模型,在新的样本上运行预测。

var newSample = new PalmerPenguinsData
                    {
                        Island = "Torgersen",
                        CulmenDepth = 18.7f,
                        CulmenLength = 39.3f,
                        FliperLength = 180,
                        BodyMass = 3700,
                        Sex = "MALE"
                    };


using (var stream = new FileStream("model.mdl", FileMode.Open, FileAccess.Read, FileShare.Read))
{
    var loadedModel = mlContext.Model.Load(stream, out _);
    var predictionEngine = mlContext.Model.CreatePredictionEngine<PalmerPenguinsData, PalmerPenguinsPrediction>(loadedModel);

    var prediction = predictionEngine.Predict(newSample);

    Console.WriteLine($"Prediction: {prediction.PredictedLabel}");
}

结论

在这篇文章中,我们探讨了如何使用*.NET交互式笔记本ML.NET相结合,用.NET* 技术栈进行现代机器学习。