2013-03-26 2 views
3

Scipy를 사용하여 로그 정규 분포에 적합하려고합니다. 이미 이전에 Matlab을 사용했지만 통계 분석을 넘어 응용 프로그램을 확장해야하기 때문에 Scipy에서 맞는 값을 재현하려고합니다. 다음은 Scipy 대 Matlab을 사용하여 로그 정규 분포를 맞추기

내가 내 데이터에 맞게 사용되는 MATLAB 코드입니다 :

% Read input data (one value per line) 
x = []; 
fid = fopen(file_path, 'r'); % reading is default action for fopen 
disp('Reading network degree data...'); 
if fid == -1 
    disp('[ERROR] Unable to open data file.') 
else 
    while ~feof(fid) 
     [x] = [x fscanf(fid, '%f', [1])]; 

    end 
    c = fclose(fid); 
    if c == 0 
     disp('File closed successfully.'); 
    else 
     disp('[ERROR] There was a problem with closing the file.'); 
    end 
end 

[f,xx] = ecdf(x); 
y = 1-f; 

parmhat = lognfit(x); % MLE estimate 
mu = parmhat(1); 
sigma = parmhat(2); 

을 그리고 여기에 장착 줄거리입니다 :

enter image description here

지금 여기 내 파이썬 코드가 동일 달성을 목표로입니다 :

import math 
from scipy import stats 
from statsmodels.distributions.empirical_distribution import ECDF 

# The same input is read as a list in Python 
ecdf_func = ECDF(degrees) 
x = ecdf_func.x 
ccdf = 1-ecdf_func.y 

# Fit data 
shape, loc, scale = stats.lognorm.fit(degrees, floc=0) 

# Parameters 
sigma = shape # standard deviation 
mu = math.log(scale) # meanlog of the distribution 

fit_ccdf = stats.lognorm.sf(x, [sigma], floc=1, scale=scale) 

다음은 Python 코드를 사용하는 경우입니다. 당신이 볼 수 있듯이

enter image description here

은, 코드의 두 세트는 적어도 시각, 잘 맞는 생산 말하기 할 수있다.

문제는 예상 매개 변수 mu 및 sigma에 큰 차이가 있다는 것입니다.

Matlab에서 : mu = 1.62 시그마 = 1.29. 파이썬에서 : mu = 2.78 시그마 = 1.74.

왜 이러한 차이가 있습니까?

참고 : 두 데이터 세트가 모두 이고 정확히이라는 것을 확인했습니다. 동일 포인트 수, 동일한 분포.

귀하의 도움에 감사드립니다! 미리 감사드립니다.

기타 정보 : matlab에의

import scipy 
import numpy 
import statsmodels 

scipy.__version__ 
'0.9.0' 

numpy.__version__ 
'1.6.1' 

statsmodels.__version__ 
'0.5.0.dev-1bbd4ca' 

버전 R2011b입니다.

에디션 :

아래 질문에 대해 답 보듯

, 오류가 Scipy 0.9로 자리 잡고 있습니다. Scipy 11.0을 사용하여 Matlab에서 mu 및 sigma 결과를 재현 할 수 있습니다.

당신의 Scipy를 업데이트하는 쉬운 방법은 다음과 같습니다

pip install --upgrade Scipy 

당신이 (당신이해야!) 핍이없는 경우 :

sudo apt-get install pip 
+1

데이터 세트의 두 세트를 보면 모양이 약간 다릅니다 (예 : 오른쪽 하단의 파란색 원의 위치 비교). 데이터가 동일하지 않은 경우 적합하다고 생각할 이유가 없습니다. – NPE

+0

두 데이터 세트는 모두 정확히 동일합니다. 그것이 사실이 아닌지 확인하기 위해 철저히 조사했습니다. Matlab에서 플롯하기 위해 사용한 코드가 라이브러리가 아닌 코드이기 때문에 플롯이 약간 다르게 표시됩니다. 어쨌든 요점은 맞는 데이터가 정확히 동일하므로 동일한 평균 및 표준 편차 값을 산출해야한다는 것입니다. – Mike

+0

미안하지만 나는 이것을 구입하지 않습니다 (플롯이 꺼져 있지 않는 한). 두 그래프의 가장 오른쪽에있는 점의 가로 좌표를 시각적으로 비교하여 두 점의 차이가 매우 다른지 확인하십시오. 데이터가 동일하다고 확신하는 경우, 질문을 파이썬과 MATLAB 모두에서 읽는 데 사용하는 코드와 함께 포함하십시오. – NPE

답변

6

scipy에서 fit 방법에 버그가 있습니다 0.9.0은 이후 버전의 scipy에서 수정되었습니다.

스크립트의 출력은 다음과 같아야합니다

Explicit formula: mu = 4.99203450, sig = 0.81691086 
Fit log(x) to norm: mu = 4.99203450, sig = 0.81691086 
Fit x to lognorm: mu = 4.99203468, sig = 0.81691081 

하지만 scipy 0.9을.

import numpy as np 
from scipy import stats 


def lognfit(x, ddof=0): 
    x = np.asarray(x) 
    logx = np.log(x) 
    mu = logx.mean() 
    sig = logx.std(ddof=ddof) 
    return mu, sig 


# A simple data set for easy reproducibility 
x = np.array([50., 50, 100, 200, 200, 300, 500]) 

# Explicit formula 
my_mu, my_sig = lognfit(x) 

# Fit a normal distribution to log(x) 
norm_mu, norm_sig = stats.norm.fit(np.log(x)) 

# Fit the lognormal distribution 
lognorm_sig, _, lognorm_expmu = stats.lognorm.fit(x, floc=0) 

print "Explicit formula: mu = %10.8f, sig = %10.8f" % (my_mu, my_sig) 
print "Fit log(x) to norm: mu = %10.8f, sig = %10.8f" % (norm_mu, norm_sig) 
print "Fit x to lognorm: mu = %10.8f, sig = %10.8f" % (np.log(lognorm_expmu), lognorm_sig) 

성병의 옵션 ddof=1로 : 0, 다음 테스트 스크립트는 동일한 결과를 얻을 수있는 세 가지 방법을 보여줍니다

Explicit formula: mu = 4.99203450, sig = 0.81691086 
Fit log(x) to norm: mu = 4.99203450, sig = 0.81691086 
Fit x to lognorm: mu = 4.23197270, sig = 1.11581240 

입니다. dev. 계산은 편견 분산 추정을 사용 :에 주석이

In [104]: x 
Out[104]: array([ 50., 50., 100., 200., 200., 300., 500.]) 

In [105]: lognfit(x, ddof=1) 
Out[105]: (4.9920345004312647, 0.88236457185021866) 

사용하지 검열 때, lognfit이 분산의 불편 추정의 제곱근을 사용하여 시그마를 계산 말한다 MATLAB의 lognfit documentation. 이것은 위의 코드에서 ddof = 1을 사용하는 것과 같습니다.

+0

내 MATLAB은이 데이터 세트에서'4.9920 0.8824'를 제공합니다. – NPE

+0

@NPE : 감사합니다. 차이점을 설명하는 추가 의견을 추가했습니다. –

+1

그럼에도 불구하고 이것이 OP의 경우의 차이를 설명한다면 100 % 확신 할 수는 없지만 (관찰 횟수가 주어짐) 그럼에도 불구하고 좋은 조사입니다. (+1) – NPE

관련 문제