Преглед изворни кода

[task-1766] 性能验证模块 开发 (二期) / 【后端】验证报告的接口开发

liyuan пре 1 година
родитељ
комит
6eb9e2141b
12 измењених фајлова са 988 додато и 3 уклоњено
  1. 8 1
      ibps-provider-root/modules/provider-business/pom.xml
  2. 20 2
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/funcs/TestFuncs.java
  3. 3 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model/CalcVO.java
  4. 69 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model/EP6AVO.java
  5. 146 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model2/PVItemBuilder.java
  6. 20 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/regression/AnalysisConstants.java
  7. 50 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/regression/MultipleLinearRegression.java
  8. 86 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/regression/PolynomialRegression.java
  9. 96 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/regression/Regression.java
  10. 50 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/regression/SimpleLinearRegression.java
  11. 212 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/regression/StatisticsTest.java
  12. 228 0
      ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/regression/StatisticsUtil.java

+ 8 - 1
ibps-provider-root/modules/provider-business/pom.xml

@@ -271,9 +271,16 @@
             <version>3.6.1</version>
             <scope>compile</scope>
         </dependency>
+		<!-- https://mvnrepository.com/artifact/net.sf.jsci/jsci -->
+		<dependency>
+			<groupId>net.sf.jsci</groupId>
+			<artifactId>jsci</artifactId>
+			<version>1.2</version>
+		</dependency>
+
 
 
-    </dependencies>
+	</dependencies>
 
 	<build>
 		<plugins>

+ 20 - 2
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/funcs/TestFuncs.java

@@ -1,7 +1,12 @@
 package com.lc.ibps.components.verification.funcs;
 
+import com.lc.ibps.components.verification.regression.PolynomialRegression;
+import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
+import org.apache.commons.math3.util.FastMath;
 import org.junit.Test;
 
+import java.util.Arrays;
+
 public class TestFuncs {
     @Test
     public  void test(){
@@ -12,12 +17,14 @@ public class TestFuncs {
         xValue xValue = xAverage.eval(cNode1);
         System.out.println(xValue.getDoub());
         xValue[] x = xLog10.eval(cNode1);
+        System.out.println(FastMath.log10(25.30));
         System.out.println(x);
         xValue xValue1 = xFuncStdevVar.evalArgs((cNode1), xFuncStdevVar.iSTDEV);
         xValue xValue2 = xFuncStdevVar.evalArgs((cNode2), xFuncStdevVar.iSTDEV);
         System.out.println(xValue1.getDoub());
         System.out.println(xValue2.getDoub());
-
+        DescriptiveStatistics stats = new DescriptiveStatistics(cNode11);
+        System.out.println("dfe:"+stats.getStandardDeviation());
         xValue b = xFuncArray2Args.evalArgs(cNode2,cNode1,  xFuncArray2Args.iSLOPE);
         System.out.println(b.getDoub());
 
@@ -25,7 +32,18 @@ public class TestFuncs {
         System.out.println(a.getDoub());
 
         xValue r = xFuncArray2Args.evalArgs(cNode2,cNode1,  xFuncArray2Args.iCORREL);
-        System.out.println(r.getDoub());
+        System.out.println(r.getDoub()*r.getDoub());
+         PolynomialRegression po = new PolynomialRegression();
+        po.addData(cNode11, cNode21, 1, 1);
+
+        System.out.println("R方为"+ po.getRSquared());
+        System.out.println("调整R方为"+ po.getAdjRSquared());
+        System.out.println(po.getFunction());
+        System.out.println("标准误为:" + Arrays.toString(po.getStdErrors()));
+
+        System.out.println("f值:" + po.getFValue() );
+//        System.out.println("f检验P值:" + StatisticsUtil.getPValue(po.getFValue(), 3, yArray.length - 4));
+
     }
 
     public static xValue[] convert(double[] data){

+ 3 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model/CalcVO.java

@@ -2,14 +2,17 @@ package com.lc.ibps.components.verification.model;
 
 import org.apache.commons.math3.distribution.TDistribution;
 
+import java.math.BigDecimal;
 import java.text.DecimalFormat;
 
 public class CalcVO {
 
     public double format(double d,int scale){
         return Double.parseDouble(String.format("%."+scale+"f", d));
+//        return new BigDecimal(d).setScale(scale,BigDecimal.ROUND_HALF_UP).doubleValue();
     }
 
+
     public double getT(double degreesOfFreedom,double p){
         TDistribution t = new TDistribution(degreesOfFreedom);
         double value = t.inverseCumulativeProbability(1 - p/2);

+ 69 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model/EP6AVO.java

@@ -0,0 +1,69 @@
+package com.lc.ibps.components.verification.model;
+
+import com.lc.ibps.components.verification.regression.PolynomialRegression;
+import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
+
+public class EP6AVO extends CalcVO{
+
+    private double[][] data;
+
+    private double[] means;
+    private double[] standardDeviations;
+
+    private double high;
+    private double low;
+    private double[] targetValues;
+
+    private int specimensNum;
+    private int repeatNum;
+    private PolynomialRegression pr1 = new PolynomialRegression();
+    private PolynomialRegression pr2 = new PolynomialRegression();
+    private PolynomialRegression pr3 = new PolynomialRegression();
+
+    public  EP6AVO(double[][] data, double high,double low){
+        this.data = data;
+        this.high = high;
+        this.low = low;
+        this.specimensNum = data.length;
+        this.repeatNum = data[0].length;
+        this.means = new double[this.specimensNum];
+        this.standardDeviations = new double[this.specimensNum];
+        this.targetValues = new double[this.specimensNum];
+        calculate();
+    }
+
+    public void calculate() {
+        calcTarget();
+        for (int i = 0; i < specimensNum; i++) {
+            DescriptiveStatistics stat = new DescriptiveStatistics(data[i]);
+            means[i] = format(stat.getMean(),2);
+            standardDeviations[i] = stat.getStandardDeviation();
+
+        }
+
+        pr1.addData(targetValues, means, repeatNum,1);
+        pr2.addData(targetValues, means, repeatNum,2);
+        pr3.addData(targetValues, means, repeatNum,3);
+        double d = getT(pr1.getDfDependent(),0.05);
+        double d2 = getT(pr2.getDfDependent(),0.05);
+        double d3 = getT(pr3.getDfDependent(),0.05);
+        pr1.getParameters();
+    }
+
+    private void calcTarget(){
+        targetValues[0] = low;
+        targetValues[specimensNum -1] = high;
+        int range = specimensNum - 1;
+        for (int i = 1; i < range; i++) {
+            targetValues[i] = format(low * (range -i)/range + high * i/range,2);
+        }
+    }
+
+    public static void main(String[] args){
+        double[][] data = {{-0.01,-0.01},{5.00,4.99},{10.18,10.05},{14.65,14.65},{19.57,19.65},{24.02,24.09}};
+        EP6AVO ep6 = new EP6AVO(data,24.56,0);
+        System.out.println(ep6);
+//        ep6.getT()
+
+    }
+}

+ 146 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/model2/PVItemBuilder.java

@@ -0,0 +1,146 @@
+package com.lc.ibps.components.verification.model2;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.annotation.JSONField;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.lc.ibps.components.poi.excel.entity.ExportParams;
+import com.lc.ibps.components.poi.excel.entity.ImportParams;
+import com.lc.ibps.components.poi.excel.entity.enmus.ExcelType;
+import com.lc.ibps.components.poi.excel.entity.params.ExcelExportEntity;
+import com.lc.ibps.components.poi.excel.entity.vo.BaseEntityTypeConstants;
+import com.lc.ibps.components.verification.excel.PVExcelExportStyler;
+import com.lc.ibps.components.verification.excel.PVExcelUtil;
+import com.lc.ibps.components.verification.funcs.xValue;
+import com.lc.ibps.components.verification.model.*;
+import org.apache.poi.ss.usermodel.Workbook;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class PVItemBuilder {
+    public static String DISPLAY_NUMBER = "次数";
+    public static String DISPLAY_VALUE = "检测值";
+
+    public static String DISPLAY_LOG = "对数值";
+
+    public static String DISPLAY_DATE = "实验日期";
+    private Map<String, SpecimensCalcVO> record = new HashMap<>();
+    private Map<String, CalcVO> record2 = new HashMap<>();
+
+    public void importExcelRecord(InspectionConfigVO config,InputStream inputstream) throws IOException {
+        ImportParams params = new ImportParams();
+        params.setTitleRows(1);
+        params.setHeadRows(1);
+        params.setSheetNum(config.getDays());
+        Map<String, List<String>> errorMessage = new HashMap<>();
+        List<ExcelSheetRecord> list = PVExcelUtil.importExcel(inputstream, Map.class, params);
+        int i = 1;
+        for (ExcelSheetRecord record : list) {
+            String sheetName = String.format("第 %d 天",i);
+            if(config.getDays() == 1){
+                sheetName = config.getName();
+            }
+            record.convert(config, sheetName);
+            if (record.getErrors().size() > 0) {
+                errorMessage.put(sheetName, record.getErrors());
+            }
+            i++;
+        }
+        if (errorMessage.size() > 0) {
+            throw new IOException(JSONObject.toJSONString(errorMessage, SerializerFeature.DisableCircularReferenceDetect));
+        }
+
+        for (String sName : config.getSpecimensName()) {
+            final xValue[] total = new xValue[config.getRepeatNum() * config.getDays()];
+            for (int j = 0; j < list.size(); j++) {
+                final xValue[] xValues = list.get(j).getConvertedData().get(sName);
+                for (int k = 0; k < xValues.length; k++) {
+                    total[j * xValues.length + k] = xValues[k];
+                }
+            }
+            record.put(sName, new SpecimensCalcVO(total, config.isConvert()));
+        }
+//        buildItemCalcVO();
+
+
+        if(config.getName().toLowerCase().contains("精密度")){
+            for (String sName : config.getSpecimensName()) {
+                SpecimensCalcVO[] data = new SpecimensCalcVO[config.getDays()];
+                for (int j = 0; j < list.size(); j++) {
+                    final xValue[] xValues = list.get(j).getConvertedData().get(sName);
+                    data[j] = new SpecimensCalcVO(xValues, config.isConvert());
+                }
+                record2.put(sName, new EP15PrecisionVO(data,config.getRepeatNum(),config.getBatchCVSValue(),config.getDailyCVSValue(),config.getDecimal()));
+            }
+        }else if(config.getName().equals("定值参考物质验证")){
+            for (String sName : config.getSpecimensName()) {
+                final xValue[] total = new xValue[config.getRepeatNum() * config.getDays()];
+                for (int j = 0; j < list.size(); j++) {
+                    final xValue[] xValues = list.get(j).getConvertedData().get(sName);
+                    for (int k = 0; k < xValues.length; k++) {
+                        total[j * xValues.length + k] = xValues[k];
+                    }
+                }
+                record2.put(sName, new EP15TruenessReferneceVO(total, config.getTargetValue()[0],config.getClaimValue(),0));
+            }
+        }else if(config.getName().equals("EP15-A方法学比对")){
+
+            record2.put("EP15-A方法学比对",
+                    new EP15TruenessPatientVO(record.get(config.getSpecimensName()[0]),record.get(config.getSpecimensName()[1]), config.getClaimValue(),0));
+
+        }
+
+
+
+    }
+
+    public Workbook exportExcelTemplate(InspectionConfigVO config) {
+        List<ExcelExportEntity> entity = new ArrayList<ExcelExportEntity>();
+
+        List<ExcelExportEntity> temp = new ArrayList<ExcelExportEntity>();
+        ExcelExportEntity e1 = new ExcelExportEntity(DISPLAY_NUMBER, "number");
+//        e1.setMergeVertical(true);
+        e1.setType(BaseEntityTypeConstants.DoubleType);
+        entity.add(e1);
+
+
+        for (int i = 0; i < config.getSpecimensNum(); i++) {
+            ExcelExportEntity e2 = new ExcelExportEntity(config.getSpecimensName()[i], "input");
+            entity.add(e2);
+        }
+//        ExcelExportEntity excelEntity = new ExcelExportEntity("", "inspection");
+//        excelEntity.setList(temp);
+//        entity.add(excelEntity);
+        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
+        Map<String, Object> map;
+        for (int i = 1; i <= config.getRepeatNum(); i++) {
+            map = new HashMap<String, Object>();
+            map.put("number", i);
+//            map.put("value", "");
+
+//            List<Map<String, Object>> tempList = new ArrayList<Map<String, Object>>();
+//            tempList.add(map);
+//            map.put("inspection", tempList);
+
+            list.add(map);
+        }
+        List<ExportParams> exportParamsList = new ArrayList<ExportParams>();
+        for (int i = 1; i < config.getDays()+1; i++) {
+            String sheetName = String.format("第 %d 天",i);
+            if(config.getDays() == 1){
+                sheetName = config.getName();
+            }
+            ExportParams exportParams = new ExportParams(config.getName() + " 数据导入模板", sheetName);
+            exportParams.setStyle(PVExcelExportStyler.class);
+            exportParamsList.add(exportParams);
+            exportParams.setType(ExcelType.XSSF);
+        }
+        Workbook workbook = PVExcelUtil.exportExcelTemplateWithMultiSheet(exportParamsList, entity, list);
+
+        return workbook;
+    }
+}

+ 20 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/regression/AnalysisConstants.java

@@ -0,0 +1,20 @@
+package com.lc.ibps.components.verification.regression;
+
+public class AnalysisConstants {
+
+    /**
+     * pearson常量
+     */
+    public static final String PEARSON_ID = "1001";
+
+    public static final String PEARSON_NAME = "pearson";
+
+    /**
+     * spearman常量
+     */
+    public static final String SPEARMAN_ID = "1002";
+
+    public static final String SPEARMAN_NAME = "spearman";
+
+    public static final String NULL_TARGET = "空指标ID";
+}

+ 50 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/regression/MultipleLinearRegression.java

@@ -0,0 +1,50 @@
+package com.lc.ibps.components.verification.regression;
+
+import org.apache.commons.math3.stat.regression.OLSMultipleLinearRegression;
+
+//多元线性回归 f(x, y . . .) = b0 + b1 * x + b2 * y + …
+public class MultipleLinearRegression extends Regression{
+
+    private final OLSMultipleLinearRegression ols;
+
+    MultipleLinearRegression() {
+        ols = new OLSMultipleLinearRegression();
+    }
+
+    public void addData(double[][] xArray, double[] yArray, int numberOfIndependent) {
+
+        int dfDependent = yArray.length - numberOfIndependent - 1;
+
+        ols.newSampleData(yArray, xArray);
+
+        this.setParameters(ols.estimateRegressionParameters());
+        this.setStdErrors(ols.estimateRegressionParametersStandardErrors());
+        this.setRSquared(ols.calculateRSquared());
+        this.setAdjRSquared(ols.calculateAdjustedRSquared());
+        this.setDfDependent(dfDependent);
+        this.setDfIndependent(numberOfIndependent);
+
+        this.setFValue(((ols.calculateTotalSumOfSquares() - ols.calculateResidualSumOfSquares()) / numberOfIndependent) / (ols.calculateResidualSumOfSquares() / dfDependent));
+        this.setHasData(true);
+
+    }
+
+    public String getFunction() {
+
+        if (!this.isHasData()) {
+            return "未构造数据";
+        }
+
+        final double[] parameters = this.getParameters();
+        StringBuilder function = new StringBuilder("y =  ");
+        for (int i = 0; i < parameters.length; i++) {
+            function.append(parameters[i]).append("x").append(i);
+            if (i != (parameters.length -1)) {
+                function.append(" + ");
+            }
+
+        }
+        return function.toString();
+    }
+
+}

+ 86 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/regression/PolynomialRegression.java

@@ -0,0 +1,86 @@
+package com.lc.ibps.components.verification.regression;
+
+import org.apache.commons.math3.stat.regression.OLSMultipleLinearRegression;
+
+import java.util.ArrayList;
+import java.util.List;
+//多项式回归 y = b0 + b1 * x + b2 * x^2 + …
+public class PolynomialRegression extends Regression{
+
+    private final OLSMultipleLinearRegression ols;
+
+    private double[] tValue;
+
+    public PolynomialRegression() {
+        ols = new OLSMultipleLinearRegression();
+    }
+
+
+    public void addData(double[] xArray, double[] yArray, int repeatNum, int power) {
+
+        double[][] independentVariable = generateVariable(xArray, power);
+        int dfDependent = yArray.length * repeatNum - power - 1;
+
+        ols.newSampleData(yArray, independentVariable);
+
+        this.setParameters(ols.estimateRegressionParameters());
+        this.setStdErrors(ols.estimateRegressionParametersStandardErrors());
+        this.setRSquared(ols.calculateRSquared());
+        this.setAdjRSquared(ols.calculateAdjustedRSquared());
+        this.setDfDependent(dfDependent);
+        this.setDfIndependent(power);
+        this.setStdError(ols.estimateRegressionStandardError());
+
+        this.setFValue(((ols.calculateTotalSumOfSquares() - ols.calculateResidualSumOfSquares()) / power) / (ols.calculateResidualSumOfSquares() / dfDependent));
+        generateTValue();
+        this.setHasData(true);
+
+    }
+
+    private void generateTValue(){
+        tValue = new double[getParameters().length];
+        for (int i = 0; i < getParameters().length; i++) {
+            tValue[i] = getParameters()[i] / getStdErrors()[i];
+        }
+
+    }
+    /**
+     * 生成多项式自变量数据
+     */
+    public static double[][] generateVariable(double[] xArray, int power) {
+
+        List<double[]> data = new ArrayList<>();
+
+        for (final double x : xArray) {
+            double[] item = new double[power];
+            for (int i = 0; i < power; i++) {
+                item[i] = Math.pow(x, i + 1);
+            }
+            data.add(item);
+        }
+        return data.toArray(new double[0][]);
+    }
+
+
+    public String getFunction() {
+        if (!this.isHasData()) {
+            return "未构造数据";
+        }
+        final double[] parameters = this.getParameters();
+        StringBuilder function = new StringBuilder("y =  ");
+        for (int i = 0; i < parameters.length; i++) {
+            function.append(parameters[i]);
+            for (int j = 0; j < i; j++) {
+                function.append(" x ");
+                if (j != (i - 1)) {
+                    function.append("*");
+                }
+            }
+            if (i != (parameters.length -1)) {
+                function.append(" + ");
+            }
+
+        }
+        return function.toString();
+    }
+}

+ 96 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/regression/Regression.java

@@ -0,0 +1,96 @@
+package com.lc.ibps.components.verification.regression;
+
+public class Regression {
+
+    private double rSquared;
+
+    private double adjRSquared;
+
+    private double[] parameters;
+
+    private double[] stdErrors;
+    private double stdError;
+
+    private double fValue;
+
+    private boolean hasData;
+
+    private Integer dfDependent;
+
+    private Integer dfIndependent;
+
+    public Integer getDfDependent() {
+        return dfDependent;
+    }
+
+    public void setDfDependent(Integer dfDependent) {
+        this.dfDependent = dfDependent;
+    }
+
+    public Integer getDfIndependent() {
+        return dfIndependent;
+    }
+
+    public void setDfIndependent(Integer dfIndependent) {
+        this.dfIndependent = dfIndependent;
+    }
+
+    public Regression() {
+    }
+
+    public double getRSquared() {
+        return rSquared;
+    }
+
+    public void setRSquared(double rSquared) {
+        this.rSquared = rSquared;
+    }
+
+    public double getAdjRSquared() {
+        return adjRSquared;
+    }
+
+    public void setAdjRSquared(double adjRSquared) {
+        this.adjRSquared = adjRSquared;
+    }
+
+    public double[] getParameters() {
+        return parameters;
+    }
+
+    public void setParameters(double[] parameters) {
+        this.parameters = parameters;
+    }
+
+    public double[] getStdErrors() {
+        return stdErrors;
+    }
+
+    public void setStdErrors(double[] stdErrors) {
+        this.stdErrors = stdErrors;
+    }
+
+    public boolean isHasData() {
+        return hasData;
+    }
+
+    public void setHasData(boolean hasData) {
+        this.hasData = hasData;
+    }
+
+    public double getFValue() {
+        return fValue;
+    }
+
+    public void setFValue(double fValue) {
+        this.fValue = fValue;
+    }
+
+    public double getStdError() {
+        return stdError;
+    }
+
+    public void setStdError(double stdError) {
+        this.stdError = stdError;
+    }
+}

+ 50 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/regression/SimpleLinearRegression.java

@@ -0,0 +1,50 @@
+package com.lc.ibps.components.verification.regression;
+
+import org.apache.commons.math3.stat.regression.RegressionResults;
+import org.apache.commons.math3.stat.regression.SimpleRegression;
+//一元线性回归 y = b0 + b1 * x
+public class SimpleLinearRegression extends Regression{
+
+    private final SimpleRegression regression;
+
+    public SimpleLinearRegression() {
+        this.regression = new SimpleRegression();
+    }
+
+
+    public void addData(final double[][] data) {
+
+        regression.addData(data); // 数据集
+
+        this.setHasData(true);
+
+        RegressionResults results = regression.regress();
+
+        this.setParameters(results.getParameterEstimates());
+        this.setRSquared(results.getRSquared());
+        this.setAdjRSquared(results.getAdjustedRSquared());
+        this.setStdErrors(results.getStdErrorOfEstimates());
+
+        this.setFValue((results.getRegressionSumSquares()) / (results.getErrorSumSquares()  / (data.length -2)) );
+
+    }
+
+
+    public String getFunction() {
+
+        if (!this.isHasData()) {
+            return "未构造数据";
+        }
+
+        double b0 = this.getParameters()[0];
+        double b1 = this.getParameters()[1];
+
+        return "f(x) =" +
+                (b0 >= 0 ? " " : " - ") +
+                Math.abs(b0) +
+                (b1 > 0 ? " + " : " - ") +
+                Math.abs(b1) +
+                "x";
+    }
+
+}

+ 212 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/regression/StatisticsTest.java

@@ -0,0 +1,212 @@
+package com.lc.ibps.components.verification.regression;
+
+import org.apache.commons.math3.distribution.TDistribution;
+import org.apache.commons.math3.stat.StatUtils;
+import org.apache.commons.math3.stat.inference.ChiSquareTest;
+import org.apache.commons.math3.stat.inference.OneWayAnova;
+import org.apache.commons.math3.stat.inference.TTest;
+import org.apache.commons.math3.stat.inference.TestUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class StatisticsTest {
+    //一元线性回归测试
+    public static void test1() {
+
+        double[][] data = linearScatters();
+
+        SimpleLinearRegression re = new SimpleLinearRegression();
+
+        re.addData(data);
+
+        System.out.println("R方为"+ re.getRSquared());
+        System.out.println("调整R方为"+ re.getAdjRSquared());
+        System.out.println(re.getFunction());
+        System.out.println("标准误为:" + re.getStdErrors()[0]);
+
+        System.out.println("f值:" + re.getFValue() );
+        System.out.println("f检验P值:" + StatisticsUtil.getPValue(re.getFValue(), 1, data.length - 2));
+
+    }
+
+    public static double[][] linearScatters() {
+        List<double[]> data = new ArrayList<>();
+        for (double x = 0; x <= 10; x += 0.1) {
+            double y = 1.5 * x + 0.5;
+            y += Math.random() * 60 - 2; // 随机数
+            double[] xy = {x, y};
+            data.add(xy);
+        }
+        return data.stream().toArray(double[][]::new);
+    }
+//多项式回归测试
+    public static void test2() {
+        // 自变量数据
+//        double[] xArray = new double[100];
+//        double k = 0.0;
+//        for (int i = 0; i < 100; i++) {
+//            xArray[i] = k;
+//            k += 0.1;
+//        }
+//
+//        // 因变量数据
+//        double[] yArray = new double[100];
+//
+//        for (int i = 0; i < xArray.length; i++) {
+//            double x = xArray[i];
+//            double x1 = x;
+//            double x2 = x * x;
+//            double x3 = x * x * x;
+//            yArray[i] = 20 + 2 * x1 + 12 * x2 + 8 * x3 + Math.random() * x1 * 500;
+//        }
+
+//        w.add(0,-0.01);
+//        w.add(4.91,5);
+//        w.add(9.82,10.12);
+//        w.add(14.74,14.65);
+//        w.add(19.65,19.61);
+//        w.add(24.56,24.06);
+        double[] xArray = {0,4.91,9.82,14.74,19.65,24.56};
+        double[] yArray = {-0.01,5,10.12,14.65,19.61,24.06};
+        final PolynomialRegression po = new PolynomialRegression();
+        po.addData(xArray, yArray, 1, 3);
+
+        System.out.println("R方为"+ po.getRSquared());
+        System.out.println("调整R方为"+ po.getAdjRSquared());
+        System.out.println(po.getFunction());
+        System.out.println("标准误为:" + Arrays.toString(po.getStdErrors()));
+
+        System.out.println("f值:" + po.getFValue() );
+        System.out.println("f检验P值:" + StatisticsUtil.getPValue(po.getFValue(), 3, yArray.length - 4));
+        TDistribution t = new TDistribution(16);
+//        t.inverseCumulativeProbability(1 - p/2);
+        System.out.println((1-t.cumulativeProbability(0.5)));
+
+//        单样本t检验 (单样本 t 检验是一种用于检验一个样本均值是否与一个已知的总体均值显著不同的统计学方法。在单样本 t 检验中,我们需要计算一个 t 统计量,其基于样本均值、样本标准差和样本大小,然后使用 t 分布表来确定 p 值)
+        //////////////////////
+        // 模拟一个样本数据
+        double[] sampleData = {10.2, 8.1, 9.5, 11.2, 12.5, 10.8, 8.9, 9.6, 10.1, 11.0};
+
+// 假设总体均值为10
+        double populationMean = 10.0;
+
+// 创建TTest对象,并进行单样本t检验
+        TTest tTest = new TTest();
+        double pValue = tTest.tTest(populationMean, sampleData);
+
+// 输出检验结果
+        System.out.println("样本数据的平均值为:" + StatUtils.mean(sampleData));
+        System.out.println("样本数据的标准差为:" + Math.sqrt(StatUtils.variance(sampleData)));
+        System.out.println("总体均值为:" + populationMean);
+        System.out.println("p值为:" + pValue);
+        System.out.println("t: "+ TestUtils.t(populationMean, sampleData));
+        System.out.println("p: "+TestUtils.tTest(populationMean, sampleData));
+        System.out.println("显著性水平: "+TestUtils.tTest(populationMean, sampleData, 0.05));
+
+// 判断p值是否小于0.05,如果小于0.05则拒绝零假设
+        if (pValue < 0.05) {
+            System.out.println("拒绝零假设,样本均值与总体均值显著不同。");
+        } else {
+            System.out.println("不能拒绝零假设,样本均值与总体均值可能相同。");
+        }
+
+
+
+
+//        5) 卡方检验(用于确定观察到的频数与期望的频数之间是否存在显著差异)
+
+        long[] observed = {10, 9, 11};
+        double[] expected = {10.1, 9.8, 10.3};
+// 设置显著性水平
+        double alpha = 0.05;
+
+        ChiSquareTest chiSquareTest = new ChiSquareTest();
+        boolean result = chiSquareTest.chiSquareTest(expected, observed, alpha);
+
+// 输出结果
+        if (result) {
+            System.out.println("拒绝零假设");
+        } else {
+            System.out.println("接受零假设");
+        }
+//        6)单因素方差分析检验ANOVA(用于比较多个组或处理之间的均值是否存在显著差异。它用于确定一个因素(独立变量)对一个连续的因变量是否有影响)
+
+// 定义三个组的数据
+        double[] group1 = {93.0, 103.0, 95.0, 101.0, 91.0, 105.0, 96.0, 94.0, 101.0};
+        double[] group2 = {99.0, 92.0, 102.0, 100.0, 102.0, 89.0};
+        double[] group3 = {110.0, 115.0, 111.0, 117.0, 128.0, 117.0 };
+
+// 将三个组的数据合并到一个二维数组中
+        ArrayList<double[]> classes = new ArrayList<>();
+        classes.add(group1);
+        classes.add(group2);
+        classes.add(group3);
+//double[][] data = {group1, group2, group3};
+
+// 进行单因素方差分析检验
+        OneWayAnova anova = new OneWayAnova();
+        double fValue = anova.anovaFValue(classes);
+
+// 打印F值和P值
+        System.out.println("F值:" + fValue);
+        System.out.println("P值:" + anova.anovaPValue(classes));
+
+//另外的方法
+        double fStatistic = TestUtils.oneWayAnovaFValue(classes); // F-value
+        double pValue2 = TestUtils.oneWayAnovaPValue(classes);     // P-value
+        System.out.println("F: "+fStatistic);
+        System.out.println("P: "+pValue2);
+    }
+    //多元回归分析测试
+    public static void test3() {
+        double[][] x = randomX3();
+        double[] y = randomY3(x);
+
+        MultipleLinearRegression mul = new MultipleLinearRegression();
+        mul.addData(x, y, 2);
+
+        System.out.println(mul.getFunction());
+        System.out.println("标准误: "  + mul.getStdErrors()[0]);
+        System.out.println("R方 : " + mul.getRSquared());
+        System.out.println("调整后R方 :" + mul.getAdjRSquared());
+        System.out.println("f值:" + mul.getFValue()) ;
+
+        System.out.println("f检验P值:" + StatisticsUtil.getPValue(mul.getFValue(), mul.getDfIndependent(), mul.getDfDependent() ));
+    }
+
+    public static double[][] randomX3() {
+        List<double[]> data = new ArrayList<>();
+        for (double i = 0; i < 10; i += 0.1) {
+            double x1 = i;
+            double x2 = Math.sqrt(i);
+            data.add(new double[]{x1, x2});
+        }
+        return data.stream().toArray(double[][]::new);
+    }
+
+    public static double[] randomY3(double[][] arr) {
+        if (arr != null && arr.length > 0) {
+            int len = arr.length;
+            double[] y = new double[len];
+            for (int i = 0; i < len; i++) {
+                double[] x = arr[i];
+                // 构造数据
+                y[i] = functionConstructorY3(x);
+            }
+            return y;
+        }
+        return null;
+    }
+
+    public static double functionConstructorY3(double[] x) {
+        double x1 = x[0];
+        double x2 = x[1];
+        return 20 + 2 * x1 + 3 * x2 + Math.random() * 30;
+    }
+
+    public static void main(String[] args){
+        test2();
+    }
+}

+ 228 - 0
ibps-provider-root/modules/provider-business/src/main/java/com/lc/ibps/components/verification/regression/StatisticsUtil.java

@@ -0,0 +1,228 @@
+package com.lc.ibps.components.verification.regression;
+
+import JSci.maths.statistics.FDistribution;
+import JSci.maths.statistics.TDistribution;
+import org.apache.commons.math3.exception.DimensionMismatchException;
+import org.apache.commons.math3.stat.correlation.PearsonsCorrelation;
+import org.apache.commons.math3.stat.correlation.SpearmansCorrelation;
+import org.apache.commons.math3.stat.descriptive.moment.Mean;
+import org.apache.commons.math3.stat.descriptive.moment.StandardDeviation;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.lc.ibps.components.verification.regression.AnalysisConstants.PEARSON_ID;
+import static com.lc.ibps.components.verification.regression.AnalysisConstants.SPEARMAN_ID;
+
+/**
+ * Statistics
+ * 统计工具类,使用统计工具用于做统计学数据分析,将计算方法进行集成调用
+ * @author pyy
+ * @since 2022/9/23 17:07
+ */
+public class StatisticsUtil {
+
+    private final  StatisticsUtil stat = new StatisticsUtil();
+
+    private static final double  NO_VALUE = Double.NaN;
+
+    private StatisticsUtil() {
+    }
+
+    public StatisticsUtil getInstance() {
+
+        return stat;
+
+    }
+
+    /**
+     * 计算数据均值
+     * @param values 双精度数组
+     * @return 平均值
+     */
+    public static double computeMean(final double[] values) {
+        if (testNull(values)) {
+            return NO_VALUE;
+        }
+        Mean mean = new Mean();
+        return mean.evaluate(values);
+    }
+
+    /**
+     * 计算数据标准差
+     * @param values 双精度数组
+     * @return 标准差
+     */
+    public static double computeStandardDeviation(final double[] values) {
+        if (testNull(values)) {
+            return NO_VALUE;
+        }
+        StandardDeviation sd = new StandardDeviation();
+        return sd.evaluate(values);
+    }
+
+    /**
+     * 获取数据最大值
+     * @param values 双精度数组
+     * @return 最大值
+     */
+    public static double getMaxValue(final double[] values) {
+        if (testNull(values)) {
+            return NO_VALUE;
+        }
+        Arrays.sort(values);
+        return values[values.length - 1];
+    }
+
+
+    /**
+     * 获取数据最小值
+     * @param values 双精度数组
+     * @return 最小值
+     */
+    public static double getMinValue(final double[] values) {
+        if (testNull(values)) {
+            return NO_VALUE;
+        }
+        Arrays.sort(values);
+        return values[0];
+    }
+
+    /**
+     * 获取数据最大值和最小值
+     * @param values - 双精度数组
+     * @return map<String, Double>
+     */
+    public static Map<String, Double> getMaxAndMin(final double[] values) {
+        Map<String, Double> result = new HashMap<>(16);
+        result.put("max", NO_VALUE);
+        result.put("min", NO_VALUE);
+        if (testNull(values)) {
+            return result;
+        }
+        Arrays.sort(values);
+        result.clear();
+        result.put("max", values[values.length - 1]);
+        result.put("min", values[0]);
+        return result;
+    }
+
+    /**
+     * 计算两个数据之间的相关系数
+     * @param xArray -- 双精度数组
+     * @param yArray -- 双精度数组
+     * @param methodId -- 相关系数方法
+     * @return double
+     */
+    public static double correlation(final double[] xArray, final double[] yArray, String methodId) {
+
+        double value = NO_VALUE;
+        if (xArray.length != yArray.length) {
+            throw new DimensionMismatchException(xArray.length, yArray.length);
+        } else if (xArray.length < 2) {
+            return value;
+        } else {
+            if (PEARSON_ID.equals(methodId)) {
+                PearsonsCorrelation pearsonsCorrelation = new PearsonsCorrelation();
+                value = pearsonsCorrelation.correlation(xArray, yArray);
+            } else if (SPEARMAN_ID.equals(methodId)) {
+                SpearmansCorrelation spearmansCorrelation = new SpearmansCorrelation();
+                value = spearmansCorrelation.correlation(xArray, yArray);
+            }
+
+        }
+        return value;
+    }
+
+    /**
+     * 计算两个数据之间的相关系数
+     * @param xArray -- 双精度数组
+     * @param yArray -- 双精度数组
+     * @return double
+     */
+    public static double correlation(final double[] xArray, final double[] yArray) {
+        return correlation(xArray, yArray, PEARSON_ID);
+    }
+
+
+    /**
+     * 计算显著性p值算法
+     * @param rValue 相关系数
+     * @param n 分析数据的个数
+     * @param methodId 使用的方法
+     * @return p-value
+     */
+    public static double getPValue(final double rValue, final int n, String methodId) {
+
+        if (n < 2) {
+            return NO_VALUE;
+        }
+        double pValue = NO_VALUE;
+        double tValue = ((rValue * Math.sqrt(n-2)) / (Math.sqrt(1 - (rValue * rValue))));
+        int free= n-2;
+        TDistribution td=new TDistribution(free);
+        if (PEARSON_ID.equals(methodId)) {
+
+            double cumulative = td.cumulative(tValue);
+            if(tValue>0) {
+                pValue=(1-cumulative)*2;
+            }else {
+                pValue=cumulative*2;
+            }
+
+        } else if (SPEARMAN_ID.equals(methodId)) {
+            if (n > 500) {
+                tValue = (rValue * Math.sqrt(n-1));
+            }
+
+            double cumulative = td.cumulative(tValue);
+            if(tValue>0) {
+                pValue=(1-cumulative)*2;
+            }else {
+                pValue=cumulative*2;
+            }
+
+        }
+
+        return pValue;
+    }
+
+    /**
+     * T检验 - 计算显著性p值算法
+     * @param rValue 相关系数
+     * @param n 分析数据的个数
+     * @return p-value
+     */
+    public static double getPValue(final double rValue, final int n) {
+        return getPValue(rValue, n, PEARSON_ID);
+    }
+
+    /**
+     * 判空
+     * @param values 双精度数组
+     * @return boolean
+     */
+    private static boolean testNull(final double[] values) {
+        return values == null;
+    }
+
+    /**
+     * F检验 - 计算显著性p值算法
+     * @param fValue f检验值 (ESS/K)/(RSS/(n-k-1))
+     * @param dgrP X的自由度 即为自变量的个数
+     * @param dgrQ Y的自由度 样本数 - 自变量个数 -1
+     * @return P-Value
+     */
+    public static double getPValue(double fValue, int dgrP, int dgrQ) {
+
+        FDistribution fd=new FDistribution(dgrP, dgrQ);
+
+        double cumulative = fd.cumulative(fValue);
+
+        return (1-cumulative);
+    }
+
+
+
+}