• 무작위 행보(Random Walks)
  • 위생 검사(Sanity Check)


Chapter 5. Random Walks 강의를 듣고 정리한 내용입니다.



무작위 행보(Random Walks)

  • 많은 영역에서 중요(사회적 규칙에서도 중요)
    • 주식 시장에서 가격의 움직임을 입증하는데 가장 좋은 모델
    • 현대의 많은 포토폴리오 분석이 기반을 두고 있음
    • 전파를 모델링할 때도 랜덤 워크를 사용, 열 전파나 분자의 전파
  • 우리 주변의 세계를 이해하기 위해 시뮬레이션을 어떻게 사용할지에 대한 좋은 사례를 제공
  • 추상적인 것들을 다루면서 프로그래밍과 소프트웨어 엔지니어링을 같이 진행
  • 강의의 예시 : 술 취한 사람의 걸음과 편향성을 가진 술 취한 사람의 걸음 차이를 파악


class Location(object) :
	def __init__(self, x, y):
		self.x = x
		self.y = y

	def move(self, deltaX, deltaY): #새로운 위치 반환, x변화량과 y 변화량을 보여줌
		return Location(self.x + deltaX,
						self.y + deltaY)

	def getX(self):
		return self.x

	def getY(self):
		return self.y

	def distFrom(self, other):
		xDist = self.x - other.getX()
		yDist = self.y - other.getY()
		return (xDist**2 + yDist**2)**0.5

	def __str__(self):
		return "<" + str(self.x) + ',' + str(self.y) + '>'


class Drunk(object):
	def __init__(self, name = None):
		self.name = name

	def __str__(self):
		if self != None:
			return self.name
		return "Anonymous"


import random

class UsualDrunk(Drunk):
	def takeStep(self):
		stepChoices = [(0,1), (0,-1), (1,0), (-1,0)]
		return random.choice(stepChices)

class MasochistDrunk(Drunk):
	def takeStep(self):
		stepChoices = [(0,0,1.1), (0.0,-0.9), #북쪽, 남쪽
						(1.0, 0.0), (-1.0,0.0)]
		return random.choice(stepChoices)


class Field(object):
	def __init__(self):
			self.drunks = {} 

	def addDrunk(self, drunk, loc):
		if drunk in self.drunks:
			raise ValueError('Duplicate drunk')
		else:
			self.drunks[drunk] = loc #loc값으로 매핑

	def getLoc(self, drunk):
		if drunk not in self.drunks: 
			raise ValueError('Drunk not in field')
		return self.drunks[drunk]

	def moveDrunk(self, drunk):
		if drunk not in self.drunks:
			raise ValueError('Drunk not in field')
		xDist, yDist = drunk.takeStep() #x의 거리와 y의 거리를 얻음
		self.drunks[drunk] = self.drunks[drunk].move(xDist, yDist)
	


  • 클래스 집합을 통해 시뮬레이션을 만들 수 있음
  • Field에 drunk를 추가할 때마다 딕셔너리 값을 바꾸고 있는 것


def walk(f, d, numSteps):
		start = f.getLoc(d)
		for s in range(numSteps): #최종위치에서 시작위치까지의 거리를 반환
			f.moveDrunk(d)
		return start.distFrom(f.getLoc(d))

# 여러 걸음에 대해서 시뮬레이션이 필요
def simWalks(numSteps, numTrials, dClass): 
	#dClass라는 drunk의 클래스를 인자로 받음
	Homer = dClass() #술취한 사람
	origin = Location(0, 0) #원점
	distances = [] #거리
	# 몇번의 시도를 하든 원점에서 술취한 사람이 얼마나 멀리있는지에 대한 리스트르 반환
	for t in range(numTrials):
		f = Field()
		f.addDrunk(Homer, origin)
		distances.append(round(walk(f, Homer, numTrials), 1))
	return distances

# 서로 다른 걸음의 수를 요소로 갖는 walkLegnth라는 리스트와 시도의 횟수, dClass를 인자로 받음
def drunkTest(walkLengths, numTrials, dClass):
	for numSteps in walkLengths:
		distances = simWalks(numSteps, numTrials, dClass)
		# dClass.__name__ : 클래스 이름을 반환
		print(dClass.__name__, 'random walk of', numSteps, 'steps')
		print('Mean =', round(sum(distances)/len(distances), 4))
		print('Max =', max(distances), 'Min =', min(distances))


위생 검사(Sanity Check)

  • 시뮬레이션을 생성할 땐 위생 검사가 필요
  • 시뮬레이션이 실제로 말이 되는 확인하는 과정
    • 의심을 가져야함
    • 코드에 버그가 있을 수 있음
  • 사용할 수 있는 라이브러리
    • numpy - 벡터, 행렬, 고차원
    • scipy - 과학자에게 유용한 수학적인 클래스와 함수
    • matplotlib


[정리]

  • 랜덤 워크를 하는 요점은 시뮬레이션 모델이 아닌 어떻게 만드는지에 관한 것
  • 클래스를 정의하는 것부터 한번의 시도와 여러번의 시도에 대응하는 함수를 만들고 결과를 보는 과정
  • 시뮬레이션에 점진적 변화를 줘서 다른문제를 조사할 수 있음
  • 처음엔 간단한 시뮬레이션으로 시작해 잘 되지 않는 이유를 알고 sanity check로 잘못된 것을 체크
  • plot 스타일로 그래프를 그림


다음강의 : Chapter 6. Monte Carlo Simulation