CASE WHEN
여러 가지 색깔의 볼펜 5자루와 연필 3자루가 있을 때
순열
중복 순열
원 순열
조합
중복 조합
순열
중복 순열
원 순열
조합
경우의 수 핵심:
순서를 따지는가? 안 따지는가?
중복을 허락하는가? 허락하지 않는가?
확률에서의 '동시에'는 시간적 요소가 아닌 "사건의 연결성"을 의미
경우의 수, 확률에서의 '동시에'는 '두 사건이 연결되어 일어나는'으로 이해
첫 번째 문제가 '선택하여 배열'이란 단어 때문에 순열로 보일 수 있지만 정확한 의미는 "일단 선택한 후 다시 배열"입니다.
모든 순열은 조합으로 식을 나타낼 수 있습니다.
→ 볼펜 2자루 선택하고, 연필 2자루 선택해서 모두 4자루를 모은 후 배열하는 4! 곱하기
※ 경우의 수나 확률을 공부함에 있어 가장 첫 출발점은 "또는"과 "그리고"의 구별!
→ 어떤 경우가 and(곱셈)이고 어떤 경우가 or(덧셈)인지 이해하기!
집에서 학원으로 가는 경우의 수 = 루트1(3×1=3) + 루트2(4×5=20) = 23가지
# 순열(Permutations)
from itertools import combinations, permutations
nums = [1,2,3,4]
perm = list(combinations(nums, 2))
# [(1, 2), (1, 3), (1, 4), (2, 1), (2, 3), (2, 4), (3, 1), (3, 2), (3, 4), (4, 1), (4, 2), (4, 3)] 출력
# 조합(Combinations)
from itertools import combinations, permutations
nums = [1,2,3,4]
combi = list(combinations(nums, 2))
# [(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)] 출력
def permutation(arr, r):
# 1.
arr = sorted(arr)
used = [0 for _ in range(len(arr))]
def generate(chosen, used):
# 2.
if len(chosen) == r:
print(chosen)
return
# 3.
for i in range(len(arr)):
if not used[i]:
chosen.append(arr[i])
used[i] = 1
generate(chosen, used)
used[i] = 0
chosen.pop()
generate([], used)
>>> permutation('ABCD', 2)
>>> permutation([1, 2, 3, 4, 5], 3)
def combination(arr, r):
# 1.
arr = sorted(arr)
# 2.
def generate(chosen):
if len(chosen) == r:
print(chosen)
return
# 3.
start = arr.index(chosen[-1]) + 1 if chosen else 0
for nxt in range(start, len(arr)):
chosen.append(arr[nxt])
generate(chosen)
chosen.pop()
generate([])
>>> combination('ABCDE', 2)
>>> combination([1, 2, 3, 4, 5], 3)
def permutation(arr, r):
# 1.
arr = sorted(arr)
used = [0 for _ in range(len(arr))]
def generate(chosen, used):
# 2.
if len(chosen) == r:
print(chosen)
return
for i in range(len(arr)):
# 3.
if not used[i] and (i == 0 or arr[i-1] != arr[i] or used[i-1]):
chosen.append(arr[i])
used[i] = 1
generate(chosen, used)
used[i] = 0
chosen.pop()
generate([], used)
>>> permutation('AABC', 2)
['A', 'B']
['A', 'C']
['B', 'A']
['B', 'C']
['C', 'A']
['C', 'B']
def combination(arr, r):
# 1.
arr = sorted(arr)
used = [0 for _ in range(len(arr))]
# 2.
def generate(chosen):
if len(chosen) == r:
print(chosen)
return
# 3.
start = arr.index(chosen[-1]) + 1 if chosen else 0
for nxt in range(start, len(arr)):
if used[nxt] == 0 and (nxt == 0 or arr[nxt-1] != arr[nxt] or used[nxt-1]):
chosen.append(arr[nxt])
used[nxt] = 1
generate(chosen)
chosen.pop()
used[nxt] = 0
generate([])
>>> combination('ABCDE', 2)
>>> combination([1, 2, 3, 4, 5], 3)
# 리스트에서 나열할 수 있는 모든 경우의 수
input_list = [1,2,3,4,5]
used = [0]*len(input_list)
print(used)
def perm(arr, n):
if n == len(input_list):
print(arr)
return
for i in range(len(input_list)):
if not used[i]:
used[i] = 1
arr.append(input_list[i])
perm(arr, n+1)
arr.pop()
used[i] = 0
perm([], 0)
# 리스트에서 뽑을 수 있는 모든 경우의 수
nums = [1, 2, 3, 4, 5]
answer_list = []
def combi(n, ans):
if n == len(nums):
temp = [i for i in ans]
answer_list.append(temp)
return
ans.append(nums[n])
combi(n + 1, ans)
ans.pop()
combi(n + 1, ans)
combi(0, [])
print(answer_list)
# 리스트에서 r개의 값을 나열할 수 있는 경우의 수
nums = [1, 2, 3, 4, 5]
answer_list = []
def nCr(n, ans, r):
if n == len(nums):
if len(ans) == r:
temp = [i for i in ans]
answer_list.append(temp)
return
ans.append(nums[n])
nCr(n + 1, ans, r)
ans.pop()
nCr(n + 1, ans, r)
nCr(0, [], 3)
print(answer_list)
사람이 사용하는 언어나 이미지는 0과 1로만 이루어진 컴퓨터 입장에서 그 의미를 파악하기가 어려움
임베딩은 다른 딥러닝 모델의 입력값으로 자주 쓰이고 품질 좋은 임베딩을 쓸수록 모델의 성능이 좋아짐
임베딩의 품질이 좋을수록 수행하려는 태스크의 성능이 올라가고 학습 손실도 적고 빠르게 감소하여 모델의 수렴이 빨라짐
높은 차원의 데이터로 인해 생기는 비효율성과 특징을 나타내기 어렵다는 단점으로 인해 임베딩을 수행하는데, 이 때 저차원의 밀집행렬(Dense Matrix)를 사용
- 'The squad is ready to win the football match'
- 'The team is prepared to achieve victory in the soccer game'
위의 두 문장은 의미는 같지만 비슷한 단어가 거의 없음 → 하지만 각 문장의 임베딩 벡터에서는 의미적 인코딩이 매우 유사하기 때문에 임베딩 공간에 서로 가까이 놓임!