如何将 "Hello ML.NET World" 示例翻译成 F#?
How can I translate the "Hello ML.NET World" example into F#?
我正在尝试将 "Hello ML.NET World" example 从 C# 转换为 F#(下面复制的代码),但我收到有关不兼容类型的 F# 编译器错误。
我看过几篇关于 ML.NET 和 F# 的博文,但它们都使用较旧的 API,其中涉及显式创建 LearningPipeline 对象。据我所知,此 API 已被删除。
C# 中有问题的行是训练管道的行:
var pipeline = mlContext.Transforms.Concatenate("Features", new[] { "Size" })
.Append(mlContext.Regression.Trainers.Sdca(labelColumnName: "Price", maximumNumberOfIterations: 100));
我试过像这样翻译成 F#:
let pipeline (mlContext:MLContext) =
mlContext.Transforms
.Concatenate("Features", [| "Size" |])
.Append(mlContext.Regression.Trainers.Sdca(labelColumnName = "Price", maximumNumberOfIterations = Nullable(100)))
但是,我遇到编译器错误:Type constraint mismatch: The type 'Transforms.ColumnConcatenatingEstimator' is not compatible with the type IEstimator<ITransformer>'
。
我还尝试过将 ColumnConcatenatingEstimator 显式向下转换为 IEstimator:
let pipeline' (mlContext:MLContext) =
let concat = mlContext.Transforms.Concatenate("Features", [| "Size" |])
let scda = mlContext.Regression.Trainers.Sdca(labelColumnName = "Price", maximumNumberOfIterations = Nullable(100))
let concatAsEstimator = concat :> IEstimator<_>
concatAsEstimator.Append(scda)
这稍微改变了编译器错误中的类型。新消息表明 IEstimator<ColumnConcatenatingTransformer>
与 IEstimator<ITransformer>
不兼容。
看来我需要将泛型中的 ColumnConcatenatingTransformer 显式向下转换为 ITransformer,但我不确定如何在 F# 中执行此操作。这可能吗?
作为参考,这里是我尝试改编的来自 Microsoft 的完整 C# 代码:
using System;
using Microsoft.ML;
using Microsoft.ML.Data;
class Program
{
public class HouseData
{
public float Size { get; set; }
public float Price { get; set; }
}
public class Prediction
{
[ColumnName("Score")]
public float Price { get; set; }
}
static void Main(string[] args)
{
MLContext mlContext = new MLContext();
// 1. Import or create training data
HouseData[] houseData = {
new HouseData() { Size = 1.1F, Price = 1.2F },
new HouseData() { Size = 1.9F, Price = 2.3F },
new HouseData() { Size = 2.8F, Price = 3.0F },
new HouseData() { Size = 3.4F, Price = 3.7F } };
IDataView trainingData = mlContext.Data.LoadFromEnumerable(houseData);
// 2. Specify data preparation and model training pipeline
var pipeline = mlContext.Transforms.Concatenate("Features", new[] { "Size" })
.Append(mlContext.Regression.Trainers.Sdca(labelColumnName: "Price", maximumNumberOfIterations: 100));
// 3. Train model
var model = pipeline.Fit(trainingData);
// 4. Make a prediction
var size = new HouseData() { Size = 2.5F };
var price = mlContext.Model.CreatePredictionEngine<HouseData, Prediction>(model).Predict(size);
Console.WriteLine($"Predicted price for size: {size.Size*1000} sq ft= {price.Price*100:C}k");
// Predicted price for size: 2500 sq ft= 1.98k
}
}
(编辑:澄清一下,这与 不是同一个问题。)这是一个不同的代码示例,它使用了更新版本的 ML.NET .该答案中的 Microsoft link 现在似乎也已损坏。
我也遇到过这个问题。试试这个辅助函数:
let append (estimator : IEstimator<'a>) (pipeline : IEstimator<'b>) =
match pipeline with
| :? IEstimator<ITransformer> as p ->
p.Append estimator
| _ -> failwith "The pipeline has to be an instance of IEstimator<ITransformer>."
let pipeline =
mlContext.Transforms.Concatenate("Features",[|"Size"|])
|> append(mlContext.Regression.Trainers.Sdca(labelColumnName = "Price", maximumNumberOfIterations = Nullable(100)))
ML.NET 是用 C# 构建的,因此有时转换为 F# 需要在任何地方添加 Nullable
和 float32
。
这是我去掉 PredictionEngine
的版本,我将 Sdca
作为训练器并使用 EstimatorChain()
附加并创建一个 IEstimator
open System
open Microsoft.ML
open Microsoft.ML.Data
type HouseData =
{
Size : float32
Price : float32
}
let downcastPipeline (x : IEstimator<_>) =
match x with
| :? IEstimator<ITransformer> as y -> y
| _ -> failwith "downcastPipeline: expecting a IEstimator<ITransformer>"
let mlContext = MLContext(Nullable 0)
let houseData =
[|
{ Size = 1.1F; Price = 1.2F }
{ Size = 1.1F; Price = 1.2F }
{ Size = 2.8F; Price = 3.0F }
{ Size = 3.4F; Price = 3.7F }
|] |> mlContext.Data.LoadFromEnumerable
let trainer =
mlContext.Regression.Trainers.Sdca(
labelColumnName= "Label",
featureColumnName = "Features",
maximumNumberOfIterations = Nullable 100
)
let pipeline =
EstimatorChain()
.Append(mlContext.Transforms.Concatenate("Features", "Size"))
.Append(mlContext.Transforms.CopyColumns("Label", "Price"))
.Append(trainer)
|> downcastPipeline
let model = pipeline.Fit houseData
let newSize = [| {Size = 2.5f; Price = 0.f} |]
let prediction =
newSize
|> mlContext.Data.LoadFromEnumerable
|> model.Transform
|> fun x -> x.GetColumn<float32> "Score"
|> Seq.toArray
printfn "Predicted price for size: %.0f sq ft= %.2fk" (newSize.[0].Size * 1000.f) (prediction.[0] * 100.f)
结果
Predicted price for size: 2500 sq ft= 270.69k
Jon Wood 的视频 F# ML.Net 也是开始在 F# 中使用 ML.Net 的好地方。
我正在尝试将 "Hello ML.NET World" example 从 C# 转换为 F#(下面复制的代码),但我收到有关不兼容类型的 F# 编译器错误。
我看过几篇关于 ML.NET 和 F# 的博文,但它们都使用较旧的 API,其中涉及显式创建 LearningPipeline 对象。据我所知,此 API 已被删除。
C# 中有问题的行是训练管道的行:
var pipeline = mlContext.Transforms.Concatenate("Features", new[] { "Size" })
.Append(mlContext.Regression.Trainers.Sdca(labelColumnName: "Price", maximumNumberOfIterations: 100));
我试过像这样翻译成 F#:
let pipeline (mlContext:MLContext) =
mlContext.Transforms
.Concatenate("Features", [| "Size" |])
.Append(mlContext.Regression.Trainers.Sdca(labelColumnName = "Price", maximumNumberOfIterations = Nullable(100)))
但是,我遇到编译器错误:Type constraint mismatch: The type 'Transforms.ColumnConcatenatingEstimator' is not compatible with the type IEstimator<ITransformer>'
。
我还尝试过将 ColumnConcatenatingEstimator 显式向下转换为 IEstimator:
let pipeline' (mlContext:MLContext) =
let concat = mlContext.Transforms.Concatenate("Features", [| "Size" |])
let scda = mlContext.Regression.Trainers.Sdca(labelColumnName = "Price", maximumNumberOfIterations = Nullable(100))
let concatAsEstimator = concat :> IEstimator<_>
concatAsEstimator.Append(scda)
这稍微改变了编译器错误中的类型。新消息表明 IEstimator<ColumnConcatenatingTransformer>
与 IEstimator<ITransformer>
不兼容。
看来我需要将泛型中的 ColumnConcatenatingTransformer 显式向下转换为 ITransformer,但我不确定如何在 F# 中执行此操作。这可能吗?
作为参考,这里是我尝试改编的来自 Microsoft 的完整 C# 代码:
using System;
using Microsoft.ML;
using Microsoft.ML.Data;
class Program
{
public class HouseData
{
public float Size { get; set; }
public float Price { get; set; }
}
public class Prediction
{
[ColumnName("Score")]
public float Price { get; set; }
}
static void Main(string[] args)
{
MLContext mlContext = new MLContext();
// 1. Import or create training data
HouseData[] houseData = {
new HouseData() { Size = 1.1F, Price = 1.2F },
new HouseData() { Size = 1.9F, Price = 2.3F },
new HouseData() { Size = 2.8F, Price = 3.0F },
new HouseData() { Size = 3.4F, Price = 3.7F } };
IDataView trainingData = mlContext.Data.LoadFromEnumerable(houseData);
// 2. Specify data preparation and model training pipeline
var pipeline = mlContext.Transforms.Concatenate("Features", new[] { "Size" })
.Append(mlContext.Regression.Trainers.Sdca(labelColumnName: "Price", maximumNumberOfIterations: 100));
// 3. Train model
var model = pipeline.Fit(trainingData);
// 4. Make a prediction
var size = new HouseData() { Size = 2.5F };
var price = mlContext.Model.CreatePredictionEngine<HouseData, Prediction>(model).Predict(size);
Console.WriteLine($"Predicted price for size: {size.Size*1000} sq ft= {price.Price*100:C}k");
// Predicted price for size: 2500 sq ft= 1.98k
}
}
(编辑:澄清一下,这与
我也遇到过这个问题。试试这个辅助函数:
let append (estimator : IEstimator<'a>) (pipeline : IEstimator<'b>) =
match pipeline with
| :? IEstimator<ITransformer> as p ->
p.Append estimator
| _ -> failwith "The pipeline has to be an instance of IEstimator<ITransformer>."
let pipeline =
mlContext.Transforms.Concatenate("Features",[|"Size"|])
|> append(mlContext.Regression.Trainers.Sdca(labelColumnName = "Price", maximumNumberOfIterations = Nullable(100)))
ML.NET 是用 C# 构建的,因此有时转换为 F# 需要在任何地方添加 Nullable
和 float32
。
这是我去掉 PredictionEngine
的版本,我将 Sdca
作为训练器并使用 EstimatorChain()
附加并创建一个 IEstimator
open System
open Microsoft.ML
open Microsoft.ML.Data
type HouseData =
{
Size : float32
Price : float32
}
let downcastPipeline (x : IEstimator<_>) =
match x with
| :? IEstimator<ITransformer> as y -> y
| _ -> failwith "downcastPipeline: expecting a IEstimator<ITransformer>"
let mlContext = MLContext(Nullable 0)
let houseData =
[|
{ Size = 1.1F; Price = 1.2F }
{ Size = 1.1F; Price = 1.2F }
{ Size = 2.8F; Price = 3.0F }
{ Size = 3.4F; Price = 3.7F }
|] |> mlContext.Data.LoadFromEnumerable
let trainer =
mlContext.Regression.Trainers.Sdca(
labelColumnName= "Label",
featureColumnName = "Features",
maximumNumberOfIterations = Nullable 100
)
let pipeline =
EstimatorChain()
.Append(mlContext.Transforms.Concatenate("Features", "Size"))
.Append(mlContext.Transforms.CopyColumns("Label", "Price"))
.Append(trainer)
|> downcastPipeline
let model = pipeline.Fit houseData
let newSize = [| {Size = 2.5f; Price = 0.f} |]
let prediction =
newSize
|> mlContext.Data.LoadFromEnumerable
|> model.Transform
|> fun x -> x.GetColumn<float32> "Score"
|> Seq.toArray
printfn "Predicted price for size: %.0f sq ft= %.2fk" (newSize.[0].Size * 1000.f) (prediction.[0] * 100.f)
结果
Predicted price for size: 2500 sq ft= 270.69k
Jon Wood 的视频 F# ML.Net 也是开始在 F# 中使用 ML.Net 的好地方。