상세 컨텐츠

본문 제목

[Python] 특정 분포가 멱법칙(Power-law Distribution)을 따르는지 확인하기

프로그래밍

by ∫2tdt=t²+c 2017. 4. 11. 20:46

본문

주변에서 찾아볼 수 있는 많은 분포들은 멱법칙(Power-law)을 따릅니다. 멱법칙을 따르는 경우 상위 몇 %가 전체의 대부분을 차지하고 나머지들이 긴 꼬리(long tail)을 형성하게 됩니다. 이는 빈부 격차와 같은 사회 경제적인 분야뿐만 아니라 음파의 주파수 별 진폭 분포처럼 자연 과학에서도 흔히 발견되는 분포입니다. 

사람이 사용하는 언어의 단어 분포(지프의 법칙)나 소셜 네트워크의 중심성 계수 값도 이런 분포를 따릅니다. 따라서 실제 실험을 통해서 얻은 결과가 이 법칙을 따르는지 확인해보는건 재미있으면서도 중요한 일이라고 할 수 있죠. 그래서 해당 분포가 멱법칙을 따르는지 계산해주는 파이썬 코드를 빠르게 짜보았습니다.


멱법칙(거듭제곱 회귀)은 위와 같은 공식으로 나타낼 수 있습니다. 주어진 자료에 가장 적합한 곡선을 찾아내는게 우리의 목표라고 할 수 있죠. 이를 수학적으로 나타낸 것이 회귀입니다. 거듭제곱식은 그대로 사용하기에 어려우므로 양변에 로그를 취해보죠.

가 되는데 이는 익히 알다시피

꼴의 선형회귀와 꼭 닮아 있습니다. 즉 x와 y에 로그를 취하면 거듭제곱 회귀는 선형 회귀와 같아집니다. 선형 회귀의 각 계수를 구하는건 어렵지 않게 할 수 있습니다

이를 바탕으로 곡선의 각 계수와 결정 계수를 계산하는 파이썬 코드를 짜보았습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#선형 회귀를 구하는 함수
def linearRegression(ys, xs):
    sxy = 0
    sx = 0
    sy = 0
    l = len(xs)
    ex = sum(xs) / l
    ey = sum(ys) / l
    for x, y in zip(xs, ys):
      nx = x - ex
      ny = y - ey
      sxy += nx * ny
      sx += nx * nx
      sy += ny * ny
    a = sxy / sx
    b = ey - a*ex
    return a, b, sxy ** 2 / sx / sy if sx != 0 and sy != 0 else 1
 
# 거듭제곱 회귀를 구하는 함수
def powerRegression(ys, xs):
    import math
    return linearRegression(list(map(math.log, ys)), list(map(math.log, xs)))
 
# 내림차순 정렬된 Y분포가 멱법칙을 따르는지 계산하는 함수
def verifyPowerLaw(ys):
    return powerRegression(ys, range(1, len(ys)+1))
 
print(verifyPowerLaw([1, 0.90, 0.81, 0.72, 0.63, 0.54]))

각 함수는 3개의 값을 반환하는데 각각 (K, A, R^2)값입니다. 간단하죠?

관련글 더보기

댓글 영역