使用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,一经查实,立即删除!

相关文章

codeforces 932D Tree 倍增法+二分搜索

题面叙述 题目给出两种操作&#xff1a; 操作1是将一个权重为W的点加到树的某个节点下。 操作2是询问一个从R开始的序列的最长可能长度。 其中这个序列要这样找&#xff1a;从R开始&#xff0c;沿着祖先方向往上找&#xff0c;凡是权重大于等于当前序列最后一个点的要被选上…

P4430-小猴打架【perfer序列】

正题 题目链接:https://www.luogu.com.cn/problem/P4430 题目大意 nnn个点&#xff0c;每次不同联通块之间连边直到成为一颗树&#xff0c;求连边方式 解题思路 根据perferperferperfer序列&#xff0c;可以将一颗无根树变为一个长度n−2n-2n−2的序列&#xff0c;所以数量是…

【DP】小明在边塞(jzoj 2147)

小明在边塞 题目大意&#xff1a; 小明在&#xff08;1,1&#xff09;&#xff0c;他要去到&#xff08;n,m&#xff09;&#xff0c;当此点为1时&#xff0c;他的体力值-1&#xff0c;当此点为2时&#xff0c;他的体力值1&#xff0c;他只会向下或向右走&#xff08;就是往终…

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

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

codeforces 932E Team Work 高等数学求导、dp

题解 这是一道纯粹的数学求导题目。 首先我们先写出要求的公式。 ans∑r1nCnrrkans \sum_{r1}^{n} C_n^{r}r^kans∑r1n​Cnr​rk 乍一看&#xff0c;雾草好吓人&#xff0c;但是学过高等数学且稍有常识的人&#xff08;不是我&#xff09;可以看出&#xff0c;这个可以由某个…

【背包】小明逛超市(jzoj 2148)

小明逛超市 题目大意&#xff1a; 有一个大小为n的背包&#xff0c;和m件物品&#xff0c;每件物品都有自己的价格和价值还有个数&#xff0c;当个数为0时则为无限件&#xff0c;为1实则为1件&#xff0c;求最大的价值 样例输入 4 5 5 3 0 5 3 1 4 4 0 2 3 0 3 2 1 样…

P4093-[HEOI2016/TJOI2016]序列【CDQ分治,树状数组】

正题 题目链接:https://www.luogu.com.cn/problem/P4093 题目大意 nnn个数字&#xff0c;每次有一个数字可能和原序列不同&#xff0c;但最多只有一个不同。 求所有情况下都满足的最长不降子序列 解题思路 定义maximax_imaxi​表示位置iii的最大数&#xff0c;minimin_imini…

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

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

codeforces 938D Buy a Ticket 有初值的Dijkstra、有趣的题目

题意 给出一些城市电影票的价格&#xff0c;以及城市之间交通的路费&#xff0c;询问每一个城市怎样才能花最少的钱看到电影&#xff08;看完电影还要再回来&#xff09;。 题解 这是一道不太难但是挺有趣的题目。 我们这样想&#xff0c;每个城市只需要查看票价比他更便宜的城…

P2480-[SDOI2010]古代猪文【中国剩余定理,Lucas定理】

大早上起来写题有助于醒脑&#xff08;其实是昨晚没睡好/kk 正题 题目链接:https://www.luogu.com.cn/problem/P2480 题目大意 给出nnn和ggg&#xff0c;求g∑d∣nCnd%999911659g^{\sum_{d|n}C_{n}^d}\% 999911659g∑d∣n​Cnd​%999911659 解题思路 因为999911659999911659…

qMISPlat入门级使用问题解答一

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

【DP】小明游天界(zjoj 2149)

小明游天界 题目大意&#xff1a; 有 m个单位时间&#xff0c;让你从1走到n&#xff08;不能早到&#xff0c;不能晚到&#xff09;&#xff0c;要使经过的城市最多&#xff0c;若无法用m个单位时间到达n就输出-1 样例输入 5 12 4 1 2 5 1 4 3 4 2 4 2 5 5 样例输出 …

codeforces 935E Fafa and Ancient Mathematics 语法树、动态规划

题解 一道很有意思的题目&#xff0c;同时把动态规划和语法树结合起来&#xff0c;很有新意&#xff0c;思路我是想出来了&#xff0c;但是我的写法较为麻烦&#xff0c;从别人的submission中找了一个写起来简介的代码分享给大家。 看到表达式的形式&#xff0c;我们可以想到使…

P1429-平面最近点对(加强版)【分治】

正题 题目链接:https://www.luogu.com.cn/problem/P1429 题目大意 平面上nnn个点&#xff0c;求最近点对 解题思路 考虑分治求最近点对&#xff0c;首先将平行于yyy轴将平面穿过xxx左边的中位数分割成两半&#xff0c;现在最近点对有三种可能&#xff0c; 在分割线左边在分…

夏季(8 ~9)月 在深圳举办线下dotnet 大会 调查

随着微软 Build 2018的落幕&#xff0c;微软为.NET Core的应用规划了七大场景&#xff1a;计划今年夏季&#xff08;8 ~9&#xff09;月 在深圳举办线下dotnet 大会 &#xff0c;特此向大家做个调查。请大家抽出5分钟做下投票&#xff1a;顺便送大家一个福利&#xff1a;.NET社…

2019.01.22【NOIP普及组】模拟赛C组总结

总结 这次模拟赛拿到了10010010060360的分数 第1,2题不怎么难&#xff0c;快速解决&#xff0c;第3题看到之后马上想到了混合背包&#xff0c;打了大概半小时解决了&#xff0c;最后一道题想来想去&#xff0c;想了一堆没用的东西&#xff0c;最后打了一个垃圾DP拿了60分&…

codeforces 938E MaxHistory 组合数学

题意 给出一个长为n的序列&#xff0c;对于这个序列的任意一个排列&#xff0c;求∑fa\sum f_a∑fa​的值。 题解 我们枚举每一个aia_iai​然后&#xff0c;计算aia_iai​出现了多少次&#xff0c;然后把ai∗numa_i*numai​∗num加入到ans里面。 考虑aia_iai​什么时候出现。 a…

.NET 图形化开源爬虫Hawk 3发布

超级图形化爬虫Hawk已经发布两年半时间了&#xff0c;2015年升级到第二版&#xff0c;收到上千条用户反馈(tucao)&#xff0c;100多个红包&#xff0c;总共666块五毛~一直想攒着这笔钱&#xff0c;去北境之王天通苑的龙德商场买最心爱的阿迪王&#xff01;啥&#xff0c;你不知…

P4027-[NOI2007]货币兑换【斜率优化dp,CDQ分治】

正题 题目链接:https://www.luogu.com.cn/problem/P4027 题目大意 nnn天开始时有SSS元钱&#xff0c;每天AAA种股票价格为aia_iai​,BBB种价格为bib_ibi​。然后出售必须AAA和BBB出售相同比例&#xff0c;买入时AAA和BBB必须按照rir_iri​的比例买入。 求最后的钱最多是多少 …

【栈】【字符】匹配(jzoj 1612)

匹配 题目大意&#xff1a; 给你一个长度为n的字符串&#xff08;有多组数据&#xff09;&#xff0c;中间有小写字母&#xff08;没用的东西&#xff09;和大写字母&#xff0c;A-M是左括号&#xff0c;与之相对的是右括号Z-N&#xff08;之所以说是Z-N而不是N-Z是因为只有Z…