用C#实现简单的线性回归

这篇具有很好参考价值的文章主要介绍了用C#实现简单的线性回归。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

最近注意到了NumSharp,想学习一下,最好的学习方式就是去实践,因此从github上找了一个用python实现的简单线性回归代码,然后基于NumSharp用C#进行了改写。

NumSharp简介

NumSharp(NumPy for C#)是一个在C#中实现的多维数组操作库,它的设计受到了Python中的NumPy库的启发。NumSharp提供了类似于NumPy的数组对象,以及对这些数组进行操作的丰富功能。它是一个开源项目,旨在为C#开发者提供在科学计算、数据分析和机器学习等领域进行高效数组处理的工具。

用C#实现简单的线性回归,C#,ML.NET,c#,线性回归

python代码

用到的python代码来源:llSourcell/linear_regression_live: This is the code for the “How to Do Linear Regression the Right Way” live session by Siraj Raval on Youtube (github.com)

用C#实现简单的线性回归,C#,ML.NET,c#,线性回归

下载到本地之后,如下图所示:

用C#实现简单的线性回归,C#,ML.NET,c#,线性回归

python代码如下所示:

#The optimal values of m and b can be actually calculated with way less effort than doing a linear regression. 
#this is just to demonstrate gradient descent

from numpy import *

# y = mx + b
# m is slope, b is y-intercept
def compute_error_for_line_given_points(b, m, points):
    totalError = 0
    for i in range(0, len(points)):
        x = points[i, 0]
        y = points[i, 1]
        totalError += (y - (m * x + b)) ** 2
    return totalError / float(len(points))

def step_gradient(b_current, m_current, points, learningRate):
    b_gradient = 0
    m_gradient = 0
    N = float(len(points))
    for i in range(0, len(points)):
        x = points[i, 0]
        y = points[i, 1]
        b_gradient += -(2/N) * (y - ((m_current * x) + b_current))
        m_gradient += -(2/N) * x * (y - ((m_current * x) + b_current))
    new_b = b_current - (learningRate * b_gradient)
    new_m = m_current - (learningRate * m_gradient)
    return [new_b, new_m]

def gradient_descent_runner(points, starting_b, starting_m, learning_rate, num_iterations):
    b = starting_b
    m = starting_m
    for i in range(num_iterations):
        b, m = step_gradient(b, m, array(points), learning_rate)
    return [b, m]

def run():
    points = genfromtxt("data.csv", delimiter=",")
    learning_rate = 0.0001
    initial_b = 0 # initial y-intercept guess
    initial_m = 0 # initial slope guess
    num_iterations = 1000
    print ("Starting gradient descent at b = {0}, m = {1}, error = {2}".format(initial_b, initial_m, compute_error_for_line_given_points(initial_b, initial_m, points)))
    print ("Running...")
    [b, m] = gradient_descent_runner(points, initial_b, initial_m, learning_rate, num_iterations)
    print ("After {0} iterations b = {1}, m = {2}, error = {3}".format(num_iterations, b, m, compute_error_for_line_given_points(b, m, points)))

if __name__ == '__main__':
    run()

用C#进行改写

首先创建一个C#控制台应用,添加NumSharp包:

用C#实现简单的线性回归,C#,ML.NET,c#,线性回归

现在我们开始一步步用C#进行改写。

python代码:

points = genfromtxt("data.csv", delimiter=",")

在NumSharp中没有genfromtxt方法需要自己写一个。

C#代码:

 //创建double类型的列表
 List<double> Array = new List<double>();

 // 指定CSV文件的路径
 string filePath = "你的data.csv路径";

 // 调用ReadCsv方法读取CSV文件数据
 Array = ReadCsv(filePath);

 var array = np.array(Array).reshape(100,2);

static List<double> ReadCsv(string filePath)
{
    List<double> array = new List<double>();
    try
    {
        // 使用File.ReadAllLines读取CSV文件的所有行
        string[] lines = File.ReadAllLines(filePath);             

        // 遍历每一行数据
        foreach (string line in lines)
        {
            // 使用逗号分隔符拆分每一行的数据
            string[] values = line.Split(',');

            // 打印每一行的数据
            foreach (string value in values)
            {
                array.Add(Convert.ToDouble(value));
            }                  
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("发生错误: " + ex.Message);
    }
    return array;
}

python代码:

def compute_error_for_line_given_points(b, m, points):
    totalError = 0
    for i in range(0, len(points)):
        x = points[i, 0]
        y = points[i, 1]
        totalError += (y - (m * x + b)) ** 2
    return totalError / float(len(points))

这是在计算均方误差:

用C#实现简单的线性回归,C#,ML.NET,c#,线性回归

C#代码:

 public static double compute_error_for_line_given_points(double b,double m,NDArray array)
 {
     double totalError = 0;
     for(int i = 0;i < array.shape[0];i++)
     {
         double x = array[i, 0];
         double y = array[i, 1];
         totalError += Math.Pow((y - (m*x+b)),2);
     }
     return totalError / array.shape[0];
 }

python代码:

def gradient_descent_runner(points, starting_b, starting_m, learning_rate, num_iterations):
    b = starting_b
    m = starting_m
    for i in range(num_iterations):
        b, m = step_gradient(b, m, array(points), learning_rate)
    return [b, m]
def step_gradient(b_current, m_current, points, learningRate):
    b_gradient = 0
    m_gradient = 0
    N = float(len(points))
    for i in range(0, len(points)):
        x = points[i, 0]
        y = points[i, 1]
        b_gradient += -(2/N) * (y - ((m_current * x) + b_current))
        m_gradient += -(2/N) * x * (y - ((m_current * x) + b_current))
    new_b = b_current - (learningRate * b_gradient)
    new_m = m_current - (learningRate * m_gradient)
    return [new_b, new_m]

这是在用梯度下降来迭代更新y = mx + b中参数b、m的值。

因为在本例中,误差的大小是通过均方差来体现的,所以均方差就是成本函数(cost function)或者叫损失函数(loss function),我们想要找到一组b、m的值,让误差最小。

成本函数如下:

用C#实现简单的线性回归,C#,ML.NET,c#,线性回归

对θ1求偏导,θ1就相当于y = mx + b中的b:

用C#实现简单的线性回归,C#,ML.NET,c#,线性回归

再对θ2求偏导,θ2就相当于y = mx + b中的m:

用C#实现简单的线性回归,C#,ML.NET,c#,线性回归

使用梯度下降:

用C#实现简单的线性回归,C#,ML.NET,c#,线性回归

θ1与θ2的表示:

用C#实现简单的线性回归,C#,ML.NET,c#,线性回归

α是学习率,首先θ1、θ2先随机设一个值,刚开始梯度变化很大,后面慢慢趋于0,当梯度等于0时,θ1与θ2的值就不会改变了,或者达到我们设置的迭代次数了,就不再继续迭代了。关于原理这方面的解释,可以查看这个链接(Linear Regression in Machine learning - GeeksforGeeks),本文中使用的图片也来自这里。

总之上面的python代码在用梯度下降迭代来找最合适的参数,现在用C#进行改写:

 public static double[] gradient_descent_runner(NDArray array, double starting_b, double starting_m, double learningRate,double num_iterations)
 {
     double[] args = new double[2];
     args[0] = starting_b;
     args[1] = starting_m;

     for(int i = 0 ; i < num_iterations; i++) 
     {
         args = step_gradient(args[0], args[1], array, learningRate);
     }

     return args;
 }
 public static double[] step_gradient(double b_current,double m_current,NDArray array,double learningRate)
 {
     double[] args = new double[2];
     double b_gradient = 0;
     double m_gradient = 0;
     double N = array.shape[0];

     for (int i = 0; i < array.shape[0]; i++)
     {
         double x = array[i, 0];
         double y = array[i, 1];
         b_gradient += -(2 / N) * (y - ((m_current * x) + b_current));
         m_gradient += -(2 / N) * x * (y - ((m_current * x) + b_current));
     }

     double new_b = b_current - (learningRate * b_gradient);
     double new_m = m_current - (learningRate * m_gradient);
     args[0] = new_b;
     args[1] = new_m;

     return args;
 }

用C#改写的全部代码:

using NumSharp;

namespace LinearRegressionDemo
{
    internal class Program
    {    
        static void Main(string[] args)
        {   
            //创建double类型的列表
            List<double> Array = new List<double>();

            // 指定CSV文件的路径
            string filePath = "你的data.csv路径";

            // 调用ReadCsv方法读取CSV文件数据
            Array = ReadCsv(filePath);

            var array = np.array(Array).reshape(100,2);

            double learning_rate = 0.0001;
            double initial_b = 0;
            double initial_m = 0;
            double num_iterations = 1000;

            Console.WriteLine($"Starting gradient descent at b = {initial_b}, m = {initial_m}, error = {compute_error_for_line_given_points(initial_b, initial_m, array)}");
            Console.WriteLine("Running...");
            double[] Args =gradient_descent_runner(array, initial_b, initial_m, learning_rate, num_iterations);
            Console.WriteLine($"After {num_iterations} iterations b = {Args[0]}, m = {Args[1]}, error = {compute_error_for_line_given_points(Args[0], Args[1], array)}");
            Console.ReadLine();

        }

        static List<double> ReadCsv(string filePath)
        {
            List<double> array = new List<double>();
            try
            {
                // 使用File.ReadAllLines读取CSV文件的所有行
                string[] lines = File.ReadAllLines(filePath);             

                // 遍历每一行数据
                foreach (string line in lines)
                {
                    // 使用逗号分隔符拆分每一行的数据
                    string[] values = line.Split(',');

                    // 打印每一行的数据
                    foreach (string value in values)
                    {
                        array.Add(Convert.ToDouble(value));
                    }                  
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("发生错误: " + ex.Message);
            }
            return array;
        }

        public static double compute_error_for_line_given_points(double b,double m,NDArray array)
        {
            double totalError = 0;
            for(int i = 0;i < array.shape[0];i++)
            {
                double x = array[i, 0];
                double y = array[i, 1];
                totalError += Math.Pow((y - (m*x+b)),2);
            }
            return totalError / array.shape[0];
        }

        public static double[] step_gradient(double b_current,double m_current,NDArray array,double learningRate)
        {
            double[] args = new double[2];
            double b_gradient = 0;
            double m_gradient = 0;
            double N = array.shape[0];

            for (int i = 0; i < array.shape[0]; i++)
            {
                double x = array[i, 0];
                double y = array[i, 1];
                b_gradient += -(2 / N) * (y - ((m_current * x) + b_current));
                m_gradient += -(2 / N) * x * (y - ((m_current * x) + b_current));
            }

            double new_b = b_current - (learningRate * b_gradient);
            double new_m = m_current - (learningRate * m_gradient);
            args[0] = new_b;
            args[1] = new_m;

            return args;
        }

        public static double[] gradient_descent_runner(NDArray array, double starting_b, double starting_m, double learningRate,double num_iterations)
        {
            double[] args = new double[2];
            args[0] = starting_b;
            args[1] = starting_m;

            for(int i = 0 ; i < num_iterations; i++) 
            {
                args = step_gradient(args[0], args[1], array, learningRate);
            }

            return args;
        }


    }
}

python代码的运行结果:

用C#实现简单的线性回归,C#,ML.NET,c#,线性回归

C#代码的运行结果:

用C#实现简单的线性回归,C#,ML.NET,c#,线性回归

结果相同,说明改写成功。

总结

本文基于NumSharp用C#改写了一个用python实现的简单线性回归,通过这次实践,可以加深对线性回归原理的理解,也可以练习使用NumSharp。文章来源地址https://www.toymoban.com/news/detail-787103.html

到了这里,关于用C#实现简单的线性回归的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 简单线性回归:预测事物间简单关系的利器

    在数据科学领域,线性回归是一种基本而强大的统计分析方法。它广泛应用于各个领域,从经济学到生物医学研究,从市场营销到城市规划,目的是建立和利用变量之间的简单关系,以便预测未来趋势或做出决策。在本文中,我们将深入探讨简单线性回归的工作原理、应用场

    2024年02月13日
    浏览(52)
  • Python构建简单线性回归模型教程

    本文介绍如何构建简单线性回归模型及计算其准确率,最后介绍如何持久化模型。 线性回归表示发现函数使用线性组合表示输入变量。简单线性回归很容易理解,使用了基本的回归技术,一旦理解了这些基本概念,可以更好地学习其他类型的回归模型。 回归用于发现输入变

    2023年04月21日
    浏览(40)
  • 机器学习简介[01/2]:简单线性回归

    Python 中的机器学习简介:简单线性回归         简单线性回归为机器学习提供了优雅的介绍。它可用于标识自变量和因变量之间的关系。使用梯度下降,可以训练基本模型以拟合一组点以供未来预测。         这是涵盖回归、梯度下降、分类和机器学习的其他基本方

    2024年02月11日
    浏览(40)
  • 简单线性回归评估指标+R Squared

    使得每一个数据集尽可能的小   均方误差 MSE :(平方和取平均值)   均方根误差 RMSE :(平方和取平均值开根号):平均误差值   平均绝对误差 MAE :(绝对值取平均):   RMSEMAE 大的原因 RMSE 会放大误差 所以评估时应尽量让 RMSE 小 -------------R Squared 评估指标 ------------

    2024年02月15日
    浏览(39)
  • 模型应用系实习生-模型训练笔记(更新至线性回归、Ridge回归、Lasso回归、Elastic Net回归、决策树回归、梯度提升树回归和随机森林回归)

    本次训练的变量是一致对应的,训练准备通过后,后续建模都不会有报错的! scikit-learn包以及镜像 必须全部为数字类型且无空值才能进行训练,关于非数据类型需要进行相对处理例如:可以采用独热编码或者label编码进行处理。 本文演示的是pandas 的dataframe数据类型的操作,

    2024年02月06日
    浏览(43)
  • 线性回归(线性拟合)与非线性回归(非线性拟合)原理、推导与算法实现(一)

    关于回归和拟合,从它们的求解过程以及结果来看,两者似乎没有太大差别,事实也的确如此。从本质上说,回归属于数理统计问题,研究解释变量与响应变量之间的关系以及相关性等问题。而拟合是把平面的一系列点,用一条光滑曲线连接起来,并且让更多的点在曲线上或

    2023年04月14日
    浏览(53)
  • 用sklearn实现线性回归和岭回归

    此文为ai创作,今天写文章的时候发现创作助手限时免费,想测试一下,于是就有了这篇文章,看的出来,效果还可以,一行没改。 线性回归 在sklearn中,可以使用线性回归模型做多变量回归。下面是一个示例: 假设我们有以下数据集,其中X是输入特征,y是输出: 我们可以

    2024年02月09日
    浏览(39)
  • 线性回归算法实现

    回归算法是一种有监督算法。 回归算法是一种比较常用的机器学习算法,用来建立“解释”变量(自变量X)和观 测值(因变量Y)之间的关系;从机器学习的角度来讲,用于构建一个算法模型(函 数)来做属性(X)与标签(Y)之间的映射关系,在算法的学习过程中,试图寻找一个 函数使

    2024年02月11日
    浏览(22)
  • 利用python实现多元线性回归

    本文介绍了如何用python进行回归分析 直线回归分析是研究两变量(自变量和因变量)之间的依存关系及其关系的具体方程的形式。分析中所形成的这种关系式称为回归模型,其中以一条直线方程表明的两个变量的依存关系的模型叫一元线性回归模型。 一元线性回归模型研究

    2024年02月11日
    浏览(36)
  • 用Pytorch实现线性回归模型

    前面已经学习过线性模型相关的内容,实现线性模型的过程并没有使用到Pytorch。 这节课主要是利用Pytorch实现线性模型。 学习器训练: 确定模型(函数) 定义损失函数 优化器优化(SGD) 之前用过Pytorch的Tensor进行Forward、Backward计算。 现在利用Pytorch框架来实现。 准备数据集

    2024年01月19日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包