Java-数据拟合

一、拟合函数常用工具:

Apache Commons Math3

<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-math3</artifactId>
	<version>3.6.1</version>
</dependency>

2、二维曲线拟合查看工具
http://tools.jb51.net/jisuanqi/fun_draw
3、三维曲线绘制工具
https://echarts.apache.org/examples/zh/editor.html?c=line3d-orthographic&gl=1

二、线性拟合:

拟合公式

定义:拟合就是把平面上一系列的点,用一条光滑的曲线连接起来的过程。找到一条最符合这些散点的曲线,使得尽可能多的落在曲线上。常用的方法是最小二乘法。也就是最小二乘问题(采用线性代数的计算对残差最小值进行逼近)
**方法:**线性拟合比较简单,主要是 SimpleRegression 类的 regress() 方法,默认使用 最小二乘法优化器

2.1 RegressionResults 常用参数
RegressionResults 中是拟合的结果
其中重要的几个参数如下:
parameters:
按照次数从低到高,由索引获取;
getParameterEstimate()
globalFitInfo
0: getErrorSumSquares 平方误差之和, SSE 
1: getTotalSumSquares 平方和, SST
2: getRSquared R 平方, RSQ
3: getMeanSquareError 均方误差, MSE
4: getAdjustedRSquared调整后的 R 平方, adjRSQ
2.2拟合代码
public static String linearFit(double[][] data) {
	SimpleRegression regression = new SimpleRegression();
	//导入原始数据集
	regression.addData(data);
	//使用回归结果类接受数据
	RegressionResults results = regression.regress();
	//按照序号获取估计参数
	DecimalFormat df = new DecimalFormat("#0.0000");
	double b = results.getParameterEstimate(0);
	double k = results.getParameterEstimate(1);
	//保留精度
	b = Double.parseDouble(df.format(b));
	k = Double.parseDouble(df.format(k));

        StringBuilder func = new StringBuilder();
        func.append("f(x) =");
        func.append(b >= 0 ? " " : " - ");
        func.append(Math.abs(b));
        func.append(k > 0 ? " + " : " - ");
        func.append(Math.abs(k));
        func.append("x");

        return func.toString();
}
2.3 拟合结果
f(x) = 1.2742 + 1.4149x

三、n次/曲线拟合:

非线性函数:
在这里插入图片描述

3.1 方法一:

Step1. 创建多项式:
ParametricUnivariateFunction function = new PolynomialFunction.Parametric();
Step2. 初始化多项式:
SimpleCurveFitter curveFitter = SimpleCurveFitter.create(function,guess);
Step3. 输入Fit函数需要的List类型参数List**:**
double[] best = curveFitter.fit(observedPoints.toList());

 public static String curveFit(double[][] data) {
        //参数单变量函数  多项式函数
        ParametricUnivariateFunction function = new PolynomialFunction.Parametric();
        //按所需次数依次为 常数项、1次项、二次项......
        double[] guess = {0,1,2,3}; 

        // 初始化多项式
        SimpleCurveFitter curveFitter = SimpleCurveFitter.create(function,guess);

        // 添加数据点  可以设置个点权重,默认平均权重
        WeightedObservedPoints observedPoints = new WeightedObservedPoints();
        for (double[] point : data) {
            observedPoints.add(point[0], point[1]);
        }
        //List<WeightedObservedPoint> weightedObservedPoints = observedPoints.toList();
        //拟合结果:依次为 常数项、1次项、二次项.......
        double[] best = curveFitter.fit(observedPoints.toList());

        String fun = "f(x) = ";
        for (int i = best.length - 1; i >= 0; i--) {
            String add = best[i] > 0 ? "+" : "";
            String x = i > 0 ? "x^" + i : "";
            if (i == best.length - 1) {
                fun += (best[i] + x);
            } else {
                fun += (add + best[i] + x);
            }
        }
        return fun;
    }
3.2 方法二:多项式回归拟合

https://alvinalexander.com/java/jwarehouse/commons-math3-3.6.1/src/main/java/org/apache/commons/math3/fitting/PolynomialCurveFitter.java.shtml
Step1. 数据放入加权点对象中:
WeightedObservedPoints points = new WeightedObservedPoints();
Step2. 初始化多项式设置阶数:
SimpleCurveFitter curveFitter = SimpleCurveFitter.create(function,guess);
Step3. 输入数据进行拟合:
double[] result = fitter.fit(points.toList());

public double[] calculatePolynomial(List<Map<String, Object>> list) {
	//创建加权点对象
    WeightedObservedPoints points = new WeightedObservedPoints();

	for (int i = 0; i < list.size(); i++) {
		//把数据点加入观察的序列 参数的格式注意一下***
		points.add(Double.valueOf(list.get(i).get("x").toString()), Double.valueOf(list.get(i).get("y").toString()));
	}
     //指定多项式阶数 可以放到参数里
	PolynomialCurveFitter fitter = PolynomialCurveFitter.create(3); 
    // 曲线拟合完成后,结果保存于数组
	double[] result = fitter.fit(points.toList());  

}

四、信号拟合:

→当数据震荡时,例如去拟合一个设备的采集站,总不可能时单调的,或者在一个大范围内不能是单调的,统计学中总是正太分布的,就决定了数据总是在一个范围内震动的;
→那么联想到了正弦、余弦函数;
→但是在数据拟合不方便对正弦、余弦函数进行拟合,那么对变量进行处理就可以实现了;

多重线性回归
Step1. 数据初始化:
Step2. 创建多重线性回归对象:
OLSMultipleLinearRegression ols = new OLSMultipleLinearRegression();
Step3. 输入数据进行拟合:
ols.newSampleData(YArray,XArray);
double[] ct = ols.estimateRegressionParameters();

    	//获取x 将单变量的数据转为多变量的数据;
        List<double[]> data = new ArrayList<>();
        for (double i = 1; i <= leng; i++) {
            double x1 = Math.cos(i);
            double x2 = Math.sin(i);
            data.add(new double[]{x1, x2});
        }
        double[][] XArray=  data.stream().toArray(double[][]::new);
        //获取y
        double[] YArray = new double[leng];
        for (int i = 0; i < leng; i++) {
            YArray[i] = stringList.get(i);
        }
        OLSMultipleLinearRegression ols = new OLSMultipleLinearRegression();
        ols.newSampleData(YArray,XArray);
        double[] ct = ols.estimateRegressionParameters();

f(x) = 0.0403-1.4025Math.cos(x)-1.3236Math.sin(x)

在这里插入图片描述

for (var t = 0; t < 25; t += 1) {
  var x = Math.cos(t);
  var y = Math.sin(t);
  var z = 0.0403-1.4025*Math.cos(x)-1.3236*Math.sin(y);
  data.push([x, y, z]);
}

在这里插入图片描述

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
log-log曲线拟合是一种数学数据拟合方法,适用于处理具有广泛动态范围的数据。在java中,我们可以使用不同的库和算法来实现log-log曲线拟合。 一种常见的方法是使用Apache Commons Math库。该库提供了丰富的数学函数和算法,其中包括曲线拟合功能。通过引入此库,我们可以使用最小二乘法进行log-log曲线拟合。 首先,我们需要将原始数据转换为对数形式。然后,我们可以使用LeastSquareCurveFitter类来执行拟合操作。该类接受一个拟合函数和初始参数值作为输入,并返回最优拟合参数。 以下是一个简单的示例代码,用于演示如何在java中进行log-log曲线拟合: ```java import org.apache.commons.math3.fitting.*; public class LogLogCurveFitting { public static void main(String[] args) { // 转换原始数据为对数形式 double[] xData = {1, 2, 3, 4, 5}; double[] yData = {1, 4, 9, 16, 25}; double[] logXData = new double[xData.length]; double[] logYData = new double[yData.length]; for (int i = 0; i < xData.length; i++) { logXData[i] = Math.log(xData[i]); logYData[i] = Math.log(yData[i]); } // 执行拟合操作 WeightedObservedPoints obs = new WeightedObservedPoints(); for (int i = 0; i < logXData.length; i++) { obs.add(logXData[i], logYData[i]); } PolynomialCurveFitter fitter = PolynomialCurveFitter.create(1); double[] fittedParams = fitter.fit(obs.toList()); // 输出最优拟合参数 System.out.println("Intercept: " + fittedParams[0]); System.out.println("Slope: " + fittedParams[1]); } } ``` 在上述示例中,我们使用了二次曲线拟合函数(即多项式拟合函数),通过PolynomialCurveFitter.create(1)方法创建一个拟合器。然后,我们添加经过对数转换的数据点,最后得到最优的拟合参数。 需要注意的是,log-log曲线拟合结果中的斜率通常表示原始数据中的幂律关系。因此,如果拟合结果中斜率非零,则说明数据存在幂律关系。 这只是一个简单的示例,实际使用中,可能需要根据具体的数据和需求选择合适的拟合函数,以及进行参数调整和性能优化。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值