用C#实现最小二乘法(用OxyPlot绘图)✨
最小二乘法介绍
最小二乘法(Least Squares Method)是一种常见的数学优化技术,广泛应用于数据拟合、回归分析和参数估计等领域。其目标是通过最小化残差平方和来找到一组参数,使得模型预测值与观测值之间的差异最小化。
最小二乘法的原理
线性回归模型将因变量 (y) 与至少一个自变量 (x) 之间的关系建立为:
在 OLS 方法中,我们必须选择一个b1和b0的值,以便将 y 的实际值和拟合值之间的差值的平方和最小化。
平方和的公式如下:
我们可以把它看成是一个关于b1和b0的函数,分别对b1和b0求偏导,然后让偏导等于0,就可以得到最小平方和对应的b1和b0的值。
先说结果,斜率最后推导出来如下所示:
截距推导出来结果如下:
don't worry about that,慢慢推导总是可以弄明白的(不感兴趣可以直接略过):
用C#实现最小二乘法
创建数据点
首先创建想要拟合的数据点:
NDArray? x, y;
x,y为全局变量。
//使用NumSharp创建线性回归的数据集
x = np.arange(0, 10, 0.2);
y = 2 * x + 3 + np.random.normal(0, 3, x.size);
使用到了NumSharp,需要为项目添加NumSharp包:
x = np.arange(0, 10, 0.2);
的意思是x从0增加到10(不包含10),步长为0.2:
np.random.normal(0, 3, x.size);
的意思是生成了一个均值为0,标准差为3,数量与x数组长度相同的正态分布随机数数组。这个数组被用作线性回归数据的噪声。
使用OxyPlot画散点图
OxyPlot是一个用于在.NET应用程序中创建数据可视化图表的开源图表库。它提供了丰富的功能和灵活性,使开发者能够轻松地在其应用程序中集成各种类型的图表,包括折线图、柱状图、饼图等。
添加OxyPlot.WindowsForms包:
将PlotView控件添加到窗体设计器上:
// 初始化散点图数据
var scatterSeries = new ScatterSeries
{
MarkerType = MarkerType.Circle,
MarkerSize = 5,
MarkerFill = OxyColors.Blue
};
表示标志为圆形,标志用蓝色填充,标志的大小为5。
for (int i = 0; i < x.size; i++)
{
scatterSeries.Points.Add(new ScatterPoint(x[i], y[i]));
}
添加数据点。
PlotModel? plotModel;
将plotModel设置为全局变量。
// 创建 PlotModel
plotModel = new PlotModel()
{
Title = "散点图"
};
plotModel.Series.Add(scatterSeries);
// 将 PlotModel 设置到 PlotView
plotView1.Model = plotModel;
这样就成功绘制了散点图,效果如下所示:
使用最小二乘法拟合数据点
double a = 0;
double c = 0;
double x_mean = x?.mean();
double y_mean = y?.mean();
//计算a和c
for(int i = 0; i < x?.size; i++)
{
a += (x[i] - x_mean) * (y?[i] - y_mean);
c += (x[i] - x_mean) * (x[i] - x_mean);
}
//计算斜率和截距
double m = a / c;
double b = y_mean - m * x_mean;
//拟合的直线
var y2 = m * x + b;
套用公式就可以,a表示上面斜率公式的上面那部分,c表示上面斜率公式的下面那部分。
double x_mean = x?.mean();
double y_mean = y?.mean();
计算x与y的平均值。
使用OxyPlot画拟合出来的直线
//画这条直线
var lineSeries = new LineSeries
{
Points = { new DataPoint(x?[0], y2[0]), new DataPoint(x?[-1], y2[-1]) },
Color = OxyColors.Red
};
// 创建 PlotModel
plotModel?.Series.Add(lineSeries);
// 为图表添加标题
if (plotModel != null)
{
plotModel.Title = $"拟合的直线 y = {m:0.00}x + {b:0.00}";
}
// 刷新 PlotView
plotView1.InvalidatePlot(true);
Points = { new DataPoint(x?[0], y2[0]), new DataPoint(x?[-1], y2[-1]) },
画直线只要添加两个点就好了x?[0], y2[0]
表示x和y的第一个点,x?[-1], y2[-1])
表示x和y的最后一个点,使用了NumSharp的切片语法。
画出来的效果如下所示:
C#实现的全部代码:
using NumSharp;
using OxyPlot.Series;
using OxyPlot;
namespace OlsRegressionDemoUsingWinform
{
public partial class Form1 : Form
{
NDArray? x, y;
PlotModel? plotModel;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//使用NumSharp创建线性回归的数据集
x = np.arange(0, 10, 0.2);
y = 2 * x + 3 + np.random.normal(0, 3, x.size);
// 初始化散点图数据
var scatterSeries = new ScatterSeries
{
MarkerType = MarkerType.Circle,
MarkerSize = 5,
MarkerFill = OxyColors.Blue
};
for (int i = 0; i < x.size; i++)
{
scatterSeries.Points.Add(new ScatterPoint(x[i], y[i]));
}
// 创建 PlotModel
plotModel = new PlotModel()
{
Title = "散点图"
};
plotModel.Series.Add(scatterSeries);
// 将 PlotModel 设置到 PlotView
plotView1.Model = plotModel;
}
private void button2_Click(object sender, EventArgs e)
{
double a = 0;
double c = 0;
double x_mean = x?.mean();
double y_mean = y?.mean();
//计算a和c
for(int i = 0; i < x?.size; i++)
{
a += (x[i] - x_mean) * (y?[i] - y_mean);
c += (x[i] - x_mean) * (x[i] - x_mean);
}
//计算斜率和截距
double m = a / c;
double b = y_mean - m * x_mean;
//拟合的直线
var y2 = m * x + b;
//画这条直线
var lineSeries = new LineSeries
{
Points = { new DataPoint(x?[0], y2[0]), new DataPoint(x?[-1], y2[-1]) },
Color = OxyColors.Red
};
// 创建 PlotModel
plotModel?.Series.Add(lineSeries);
// 为图表添加标题
if (plotModel != null)
{
plotModel.Title = $"拟合的直线 y = {m:0.00}x + {b:0.00}";
}
// 刷新 PlotView
plotView1.InvalidatePlot(true);
}
}
}
用Python实现最小二乘法
import numpy as np
import matplotlib.pyplot as plt
# 用最小二乘法拟合 y = mx + b
# 设置随机数种子以保证结果的可复现性
np.random.seed(0)
# 生成一个在[0, 10]区间内均匀分布的100个数作为x
x = np.linspace(0, 10, 100)
# 生成y,y = 2x + 噪声,其中噪声是[0, 10)之间的随机整数
y = 2 * x + 5 + np.random.randint(0, 10, size=100)
# 计算x和y的均值
x_mean = np.mean(x)
y_mean = np.mean(y)
a = 0
c = 0
for i in range(x.shape[0]):
a += (x[i] - x_mean) * (y[i] - y_mean)
c += (x[i] - x_mean) ** 2
# 计算斜率和截距
m = a / c
b = y_mean - m * x_mean
# 画这条直线
y2 = m * x + b
plt.plot(x, y2, color='red')
# 画数据点
plt.scatter(x, y)
plt.xlabel('x')
plt.ylabel('y')
plt.title(f'y = {m:.2f}x + {b:.2f}')
plt.show()
运行效果如下所示:
总结
本文向大家介绍了最小二乘法以及公式推导的过程,并使用C#与Python进行实现。重点介绍了C#中是如何实现的,同时介绍了在C#中如何使用OxyPlot绘图。希望对你有所帮助。
参考
1、Understanding Ordinary Least Squares (OLS) Regression | Built In
2、Machine Learning Series-Linear Regression Ordinary Least Square Method - YouTube
用C#实现最小二乘法(用OxyPlot绘图)✨的更多相关文章
- 这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧
注意:有网友提出部分项目停止更新的事情,这个问题我特意注意过,很多都是小功能组件,功能稳定,没有bug,没更新是正常的.够用就行了.其次技术支持的事情,对开源免费来说,不能太强求,这里发布的都是小功能 ...
- C#.NET开源项目、机器学习、商务智能
所以原谅我,不能把所有的都发上来,太杂了,反而不好. 1..NET时间周期处理组件 这个组件很小,主要是对时间日期,特别是处理时间间隔以及时间范围非常方便.虽然.NET自带了时间日期的部分功能,但可能 ...
- 机器学习:R语言中如何使用最小二乘法
详细内容见上一篇文章:http://www.cnblogs.com/lc1217/p/6514734.html 这里只是介绍下R语言中如何使用最小二乘法解决一次函数的线性回归问题. 代码如下:(数据同 ...
- 机器学习:Python中如何使用最小二乘法
之所以说"使用"而不是"实现",是因为python的相关类库已经帮我们实现了具体算法,而我们只要学会使用就可以了.随着对技术的逐渐掌握及积累,当类库中的算法已经 ...
- 机器学习:scipy和sklearn中普通最小二乘法与多项式回归的使用对
相关内容连接: 机器学习:Python中如何使用最小二乘法(以下简称文一) 机器学习:形如抛物线的散点图在python和R中的非线性回归拟合方法(以下简称文二) 有些内容已经在上面两篇博文中提到了,所 ...
- Mathematica/偏导数/最小二乘法(线性回归)
a = / a //输出的还是2/123 N[a] //输出的就是小数点 N[a,] //保留三位小数点 Clear[a] Solve[== x^- , x] //结果-3 和 3 Plot[Sin[ ...
- 最小二乘法 及python 实现
参考 最小二乘法小结 机器学习:Python 中如何使用最小二乘法 什么是” 最小二乘法” 呢 定义:最小二乘法(又称最小平方法)是一种数学优化技术,它通过最小化误差的平方和寻找数据的最佳 ...
- 转悠望南山 Python闲谈(二)聊聊最小二乘法以及leastsq函数
1 最小二乘法概述 自从开始做毕设以来,发现自己无时无刻不在接触最小二乘法.从求解线性透视图中的消失点,m元n次函数的拟合,包括后来学到的神经网络,其思想归根结底全都是最小二乘法. 1-1 “多线 ...
- Python闲谈(二)聊聊最小二乘法以及leastsq函数
1 最小二乘法概述 自从开始做毕设以来,发现自己无时无刻不在接触最小二乘法.从求解线性透视图中的消失点,m元n次函数的拟合,包括后来学到的神经网络,其思想归根结底全都是最小二乘法. 1-1 “多线→一 ...
- C#使用Oxyplot绘制监控界面
C#中可选的绘图工具有很多,除了Oxyplot还有DynamicDataDisplay(已经改名为InteractiveDataDisplay)等等.不过由于笔者这里存在一些环境上的特殊要求,.Net ...
随机推荐
- PTA数组及排序查找题解与解题思路
PTA数组及排序查找题解与解题思路 函数题目 函数题目为平台提供的裁判程序调用所完成的函数进行判题,题目规定语言为C语言 6-1 求出二维数组的最大元素及其所在的坐标 本题较为简单,考察的是如何遍历一 ...
- 数字孪生结合GIS能够在公共交通领域作出什么贡献?
数字孪生结合地理信息系统(GIS)在公共交通领域具有潜在的重大贡献,这种结合可以帮助城市更高效地规划.运营和改进公共交通系统.以下是一些关键方面的讨论,以说明数字孪生和GIS在这一领域的作用: 数字孪 ...
- Navicat Premium多用户破解方法 12以上版本
https://www.cnblogs.com/cgqplus/p/15267306.html 本文不提供注册机或者破解工具,本论坛多的是,搜索一下就好了. 本方法适用于多用户环境下使用,比如在服务器 ...
- libGDX游戏开发之打包游戏(十二)
libGDX游戏开发之打包游戏(十二) libGDX系列,游戏开发有unity3D巴拉巴拉的,为啥还用java开发?因为我是Java程序员emm-国内用libgdx比较少,多数情况需要去官网和goog ...
- 初探 Linux Cgroups:资源控制的奇妙世界
Cgroups 是 linux 内核提供的功能,由于牵涉的概念比较多,所以不太容易理解.本文试图通过简单的描述和 Demo 帮助大家理解 Cgroups . 如果你对云原生技术充满好奇,想要深入了解更 ...
- Programming Abstractions in C阅读笔记:p246-p247
<Programming Abstractions in C>学习第68天,p246-p247总结,总计2页. 一.技术总结 本章通过"the game of nim(尼姆游戏) ...
- 华为IoT首席架构师王启军:全栈工程师“养成记”
在王启军的公众号里,有一篇<My Team>的文章,里面记录了早年他所带团队成长的心得. 这个被他称为完美组合的团队,并不是来自大厂名企,彼时王启军给不起高待遇,团队核心成员中还有很多人是 ...
- 华为云MVP朱有鹏:做IoT开发乐趣无穷,年轻开发者更要厚积薄发
[摘要] 可以预见的是,AIoT会是未来一段时间主流的技术趋势方向,当前也有不少科技巨头涌入其中,蓄势待发,而5G的到来加速了AIoT产业的扩张速度,所以如华为云MVP朱有鹏所说,年轻的开发者应该要拥 ...
- 5种Python使用定时调度任务的方式
摘要:Python 有几种方法可以定时调度一个任务,这就是我们将在本文中学习的内容. 本文分享自华为云社区<Python中使用定时调度任务(Schedule Jobs)的5种方式)>,作者 ...
- 一个Camel Multicast组件聚合策略问题的解决过程
摘要:本文通过案例,发现了一个Camel Multicast组件聚合策略相关的问题.通过查看Camel源代码,找到了问题原因并给出了解决方案.希望本文可以帮助到遇到同样问题的Camel用户. 本文分享 ...