【问题标题】:How to get Q-Q plot for Pareto distribution in Python?如何在 Python 中获得帕累托分布的 QQ 图?
【发布时间】:2019-05-16 17:24:22
【问题描述】:

Q-Q 图用于获得一组数据点与理论分布之间的拟合优度。以下是获得积分的过程。

  1. 选择要使用的样本。用 X(i) 对选定的样本进行排序,表示第 i 个样本
  2. 找到与样本对应的模型值。这分两步完成,

    一个。将每个样本与其代表的百分位数相关联。 pi = (i-0.5)/n

    b.计算与该百分位数相关的模型值。这是通过反转模型 CDF 来完成的,就像从模型分布生成随机变量时所做的那样。因此样本 i 对应的模型值为 Finverse(pi)。

    c。使用n个点绘制QQ图

( X(i), Finverse(pi)) 1 ≤ i ≤ n

使用这种方法,我想出了以下 python 实现。

_distn_names = ["pareto"]
def fit_to_all_distributions(data):
    dist_names = _distn_names

    params = {}
    for dist_name in dist_names:
        try:
            dist = getattr(st, dist_name)
            param = dist.fit(data)

            params[dist_name] = param
        except Exception:
            print("Error occurred in fitting")
            params[dist_name] = "Error"

    return params 

def get_q_q_plot(values, dist, params):
    values.sort()

    arg = params[:-2]
    loc = params[-2]
    scale = params[-1]

    x = []

    for i in range(len(values)):
        x.append((i-0.5)/len(values))

    y = getattr(st, dist).ppf(x, loc=loc, scale=scale, *arg)

    y = list(y)

    emp_percentiles = values
    dist_percentiles = y

    print("Emperical Percentiles")
    print(emp_percentiles)

    print("Distribution Percentiles")
    print(dist_percentiles)

    plt.figure()
    plt.xlabel('dist_percentiles')
    plt.ylabel('actual_percentiles')
    plt.title('Q Q plot')
    plt.plot(dist_percentiles, emp_percentiles)
    plt.savefig("/path/q-q-plot.png")

b = 2.62
latencies = st.pareto.rvs(b, size=500)
data = pd.Series(latencies)
params = fit_to_all_distributions(data)

pareto_params = params["pareto"]

get_q_q_plot(latencies, "pareto", pareto_params)

理想情况下我应该得到一条直线,但这就是我得到的。

为什么我没有得到一条直线?我的实施有什么问题吗?

【问题讨论】:

  • 我所做的是:scipy.stats.probplot(dist_you_want_to_check, dist='pareto', sparams=(scale_param_for_pareto, ), plot=matplotlib.pyplot) 然后matplotlib.pyplot.show()

标签: python statistics probability


【解决方案1】:

您可以使用以下代码获取任何分布的 QQ 图(scipy stats 中有 82 个)。

import os
import matplotlib.pyplot as plt
import sys
import math
import numpy as np
import scipy.stats as st
from scipy.stats._continuous_distns import _distn_names
from scipy.optimize import curve_fit

def get_q_q_plot(latency_values, distribution):

    distribution = getattr(st, distribution)
    params = distribution.fit(latency_values)

    latency_values.sort()

    arg = params[:-2]
    loc = params[-2]
    scale = params[-1]

    x = []

    for i in range(1, len(latency_values)):
        x.append((i-0.5) / len(latency_values))

    y = distribution.ppf(x, loc=loc, scale=scale, *arg)

    y = list(y)

    emp_percentiles = latency_values[1:]
    dist_percentiles = y

    return emp_percentiles, dist_percentiles

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-26
    • 1970-01-01
    • 1970-01-01
    • 2019-05-03
    • 2011-03-15
    • 1970-01-01
    • 2021-04-19
    • 1970-01-01
    相关资源
    最近更新 更多