할인
미끄러운 보행 Slippery Walk
- 격자 세계(grid world)
- 상태:
- 구멍: 종료
- 골: +1점을 보상으로 받고 종료
- 중간: 비종료 상태
- 가운데서 시작
- 행동: 좌우로만 이동
- 전이 함수: 행동한대로 이동(1/2). 제자리(1/3). 반대방향(1/6)
| 구멍 | 1 | 2 | 3 | 4 | 5 | 골 |
|---|
SlipperyWalk 사용
import gymnasium as gym
import numpy as np
class SlipperyWalk(gym.Env):
def __init__(self, length):
super().__init__()
self.action_space = gym.spaces.Discrete(2)
self.observation_space = gym.spaces.Discrete(length)
self.start_state = length // 2 # 2로 나눈 몫
self.state = self.start_state
self.done = False
self.truncated = False
self.length = length
self.P = self.set_transition()
def set_transition(self):
P = {}
transition_probs = {'MOVE': 1/2, 'STAY': 1/3, 'OPPOSITE': 1/6}
goal = self.length - 1
for s in range(self.length):
P[s] = {}
for a in range(2):
if s == 0:
P[s][a] = [(1.0, s, 0, True)] # 확률, 상태, 보상, 종료 여부
elif s == goal:
P[s][a] = [(1.0, s, 1, True)]
else:
transitions = []
for transition, prob in transition_probs.items():
if transition == 'MOVE':
next_state = s + 1 if a == 1 else s - 1
elif transition == 'STAY':
next_state = s
elif transition == 'OPPOSITE':
next_state = s - 1 if a == 1 else s + 1
next_state = max(0, min(goal, next_state)) # 범위 제한 표현
reward = 1 if next_state == goal else 0 # 삼항 연산자
done = next_state == 0 or next_state == goal
transitions.append((prob, next_state, reward, done))
P[s][a] = transitions
return P
def reset(self):
self.state = self.start_state
self.done = False
self.truncated = False
self.steps = 0
return self.state, {}
def step(self, action):
transitions = self.P[self.state][action]
probs = np.array([t[0] for t in transitions])
i = np.random.choice(np.arange(len(transitions)), p=probs)
_, self.state, reward, self.done = transitions[i]
self.steps += 1
self.truncated = self.steps >= 100
return self.state, reward, self.done, self.truncated, {}
def render(self, mode='human'):
grid = ['X'] + ([' '] * (self.length - 2)) + ['O'] # 리스트 연산
grid[self.state] = 'A'
print('|' + '|'.join(grid) + '|') # 문자열 연산
@property
def unwrapped(self):
return self
환경 생성(총 9칸):
env = SlipperyWalk(9)
리셋:
env.reset()
왼쪽으로 한 걸음:
env.step(0)
그리기:
env.render()
할인 discounting
- 동일한 보상이라도 나중에 받는 것보다 먼저 받는 것이 나음
- 예) 오늘 100만원 vs. 1년 후 100만원
- 시간에 따른 차이를 보정하기 위해 미래의 보상은 할인하여 계산
- 할인율(discount factor): 한 스텝마다 할인하는 비율
- 그리스 문자 감마(γ)로 표시
- 이자율과 반대 관계로 이해할 수있음
- 할인율이 0.9일 경우: 81t=0=90t=1=100t=2
- 현재 스텝의 90만원 = 다음 스텝의 100만원
- 수익을 계산할 때도 할인을 적용
수익 return
- 시점 t 이후에 얻는 보상의 누적합
- 할인된 수익
- 재귀적 표현
미끄러운 보행에서 할인이 없다면?
- 할인율 γ=1.0이면
- 골로 바로 가는 경우:
3 → 4 → 5 → 골
- 빙 돌아가는 경우:
- 예:
3 → 2 → 3 → 4 → 5 → 골
- 예:
- 수익이 같음
- 보상은 골에 도착할 때 한 번만 받으므로
긴급성 urgency
- 할인은 긴급성에 대한 정보를 제공
- 할인을 적게 할 경우(γ가 클 경우):
- 현재와 미래의 보상에 큰 차이가 없음 → 언제 해도 상관 X
- 할인을 많이 할 경우(γ가 작을 경우):
- 현재와 미래의 보상의 차이가 큼 → 보상을 빨리 얻는 것이 유리
쌍곡선 할인 hyperbolic discounting
- 사람들의 심리적인 할인
- 강화학습이나 경제학 등에서는 할인율이 일정하다고 가정
- 사람들은 가까운 미래는 할인을 많이 하고, 먼 미래는 할인을 조금 함
- 할 일을 미루거나, 노후 대비를 하지 않는 등의 행동에 대한 행동경제학적 원인

시간 불일치 Time Inconsistency
- 쌍곡선 할인 모델에서는 시간이 지남에 따라 사람들의 선호가 변할 수 있음
- 현재 시점에서 미래의 결정을 내리는 것과 실제 미래 시점에서의 결정이 일치하지 않을 수 있음
- 예:
- 현재는 1년 후의 100달러보다 1년 1주일 후의 110달러를 선호
- 1년이 지나고 1주일이 남았을 때는 1주일 후의 110달러보다 당장의 100달러를 더 선호할 수 있음
지수형 할인 vs. 쌍곡형 할인
- 지수형 할인
- 항상 같은 비율로 할인
- 둘 다 멀리 떨어져 있을 때는 큰 이익의 가치가 큼
- 쌍곡형 할인
- 시점에 따라 다른 비율로 할인
- 작은 이익에 가까워지면 큰 이익의 가치는 급격히 떨어져 있고 작은 이익의 가치는 아직 떨어지지 않아서 작은 이익의 가치가 더 큼

퀴즈
Slippery Walk 환경에 대한 설명으로 올바른 것을 모두 고르세요.
퀴즈를 풀려면 대화형 기능을 불러와야 합니다.