• JS 对数据进行 正态分布拟合对比(echarts 做图)


    对一组看似正态分布的数据进行标准正态分布的拟合,用来做对比

    准备:math.js

    给定一组数据

    yData = [
    53, 53, 58.5, 78, 115, 154.5, 200, 300.5, 383.5, 518, 871.5, 1382.5, 2192.5, 3340.5, 5249, 8979.5, 15448, 26225, 44057.5, 71392, 109113, 159006, 224595.5, 307191.5, 405623, 520332, 646965.5, 785170.5, 930962.5, 1078572.5, 1227179.5, 1373870, 1522723.5, 1671622.5, 1812839.5, 1944963, 2068185, 2180604.5, 2280685.5, 2361196.5, 2417123.5, 2457786, 2483891, 2494890, 2496943.5, 2498862.5, 2500857.5, 2500175, 2501485, 2499141, 2492862, 2478390, 2459869.5, 2443707, 2430140, 2421345.5, 2404805, 2377592.5, 2334130, 2263164, 2163510.5, 2031018.5, 1872739.5, 1698482, 1507286, 1306381.5, 1114865.5, 938499, 771654.5, 619227.5, 488654.5, 379699.5, 289925.5, 218837.5, 165510.5, 126806, 97552, 75560, 59062, 46304.5, 36476, 28583, 22280.5, 16965.5, 12631.5, 9265.5, 6629, 4548.5, 3091, 2102.5, 1396.5, 921, 580, 345, 203.5, 137, 87, 46, 27.5, 12, 6
    ]

    xData=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]

    绘制的图形如下

     现在要对这个曲线进行正态分布的拟合

      1.求出均值

        

    var yArr = [];var sumFuc = (s, c) => formulaCalcByFunc(s + c, 6);//求和匿名函数,formulaCalc为了减少精度误差,可以自己写var ysum = yData.reduce(sumFuc, 0);
    for (var n = 0; n < yData.length; n++) {
    var y = yData[n] / ysum;
    yArr.push(y);
    }
    var avg = math.mean(yArr);

      2.编写最小二乘法高斯拟合函数

    function gaussFit(xOriginal, yOriginal, average) {
        var x = [];
        var y = [];
        // 过滤平滑部分
        for (var i = 0; i < yOriginal.length; i++)
            if (yOriginal[i] > average) {
                x.push(xOriginal[i]);
                y.push(yOriginal[i]);
            }
    
        var zMatrix = math.matrix(math.log(y));
        var zMatrixT = math.transpose(zMatrix);
        var xMatrix = math.ones([y.length, 3]);
    
        for (var j = 0; j < y.length; j++) {
            xMatrix[j][1] = x[j];
            xMatrix[j][2] = x[j] * x[j];
        }
        // 最小二乘法
        var xMatrixT = math.transpose(xMatrix);
        var bMatrix = math.multiply(math.multiply(math.inv(math.multiply(xMatrixT,xMatrix)), xMatrixT), zMatrixT);
    
        var b2 = math.subset(bMatrix, math.index(2));
        var b1 = math.subset(bMatrix, math.index(1));
        var b0 = math.subset(bMatrix, math.index(0));
    
        var s = -1 / b2;
        var xMaxi = s * b1 / 2;//均值
        var yMaxi = math.exp(b0 + xMaxi * xMaxi / s);//正态分布归一系数
    
        var yFit = []
        for (var n = 0; n < yOriginal.length; n++) {
            yFit.push(gaussFunc(xOriginal[n], xMaxi, yMaxi, s));
        }
    
        return yFit;
    }
    
    
    //正态分布公式
    function gaussFunc(x, xMaxi, yMaxi, s) {
    return yMaxi * math.exp(-((x - xMaxi) * (x - xMaxi) / s));
    }

      3.求出y轴数据的系数,并还原出原始数据

    datas2 = gaussFit(xArr, yArr, avg);
    for (var k = 0; k < datas2.length; k++) {
        var l = datas2[k] / yArr[k];
        var y = yData[k] * l;
        yData2.push(y);
    }

    最终绘制的图形如下:

     第二种方法,使用标准正态分布公式实现(结果将会偏向原始数据峰值):

    /**
    * 正态分布函数
    * @@param x 数据
    * @@param mean 平均数
    * @@param stdev 标准差
    */
    function normalDistributionfun(x, mean, stdev) {
        return (1 / (Math.sqrt(2 * Math.PI) * stdev)) * Math.exp(-1 * ((x - mean) * (x - mean)) / (2 * stdev * stdev));
    }
    
    
    function calcNormallineDta(xData, yData) {
                var result = [];
             
                var totalCount = 0;
    
                var firstMode = 0;//峰值起始位置
                var modeCount = 0;//找到目前数据的峰值
            
                for (var i = 0; i < yData.length;i++) {
                    totalCount += yData[i];
                    if (yData[i] > modeCount) {
                        modeCount = yData[i];
                        firstMode = i;
                    }
                 
                }
                //找出出x轴左右范围内的均值(关键代码)
                var mode = 0;
                var modeDuplicates = 0;
            
                var fellOffTop = true;
    
                for (var j = firstMode; j < yData.length; j ++) {
                    if (yData[j] > yData[firstMode] - (yData[firstMode]/10)) {//10:分布线系数
                        mode += j ;
                        modeDuplicates++;
                    }
                    else {
                        fellOffTop = false;
                        break;
                    }
                }
    
                var fellOffBottom = true;
            
                for (var k=firstMode-1;k>=0;k--) {
                    if (yData[k] > yData[firstMode] - (yData[firstMode] / 10)) {//10:分布线系数
                        mode += k;
                        modeDuplicates++;
                    }
                    else {
                        fellOffBottom = false;
                        break;
                    }
                }
                var mean;
                if (fellOffBottom || fellOffTop) {
                   
                    mean = firstMode;
                }
                else {
                    mean = mode/ modeDuplicates;
                }
                //求出标准差
              
                var stdev = 0;
            
                for (var n = 0; n < yData.length;n++) {
                    stdev += Math.pow((n - mean), 2) * yData[n];
                }
            
                stdev /= totalCount-1;
            
                stdev = Math.sqrt(stdev);
                //带入正态分布公式
                for (var m = 0; m < yData.length;m++) {
                    var probability =normalDistributionfun(m,mean,stdev);
                    result.push(Math.round(probability * totalCount*100)/100);
                }
                return result;
            }
          

     完整代码在echart作品上查看

    作品地址:https://gallery.echartsjs.com/editor.html?c=xBtzYvoXr2

  • 相关阅读:
    第37月第23天 cmmi3
    7. HTML Web Server的选择
    6. HTML URL字符编码
    5. HTML URL(Uniform Resource Locator 统一资源定位符)
    4. HTML 字符实体
    3. HTML 脚本
    2. HTML 头部 <head>
    1. HTML 文档类型 <!DOCTYPE>
    22. HTML 颜色名
    21. HTML 颜色
  • 原文地址:https://www.cnblogs.com/daxiongblog/p/12679363.html
Copyright © 2020-2023  润新知