मेरे पास कई क्वेरी आवृत्तियां हैं, और मुझे जिपफ के कानून के गुणांक का अनुमान लगाने की आवश्यकता है। ये शीर्ष आवृत्तियाँ हैं:
26486
12053
5052
3033
2536
2391
1444
1220
1152
1039
मेरे पास कई क्वेरी आवृत्तियां हैं, और मुझे जिपफ के कानून के गुणांक का अनुमान लगाने की आवश्यकता है। ये शीर्ष आवृत्तियाँ हैं:
26486
12053
5052
3033
2536
2391
1444
1220
1152
1039
जवाबों:
अपडेट मैंने @whuber सुझाव के अनुसार अधिकतम संभावना अनुमानक के साथ कोड को अपडेट किया है। लॉग सैद्धांतिक संभावनाओं और लॉग फ़्रीक्वेंसी के बीच अंतर के वर्गों को न्यूनतम करने पर हालांकि एक उत्तर देता है एक सांख्यिकीय प्रक्रिया होगी यदि यह दिखाया जा सकता है कि यह किसी प्रकार का एम-अनुमानक है। दुर्भाग्य से मैं ऐसा कोई भी नहीं सोच सकता था जो एक ही परिणाम दे सके।
यहाँ मेरा प्रयास है। मैं आवृत्तियों के लघुगणक की गणना करता हूं और उन्हें इस सूत्र द्वारा दी गई सैद्धांतिक संभावनाओं के लघुगणक में फिट करने का प्रयास करता हूं । अंतिम परिणाम उचित लगता है। यहाँ आर में मेरा कोड है।
fr <- c(26486, 12053, 5052, 3033, 2536, 2391, 1444, 1220, 1152, 1039)
p <- fr/sum(fr)
lzipf <- function(s,N) -s*log(1:N)-log(sum(1/(1:N)^s))
opt.f <- function(s) sum((log(p)-lzipf(s,length(p)))^2)
opt <- optimize(opt.f,c(0.5,10))
> opt
$minimum
[1] 1.463946
$objective
[1] 0.1346248
सबसे अच्छा द्विघात फिट तो ।
R में अधिकतम संभावना mle
फ़ंक्शन ( stats4
पैकेज से) के साथ की जा सकती है , जो मानक त्रुटियों की गणना करने में मदद करता है (यदि सही नकारात्मक अधिकतम संभावना फ़ंक्शन की आपूर्ति की जाती है):
ll <- function(s) sum(fr*(s*log(1:10)+log(sum(1/(1:10)^s))))
fit <- mle(ll,start=list(s=1))
> summary(fit)
Maximum likelihood estimation
Call:
mle(minuslogl = ll, start = list(s = 1))
Coefficients:
Estimate Std. Error
s 1.451385 0.005715046
-2 log L: 188093.4
यहाँ लॉग-लॉग स्केल में फिट का ग्राफ (जैसा कि @whuber ने सुझाया है):
s.sq <- opt$minimum
s.ll <- coef(fit)
plot(1:10,p,log="xy")
lines(1:10,exp(lzipf(s.sq,10)),col=2)
lines(1:10,exp(lzipf(s.ll,10)),col=3)
लाल रेखा वर्गों के योग का योग है, हरे रंग की रेखा अधिकतम-उपयुक्त है।
किसी भी अनुमान समस्या में हमारे सामने कई मुद्दे हैं :
पैरामीटर का अनुमान लगाएं।
उस अनुमान की गुणवत्ता का आकलन करें।
डेटा का अन्वेषण करें।
फिट का मूल्यांकन करें।
उन लोगों के लिए जो समझ और संचार के लिए सांख्यिकीय तरीकों का उपयोग करेंगे, पहले दूसरों के बिना कभी नहीं किया जाना चाहिए।
इस प्रकार डेटा के लिए लॉग संभावना है
ज़िपफ के नियम की प्रकृति को देखते हुए, इस फिट को ग्राफ करने का सही तरीका लॉग-लॉग प्लॉट पर है , जहां फिट रैखिक होगा (परिभाषा के अनुसार):
फिट और डेटा का पता लगाने की अच्छाई का मूल्यांकन करने के लिए, अवशिष्ट (डेटा / फिट, लॉग-लॉग कुल्हाड़ियों को फिर से देखें):
क्योंकि अवशिष्ट यादृच्छिक दिखाई देते हैं, कुछ अनुप्रयोगों में हम ज़िपफ लॉ (और पैरामीटर का हमारा अनुमान) को स्वीकार करने के लिए संतुष्ट हो सकते हैं , क्योंकि आवृत्तियों के एक स्वीकार्य मोटे विवरण के रूप में । हालांकि, यह विश्लेषण दिखाता है कि यह अनुमान लगाना एक गलती होगी कि इस जांचे गए डेटासेट के लिए कोई भी व्याख्यात्मक या भविष्य कहनेवाला मूल्य है।
PyMC3 जैसी संभाव्य प्रोग्रामिंग भाषाओं में से एक इस अनुमान को अपेक्षाकृत सरल बनाती है। अन्य भाषाओं में स्टेन शामिल हैं जिनमें महान विशेषताएं और सहायक समुदाय हैं।
यहाँ मॉडल (पर भी ऑप्स डेटा पर फिट की मेरी अजगर कार्यान्वयन है Github ):
import theano.tensor as tt
import numpy as np
import pymc3 as pm
import matplotlib.pyplot as plt
data = np.array( [26486, 12053, 5052, 3033, 2536, 2391, 1444, 1220, 1152, 1039] )
N = len( data )
print( "Number of data points: %d" % N )
def build_model():
with pm.Model() as model:
# unsure about the prior...
#s = pm.Normal( 's', mu=0.0, sd=100 )
#s = pm.HalfNormal( 's', sd=10 )
s = pm.Gamma('s', alpha=1, beta=10)
def logp( f ):
r = tt.arange( 1, N+1 )
return -s * tt.sum( f * tt.log(r) ) - tt.sum( f ) * tt.log( tt.sum(tt.power(1.0/r,s)) )
pm.DensityDist( 'obs', logp=logp, observed={'f': data} )
return model
def run( n_samples=10000 ):
model = build_model()
with model:
start = pm.find_MAP()
step = pm.NUTS( scaling=start )
trace = pm.sample( n_samples, step=step, start=start )
pm.summary( trace )
pm.traceplot( trace )
pm.plot_posterior( trace, kde_plot=True )
plt.show()
if __name__ == '__main__':
run()
कुछ बुनियादी नमूना निदान प्रदान करने के लिए, हम देख सकते हैं कि नमूना "अच्छी तरह से मिश्रण कर रहा था" क्योंकि हम ट्रेस में कोई संरचना नहीं देखते हैं:
कोड को चलाने के लिए, एक को थीनो और PyMC3 संकुल के साथ पायथन की आवश्यकता होती है।
उनके शानदार जवाब और टिप्पणियों के लिए @ w-huber को धन्यवाद!
यहां वीजीएएम का उपयोग करके परिणामों को फिट करने, मूल्यांकन करने और परिणामों का पता लगाने का मेरा प्रयास है:
require("VGAM")
freq <- dzipf(1:100, N = 100, s = 1)*1000 #randomizing values
freq <- freq + abs(rnorm(n=1,m=0, sd=100)) #adding noize
zdata <- data.frame(y = rank(-freq, ties.method = "first") , ofreq = freq)
fit = vglm(y ~ 1, zipf, zdata, trace = TRUE,weight = ofreq,crit = "coef")
summary(fit)
s <- (shat <- Coef(fit)) # the coefficient we've found
probs <- dzipf(zdata$y, N = length(freq), s = s) # expected values
chisq.test(zdata$ofreq, p = probs)
plot(zdata$y,(zdata$ofreq),log="xy") #log log graph
lines(zdata$y, (probs)*sum(zdata$ofreq), col="red") # red line, num of predicted frequency
Chi-squared test for given probabilities
data: zdata$ofreq
X-squared = 99.756, df = 99, p-value = 0.4598
हमारे मामले में ची स्क्वायर की अशक्त परिकल्पना यह है कि डेटा को zipf के कानून के अनुसार वितरित किया जाता है, इसलिए बड़े पी-मान इस दावे का समर्थन करते हैं कि डेटा उसके अनुसार वितरित किया गया है। ध्यान दें कि बहुत बड़े पी-मान भी एक प्रमाण नहीं हैं, बस एक संकेतक हैं।
फिर, यूडब्ल्यूएसई केवल एक सुसंगत अनुमान प्रदान करता है - कोई विश्वास अंतराल नहीं, और हम सटीकता में कुछ व्यापार बंद देख सकते हैं। ऊपर दिए गए mpiktas का समाधान भी UWSE का एक अनुप्रयोग है - हालांकि प्रोग्रामिंग की आवश्यकता है। आकलनकर्ता की पूरी व्याख्या के लिए देखें: https://paradsp.wordpress.com/ - नीचे सभी तरह से।
मेरा समाधान mpiktas द्वारा प्रदान किए गए उत्तरों के पूरक होने का प्रयास करता है और पायथन में एक कार्यान्वयन कर रहा है। हमारी आवृत्तियों और रेंज x हैं:
freqs = np.asarray([26486, 12053, 5052, 3033, 2536, 2391, 1444, 1220, 1152, 1039])
x = np.asarray([1, 2, 3, 4, 5 ,6 ,7 ,8 ,9, 10])
जैसा कि हमारे कार्य को सभी सीमा में परिभाषित नहीं किया गया है, हमें यह जांचने की आवश्यकता है कि हम हर बार इसे गणना करते समय सामान्य कर रहे हैं। असतत मामले में, एक साधारण सन्निकटन सभी y (x) के योग से विभाजित होता है। इस तरह हम विभिन्न मापदंडों की तुलना कर सकते हैं।
f,ax = plt.subplots()
ax.plot(x, f1, 'o')
ax.set_xscale("log")
ax.set_yscale("log")
def loglik(b):
# Power law function
Probabilities = x**(-b)
# Normalized
Probabilities = Probabilities/Probabilities.sum()
# Log Likelihoood
Lvector = np.log(Probabilities)
# Multiply the vector by frequencies
Lvector = np.log(Probabilities) * freqs
# LL is the sum
L = Lvector.sum()
# We want to maximize LogLikelihood or minimize (-1)*LogLikelihood
return(-L)
s_best = minimize(loglik, [2])
print(s_best)
ax.plot(x, freqs[0]*x**-s_best.x)
परिणाम हमें पिछले उत्तरों की तरह 1.450408 की ढलान देता है।