numpy로 바꿨더니, 훨씬 빠르네.


numpy에 array count 구하는 게 없어서 불편했는데,

bincount로 대신해서 쓸 수 있었다.

numpy.bincount

>>> np.bincount(np.array([0, 1, 1, 3, 2, 1, 7]))
array([1, 3, 1, 1, 0, 0, 0, 1])

전체 count를 구하는 것인데도 O(n)보다 더 빠른 것 같아... 내 착각인가


np.histogram이나 Counter도 쓸 수 있나보다.

find the most frequent number in a numpy vector

How can I generate a complete histogram with numpy?


결과를 python list 변수 그대로 출력해두기

execfile("...py")로 불러들일 수 있다.


계산에 1시간 쯤 걸리는 것 같다.


고친 부분

n_slots = 1000

n_iterations = 10000

n_people_range = range(n_slots*2, 50000, n_iterations/100)

...

votes = numpy.random.randint(n_slots, size=n_people)

#slot_histogram, n_bins = numpy.histogram(votes)

slot_histogram = numpy.bincount(votes)

#for i in votes:

# slot_histogram[i] = slot_histogram[i] + 1


...

counts = numpy.bincount(slot_histogram)

n_0_slots = counts[0]

n_1_slots = counts[1]

...


n_0_blur_hist = [x/float(n_iterations) for x in n_0_hist]

n_1_blur_hist = [x/float(n_iterations) for x in n_1_hist]


postfix = str(n_slots) + "_" + str(n_people_range[-1] + 1)

fp = open(os.path.dirname(os.path.abspath(__file__)) + "/blur_hist_" + postfix + ".py", "w")

print >>fp, ("range_" + postfix + " = " + str(people_x_range))

print >>fp, ("n_0_hist_" + postfix + " = " + str(n_0_blur_hist))

print >>fp, ("n_1_hist_" + postfix + " = " + str(n_1_blur_hist))

fp.close()






블로그 이미지

언제나19

기본에 충실하는 19식 재테크. 교과서 중심으로 공부했어요.

,



지난 번 계산에 초록색 선을 더했다.

제일 많이 겹치는 slot의 사람 수

80배 사람이 슈팅하더라도 110명 정도밖에 안 겹친다.

160배 사람이면, 200명 정도 겹친다.


하지만, 사람들이 아주 랜덤으로 선택하는 게 아니므로, 예측 결과의 1/2 정도만 겹친다고 생각하면 될까나





추가한 code

n_max_slots = max(slot_histogram)


n_max_hist[i_hist] += n_max_slots


plot.scatter(n_people_range, n_max_blur_hist, c='green', lw=0, alpha=0.5)




블로그 이미지

언제나19

기본에 충실하는 19식 재테크. 교과서 중심으로 공부했어요.

,




가격 구간, 사람 수가 얼마나 되던 간에 밀도에만 관련이 있다는 것을 확인해 봤다.


500 slots, 10,000 people까지

50 slots, 1,000 people까지

2번 계산한 다음에

2번째 계산 결과를 x, y 10배로 늘려 봤더니, 그래프가 거의 일치한다.

import matplotlib.pyplot as plot

import os


n_0_hist_500_10000 = []

n_1_hist_500_10000 = []

n_0_hist_50_1000 = []

n_1_hist_50_1000 = []


execfile("blur_hist_500_10000.py")

execfile("blur_hist_50_1000.py")


n_0_hist_50_1000_x10 = []

n_1_hist_50_1000_x10 = []


people_x_range = range(0, len(n_0_hist_500_10000))


for i in people_x_range:

n_0_hist_50_1000_x10.append( n_0_hist_50_1000[i/10] * 10)

for i in people_x_range:

n_1_hist_50_1000_x10.append( n_1_hist_50_1000[i/10] * 10)


plot.scatter(people_x_range, n_0_hist_500_10000, c='red', lw=0, alpha=0.5)

plot.scatter(people_x_range, n_1_hist_500_10000, c='blue', lw=0, alpha=0.5)


plot.scatter(people_x_range, n_0_hist_50_1000_x10, c='green', lw=0, alpha=0.5)

plot.scatter(people_x_range, n_1_hist_50_1000_x10, c='yellow', lw=0, alpha=0.5)


plot.show()









블로그 이미지

언제나19

기본에 충실하는 19식 재테크. 교과서 중심으로 공부했어요.

,


경우의 수 계산이 어려워서, 프로그래밍으로 했다.


100개 slots에 무작위로 아무 숫자에나 사람들이 슈팅을 한다고 했을 때,

빨간 색은 사람이 0명인 slot 개수

파란 색은 사람이 1명인 slot 개수

사람이 10배 이상으로 모이면, 그 slot은 포기해야 할 듯.

import matplotlib.pyplot as plot

import random



n_slots = 100


n_people_range = range(0, 3000)


def random_histogram(n_slots, n_people):

slots = range(0, n_slots)

slot_histogram = [0 for i in slots]

#print slot_histogram

for i in range(0, n_people):

slot = random.randint(0, n_slots - 1)

slot_histogram[slot] = slot_histogram[slot] + 1

return slots, slot_histogram


people_x_range = range(n_people_range[-1] + 1)

n_0_hist = [0 for i in people_x_range]

n_1_hist = [0 for i in people_x_range]


for i_n_people in n_people_range:

#print i_n_people

slots, slot_histogram = random_histogram(n_slots, i_n_people)

n_0_slots = 0

n_1_slots = 0

for n_people_each_slot in slot_histogram:

if (n_people_each_slot == 0):

n_0_slots = n_0_slots + 1

if (n_people_each_slot == 1):

n_1_slots = n_1_slots + 1


n_0_hist[i_n_people] = n_0_slots if n_0_slots > 0 else -5

n_1_hist[i_n_people] = n_1_slots if n_1_slots > 0 else -5

print i_n_people, n_0_slots, n_1_slots


plot.scatter(people_x_range, n_0_hist, c='red', lw=0, alpha=0.5)

plot.scatter(people_x_range, n_1_hist, c='blue', lw=0, alpha=0.5)


plot.show()


한 번 더 계산해봐도 거의 비슷한 그래프


n_slots = 1000

#50000 people --> 1000 < 7000 < 10000

n_people_range = range(0, 10000)

으로 많이 계산하고,

def blur_histogram(histogram):

result = [0 for i in range(len(histogram))]

for i in range(len(histogram)):

blur_wing = 30

if (i - blur_wing > 0 and i + blur_wing < len(histogram)):

for j in range(i - blur_wing, i + blur_wing):

around_i = histogram[i - blur_wing : i + blur_wing]

result[i] = reduce(lambda x, y: x + y, around_i) / len(around_i)

으로 blur했더니, 예쁜 그래프가 됐다.














블로그 이미지

언제나19

기본에 충실하는 19식 재테크. 교과서 중심으로 공부했어요.

,


온라인 마켓에서 가격 맞추기 행사를 할 때가 있다.

규칙은

  1. 개인 별로 아무 숫자나 입력한다.
  2. 다른 사람과 겹치지 않은 숫자 중에서
  3. 가장 적은 숫자를 입력한 사람이 승리

이런 게임을 뭐라고 하지?

우리 나라에서도 이런 행사 하지 않았나?


어떤 숫자가 입력될 확률이 가장 높은지 구하고 싶고, 확률 분포를 구하고 싶다.


처음엔 불가능할 것 같은데, 몇 가지 모델을 만들다 보면, 비교적 정확하게 구할 수 있겠다.

실제로 데이터도 뭔가 패턴이 있게 나오고 있고, 사람들도 머리를 써서 입력하곤 한다.


알아낼 수 있는 데이터는

지난 번 승리한 숫자 1등, 2등, 3등, 4등, 5등 (다른 사람과 겹치지 않은 숫자 중 가장 적은 숫자들)

그리고, 전체 입력한 사람 수

가장 많이 겹친 숫자도 알 수 있는데 별 도움이 안 된다. noise가 너무 많이 끼어서.

언제나 1000 이나 1을 입력한 사람이 많곤 하다.


적용하려고 하는 모델은

  1. uniform distribution, 가우시안
  2. 적은 숫자로 치우치는 현상
  3. 게임 이론,
  4. 노이즈 추가
  5. 조합 구성 변경










블로그 이미지

언제나19

기본에 충실하는 19식 재테크. 교과서 중심으로 공부했어요.

,