C#,数值计算——用于从连续的数据值流估计任意分位数的计算方法与源程序

1 分位数Quantile

分位数(Quantile),亦称分位点,是指将一个随机变量的概率分布范围分为几个等份的数值点,常用的有中位数(即二分位数)、四分位数、百分位数等。

2 常见各类分位数

2.1 二分位数

对于有限的数集,可以通过把所有观察值高低排序后找出正中间的一个作为中位数。如果观察值有偶数个,则中位数不唯一,通常取最中间的两个数值的平均数作为中位数,即二分位数。
一个数集中最多有一半的数值小于中位数,也最多有一半的数值大于中位数。如果大于和小于中位数的数值个数均少于一半,那么数集中必有若干值等同于中位数。
计算有限个数的数据的二分位数的方法是:把所有的同类数据按照大小的顺序排列。如果数据的个数是奇数,则中间那个数据就是这群数据的中位数;如果数据的个数是偶数,则中间那2个数据的算术平均值就是这群数据的中位数。

2.2 四分位数

四分位数(Quartile)是统计学中分位数的一种,即把所有数值由小到大排列并分成四等份,处于三个分割点位置的数值就是四分位数。
1)第一四分位数(Q1),又称“较小四分位数”,等于该样本中所有数值由小到大排列后第25%的数字;
2)第二四分位数(Q2),又称“中位数”,等于该样本中所有数值由小到大排列后第50%的数字;
3)第三四分位数(Q3),又称“较大四分位数”,等于该样本中所有数值由小到大排列后第75%的数字。
第三四分位数与第一四分位数的差距又称四分位距。

2.3 百分位数

百分位数,统计学术语,如果将一组数据从小到大排序,并计算相应的累计百分位,则某一百分位所对应数据的值就称为这一百分位的百分位数。运用在教育统计学中,例如表现测验成绩时,称PR值。

3 分位数的应用

分位数回归思想的提出至今已经有近30多年了,经过这近30多年的发展,分位数回归在理论和方法上都越来越成熟,并被广泛应用于多种学科中。它对于实际问题能提供更加全面的分析,无论是线性模型还是非线性模型,分位数回归都是一种很好的工具,它对一般回归模型做了有益的补充。

分位数回归是对以古典条件均值模型为基础的最小二乘法的延伸,它用几个分位函数来估计整体模型。分位数回归法的特殊情况就是中位数回归(最小一乘回归),用对称权重解决残差最小化问题,而其他条件分位数回归则需要用非对称权重解决残差最小化 [2] 。

分位数回归采用加权残差绝对值之和的方法估计参数,其优点体现在以下几方面:首先,它对模型中的随机扰动项不需做任何分布的假定,这样整个回归模型就具有很强的稳健性;其次,分位数回归本身没有使用一个连接函数来描述因变量的均值和方差的相互关系,因此分位数回归有着比较好的弹性性质;第三,分位数回归由于是对所有分位数进行回归,因此对于数据中出现的异常点具有耐抗性;第四,不同于普通的最小二乘回归,分位数回归对于因变量具有单调变换性;最后,分位数回归估计出来的参数具有在大样本理论下的渐进优良性。

4 计算分位数的C#源程序

using System;

namespace Legalsoft.Truffer
{
    /// <summary>
    /// Object for estimating arbitrary quantile values 
    /// from a continuing stream of data values.
    /// </summary>
    public class IQagent
    {
        public const int nbuf = 1000;
        private int nq { get; set; }
        private int nt { get; set; }
        private int nd { get; set; }
        private double[] pval { get; set; }
        private double[] dbuf;
        private double[] qile { get; set; }
        private double q0 { get; set; }
        private double qm { get; set; }

        public IQagent()
        {
            this.nq = 251;
            this.nt = 0;
            this.nd = 0;
            this.pval = new double[nq];
            this.dbuf = new double[nbuf];
            this.qile = new double[nq];
            this.q0 = 1.0e99;
            this.qm = -1.0e99;

            for (int j = 85; j <= 165; j++)
            {
                pval[j] = (j - 75.0) / 100.0;
            }

            // Set general purpose array of p - values ranging from 1.0e-6 to 1~1.0e-6.
            // You can change this if you want.
            for (int j = 84; j >= 0; j--)
            {
                pval[j] = 0.87191909 * pval[j + 1];
                pval[250 - j] = 1.0 - pval[j];
            }
        }

        /// <summary>
        /// Assimilate a new value from the stream.
        /// </summary>
        /// <param name="datum"></param>
        public void add(double datum)
        {
            dbuf[nd++] = datum;
            if (datum < q0)
            {
                q0 = datum;
            }
            if (datum > qm)
            {
                qm = datum;
            }
            if (nd == nbuf)
            {
                update();
            }
        }

        /// <summary>
        /// Batch update.
        /// This function is called by add or report and should not be called directly
        /// by the user.
        /// </summary>
        public void update()
        {
            int jd = 0;
            int jq = 1;
            double told = 0.0;
            double tnew = 0.0;
            double[] newqile = new double[nq];

            Sorter.sort(dbuf, nd);

            double qold = q0;
            double qnew = q0;
            qile[0] = newqile[0] = q0;
            qile[nq - 1] = newqile[nq - 1] = qm;
            pval[0] = Math.Min(0.5 / (nt + nd), 0.5 * pval[1]);
            pval[nq - 1] = Math.Max(1.0 - 0.5 / (nt + nd), 0.5 * (1.0 + pval[nq - 2]));
            for (int iq = 1; iq < nq - 1; iq++)
            {
                double target = (nt + nd) * pval[iq];
                if (tnew < target)
                {
                    for (; ; )
                    {
                        if (jq < nq && (jd >= nd || qile[jq] < dbuf[jd]))
                        {
                            qnew = qile[jq];
                            tnew = jd + nt * pval[jq++];
                            if (tnew >= target)
                            {
                                break;
                            }
                        }
                        else
                        {
                            qnew = dbuf[jd];
                            tnew = told;
                            if (qile[jq] > qile[jq - 1])
                            {
                                tnew += nt * (pval[jq] - pval[jq - 1]) * (qnew - qold) / (qile[jq] - qile[jq - 1]);
                            }
                            jd++;
                            if (tnew >= target)
                            {
                                break;
                            }
                            told = tnew++;
                            qold = qnew;
                            if (tnew >= target)
                            {
                                break;
                            }
                        }
                        told = tnew;
                        qold = qnew;
                    }
                }
                //if (tnew == told)
                if (Math.Abs(tnew - told) <= float.Epsilon)
                {
                    newqile[iq] = 0.5 * (qold + qnew);
                }
                else
                {
                    newqile[iq] = qold + (qnew - qold) * (target - told) / (tnew - told);
                }
                told = tnew;
                qold = qnew;
            }
            // qile = newqile;
            qile = Globals.CopyFrom(newqile);
            nt += nd;
            nd = 0;
        }

        /// <summary>
        /// Return estimated p-quantile for 
        /// the data seen so far. (E.g., p D 0:5 for median.)
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public double report(double p)
        {
            if (nd > 0)
            {
                update();
            }
            int jl = 0;
            int jh = nq - 1;
            int j;
            while (jh - jl > 1)
            {
                j = (jh + jl) >> 1;
                if (p > pval[j])
                {
                    jl = j;
                }
                else
                {
                    jh = j;
                }
            }
            j = jl;
            double q = qile[j] + (qile[j + 1] - qile[j]) * (p - pval[j]) / (pval[j + 1] - pval[j]);
            return Math.Max(qile[0], Math.Min(qile[nq - 1], q));
        }
    }
}
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/62463.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java可执行命令】(十八)可视化监控和管理工具 jconsole:获取 JVM的内存使用情况、线程活动、GC 行为等重要指标的可视化工具 ~

Java可执行命令之jconsole 1️⃣ 概念2️⃣ 优势和缺点3️⃣ 使用3.1 语法格式3.2 注意事项 4️⃣ 应用场景&#x1f33e; 总结 1️⃣ 概念 jconsole 是 Java Development Kit (JDK) 自带的一款图形化监控和管理工具。它旨在提供一个简单而强大的界面&#xff0c;用于监视和管…

在安装 ONLYOFFICE 协作空间社区版时如何使用额外脚本参数

ONLYOFFICE 协作空间社区版是免费的文档中心工具&#xff0c;可帮助您将用户与文档聚合至同一处&#xff0c;提高协作效率。 ONLYOFFICE 协作空间主要功能 使用 ONLYOFFICE 协作空间&#xff0c;您可以&#xff1a; 邀请他人&#xff0c;协作和沟通完成工作创建协作房间&…

【生成式AI】ProlificDreamer论文阅读

ProlificDreamer 论文阅读 Project指路&#xff1a;https://ml.cs.tsinghua.edu.cn/prolificdreamer/ 论文简介&#xff1a;截止2023/8/10&#xff0c;text-to-3D的baseline SOTA&#xff0c;提出了VSD优化方法 前置芝士:text-to-3D任务简介 text-to-3D Problem text-to-3D…

【解密算法:时间与空间的博弈】

本章重点 ​​什么是数据结构&#xff1f; 什么是算法&#xff1f; 算法效率 时间复杂度 空间复杂度 常见时间复杂度以及复杂度oj练习 1. 什么是数据结构&#xff1f; 数据结构(Data Structure)是计算机存储、组织数据的方式&#xff0c;指相互之间存在一种或多种特定关系…

AI抢饭碗!多部由Midjourney+Runway,制作的电影火了!丨IDCF

ChatGPT等生成式AI正在重塑各个行业的工作模式&#xff0c;尤其是影视领域。最近&#xff0c;多部由MidjourneyRunway生成式AI制作的电影预告片在社交平台上火了。 一部名叫的《芭本海默》的电影从对白、场景、人物、切镜完全由生成式AI制作完成并受到了用户的好评。该片结合了…

年轻代频繁GC ParNew导致http变慢

背景介绍 某日下午大约四点多&#xff0c;接到合作方消息&#xff0c;线上环境&#xff0c;我这边维护的某http服务突然大量超时&#xff08;对方超时时间设置为300ms&#xff09;&#xff0c;我迅速到鹰眼平台开启采样&#xff0c;发现该服务平均QPS到了120左右&#xff0c;平…

ROS入门-第 1 章 ROS概述与环境搭建

目录 第 1 章 ROS概述与环境搭建 1.1 ROS简介 1.1.1 ROS概念 1.1.2 ROS设计目标 1.1.3 ROS发展历程 1.3 ROS快速体验 1.3.1 HelloWorld实现简介 1.3.2 HelloWorld&#xff08;C版&#xff09; 步骤 1&#xff1a;创建工作空间 步骤 2&#xff1a;创建发布者节点 步骤…

Linux系统USB转串口芯片 GPIO使用教程

一、简介 WCH的多款USB转单路/多路异步串口芯片&#xff0c;除串口接口以外&#xff0c;还提供独立的GPIO接口&#xff0c;各GPIO引脚支持独立的输出输入&#xff0c;GPIO功能的使用需要与计算机端厂商驱动程序和应用软件配合使用。各芯片的默认GPIO引脚状态有所区别&#xff…

ESP-IDF插件去除红色波浪线

如图&#xff0c;新装的ESP-IDF打开别人的工程有好多红色波浪线。 把这里的第一个文件夹删除&#xff0c;就是那个.vscode&#xff0c;接下来按ctrlshiftP&#xff0c;输入vscode&#xff0c; 选第一个&#xff0c;添加配置文件夹。 问题解决。 之后记得重新配置板子信息和串…

STM32 低功耗-停止模式

STM32 停止模式 文章目录 STM32 停止模式第1章 低功耗模式简介第2章 停止模式简介2.1 进入停止模式2.1 退出停止模式 第3章 停止模式程序部分总结 第1章 低功耗模式简介 在 STM32 的正常工作中&#xff0c;具有四种工作模式&#xff1a;运行、睡眠、停止以及待机模式。 在系统…

linux自启动程序

嵌入式linux下有软件需要自启动&#xff0c;只需要在/etc/init.d/rcS末尾添加所要启动的程序即可&#xff0c;开机就会自动运行 vi /etc/init.d/rcS在文件末尾添加 例&#xff1a;

PLL 的 verilog 实现

锁相环&#xff08;PLL&#xff09;是一种常用的频率、相位追踪算法&#xff0c;在信号解调、交流并网等领域有着广泛的应用。本文对全数字锁相环的原理进行介绍&#xff0c;随后给出 verilog 实现及仿真。 PLL 锁相原理 锁相环结构如下图所示&#xff0c;主要由鉴相器、环路滤…