文章目录
一、导入 commons-math3 依赖
1、Gradle 项目导入 commons-math3 库
在 Gradle 项目的根目录下 , 找到 build.gradle 构建脚本 , 添加如下依赖 :
dependencies {
implementation 'org.apache.commons:commons-math3:3.6.1'
}
2、Maven 项目导入 commons-math3 库
在 Maven 项目的根目录下 , 找到 pom.xml 构建脚本 , 添加如下依赖 :
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>
</dependencies>
导入 Apache Commons Math 3 库后 , 就可以使用该库的功能了 , 注意配置了上述依赖后 , 确保网络通常 , Gradle 或 Maven 构建工具会自动从远程 Maven 中央仓库下载对应的依赖库 ;
二、WeightedObservedPoints 收集离散点
WeightedObservedPoints 是 commons-math3 库 中的一个类 , 用于存储带有权重的观测数据点 , 可以理解成平面坐标上的离散点 , 默认权重都是一样的 ;
WeightedObservedPoints 类 提供了一种方便的方式来 管理 带有权重的数据点 , 这些数据点 和 权重 可用于 数值分析 和 拟合和统计问题 ;
WeightedObservedPoints 作用 :
- 存储数据点 : WeightedObservedPoints 实例对象 可以存储一组数据点 , 每个数据点包含一个 二维坐标系中的 x 值 和 对应的 y 值 ; 调用 WeightedObservedPoints#add 方法 将 数据点 添加到该对象中 ;
WeightedObservedPoints weightedObservedPoints = new WeightedObservedPoints();
weightedObservedPoints.add(1.0, 1.1);
- 为数据点设置权重: 除了 x 和 y 值外 , WeightedObservedPoints 还支持为每个数据点设置 权重 ; 权重可以表示数据点的可靠性或重要性 , 用于影响拟合过程中的数据点权重 , 通过调用setWeight方法 , 您可以为每个数据点设置权重 ;
- 获取数据点和权重: 通过 getX 和 getY 函数 , 您可以获取已存储在 WeightedObservedPoints 对象中的数据点的 x 和 y 值 ; 通过 getWeight 方法可以获取每个数据点的权重 ;
- 遍历数据点: WeightedObservedPoints 支持使用 迭代器 遍历已存储的数据点 ; 通过调用 iterator 方法 , 您可以获取一个迭代器对象 , 然后使用标准的迭代方式来访问数据点 ;
- 删除数据点 : 使用 WeightedObservedPoints#clear 函数 , 删除存储在 WeightedObservedPoints 实例对象中的 数据点 和 权重值 ;
WeightedObservedPoints 用于 拟合算法 , 会根据这些 数据点 和 权重 来拟合出最佳的 曲线 或 模型 ;
在 拟合问题 中 , 数据点 的 权重可以用于指示数据点的可靠性,如 : 根据测量误差或其他因素为每个数据点分配权重 ;
三、PolynomialCurveFitter 多项式曲线拟合
PolynomialCurveFitter 是 commons-math3 库 中的一个类 , 用于拟合多项式曲线到一组数据点 ;
PolynomialCurveFitter 可以根据给定的数据点 , 自动选择最佳的多项式阶数 , 并计算出拟合的多项式系数 ;
PolynomialCurveFitter 作用 :
- 多项式拟合 : PolynomialCurveFitter 可以 根据 给定的 WeightedObservedPoints 对象中的数据点 进行多项式拟合 , 只需要提供数据点的 x 值 和 y 值 , PolynomialCurveFitter 可以根据这些数据点拟合出最佳的多项式曲线 ;
- 自动选择阶数 : PolynomialCurveFitter 可以根据数据点的数量自动选择最佳的多项式阶数 ; 该机制使用了一种称为 " Akaike’s Information Criterion " 的 统计指标 来评估不同阶数的多项式模型的拟合效果 , 并选择具有最小信息准则值的阶数 ;
- 计算多项式系数 : 一旦拟合完成 , PolynomialCurveFitter 会计算出拟合的多项式曲线的系数 , 这些系数表示多项式中每个项的权重 , 可以用于计算拟合曲线的值或进行进一步的分析 ;
使用 PolynomialCurveFitter 进行多项式拟合 步骤 :
准备数据点 : 收集 待拟合的 数据点 , 每个数据点包含一个 x 值和对应的 y 值。
创建 WeightedObservedPoints 实例对象 : 使用 WeightedObservedPoints 对象来存储数据点 , 调用 add 方法逐个添加数据点 ;
// 离散的点
WeightedObservedPoints weightedObservedPoints = new WeightedObservedPoints();
weightedObservedPoints.add(1.0, 1.1);
weightedObservedPoints.add(2.0, 2.1);
weightedObservedPoints.add(3.0, 3.2);
weightedObservedPoints.add(4.0, 4.2);
weightedObservedPoints.add(5.0, 5.3);
调用 PolynomialCurveFitter 的 create 方法 : 调用 PolynomialCurveFitter 的 create 方法 , 创建 PolynomialCurveFitter 对象 , 并指定 要拟合的多项式的最大阶数 ;
// 多项式曲线装配器
// 传入参数 2 表示该多项式是 一元二次 函数
PolynomialCurveFitter polynomialCurveFitter = PolynomialCurveFitter.create(2);
调用 PolynomialCurveFitter 的 fit 方法 : 开始进行拟合 , 需要指定 WeightedObservedPoints 对象中点的列表 ;
// 检索拟合参数
// 这是 最小二乘拟合 的核心操作
// 最终得到一个 多项式系数 数组
final double[] polynomialCoefficient = polynomialCurveFitter.fit(weightedObservedPoints.toList());
获取拟合的多项式系数 : 拟合完成后,通过调用getCoefficients方法获取拟合的多项式曲线的系数。
// 检索拟合参数
// 这是 最小二乘拟合 的核心操作
// 最终得到一个 多项式系数 数组
final double[] polynomialCoefficient
使用拟合结果 : 使用拟合的多项式系数进行 曲线插值 / 预测新数据点的值 / 进行其他分析和应用 ;
四、使用 commons-math3 库实现最小二乘拟合 - Java 代码示例
build.gradle 构建脚本如下 :
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
implementation 'org.apache.commons:commons-math3:3.6.1'
}
test {
useJUnitPlatform()
}
最小二乘示例 :
import org.apache.commons.math3.fitting.PolynomialCurveFitter;
import org.apache.commons.math3.fitting.WeightedObservedPoints;
public class LeastSquaresExample {
public static void main(String[] args) {
// 离散的点
WeightedObservedPoints weightedObservedPoints = new WeightedObservedPoints();
weightedObservedPoints.add(1.0, 1.1);
weightedObservedPoints.add(2.0, 2.1);
weightedObservedPoints.add(3.0, 3.2);
weightedObservedPoints.add(4.0, 4.2);
weightedObservedPoints.add(5.0, 5.3);
// 多项式曲线装配器
// 传入参数 2 表示该多项式是 一元二次 函数
PolynomialCurveFitter polynomialCurveFitter = PolynomialCurveFitter.create(2);
// 检索拟合参数
// 这是 最小二乘拟合 的核心操作
// 最终得到一个 多项式系数 数组
final double[] polynomialCoefficient = polynomialCurveFitter.fit(weightedObservedPoints.toList());
// 打印一元二次函数
String polynomial = "f(x) = ";
for (int i = polynomialCoefficient.length - 1; i >= 0; i--) {
// 多项式系数 数字
String itemNum = polynomialCoefficient[i] > 0 ? "+" : "";
// 多项式 中的 x 次幂
String itemXPower = i > 0 ? "x^" + i : "";
if (i == polynomialCoefficient.length - 1) {
// 最后一项常数
polynomial += (polynomialCoefficient[i] + itemXPower);
} else {
// 带 x 的系数的项
polynomial += (itemNum + polynomialCoefficient[i] + itemXPower);
}
}
System.out.println("多项式函数 : " + polynomial);
}
}
执行结果 :
多项式函数 : f(x) = 0.007142857142857327x^2+1.0071428571428562x^1+0.08000000000000096