C#与Minitab:Box-Cox变换最优Lambda值计算

需要安装包 MathNet.Numerics

公式地址

https://support.minitab.com/zh-cn/minitab/18/help-and-how-to/quality-and-process-improvement/control-charts/how-to/box-cox-transformation/methods-and-formulas/methods-and-formulas/

最优Lambda求解代码

using MathNet.Numerics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Spc.Core
{
    /// <summary>
    /// 最优Lambda求解
    /// </summary>
    public class OptimalSolutionLambda
    {
        private readonly double MAXLAMBDA = 5D;
        private readonly double MINLAMBDA = -5D;
        /// <summary>
        /// 最优Lambda求解 移动极差平均法
        /// </summary>
        /// <param name="sample"></param>
        /// <param name="step"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public double GetLambda(double[] sample, double step = 0.5D)
        {
            step = Math.Abs(step);
            if (step == 0)
            {
                throw new Exception("步长不能为0!");
            }
            double product = 1D;
            double geometricAverage;

            for (int i = 0; i < sample.Length; i++)
            {
                product = product.Mul(sample[i]);
            }

            IEstimateSigma sigma = new MovingRangeAverageEstimateSigma();

            geometricAverage = Math.Pow(product, 1 / sample.Length);

            Dictionary<double, double> list = new Dictionary<double, double>();

            for (double lambda = MINLAMBDA; lambda <= MAXLAMBDA; lambda = lambda.Add(step))
            {
                double[] zValue = new double[sample.Length];
                if (lambda == 0D)
                {
                    for (int i = 0; i < sample.Length; i++)
                    {
                        zValue[i] = geometricAverage.Mul(SpecialFunctions.Gamma(sample[i]));
                    }
                }
                else
                {
                    for (int i = 0; i < sample.Length; i++)
                    {
                        zValue[i] = (Math.Pow(sample[i], lambda).Sub(1)).Div(lambda.Mul(Math.Pow(geometricAverage, lambda.Sub(1))));
                    }
                }
                list.Add(lambda, sigma.GetSigma(zValue, true));
            }

            return list.First(m => m.Value == list.Min(m => m.Value)).Key;
        }
        /// <summary>
        /// 最优Lambda求解 合并标准差法
        /// </summary>
        /// <param name="sample"></param>
        /// <param name="step"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public double GetLambda(double[][] sample, double step = 0.5D)
        {
            step = Math.Abs(step);
            if (step == 0)
            {
                throw new Exception("步长不能为0!");
            }
            double product = 1;
            double geometricAverage;
            int count = 0;
            for (int i = 0; i < sample.Length; i++)
            {
                for (int j = 0; j < sample[i].Length; j++)
                {
                    product = product.Mul(sample[i][j]);
                    count++;
                }
            }

            IEstimateSigma sigma = new OverallEstimateSigma();

            geometricAverage = Math.Pow(product, 1 / count);

            Dictionary<double, double> list = new Dictionary<double, double>();

            for (double lambda = MINLAMBDA; lambda <= MAXLAMBDA; lambda = lambda.Add(step))
            {
                double[][] zValue = new double[sample.Length][];
                if (lambda == 0D)
                {
                    for (int i = 0; i < sample.Length; i++)
                    {
                        zValue[i] = new double[sample[i].Length];
                        for (int j = 0; j < sample[i].Length; j++)
                        {
                            zValue[i][j] = geometricAverage.Mul(SpecialFunctions.Gamma(sample[i][j]));
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < sample.Length; i++)
                    {
                        zValue[i] = new double[sample[i].Length];
                        for (int j = 0; j < sample[i].Length; j++)
                        {
                            zValue[i][j] = (Math.Pow(sample[i][j], lambda).Sub(1)).Div(lambda.Mul(Math.Pow(geometricAverage, lambda.Sub(1))));
                        }
                    }
                }
                list.Add(lambda, sigma.GetSigma(zValue, true));
            }

            return list.First(m => m.Value == list.Min(m => m.Value)).Key;
        }
    }
}

cut-off

Box-Cox 变换代码

using MathNet.Numerics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Spc.Core
{
    /// <summary>
    ///  Box-Cox
    /// </summary>
    public class BoxCoxFunc
    {
        /// <summary>
        /// Box-Cox转换
        /// </summary>
        /// <param name="sample"></param>
        /// <param name="lambda"></param>
        /// <returns></returns>
        public double[] Transform(double[] sample, double lambda)
        {
            double[] result = new double[sample.Length];
            if (lambda == 0D)
            {
                for (int i = 0; i < sample.Length; i++)
                {
                    result[i] = Math.Pow(sample[i], lambda);
                }
            }
            else
            {
                for (int i = 0; i < sample.Length; i++)
                {
                    result[i] = Math.Log(sample[i]);
                }
            }
            return result;
        }
        /// <summary>
        /// Box-Cox转换
        /// </summary>
        /// <param name="sample"></param>
        /// <param name="lambda"></param>
        /// <returns></returns>
        public double[][] Transform(double[][] sample, double lambda)
        {
            double[][] result = new double[sample.Length][];
            if (lambda == 0D)
            {
                for (int i = 0; i < sample.Length; i++)
                {
                    result[i] = new double[sample[i].Length];
                    for (int j = 0; j < sample[i].Length; j++)
                    {
                        result[i][j] = Math.Pow(sample[i][j], lambda);
                    }
                }
            }
            else
            {
                for (int i = 0; i < sample.Length; i++)
                {
                    result[i] = new double[sample[i].Length];
                    for (int j = 0; j < sample[i].Length; j++)
                    {
                        result[i][j] = Math.Log(sample[i][j]);
                    }
                }
            }
            return result;
        }
    }
}

cut-off

---------------------------------END--------------------------------

QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空