Làm cách nào để tính hệ số luật của Zipf từ một tập hợp tần số cao nhất?


25

Tôi có một số tần số truy vấn và tôi cần ước tính hệ số của luật Zipf. Đây là những tần số hàng đầu:

26486
12053
5052
3033
2536
2391
1444
1220
1152
1039

theo trang wikipedia luật của Zipf có hai tham số. Số phần tử Ns số mũ. là gì Ntrong trường hợp của bạn, 10? Và tần số có thể được tính bằng cách chia giá trị được cung cấp của bạn cho tổng của tất cả các giá trị được cung cấp?
mpiktas

hãy để nó là mười và tần số có thể được tính bằng cách chia các giá trị được cung cấp của bạn cho tổng của tất cả các giá trị được cung cấp .. làm thế nào tôi có thể ước tính?
Diegolo

Câu trả lời:


22

Cập nhật Tôi đã cập nhật mã với công cụ ước tính khả năng tối đa theo đề xuất @whuber. Tối thiểu hóa tổng bình phương của sự khác biệt giữa xác suất lý thuyết log và tần số log mặc dù đưa ra câu trả lời sẽ là một thủ tục thống kê nếu có thể chỉ ra rằng đó là một loại công cụ ước lượng M. Thật không may, tôi không thể nghĩ ra cái nào có thể cho kết quả tương tự.

Đây là nỗ lực của tôi. Tôi tính toán logarit của các tần số và cố gắng khớp chúng với logarit của xác suất lý thuyết được đưa ra bởi công thức này . Kết quả cuối cùng có vẻ hợp lý. Đây là mã của tôi trong R.

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

Phù hợp bậc hai tốt nhất sau đó là .s=1.47

Khả năng tối đa trong R có thể được thực hiện bằng mlehàm (từ stats4gói), tính toán một cách hữu ích các lỗi tiêu chuẩn (nếu chức năng khả năng tối đa âm chính xác được cung cấp):

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 

Dưới đây là biểu đồ về sự phù hợp trong thang đo log-log (một lần nữa như @whuber đề xuất):

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)

Đường màu đỏ là tổng của hình vuông phù hợp, đường màu xanh là khả năng phù hợp tối đa.

Biểu đồ log-log phù hợp


1
Ngoài ra còn có gói R zipfR cran.r-project.org/web/packages/zipfR/index.html Mặc dù vậy tôi vẫn chưa thử.
onestop

@onestop, cảm ơn vì đường link. Sẽ thật tuyệt nếu ai đó trả lời câu hỏi này bằng gói này. Giải pháp của tôi chắc chắn thiếu chiều sâu, mặc dù nó đưa ra một số loại câu trả lời.
mpiktas

(+1) Bạn thực sự ấn tượng. Vì vậy, nhiều đóng góp tốt trong nhiều lĩnh vực thống kê khác nhau!
chl

@chl, cảm ơn! Tôi chắc chắn cảm thấy rằng tôi không phải là người duy nhất có đặc điểm như vậy trong trang web này;)
mpiktas

25

Có một số vấn đề trước chúng tôi trong bất kỳ vấn đề ước tính nào :

  1. Ước tính tham số.

  2. Đánh giá chất lượng của ước tính đó.

  3. Khám phá dữ liệu.

  4. Đánh giá sự phù hợp.

Đối với những người sẽ sử dụng các phương pháp thống kê để hiểu và giao tiếp, việc đầu tiên không bao giờ nên được thực hiện mà không có những người khác.

Để ước tính , thuận tiện để sử dụng khả năng tối đa (ML). Các tần số rất lớn, chúng ta có thể mong đợi các thuộc tính tiệm cận nổi tiếng sẽ được giữ. ML sử dụng phân phối xác suất giả định của dữ liệu.i=1,2,,nisss>0

Hs(n)=11s+12s++1ns.

i1n

log(Pr(i))=log(isHs(n))=slog(i)log(Hs(n)).

fi,i=1,2,,n

Pr(f1,f2,,fn)=Pr(1)f1Pr(2)f2Pr(n)fn.

Do đó, xác suất đăng nhập cho dữ liệu là

Λ(s)=si=1nfilog(i)(i=1nfi)log(Hs(n)).

s

s^=1.45041Λ(s^)=94046.7s^ls=1.463946Λ(s^ls)=94049.5 mã được cung cấp bởi mpiktas.)

s[1.43922,1.46162] (nếu tôi thực hiện các phép tính chính xác :-).

Với bản chất của luật Zipf, cách phù hợp để vẽ biểu đồ sự phù hợp này là trên biểu đồ log-log , trong đó sự phù hợp sẽ là tuyến tính (theo định nghĩa):

nhập mô tả hình ảnh ở đây

Để đánh giá mức độ phù hợp và khám phá dữ liệu, hãy xem phần dư (dữ liệu / sự phù hợp, trục log-log một lần nữa):

nhập mô tả hình ảnh ở đây

χ2=656.476


Do phần dư xuất hiện ngẫu nhiên, nên trong một số ứng dụng, chúng tôi có thể chấp nhận Luật của Zipf (và ước tính của chúng tôi về tham số) dưới dạng mô tả sơ bộ về tần số . Tuy nhiên, phân tích này cho thấy sẽ là một sai lầm khi cho rằng ước tính này có bất kỳ giá trị giải thích hoặc dự đoán nào cho bộ dữ liệu được kiểm tra ở đây.


1
@whuber, tôi có thể khiêm tốn đề nghị một chút thận trọng với công thức được đưa ra ở trên. Luật của Zipf thường được nêu là kết quả tần số tương đối. Nó không (thường được xem xét) phân phối mà từ đó một mẫu iid được rút ra. Một khung iid có lẽ không phải là ý tưởng tốt nhất cho những dữ liệu này. Có lẽ tôi sẽ đăng thêm về điều này sau.
Đức hồng y

3
@cardinal Tôi mong chờ những gì bạn nói. Nếu bạn không có thời gian để trả lời thấu đáo, thậm chí một bản phác thảo về những gì bạn nghĩ có thể là "ý tưởng tốt nhất cho những dữ liệu này" sẽ được hoan nghênh nhất. Tôi có thể đoán bạn sẽ đi đâu với điều này: dữ liệu đã được xếp hạng, một quá trình tạo ra sự phụ thuộc và sẽ yêu cầu tôi bảo vệ khả năng xuất phát mà không nhận ra các tác động tiềm năng của xếp hạng. Sẽ thật tuyệt khi thấy một thủ tục ước tính với sự biện minh hợp lý hơn. Tuy nhiên, tôi hy vọng rằng phân tích của tôi có thể được giải cứu bằng kích thước tuyệt đối của bộ dữ liệu.
ai

1
@cardinal, đừng làm Fermat với chúng tôi :) Nếu bạn có một số hiểu biết khác so với những người trả lời khác, hãy thoải mái thể hiện nó trong câu trả lời riêng biệt, ngay cả khi nó sẽ không tạo thành một câu trả lời hợp lệ mỗi se. Trong math.SE ví dụ những tình huống như vậy phát sinh khá thường xuyên.
mpiktas

1
@cardinal Dễ dàng. Ví dụ: bạn thu thập tần số và xác định và xếp hạng mười cao nhất. Bạn đưa ra giả thuyết về Luật của Zipf. Bạn thu thập một bộ tần số mới và báo cáo chúng theo bảng xếp hạng trước đó . Đó là tình huống khó khăn, mà phân tích của tôi hoàn toàn phù hợp, tùy thuộc vào các cấp bậc mới đồng ý với các cấp bậc cũ.
whuber

1
@whuber, cảm ơn sự kiên nhẫn của bạn. Bây giờ tôi hoàn toàn rõ ràng về lý luận của bạn. Theo mô hình lấy mẫu mà bạn đã hoàn toàn xác định, tôi đồng ý với phân tích của bạn. Có lẽ câu nói cuối cùng của bạn vẫn còn hơi trơn. Nếu việc sắp xếp không gây ra sự phụ thuộc mạnh mẽ hơn phương pháp của bạn sẽ là bảo thủ. Nếu sự phụ thuộc cảm ứng là mạnh vừa phải, nó có thể trở thành thuốc chống ung thư. Thx cho bạn sự kiên nhẫn khi đối mặt với nhà sư phạm của tôi.
Đức hồng y

2

S

Một trong những ngôn ngữ lập trình xác suất như PyMC3 đưa ra ước tính này tương đối đơn giản. Các ngôn ngữ khác bao gồm Stan có các tính năng tuyệt vời và cộng đồng hỗ trợ.

Dưới đây là triển khai Python của tôi về mô hình được trang bị trên dữ liệu OP (cũng trên 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()

S ở dạng phân phối. Thông báo làm thế nào nhỏ gọn là ước tính! Với xác suất 95% giá trị thực của tham sốSnằm trong phạm vi [1.439,1.461]; giá trị trung bình là khoảng 1,45, rất gần với ước tính của MLE.

nhập mô tả hình ảnh ở đây

Để cung cấp một số chẩn đoán lấy mẫu cơ bản, chúng ta có thể thấy rằng việc lấy mẫu là "trộn tốt" vì chúng ta không thấy bất kỳ cấu trúc nào trong dấu vết:

nhập mô tả hình ảnh ở đây

Để chạy mã, người ta cần Python với các gói Theano và PyMC3 được cài đặt.

Cảm ơn @ w-huber vì câu trả lời và bình luận tuyệt vời của anh ấy!


1

Đây là nỗ lực của tôi để phù hợp với dữ liệu, đánh giá và khám phá kết quả bằng VGAM:

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

nhập mô tả hình ảnh ở đây

    Chi-squared test for given probabilities

data:  zdata$ofreq
X-squared = 99.756, df = 99, p-value = 0.4598

Trong trường hợp của chúng tôi, giả thuyết null của Chi vuông là dữ liệu được phân phối theo luật của zipf, do đó giá trị p lớn hơn hỗ trợ cho tuyên bố rằng dữ liệu được phân phối theo dữ liệu đó. Lưu ý rằng ngay cả các giá trị p rất lớn không phải là một bằng chứng, chỉ là một chỉ báo.


0

Để cho vui, đây là một trường hợp khác trong đó UWSE có thể cung cấp giải pháp dạng đóng chỉ sử dụng tần số cao nhất - mặc dù với chi phí chính xác. Xác suất trênx= =1là duy nhất trên các giá trị tham số. Nếuwx= =1^ biểu thị tần số tương đối sau đó,

SBạnWSE^= =H10-1(1wx= =1^)

Trong trường hợp này, kể từ khi wx= =1^= =0.4695599775, chúng tôi nhận được:

SBạnWSE^= =1,4

Một lần nữa, UWSE chỉ cung cấp một ước tính nhất quán - không có khoảng tin cậy và chúng ta có thể thấy một số sự đánh đổi chính xác. giải pháp của mpiktas ở trên cũng là một ứng dụng của UWSE - mặc dù việc lập trình là bắt buộc. Để biết giải thích đầy đủ về công cụ ước tính, hãy xem: https://paradsp.wordpress.com/ - tất cả các cách ở phía dưới.


UWSE liên quan đến luật của Zipf như thế nào?
Michael R. Chernick

UWSE (Ước tính không gian trọng lượng duy nhất) sử dụng thực tế là xác suất / tần số cao nhất là duy nhất trên các giá trị khác nhau của tham số s, đối với N đã cho, để tìm s. Liên quan đến luật của Zipf, điều này cho chúng ta biết rằng đã đưa ra một số mục để xếp hạng, N và tần suất cao nhất, chỉ có một cách chỉ định tần số cho các mục còn lại (2, ..., N) để chúng ta có thể nói "mục thứ n lớn gấp 1 / n ^ s lần so với mục thường xuyên nhất, đối với một số s". Nói cách khác, được cung cấp thông tin này, chỉ có một cách để luật của Zipf nắm giữ - tất nhiên, giả sử rằng luật của Zipf thực tế có hiệu lực.
CYP450

0

Giải pháp của tôi cố gắng bổ sung cho các câu trả lời được cung cấp bởi mpiktas và whuber khi thực hiện bằng Python. Tần số và phạm vi x của chúng tôi là:

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])

Vì chức năng của chúng tôi không được xác định trong tất cả các phạm vi, chúng tôi cần kiểm tra xem chúng tôi có đang bình thường hóa mỗi lần chúng tôi tính toán nó không. Trong trường hợp riêng biệt, một xấp xỉ đơn giản là chia cho tổng của tất cả y (x). Bằng cách này, chúng ta có thể so sánh các tham số khác nhau.

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)

enter image description here

Kết quả cho chúng ta độ dốc 1.450408 như trong các câu trả lời trước.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.