Java代码使用最小二乘法实现线性回归预测

news2024/11/13 12:02:17

最小二乘法

简介

最小二乘法是一种在误差估计、不确定度、系统辨识及预测、预报等数据处理诸多学科领域得到广泛应用的数学工具。

它通过最小化误差(真实目标对象与拟合目标对象的差)的平方和寻找数据的最佳函数匹配。利用最小二乘法可以简便地求得未知的数据,并使得这些求得的数据与实际数据之间误差的平方和为最小。

  • 最小二乘法还可用于曲线拟合。对于平面中的这n个点,可以使用无数条曲线来拟合。要求样本回归函数尽可能好地拟合这组值。综合起来看,这条直线处于样本数据的中心位置最合理。选择最佳拟合曲线的标准可以确定为:使总的拟合误差(即总残差)达到最小

  • 最小二乘法也是一种优化方法,求得目标函数的最优值。并且也可以用于曲线拟合,来解决回归问题。回归学习最常用的损失函数是平方损失函数,在此情况下,回归问题可以著名的最小二乘法来解决。

简而言之,最小二乘法同梯度下降类似,都是一种求解无约束最优化问题的常用方法,并且也可以用于曲线拟合,来解决回归问题。

图解

最小二乘求解,即给定一组x和y的样本数据,计算出一条斜线,距离每个样本的y的距离的平均值最小,如下图(这个以水平线为例):

公式

普通最小二乘法一般形式可以写成(字母盖小帽表示估计值,具体参考应用概率统计):

即:

代码


import java.util.HashMap;
import java.util.Map;

/**
 *  线性回归
 * @author tarzan
 */
public class LineRegression {

    /** 直线斜率 */
    private static double k;
    /** 截距 */
    private static double b;
    /**
     * 最小二乘法
     * @param xs
     * @param ys
     * @return y = kx + b, r
     */
    public Map<String, Double> leastSquareMethod(double[] xs, double[] ys) {
        if(0 == xs.length || 0 == ys.length || xs.length != ys.length) {
            throw new RuntimeException();
        }
        // x平方差和
        double Sx2 = varianceSum(xs);
        // y平方差和
        double Sy2 = varianceSum(ys);
        // xy协方差和
        double Sxy = covarianceSum(xs, ys);

        double xAvg = arraySum(xs) / xs.length;
        double yAvg = arraySum(ys) / ys.length;

         k = Sxy / Sx2;
         b = yAvg - k * xAvg;
        //拟合度
        double r = Sxy / Math.sqrt(Sx2 * Sy2);
        Map<String, Double> result = new HashMap<>(5);
        result.put("k", k);
        result.put("b", b);
       result.put("r", r);
        return result;
    }

    /**
     * 根据x值预测y值
     *
     * @param x x值
     * @return y值
     */
    public double getY(double x) {
        return k*x+b;
    }

    /**
     * 根据y值预测x值
     *
     * @param y y值
     * @return x值
     */
    public double getX(double y) {
        return (y-b)/k;
    }


    /**
     * 计算方差和
     * @param xs
     * @return
     */
    private double varianceSum(double[] xs) {
        double xAvg = arraySum(xs) / xs.length;
        return arraySqSum(arrayMinus(xs, xAvg));
    }

    /**
     * 计算协方差和
     * @param xs
     * @param ys
     * @return
     */
    private double covarianceSum(double[] xs, double[] ys) {
        double xAvg = arraySum(xs) / xs.length;
        double yAvg = arraySum(ys) / ys.length;
        return arrayMulSum(arrayMinus(xs, xAvg), arrayMinus(ys, yAvg));
    }

    /**
     * 数组减常数
     * @param xs
     * @param x
     * @return
     */
    private double[] arrayMinus(double[] xs, double x) {
        int n = xs.length;
        double[] result = new double[n];
        for(int i = 0; i < n; i++) {
            result[i] = xs[i] - x;
        }
        return result;
    }

    /**
     * 数组求和
     * @param xs
     * @return
     */
    private double arraySum(double[] xs) {
        double s = 0 ;
        for( double x : xs ) {
            s = s + x ;
        }
        return s ;
    }

    /**
     * 数组平方求和
     * @param xs
     * @return
     */
    private double arraySqSum(double[] xs) {
        double s = 0 ;
        for( double x : xs ) {
            s = s + Math.pow(x, 2);
        }
        return s ;
    }

    /**
     * 数组对应元素相乘求和
     * @param xs
     * @return
     */
    private double arrayMulSum(double[] xs, double[] ys) {
        double s = 0 ;
        for( int i = 0 ; i < xs.length ; i++ ){
            s = s + xs[i] * ys[i] ;
        }
        return s ;
    }

    public static void main(String[] args) {
        double[] xData = new double[]{1, 2, 3, 4,5,6,7,8,9,10,11,12};
        double[] yData = new double[]{4200,4300,4000,4400,5000,4700,5300,4900,5400,5700,6300,6000};
        LineRegression lineRegression= new LineRegression();
        System.out.println(lineRegression.leastSquareMethod(xData, yData)); 
        //预测
        System.out.println(lineRegression.getY(10d));
    }
}

代码中的k为线性直线的斜率,b为截距,r代表计算结果的直线拟合度。

当r = 1时称为完美拟合,当r =0 时称为糟糕拟合,

  • 事实上,R2不因y 或x 的单位变化而变化。

  • 零条件均值,指给定解释变量的任何值,误差的期望值为零。换言之,即 E(u|x)=0。

测试

idea中运行上面代码的主方法,控制台输出为:

r的值接近于1,说明拟合度高。 测试x=10 时,输出结果5689.7与真实值误差约为11。

最小二乘法线性回测,常用股票、公司未来营收的预测。有着广泛的应用。

文章还有没讲清楚的地方,或为你有疑问的地方,欢迎评论区留言!!!

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

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

相关文章

如何写一个 things3 client

Things3[1] 是一款苹果生态内的任务管理软件&#xff0c;是一家德国公司做的&#xff0c;非常好用。我前后尝试了众多任务管理软件&#xff0c;最终选定 things3&#xff0c;以后有机会会写文章介绍我是如何用 things3 来管理我的日常任务。本文主要介绍欧神写的 tli[2] 工具来…

3D沉浸式体验开发技巧【Three.js】

在本文中&#xff0c;我们将看看如何使用 Three.js 创建一个充满后期效果和微交互的迷你城市。 推荐&#xff1a;将 NSDT场景编辑器 加入你的3D开发工具链。 1、背景介绍 我是一个游戏爱好者。 我一直梦想创建一个交互式迷你城市&#xff0c;使用饱和的颜色&#xff0c;类似于…

Android自动化测试(UiAutomator)——UiObject

本文主要讲解使用UiAutomator的一些技巧&#xff0c;希望对于初学者有一定的帮助 UiObject 1、首先要声明对象 UiObject XXX new UiObject(new Selector) ; 2、其次对对象进行操作 操作类型包括&#xff1a; 执行类&#xff1a;文本输入与清除、点击/长按、拖动/滑动、 …

JAVA JDK 常用工具类和工具方法

目录 Pair与Triple Lists.partition-将一个大集合分成若干 List集合操作的轮子 对象工具Objects 与ObjectUtils 字符串工具 MapUtils Assert断言 switch语句 三目表达式 IOUtils MultiValueMap MultiMap JAVA各个时间类型的转换&#xff08;LocalDate与Date类型&a…

开源软件AirByte:入湖入仓,数据集成管道

从ETL到ELT就传统的 ETL而言&#xff0c;当我们开始构建数据仓库时&#xff0c;都要先去了解业务流程&#xff0c;明晰业务是如何运转的&#xff0c;数据是如何留痕的。通过收集用户的相关需求&#xff0c;从而去规划设计报表。企业需要进行数仓分域、分层、逻辑建模等一系列操…

Linux下程序调试的方法【GDB】GDB相关命令和基础操作(命令收藏)

目录 1、编译 2、启动gdb调试 2.1 直接运行 2.2 运行gdb后使用run命令 2.3 调试已运行的程序 3、图形界面提示 4、调试命令 1、查看源码 2、运⾏程序/查看运⾏信息 3、设置断点 5、单步/跳步执⾏ 6、分割窗口 7、其他命令 8、相关参数 1、编译 在编译时要加上-g选…

stm32f407探索者开发板(十七)——串口寄存器库函数配置方法

文章目录一、STM32串口常用寄存器和库函数1.1 常用的串口寄存器1.2 串口相关的库函数1.3 状态寄存器&#xff08;USART_ SR&#xff09;1.4 数据寄存器&#xff08;USART_ DR&#xff09;1.5 波特率寄存器&#xff08;USART_BRR&#xff09;二、串口配置一般步骤一、STM32串口常…

java static关键字 万字详解

目录 一、为什么需要static关键字&#xff1a; 二、static关键字概述 : 1.作用 : 2.使用 : 三、static修饰成员变量详解 : 1.特点 : 2.细节 : ①什么时候考虑使用static关键字? ②静态变量和非静态变量的区别&#xff1f; ③关于静态变量的初始化问题 : ④关于静态变…

基于springboot+vue的器官捐献系统

基于springbootvue的器官捐献系统 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&…

内网渗透(四十一)之横向移动篇-PsExec工具远程命令执行横向移动

系列文章第一章节之基础知识篇 内网渗透(一)之基础知识-内网渗透介绍和概述 内网渗透(二)之基础知识-工作组介绍 内网渗透(三)之基础知识-域环境的介绍和优点 内网渗透(四)之基础知识-搭建域环境 内网渗透(五)之基础知识-Active Directory活动目录介绍和使用 内网渗透(六)之基…

CCNP350-401学习笔记(201-250题)

201、An engineer attempts to configure a trunk between switch SW1 and switch SW2 using DTP, but the trunk does not form. Which command should the engineer apply to switch SW2 to resolve this issue? A. switchport mode dynamic desirable B. switchport mode a…

GNU make 中文手册 第一二章 概述与介绍

一、第一章&#xff1a;概述 准备知识 在开始我们关于 make 的讨论之前&#xff0c;首先需要明确一些基本概念&#xff1a; 编译&#xff1a;把高级语言书写的代码&#xff0c;转换为机器可识别的机器指令。编译高级语言后生成的指令虽然可被机器识别&#xff0c;但是还不能…

小程序 npm sill idealTree buildDeps 安装一直没反应

目录 一、问题 二、解决 1、删除.npmsrc 、清除缓存 2、更换镜像源 3、最终检测 一、问题 记录&#xff1a;今天npm 一直安装不成功 显示&#xff1a;sill idealTree buildDeps 我的版本&#xff1a; 我百度到换镜像源安装方法&#xff0c;但我尝试后&#xff0c;依然…

CUDA性能指南

CUDA性能指南 文章目录CUDA性能指南5.1 整体性能优化策略5.2 最大化利用率5.2.1 应用程序层次5.2.2 设备层次5.2.3 多处理器层次5.2.3.1 占用率计算5.3 最大化存储吞吐量5.3.1 设备与主机之间的数据传输5.3.2 设备内存访问5.4最大化指令吞吐量5.4.1 算数指令5.4.2 控制流指令5.…

前端 ES6 环境下 require 动态引入图片以及问题

前端 ES6 环境下 require 动态引入图片以及问题require 引入图片方式打包体积对比总结ES6 环境中&#xff0c;通过 require 的方式引入图片很方便&#xff0c;一直以来也没有出过什么问题&#xff0c;后来项目中&#xff0c;需要动态引入图片。 require 动态引入也容易实现&am…

第一章 Kafka快速实战与基本原理

第一章 Kafka快速实战与基本原理 1、介绍 Kafka 是最初由 Linkedin 公司开发的&#xff0c;是一个分布式、支持分区的&#xff08;partition&#xff09;、多副本的&#xff08;replica&#xff09;&#xff0c;基于 zookeeper 协调的分布式消息系统&#xff0c;它最大的特性就…

分布式(四)

五、分布式锁 1. 概念 1.1 本地锁 使用ReetrantLock类和synchronized关键字JDK自带的本地锁来控制一个JVM进程内的多个线程对本地共享资源的访问。 1.2 分布式锁 分布式系统下&#xff0c;不同的服务器/客户端通常运行在独立的JVM进程上。 多个JVM进程共享一份资源的话&…

leetcode 1~10 学习经历

LeetCode 习题 1 - 101. 两数之和2. 两数相加3. 无重复字符的最长子串4. 寻找两个正序数组的中位数5. 最长回文子串6. N 字形变换7. 整数反转8. 字符串转换整数 (atoi)9. 回文数10. 正则表达式匹配1. 两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在…

大数据处理学习笔记1.5 掌握Scala内建控制结构

文章目录零、本讲学习目标一、条件表达式&#xff08;一&#xff09;语法格式&#xff08;二&#xff09;执行情况&#xff08;三&#xff09;案例演示任务1、根据输入值的不同进行判断任务2、编写Scala程序&#xff0c;判断奇偶性二、块表达式&#xff08;一&#xff09;语法格…

科学推理~

科学推理 【物理】 1、力学 重力 重力并不是指向地心的&#xff0c;只有赤道可以 弹力 【重点】判断弹力方向 相互作用力 摩擦力 静摩擦力 滑动摩擦力 注意&#xff1a;最大静摩擦力默认等于滑动摩擦力 压强 固体压强 液体压强 连通器 气体压强 气体对外做功&#xff0c;T 下…