使用ML.NET预测纽约出租车费

有了上一篇《.NET Core玩转机器学习》打基础,这一次我们以纽约出租车费的预测做为新的场景案例,来体验一下回归模型。

场景概述


我们的目标是预测纽约的出租车费,乍一看似乎仅仅取决于行程的距离和时长,然而纽约的出租车供应商对其他因素,如额外的乘客数、信用卡而不是现金支付等,会综合考虑而收取不同数额的费用。纽约市官方给出了一份样本数据。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

 

确定策略


为了能够预测出租车费,我们选择通过机器学习建立一个回归模型。使用官方提供的真实数据进行拟合,在训练模型的过程中确定真正能影响出租车费的决定性特征。在获得模型后,对模型进行评估验证,如果偏差在接受的范围内,就以这个模型来对新的数据进行预测。

 

解决方案


  • 创建项目

    看过上一篇文章的读者,就比较轻车熟路了,推荐使用Visual Studio 2017创建一个.NET Core的控制台应用程序项目,命名为TaxiFarePrediction。使用NuGet包管理工具添加对Microsoft.ML的引用。

    640?wx_fmt=png

    640?wx_fmt=png

  • 准备数据集

    下载训练数据集taxi-fare-train.csv和验证数据集taxi-fare-test.csv,数据集的内容类似为:

vendor_id,rate_code,passenger_count,trip_time_in_secs,trip_distance,payment_type,fare_amount

VTS,1,1,1140,3.75,CRD,15.5

VTS,1,1,480,2.72,CRD,10.0

VTS,1,1,1680,7.8,CSH,26.5

VTS,1,1,600,4.73,CSH,14.5

VTS,1,1,600,2.18,CRD,9.5

...

  • 对字段简单说明一下:

    字段名含义说明
    vendor_id供应商编号特征值
    rate_code比率码特征值
    passenger_count乘客人数特征值
    trip_time_in_secs行程时长特征值
    trip_distance行程距离特征值
    payment_type支付类型特征值
    fare_amount费用目标值

    在项目中添加一个Data目录,将两份数据集复制到该目录下,对文件属性设置“复制到输出目录”。

  • 640?wx_fmt=png
    640?wx_fmt=png

  • 定义数据类型和路径

    首先声明相关的包引用。


using System;

using Microsoft.ML.Models;

using Microsoft.ML.Runtime;

using Microsoft.ML.Runtime.Api;

using Microsoft.ML.Trainers;

using Microsoft.ML.Transforms;

using System.Collections.Generic;

using System.Linq;

using Microsoft.ML;


在Main函数的上方定义一些使用到的常量。

const string DataPath = @".\Data\taxi-fare-test.csv";const string TestDataPath = @".\Data\taxi-fare-train.csv";const string ModelPath = @".\Models\Model.zip";const string ModelDirectory = @".\Models";


接下来定义一些使用到的数据类型,以及和数据集中每一行的位置对应关系。

public class TaxiTrip

{

    [Column(ordinal: "0")]

    public string vendor_id;

    [Column(ordinal: "1")]

    public string rate_code;

    [Column(ordinal: "2")]

    public float passenger_count;

    [Column(ordinal: "3")]

    public float trip_time_in_secs;

    [Column(ordinal: "4")]

    public float trip_distance;

    [Column(ordinal: "5")]

    public string payment_type;

    [Column(ordinal: "6")]

    public float fare_amount;

}


public class TaxiTripFarePrediction

{

    [ColumnName("Score")]

    public float fare_amount;

}


static class TestTrips

{

    internal static readonly TaxiTrip Trip1 = new TaxiTrip

    {

        vendor_id = "VTS",

        rate_code = "1",

        passenger_count = 1,

        trip_distance = 10.33f,

        payment_type = "CSH",

        fare_amount = 0 // predict it. actual = 29.5

    };

}

创建处理过程

创建一个Train方法,定义对数据集的处理过程,随后声明一个模型接收训练后的结果,在返回前把模型保存到指定的位置,以便以后直接取出来使用不需要再重新训练。

public static async Task<PredictionModel<TaxiTrip, TaxiTripFarePrediction>> Train()

{

    var pipeline = new LearningPipeline();


    pipeline.Add(new TextLoader<TaxiTrip>(DataPath, useHeader: true, separator: ","));

    pipeline.Add(new ColumnCopier(("fare_amount", "Label")));

    pipeline.Add(new CategoricalOneHotVectorizer("vendor_id",

                                        "rate_code",

                                        "payment_type"));

    pipeline.Add(new ColumnConcatenator("Features",

                                        "vendor_id",

                                        "rate_code",

                                        "passenger_count",

                                        "trip_distance",

                                        "payment_type"));

    pipeline.Add(new FastTreeRegressor());

    PredictionModel<TaxiTrip, TaxiTripFarePrediction> model = pipeline.Train<TaxiTrip, TaxiTripFarePrediction>();

    if (!Directory.Exists(ModelDirectory))

    {

        Directory.CreateDirectory(ModelDirectory);

    }

    await model.WriteAsync(ModelPath);

    return model;

}

评估验证模型

创建一个Evaluate方法,对训练后的模型进行验证评估。

public static void Evaluate(PredictionModel<TaxiTrip, TaxiTripFarePrediction> model)

{

    var testData = new TextLoader<TaxiTrip>(TestDataPath, useHeader: true, separator: ",");

    var evaluator = new RegressionEvaluator();

    RegressionMetrics metrics = evaluator.Evaluate(model, testData);

    // Rms should be around 2.795276

    Console.WriteLine("Rms=" + metrics.Rms);

    Console.WriteLine("RSquared = " + metrics.RSquared);

}

预测新数据

定义一个被用于预测的新数据,对于各个特征进行恰当地赋值。

static class TestTrips

{

    internal static readonly TaxiTrip Trip1 = new TaxiTrip

    {

        vendor_id = "VTS",

        rate_code = "1",

        passenger_count = 1,

        trip_distance = 10.33f,

        payment_type = "CSH",

        fare_amount = 0 // predict it. actual = 29.5

    };

}

  • 预测的方法很简单,prediction即预测的结果,从中打印出预测的费用和真实费用。

    var prediction = model.Predict(TestTrips.Trip1);Console.WriteLine("Predicted fare: {0}, actual fare: 29.5", prediction.fare_amount);

     

  • 运行结果

    640?wx_fmt=png

到此我们完成了所有的步骤,关于这些代码的详细说明,可以参看《Tutorial: Use ML.NET to Predict New York Taxi Fares (Regression)》,只是要注意该文中的部分代码有误,由于使用到了C# 7.1的语法特性,本文的代码是经过了修正的。完整的代码如下:

using System;

using Microsoft.ML.Models;

using Microsoft.ML.Runtime;

using Microsoft.ML.Runtime.Api;

using Microsoft.ML.Trainers;

using Microsoft.ML.Transforms;

using System.Collections.Generic;

using System.Linq;

using Microsoft.ML;

using System.Threading.Tasks;

using System.IO;


namespace TaxiFarePrediction

{

    class Program

    {

        const string DataPath = @".\Data\taxi-fare-test.csv";

        const string TestDataPath = @".\Data\taxi-fare-train.csv";

        const string ModelPath = @".\Models\Model.zip";

        const string ModelDirectory = @".\Models";


        public class TaxiTrip

        {

            [Column(ordinal: "0")]

            public string vendor_id;

            [Column(ordinal: "1")]

            public string rate_code;

            [Column(ordinal: "2")]

            public float passenger_count;

            [Column(ordinal: "3")]

            public float trip_time_in_secs;

            [Column(ordinal: "4")]

            public float trip_distance;

            [Column(ordinal: "5")]

            public string payment_type;

            [Column(ordinal: "6")]

            public float fare_amount;

        }


        public class TaxiTripFarePrediction

        {

            [ColumnName("Score")]

            public float fare_amount;

        }


        static class TestTrips

        {

            internal static readonly TaxiTrip Trip1 = new TaxiTrip

            {

                vendor_id = "VTS",

                rate_code = "1",

                passenger_count = 1,

                trip_distance = 10.33f,

                payment_type = "CSH",

                fare_amount = 0 // predict it. actual = 29.5

            };

        }


        public static async Task<PredictionModel<TaxiTrip, TaxiTripFarePrediction>> Train()

        {

            var pipeline = new LearningPipeline();


            pipeline.Add(new TextLoader<TaxiTrip>(DataPath, useHeader: true, separator: ","));

            pipeline.Add(new ColumnCopier(("fare_amount", "Label")));

            pipeline.Add(new CategoricalOneHotVectorizer("vendor_id",

                                              "rate_code",

                                              "payment_type"));

            pipeline.Add(new ColumnConcatenator("Features",

                                                "vendor_id",

                                                "rate_code",

                                                "passenger_count",

                                                "trip_distance",

                                                "payment_type"));

            pipeline.Add(new FastTreeRegressor());

            PredictionModel<TaxiTrip, TaxiTripFarePrediction> model = pipeline.Train<TaxiTrip, TaxiTripFarePrediction>();

            if (!Directory.Exists(ModelDirectory))

            {

                Directory.CreateDirectory(ModelDirectory);

            }

            await model.WriteAsync(ModelPath);

            return model;

        }


        public static void Evaluate(PredictionModel<TaxiTrip, TaxiTripFarePrediction> model)

        {

            var testData = new TextLoader<TaxiTrip>(TestDataPath, useHeader: true, separator: ",");

            var evaluator = new RegressionEvaluator();

            RegressionMetrics metrics = evaluator.Evaluate(model, testData);

            // Rms should be around 2.795276

            Console.WriteLine("Rms=" + metrics.Rms);

            Console.WriteLine("RSquared = " + metrics.RSquared);

        }


        static async Task Main(string[] args)

        {

            PredictionModel<TaxiTrip, TaxiTripFarePrediction> model = await Train();

            Evaluate(model);


            var prediction = model.Predict(TestTrips.Trip1);


            Console.WriteLine("Predicted fare: {0}, actual fare: 29.5", prediction.fare_amount);

        }

    }

}

不知不觉我们的ML.NET之旅又向前进了一步,是不是对于使用.NET Core进行机器学习解决现实生活中的问题更有兴趣了?请保持关注吧。

原文地址: http://www.cnblogs.com/BeanHsiang/p/9017618.html 

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/321327.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用ML.NET实现情感分析[新手篇]

在发出《.NET Core玩转机器学习》和《使用ML.NET预测纽约出租车费》两文后&#xff0c;相信读者朋友们即使在不明就里的情况下&#xff0c;也能按照内容顺利跑完代码运行出结果&#xff0c;对使用.NET Core和ML.NET&#xff0c;以及机器学习的效果有了初步感知。得到这些体验后…

潘正磊:再过三五年 AI会变成开发人员的基本概念

在微软Build 2018开发者大会上&#xff0c;微软公司全球开发平台事业部的资深副总裁潘正磊&#xff08;Julia Liuson&#xff09;接受了界面记者在内的采访。潘正磊在微软西雅图总部带领一千多人组成的团队&#xff0c;微软的开发工具&#xff0c;包括Visual Studio&#xff0c…

qMISPlat入门级使用问题解答一

qMISPlat 2.0(业务配置开发平台) 自2018-4-18号正式开源以来&#xff0c;得到了众多.net core爱好者的关注&#xff0c;现将近半个月以来&#xff0c;大家反馈的一些使用配置方面的问题统一作如下解答。如你对qMISPlat不了解&#xff0c;请查看文章qMISPlat产品介绍。一、从码云…

【模拟】游戏(jzoj 1614)

游戏 题目大意&#xff1a; 有一个n*n的棋盘&#xff0c;有一个坐标在x,y的棋子&#xff0c; 1、2号玩家可以将他向左&#xff0c;向下&#xff0c;向左下&#xff08;45∘45^{\circ}45∘&#xff09;移动若干格&#xff0c;假如他们都是AKIOI聪明绝顶的巨佬&#xff0c;请问…

P4593-[TJOI2018]教科书般的亵渎【拉格朗日差值】

正题 题目链接:https://www.luogu.com.cn/problem/P4593 题目大意 场上有若干只怪&#xff0c;最高的为nnn&#xff0c;每个怪血量不同&#xff0c;有mmm个血量不存在。 不停释放亵渎&#xff08;全场打一&#xff0c;如果有怪死亡就再次生效&#xff09;&#xff0c;每次一…

如何创建一个基于 MSBuild Task 的跨平台的 NuGet 工具包

MSBuild 的 Task 为我们扩展项目的编译过程提供了强大的扩展性&#xff0c;它使得我们可以用 C# 语言编写扩展&#xff1b;利用这种扩展性&#xff0c;我们可以为我们的项目定制一部分的编译细节。NuGet 为我们提供了一种自动导入 .props 和 .targets 的方法&#xff0c;同时还…

Platform.Uno介绍

编者语&#xff1a;Xamarin国内很多人说缺乏可用的实例&#xff0c;我在写书过程中在完善一些常用场景的例子&#xff0c;希望帮到大家。Build 2018结束一周了&#xff0c;善友问我要不要谈谈Xamarin的一些变化&#xff0c;但碍于时间有限一直没有付诸行动。想想总得写点什么给…

ASP.NET Core amp; Docker 实战经验分享

一.前言最近一直在研究和实践ASP.NET Core、Docker、持续集成。在ASP.NET Core 和 Dcoker结合下遇到了一些坑&#xff0c;在此记录和分享&#xff0c;希望对大家有一些帮助。二.中间镜像我前面写过一个 《ASP.NET Core & Docker 零基础持续集成 》的教程。里面我们通过持续…

【图论】【最短路】【SPFA】香甜的黄油 Sweet Butter (luogu 1828)

香甜的黄油 Sweet Butter luogu 1828 题目大意&#xff1a; 有n头奶牛&#xff0c;他们在不同的牧场中&#xff0c;他们之间有一些路&#xff0c;现在要让他们去一个地方吃黄油&#xff0c;使他们的总距离最小 题目描述 农夫John发现做出全威斯康辛州最甜的黄油的方法&…

【dfs】简单游戏(jzoj 2121)

简单游戏 题目大意 原本有n个数字&#xff0c;第1,2个相加&#xff0c;第2&#xff0c;3个相加……第n-1,n个相加&#xff0c;由此得出一个长度为n-1的新序列&#xff0c;然后不停重复&#xff0c;最后得出一个t&#xff0c;现在给出一开始的n和t求符合的序列&#xff08;字典…

[翻译] 比较 Node.js,Python,Java,C# 和 Go 的 AWS Lambda 性能

原文: Comparing AWS Lambda performance of Node.js, Python, Java, C# and GoAWS 最近宣布他们支持了 C&#xff03; (Net Core 2.0 版本) 和 Go 语言来实现 Lambda 功能。(译者注: AWS Lambda 是 AWS 推出的 Serverless 功能&#xff0c;请参阅这里或 Serverless 相关资料)做…

【结论】立体井字棋(jzoj 2124)

立体井字棋 题目大意&#xff1a; 在一个nnn的正方体中&#xff0c;由n个格子连成一条直线的方案数&#xff08;多少种可能用n个格子连成一条直线&#xff09; 样例输入 2 样例输出 28 数据范围限制 对于30%的数据&#xff0c; n<10&#xff1b; 对于100%的数据&am…

ASP.NET Core Identity 实战(3)认证过程

如果你没接触过旧版Asp.Net Mvc中的 Authorize 或者 Cookie登陆&#xff0c;那么你一定会疑惑 认证这个名词&#xff0c;这太正式了&#xff0c;这到底代表这什么&#xff1f;获取资源之前得先过两道关卡Authentication & Authorization要想了解Identity中用户登录之后&…

简明 ASP.NET Core 手册

编者&#xff1a;在4月份推送过这篇文章 简明 ASP.NET Core 手册 &#xff0c;今天再次推荐这篇文章&#xff0c;是因为原作者更新到了新版本1.1.0&#xff0c;改动很大&#xff0c;几乎所有章节都有很大程度的调整&#xff0c;这些调整都是根据读者的建议而做&#xff0c;而且…

《你必须掌握的Entity Framework 6.x与Core 2.0》正式出版感想

前言借书正式出版之际&#xff0c;完整回顾下从写博客到写书整个历程&#xff0c;也算是对自己近三年在技术上的一个总结&#xff0c;整个历程可通过三个万万没想到来概括&#xff0c;请耐心阅读。写博、写书完整历程回顾从2013年12月注册博客园账号&#xff0c;注册博客园账号…

Entity Framework Core 2.1带来更好的SQL语句生成方案

微软发布了Entity Framework Core2.1&#xff0c;为EF开发者带来了很多期待已久的特性。EF Core 2.1增加了对SQL GROUP BY的支持&#xff0c;支持延迟加载和数据种子等。EF Core 2.1的第一个重要新增特性是将GroupBy操作符翻译成包含GROUP BY子句的SQL。缺乏这种支持被认为是EF…

【枚举】数列(jzoj 1507)

数列 题目大意&#xff1a;给出一个等差数列的初始值和差值还有一个等比数列的处值和比值&#xff0c;问不大于n的数中&#xff0c;问这两个序列中&#xff0c;有多少个数小于n&#xff08;只要在一个序列中就行了&#xff0c;在两个序列中只记一次&#xff09; 样例输入 1 …

【模拟】蚂蚁(jzoj 1508)

蚂蚁 题目大意&#xff1a; 有n只蚂蚁&#xff0c;他们各往一个方向走&#xff08;上北&#xff0c;下南&#xff0c;左西和有东四个方向&#xff09;&#xff0c;他们如果撞到一起就会直接消失&#xff0c;每个单位时间走一格&#xff0c;但有一种情况&#xff1a;两只蚂蚁相…

【结论】单元格(jzoj 1509)

单元格 题目大意&#xff1a; 在一个RC的矩形中选三个点&#xff0c;使他们行列各不同&#xff0c;定义“费用”为&#xff0c;这三个点之间的行列的差值的和&#xff08;1,2和3,4费用是差值是&#xff08;3-1&#xff09;&#xff08;4-2&#xff09;224&#xff09;&#x…

【DP】剪草(jzoj 1510)

剪草 题目大意&#xff1a; 有n棵小草&#xff0c;B某看它们很不顺眼&#xff0c;想让他们的高度总和不大于H&#xff0c;它们一开始各有一个高度&#xff0c;然后它们各有一个固定的生长值&#xff0c;B某每个单位时间可以将一棵草减掉&#xff08;让他的高度变为0&#xff…