Rozdział 4 Rozkład beta


4.1 Funkcja gęstości

Rozkład beta na przedziale \([a,b]\) został zaimplementowany do funkcji scipy.stats.beta gdzie: loc\(=a\) oraz scale\(=b-a\). Funkcję gęstości prawdopodobieństwa tego rozkładu można zapisać za pomocą wzoru: \[\begin{equation} f(x\;|\;a,b,\alpha,\beta)=\frac{1}{\mathrm{B}(\alpha,\beta)(b-a)^{\alpha+\beta-1}}(x-a)^{\alpha-1}(b-x)^{\beta-1} \tag{4.1} \end{equation}\] po podstawieniu: \[\mathrm{B}(\alpha,\beta)(b-a)^{\alpha+\beta-1}=\int_{a}^{b}u^{\alpha-1}(1-u)^{\beta-1}du=\frac{\Gamma(\alpha)\Gamma(\beta)}{\Gamma(\alpha+\beta)}(b-a)^{\alpha+\beta-1}\] otrzymamy: \[\begin{equation} f(x\;|\;a,b,\alpha,\beta)=\frac{\Gamma(\alpha+\beta)}{\Gamma(\alpha)\Gamma(\beta)(b-a)^{\alpha+\beta-1}}(x-a)^{\alpha-1}(b-x)^{\beta-1} \tag{4.2} \end{equation}\] gdzie: \(E(x)=a+\frac{\alpha}{\alpha+\beta}(b-a)\) oraz \(V(x)=\frac{\alpha\beta}{(\alpha+\beta)^2(\alpha+\beta+1)}(b-a)^2\).

Standardowa wersja rozkładu beta jest rozpatrywana na przedziale \([0;1]\) a więc wzór (4.2) upraszcza się do postaci: \[\begin{equation} f(x\;|\;\alpha,\beta)=\frac{\Gamma(\alpha+\beta)}{\Gamma(\alpha)\Gamma(\beta)}x^{\alpha-1}(1-x)^{\beta-1} \tag{4.3} \end{equation}\] gdzie: \(E(x)=\frac{\alpha}{\alpha+\beta}\) oraz \(V(x)=\frac{\alpha\beta}{(\alpha+\beta)^2(\alpha+\beta+1)}\).

Jeśli do wzoru (4.3) podstawimy \(\alpha=\mu\phi\) oraz \(\beta=(1-\mu)\phi\) dla \(\alpha+\beta=\phi\) to otrzymamy: \[\begin{equation} f(x\;|\;\mu,\phi)=\frac{\Gamma(\phi)}{\Gamma(\mu\phi)\Gamma\big((1-\mu)\phi\big)}x^{\mu\phi-1}(1-x)^{(1-\mu)\phi-1} \tag{4.4} \end{equation}\] gdzie: \(E(X)=\mu\) oraz \(V(X)=\frac{\mu(1-\mu)}{1+\phi}\).

Po zlogarytmowaniu funkcji prawdopodobieństwa (4.4) otrzymamy funkcję logarytmu wiarygodności o postaci: \[\begin{equation} LL_{beta}=\ln\Gamma(\phi)-\ln\Gamma(\mu\phi)-\ln\Gamma\big((1-\mu)\phi\big)+(\mu\phi-1)\ln(x)+\big((1-\mu)\phi-1\big)\ln(1-x) \tag{4.5} \end{equation}\]

import scipy.stats as stats
  
y = stats.beta.rvs(1.78, 2.34, size=100, random_state=2305)

f = stats.beta.fit(y)
logLik = sum(stats.beta.logpdf(y, a=f[0], b=f[1], loc=f[2], scale=f[3]))

print("alpha= %.4f, beta= %.4f, loc= %.4f, scale= %.4f" \
      % (f[0],f[1],f[2],f[3]))
print("\nlogLik= %.4f" % (logLik))
## alpha= 0.9859, beta= 0.9528, loc= 0.0152, scale= 0.8953
## 
## logLik= 12.6281

4.2 Liniowy model beta regresji

Rozkład beta zdefiniowany za pomocą wzoru (4.4) jest wykorzystywany do budowy liniowego modelu regresji dla proporcji. Inaczej mówiąc, w regresji beta wartości zmiennej zależnej mogą określać np. pewną frakcję dochodów gospodarstw domowych wydawanych na żywność. Po podstawieniu do wzoru (4.5) \(\hat{\mu}=\frac{1}{1+\exp(-\hat{y})}\) gdzie \(\hat{y}=\beta_0+\sum_{j=1}^{n}\beta_j x_{ij}\) otrzymamy parametry modelu beta regresji. Dodatkowo parametr precyzji \(\phi\) może być uważany za stały lub można go rozszerzyć o dodatkowy zestaw regresorów tzn. \(\phi=\exp(\hat{y})\). Zastosowanie liniowego modelu beta regresji zostanie zaprezentowane na przykładzie zestawu danych FoodExpenditure.

import numpy as np
import scipy.stats as stats
import matplotlib.pyplot as plt
import pandas as pd
import statsmodels.api as sm
import patsy
from scipy.optimize import minimize

df = pd.read_csv("https://raw.githubusercontent.com/krzysiektr/datacsv/master/FoodExpenditure.csv")
df["frac"] = df["food"]/df["income"]

y, x = patsy.dmatrices('frac ~ income', df, return_type='dataframe')
ols = sm.OLS(y,x).fit()
b = ols.params.values

def L_beta(par):
    mod = par[0]+ par[1]*df["income"]
    mu = stats.logistic.cdf(mod)
    phi = par[2]
    shape1 = mu*phi
    shape2 = (1-mu)*phi
    logLik = -np.sum( stats.beta.logpdf(df["frac"], a=shape1, b=shape2) )
    return(logLik)

def L_gamma(par):
    mod = par[0]+ par[1]*df["income"]
    mu = 1/mod
    shape = par[2]
    scale = mu/shape
    logLik = -np.sum( stats.gamma.logpdf(df["frac"], a=shape, scale=scale) )
    return(logLik)

initParams = [b[0],b[1],1]
res = [minimize(i, initParams, method= "Nelder-Mead") for i in [L_beta,L_gamma]]

fig = plt.figure(figsize=(14,6))
ax1 = fig.add_subplot(1,2,1)
ax2 = fig.add_subplot(1,2,2)
Xg = np.linspace(20,150, 1000)
ax1.plot(df["income"],df["frac"],'o',alpha=0.5,color='C1')
ax1.plot(Xg,1/(1+np.exp(-1*(res[0].x[0]+res[0].x[1]*Xg))),color='C0',
         label='a= %.4f, b= %.4f' % (res[0].x[0],res[0].x[1]))
ax1.set_xlabel("income")
ax1.set_ylabel("frac")
ax1.set_title("GLM: Rozkład beta - model logistyczny: $\\hat{\\mu}=\\frac{1}{1+\\exp(-(a+bx))}$\n logLik= %.4f, phi= %.4f" % (-1*res[0].fun,res[0].x[2]))
ax1.legend()
ax2.plot(df["income"],df["frac"],'o',alpha=0.5,color='C1')
ax2.plot(Xg,1/(res[1].x[0]+res[1].x[1]*Xg),color='C0',
         label='a= %.4f, b= %.4f' % (res[1].x[0],res[1].x[1]))
ax2.set_xlabel("income")
ax2.set_ylabel("frac")
ax2.set_title("GLM: Rozkład gamma - model odwrotny: $\\hat{\\mu}=\\frac{1}{a+bx}$\n logLik= %.4f, phi= %.4f" % (-1*res[1].fun,res[1].x[2]))
ax2.legend()
fig.tight_layout()
plt.savefig('prop01.png')
Graficzna prezentacja nieliniowej zależności frakcji wydatków na żywność i dochodów.

Rysunek 4.1: Graficzna prezentacja nieliniowej zależności frakcji wydatków na żywność i dochodów.