QT-线性拟合(自动找直线区域)

news2024/11/17 2:36:26

最近有个需求,需要对一个S曲线的散点图做线性拟合,百度上线性拟合和曲线拟合公式很多,没什么问题,但需求里面有一个预期就是自动找出直线部分,前面因为其它事情耽搁,一直没有实现,心里多少有点梗。

1.线性拟合算法

这个是百度上找到的,个人认为还可以

void calculate(double *x,double *y,uint32_t size,float *slop,float *Intercept)
{
    float fXY = 0, fXX = 0, fXA = 0, fYA = 0, fYY = 0;
    //得到平均值
    for(int i = 0;i < size;i++)
    {
        fXA += x[i]/size;
        fYA += y[i]/size;
    }
    //得到拟合所必需的数据
    for(int i = 0;i < size;i++)
    {
        fXY  += (x[i] - fXA)*(y[i] - fYA);
        fXX += (x[i] - fXA)*(x[i] - fXA);
        fYY += (y[i] - fYA)*(y[i] - fYA);
    }
    *slop = fXY / fXX;
    *Intercept = fYA - ((*slop) * fXA);
}

这是我测试的结果:y=1.40467x-975.062

这是第三方软件的测试结果:F(x) = 1.4046744537015599*x+-975.0620148430177

结果是一致的

2.找直线思路-先分段找斜率

这个是挺头疼的,网上文章也有一些,但大多数是一些理论性的,反正找了一段时间,没看到合适的

目前思路是这样的

对整个数据,分段拟合直线,再对斜率做方差,找出斜率变化最大的位置和最小的位置,取中间点作为曲线的拐点

S曲线上来看,斜率变化是有规律的,从小到大再变小,放到方差结果来看,猜测也是一样的结果

理想状态下的结果应该是下图的结果

对方差结果绘图查看一下

1.从第一个数据开始,拿固定数据量,做线性拟合,比如第一次拿1~10个数据,第二次拿2~11个数据,以此类推,一直取到(size/2)-range个数据,size是总的数据量,range是每次拿的数据个数

2.从size/2开始,以同样方式,收集斜率

3.理想状态下,上图会被分成左右两半

斜率不能直接用,因为实际状态下,数据是散点图,如果range不够大,实际拟合的结果和下面类似

如果范围较宽,结果应该是这样的

黑色部分是按一定range拟合的曲线,虽然整体状态下是一个S曲线的趋势,但不管哪种,还是比较乱的,实际计算结果如下

从中间分开,每5个数据,拟合一个直线,将所有斜率打印出来

slop_f: 0 slop_b: 3.85714
slop_f: 0 slop_b: 3.21429
slop_f: 0 slop_b: 2.5
slop_f: 0 slop_b: 3
slop_f: 0 slop_b: 3.15385
slop_f: 0 slop_b: 3.30769
slop_f: 0 slop_b: 3.25
slop_f: 0 slop_b: 2.69231
slop_f: 0 slop_b: 2.38462
slop_f: 0.2 slop_b: 2.25
slop_f: 0.3 slop_b: 2.375
slop_f: 0.3 slop_b: 2.66667
slop_f: 0.2 slop_b: 3.41667
slop_f: 0.189189 slop_b: 3.33333
slop_f: 0.244186 slop_b: 3.27273
slop_f: 0.244186 slop_b: 2.31395
slop_f: 0.189189 slop_b: 2.06604
slop_f: 0 slop_b: 1.97368
slop_f: 0.2 slop_b: 1.82609
slop_f: 0.3 slop_b: 3.83333
slop_f: 0.22973 slop_b: 2.35714
slop_f: 0.139535 slop_b: 1.92308
slop_f: 0.121212 slop_b: 2.08824
slop_f: 0.23913 slop_b: 2.7
slop_f: 0.346154 slop_b: 2.43396
slop_f: 0.176471 slop_b: 2.60377
slop_f: 0.176471 slop_b: 2.78947
slop_f: 0.615385 slop_b: 3.04348
slop_f: 0.769231 slop_b: 3.11765
slop_f: 0.794118 slop_b: 2.45455
slop_f: 0.5 slop_b: 2.03488
slop_f: 0.608108 slop_b: 1.86486
slop_f: 0.672414 slop_b: 2
slop_f: 0.576923 slop_b: 2
slop_f: 0.424658 slop_b: 2.5625
slop_f: 0.263158 slop_b: 3.5
slop_f: 0.333333 slop_b: 4.5
slop_f: 0.517544 slop_b: 4.66667
slop_f: 0.833333 slop_b: 2.54167
slop_f: 0.804348 slop_b: 2.375
slop_f: 0.673913 slop_b: 2.58696
slop_f: 0.590909 slop_b: 2.32609
slop_f: 0.604651 slop_b: 3.92857
slop_f: 0.810811 slop_b: 4.16667
slop_f: 1 slop_b: 2.29167
slop_f: 1 slop_b: 2.41667
slop_f: 1 slop_b: 2.25
slop_f: 1 slop_b: 2.25
slop_f: 1.35294 slop_b: 4.5
slop_f: 1.54545 slop_b: 2.6875
slop_f: 1.80556 slop_b: 2.14706
slop_f: 1.91667 slop_b: 1.9
slop_f: 1.77273 slop_b: 2.08824
slop_f: 2.17647 slop_b: 2.69231
slop_f: 1.62162 slop_b: 1.95652
slop_f: 1.36047 slop_b: 2.13043
slop_f: 1.40351 slop_b: 2.09259
slop_f: 1.35616 slop_b: 2.11364
slop_f: 1.5 slop_b: 2.14706
slop_f: 1.41096 slop_b: 1.5
slop_f: 1.41096 slop_b: 1.55882
slop_f: 1.61538 slop_b: 1.92308
slop_f: 1.93103 slop_b: 2.92857
slop_f: 2.25 slop_b: 2.5
slop_f: 2.5 slop_b: 2.2963
slop_f: 2.63953 slop_b: 2.29688
slop_f: 1.81343 slop_b: 1.95
slop_f: 1.69403 slop_b: 2.4375
slop_f: 1.51942 slop_b: 2.2037
slop_f: 1.47573 slop_b: 2.20455
slop_f: 1.85075 slop_b: 2.11765
slop_f: 1.92453 slop_b: 2.29412
slop_f: 2.6 slop_b: 3.19231
slop_f: 2.8 slop_b: 3.92857
slop_f: 2.37838 slop_b: 4.35714
slop_f: 2.13953 slop_b: 3.78571
slop_f: 2.13953 slop_b: 2.5
slop_f: 2.37838 slop_b: 2.33333
slop_f: 2.6 slop_b: 2.41667
slop_f: 2.5 slop_b: 2.5
slop_f: 2.79412 slop_b: 4
slop_f: 3.30769 slop_b: 2.75
slop_f: 3.28261 slop_b: 2.75
slop_f: 3.07576 slop_b: 2.69231
slop_f: 3.07576 slop_b: 3.28571
slop_f: 3.28261 slop_b: 2.64286
slop_f: 2.63043 slop_b: 2.5
slop_f: 2.43939 slop_b: 2.71429
slop_f: 2.33721 slop_b: 2.85714
slop_f: 2.15 slop_b: 4
slop_f: 2.31395 slop_b: 2.5
slop_f: 2.33333 slop_b: 2
slop_f: 2.73913 slop_b: 2
slop_f: 2.60811 slop_b: 2.125
slop_f: 2.42857 slop_b: 3.75
slop_f: 2.38298 slop_b: 2.25
slop_f: 2.53191 slop_b: 2.16667
slop_f: 2.77273 slop_b: 2
slop_f: 2.04386 slop_b: 1.5
slop_f: 1.76027 slop_b: 1.5625
slop_f: 1.61538 slop_b: 1.75
slop_f: 1.7069 slop_b: 1.96154
slop_f: 2.14865 slop_b: 2.11538
slop_f: 2.3 slop_b: 2.25
slop_f: 2.55882 slop_b: 1.92308
slop_f: 2.92308 slop_b: 1.76923
slop_f: 3.35714 slop_b: 2.05882
slop_f: 5.16667 slop_b: 2
slop_f: 3.16667 slop_b: 2.29412
slop_f: 2.75 slop_b: 3
slop_f: 2.78261 slop_b: 2
slop_f: 2.61765 slop_b: 1.4375
slop_f: 5.5 slop_b: 1.5
slop_f: 3.5 slop_b: 1.875
slop_f: 3.66667 slop_b: 2.5
slop_f: 3 slop_b: 2.16667
slop_f: 2.85714 slop_b: 1.5
slop_f: 2 slop_b: 1.35714
slop_f: 1.81481 slop_b: 1.35714
slop_f: 1.84375 slop_b: 1.21429
slop_f: 1.86486 slop_b: 1.21429
slop_f: 2.79412 slop_b: 1.07692
slop_f: 3.6875 slop_b: 1.17647
slop_f: 4.5 slop_b: 1
slop_f: 4.5 slop_b: 0.8
slop_f: 2.78571 slop_b: 0.5
slop_f: 2.92857 slop_b: 0.2
slop_f: 3.35714 slop_b: 0
slop_f: 2.61538 slop_b: 0
slop_f: 2.75 slop_b: 0
slop_f: 2.38462 slop_b: 0
slop_f: 3.30769 slop_b: 0
slop_f: 2.85294 slop_b: 0.151163
slop_f: 2.3 slop_b: 0.22093
slop_f: 2.5 slop_b: 0.243243
slop_f: 1.84091 slop_b: 0.4
slop_f: 2.02778 slop_b: 0.3
slop_f: 2 slop_b: 0.3
slop_f: 1.625 slop_b: 0.2
slop_f: 2.5 slop_b: 0.189189
slop_f: 1.78571 slop_b: 0.244186
slop_f: 2.07143 slop_b: 0.201754
slop_f: 1.5 slop_b: 0.140351
slop_f: 1.57407 slop_b: 0
slop_f: 1.76087 slop_b: 0
slop_f: 1.85294 slop_b: 0
slop_f: 2.45833 slop_b: 0.111111

肉眼来看,和预期是一样的,前半段,斜率在上升,后半段,斜率在下降

斜率总体趋势能看出来,但不太好处理,这里考虑从方差入手,理想状态下,S曲线可以看作这样的

3.找直线思路-斜率计算方差,看变化程度

前半段方差绘制成曲线

后半段方差绘制成曲线

这段测试数据完整的方差曲线应该是这样的

再看一下实际数据,两头平缓,方差上的值应该比较小,中间比较抖,因为数据并不是一个完全直线,所以在高处,是有点波动的

方差和曲线的对应关系应该是这样的

4.找直线思路-找出真实拐点

这里想了蛮久,怎么去找最真实的拐点,后面想通了,其实直接用方差的最大值减去方差的最小值,再除以2就是方差曲线的拐点,这个点也对应S曲线的拐点,误差肯定有,但对数据而言,误差应该是不会很大的

前半段拐点计算

double min_p = 0,max_p = 0;
double min_v = 0,max_v = 0;
double start_val = variance_f[0] > variance_f[1]?variance_f[0] - variance_f[1]:variance_f[1] - variance_f[0];
min_v = start_val;
max_v = start_val;
for(uint32_t i=0;i<variance_f.size()-1;i++)
{
    if(min_v > variance_f[i] || min_v == 0)
    {
    min_v = variance_f[i];
    min_p = i;
    }
    if(max_v < variance_f[i])
    {
        max_v = variance_f[i];
        max_p = i;
    }
}
//计算拟合位置
if(max_p > min_p)
    start = (max_p - min_p)/2 + min_p;
else
    start = (min_p - max_p)/2 + max_p;

后半段拐点计算

min_p = 0,max_p = 0;
    min_v = 0,max_v = 0;
    start_val = variance_b[0] > variance_b[1]?variance_b[0] - variance_b[1]:variance_b[1] - variance_b[0];
    min_v = start_val;
    max_v = start_val;
    for(uint32_t i=0;i<variance_b.size()-1;i++)
    {
        if(min_v > variance_b[i] || min_v == 0)
        {
            min_v = variance_b[i];
            min_p = i;
        }

        if(max_v < variance_b[i])
        {
            max_v = variance_b[i];
            max_p = i;
        }
    }
    if(max_p > min_p)
        end = size - (max_p - min_p)/2;
    else
        end = size - (min_p - max_p)/2;

5.影响因素

这里有一个关键的参数,就是每隔多少个数据,拟合曲线,数据量会决定光滑程度

比如每隔5个数拟合,后半段方差状态是这样的

每隔20个数据,效果是这样的

这个貌似只能根据实际情况调整,没有固定的值

不过就最终结果而言,这个测试数据的影响好像差距不是很大

如以5个数据做拟合的话,结果如下

每隔20个数据的结果如下

直线方程f分别是y=2.75334x-2352.68和y=2.71389x-2311.79

6.测试异常情况

上面的曲线数据还比较近似S曲线,尝试对波动更大的情况做测试,这是取样范围是20的时候拟合出来的直线

方差状态

如果取样范围是5,偏差会比较大

前后两段方差状态有点变态

再看看其它情况下的拟合结果

这是直线部分不稳定的情况,现在拟合的范围是5

这是拐点前后不稳定的情况

可以看出,影响程度来看,中间数据变动对拟合结果影响相对较小,两头不稳定影响程度是比较大的

查看这个时候的方差状态

当出现数据两头数据不稳定时,需要对更大范围的数据做拟合,来抑制影响

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

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

相关文章

SpringBoot微服务项目,转发并响应下载请求

在微服务项目中&#xff0c;我经常会碰到从一个微服务项目转发下载请求并实现下载文件的需求&#xff0c;因此在此做一个转发下载的示例。总的下载转发流程如下&#xff0c;我会按照这个流程一一介绍下载流程。 1、客户端的下载请求 这里主要介绍controller层是如何接收客户端…

apple pencil一代平替笔有哪些?平替电容笔推荐

当今社会&#xff0c;高科技推动了数字产品的发展。无论是在工作中&#xff0c;还是在学习中&#xff0c;大的屏幕都能让画面变得更清楚。不管是现在还是未来&#xff0c;Ipad设备都会变成我们每天的一个重要组成部分。如果ipad与一款易于使用的电容笔相结合&#xff0c;将会大…

git-secret:在 Git 存储库中加密和存储密钥(下)

在本篇文章中&#xff0c;将带你了解如何在 Docker 容器中设置git-secret和gpg&#xff0c;通过 Makefile recipe 为不同的场景创建工作流。 Makefile Adjustment 将git-secret和gpg指令添加到 Makefile 中.make/01-00-application-setup.mk&#xff1a; # File: .make/01-0…

C语言基础复习

目录 数组 一维数组 完全初始化int a[5]{1,2,3,4,5}; 不完全初始化int a[5]{1,2} 完全不初始化”&#xff0c;int a[5] 二维数组 完全初始化 不完全初始化 指针 变量的访问方式&#xff1a; 指针变量的定义&#xff1a; 指针变量的赋值&#xff1a; 指针变量的运算…

Spring-Security入门

简介 Security 是 Spring 家族中的一个安全管理框架。相比与另外一个安全框架Shiro&#xff0c;它提供了更丰富的功能&#xff0c;社区资源也比Shiro丰富。 ​ 一般来说中大型的项目都是使用SpringSecurity 来做安全框架。小项目有Shiro的比较多&#xff0c;因为相比与Spring…

ChatGPT - InstructGPT 论文简读

发表于NLP会议:NeurlPS,EMNLP EMNLP: Empirical Methods in Natural Language Processing,自然语言处理中的经验方法NeurlPS: Neural Information Processing Systems,神经信息处理系统ChatGPT: Optimizing Language Models for Dialogue,优化对话的语言模型 ChatGPT:htt…

一文了解编程领域的模版

文章目录模版含义代码模版泛型模版引擎小结&#x1f34a;在编程领域&#xff0c;模板是一种代码片段&#xff0c;它可以被重复使用&#xff0c;并允许您在保持代码的基本结构不变的情况下&#xff0c;根据需要调整其中的内容。模板通常在构建大型程序或开发一类相关程序时非常有…

Arthas的学习与使用

一、简介 Arthas 是一款线上监控诊断产品&#xff0c;通过全局视角实时查看应用 load、内存、gc、线程的状态信息&#xff0c;并能在不修改应用代码的情况下&#xff0c;对业务问题进行诊断&#xff0c;包括查看方法调用的出入参、异常&#xff0c;监测方法执行耗时&#xff0c…

Maven知识点-反应堆

前言 在一个多模块的Maven项目中&#xff0c;反应堆&#xff08;Reactor&#xff09;是指所有模块组成的一个构建结构。对于单模块的项目&#xff0c;反应堆就是该模块本身&#xff1b;但是对于多模块项目来说&#xff0c;反应堆就包含了各模块之间继承和依赖的关系&#xff0…

一篇带你MySQL入门

文章目录1. MySQL概述1.1 数据库相关概念1.2 MySQL数据库1.2.1 版本1.2.2 下载1.2.3 数据模型2. SQL2.1 SQL通用语法2.2 SQL分类2.3 DDL2.3.1 数据库操作2.3.2 表操作2.4 图形化界面工具2.4.1 安装2.4.2 使用2.5 DML2.5.1 添加数据2.5.2 修改数据2.5.3 删除数据2.6 DQL2.6.1 基…

每天一道大厂SQL题【Day04】大数据排序统计

每天一道大厂SQL题【Day04】大数据排序统计 大家好&#xff0c;我是Maynor。相信大家和我一样&#xff0c;都有一个大厂梦&#xff0c;作为一名资深大数据选手&#xff0c;深知SQL重要性&#xff0c;接下来我准备用100天时间&#xff0c;基于大数据岗面试中的经典SQL题&#x…

酒店管理|基于Springboot+Vue前后端分离实现酒店管理系统

作者主页&#xff1a;编程指南针 作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容&#xff1a;Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助 收藏点赞不迷路 关注作者有好处 文末获取源…

webpack5从入门到精通

前言 webpack是什么&#xff1f; 摘自官网的一段话&#xff1a;webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。当 webpack 处理应用程序时&#xff0c;它会在内部从一个或多个入口点构建一个 依赖图(dependency graph)&#xff0c;然后将你项目中所需的每…

[oeasy]python0072_修改字体前景颜色_foreground_color_font

修改颜色 回忆上次内容 m 可以改变字体样式 0-9 之间设置的都是字体效果0 重置为默认1 变亮2 变暗3 斜体4 下划线5 慢闪6 快闪7 前景背景互换8 隐藏9 中划线 叠加效果 \33[1;3moeasy;分割 取消效果 21 取消 122 取消 223 取消 3一直到 290 是全部取消&#xff0c;回到默认 最…

静态链接库与动态链接库

静态链接库与动态链接库的区别 静态链接库&#xff1a;在项目中引用了库函数&#xff0c;编译时链接器会将引用的函数代码或变量&#xff0c;链接到可执行文件里&#xff0c;和可执行程序组装在一起 动态链接库&#xff1a;在编译阶段不参与链接&#xff0c;不会和可执行文件…

【Unity】流式播放远端音频:WAV格式音频篇(一)

先了解一下wav的格式&#xff1a; 参考1&#xff1a;【音频】WAV 格式详解_tyustli的博客-CSDN博客_wav文件格式详解wav 文件支持多种不同的比特率、采样率、多声道音频。WAV 文件格式是 Microsoft 的 RIFF 规范的一个子集&#xff0c;用于存储多媒体文件。RIFF&#xff08;res…

git-secret:在 Git 存储库中加密和存储密钥(上)

目前市面上已经存在许多较为成熟的密钥管理产品&#xff0c;比如 HashiCorp Vault&#xff0c;AWS Secrets Manager 以及 GCP Secret Manager。由于这些产品需要集成和维护等服务&#xff0c;因此在项目中引入会增加一定成本和开销。阅读本文&#xff0c;将带你了解如何在 Dock…

numpy数值差分

文章目录diffediff1ddiff diff是numpy中用于求差分的函数&#xff0c;函数定义为 diff(a, n1, axis-1, prepend<no value>, append<no value>)其中a为数组&#xff0c;n为差分的阶数&#xff0c;axis为求导对应的坐标轴&#xff0c;默认-1表示最后一个轴。 例如…

提分必练,中创教育PMP全真模拟题分享

湖南中创教育每日五题分享来啦&#xff0c;“日日行&#xff0c;不怕千万里&#xff1b;常常做&#xff0c;不怕千万事。”&#xff0c;每日五题我们练起来&#xff01; 1、一个建筑项目所在的地区即将进入台风季节&#xff0c;恶劣的天气会严重影响项目的进度。高层管理者要求…

Java poi之word文本替换

目录结构前言文档准备引入Maven依赖代码块替换结果验证孤勇者替换结果对比青鸟替换结果对比前言 应公司需求&#xff0c;需实现以下功能 word文本内容的替换&#xff1b;word文本内容的提取&#xff1b;word文档中图片的提取存放 此文章将使用Apache POI实现Word文档中文本内…