728x90
확률(Probability)이란
- 불확실한 상황에서 특정 사건이 발생할 가능성을 수치화한 개념
- 0부터 1(100%) 사이의 실수로 표현된다.
확률이 사용되는 예시
- 날씨 예보
- 예시 : "내일 비가 올 확률이 70%라고 가정"
- 현재의 기상 데이터와 과거 유사한 조건에서 70%는 비가 왔다는 통계적 분석
- 우산을 가져갈지, 야외활동을 계획할지 결정하는 데 도움
- 스포츠 경기
- 예시 : "A팀이 B팀을 이길 확률이 65%라고 가정"
- 팀의 과거 성적, 선수 컨디션, 홈/원정 요소 등을 고려한 승리 가능성
- 베팅, 전략 수립, 방송 해설 등에 활용
- 이상 탐지
- 예시 : "이 거래가 정상적인 패턴일 확률은 0.01%로, 사기 의심"
- 정상 데이터의 확률 분포를 학습하고, 이 분포에서 벗어난 데이터 탐지
- 사기 탐지, 시스템 장애 예측, 품질 관리 등에 활용
경우의 수
- 확률 계산에 기초가 되는 경우의 수
- 사건의 가능한 결과를 체계적으로 세는 방법
- 필요한 수식과 시각자료
- 경우의 수를 계산하는 방법으로는 곱의 법칙, 합의 법칙, 순열, 조합 등이 있다.
곱의 법칙(Multiplication Principle)
- 여러 단계의 선택이 있을 때, 각 단계에서의 선택 가능한 경우의 수를 모두 곱하여 전체 경우의 수를 구하는 방법
- 공식 : 첫 번째 선택이 n₁가지, 두 번째 선택이 n₂가지, ..., k번째 선택이 nₖ가지일 때:
- 전체 경우의 수 = n₁ × n₂ × ... × nₖ
- 예시 : 암호 경우의 수 : 4자리 PIN 코드에서 각 자리가 0-9의 숫자일 때
- 10 × 10 × 10 × 10 = 10⁴ = 10,000 가지
- 예시 : 셔츠 4개, 바지 3개, 신발 2개가 있을 때 가능한 전체 복장 조합
- 4 × 3 × 2 = 24가지
def multiplication_principle(*choices):
"""곱의 법칙을 사용하여 총 경우의 수를 계산"""
total_outcomes = 1
for choice in choices:
total_outcomes *= choice
return total_outcomes
# 예시: 의상 조합
shirts, pants, shoes = 4, 3, 2
outfit_combinations = multiplication_principle(shirts, pants, shoes)
print(f"가능한 의상 조합의 수: {outfit_combinations}") # 출력: 24
# 예시: PIN 코드
pin_combinations = multiplication_principle(10, 10, 10, 10)
print(f"가능한 PIN 코드의 수: {pin_combinations}") # 출력: 10000
합의 법칙(Addition Principle)
- 합의 법칙은 서로 배타적인(겹치지 않는) 여러 사건 중 하나가 발생하는 경우의 수를 구할 때, 각 사건의 경우의 수를 더하는 방법
- 공식 : 배타적 사건(겹치지 않는 경우) : 사건 A 또는 사건 B가 일어나는 경우의 수 = |A| + |B|
- 공식 : 비배타적 사건(겹치는 경우) : 사건 A또는 사건 B가 일어나는 경우의 수 = |A| + |B| - |A ∩ B|
- 여기서 |A ∩ B| 는 A와 B가 동시에 일어나는 경우의 수
- 예시 : 배타적 사건 : 주사위를 던져 1이 나오거나 짝수(2,4,6)이 나오는 경우
- 1(1의 경우의 수) + 3(짝수의 경우의 수) = 4가지
- 예시 : 비배타적 사건 : 카드 한 장을 뽑아 하트 무늬이거나페이스 카드(J,Q,K)인 경우
- 하트 무늬 : 13장
- 페이스 카드: 12장 (각 무늬당 3장씩, 총 4개 무늬)
- 하트 무늬이면서 페이스 카드 : 3장 (하트 J,Q,K)
- 따라서 경우의 수 = 13 + 12 - 3 = 22장
def addition_principle_disjoint(event_a, event_b):
"""배타적 사건에 대한 합의 법칙 적용"""
return event_a + event_b
def addition_principle_non_disjoint(event_a, event_b, intersection):
"""비배타적 사건에 대한 합의 법칙 적용"""
return event_a + event_b - intersection
# 예시: 배타적 사건 (주사위)
ones = 1 # 주사위에서 1이 나오는 경우의 수
even_numbers = 3 # 주사위에서 짝수가 나오는 경우의 수 (2,4,6)
total_outcomes = addition_principle_disjoint(ones, even_numbers)
print(f"주사위에서 1이 나오거나 짝수가 나오는 경우의 수: {total_outcomes}") # 출력: 4
# 예시: 비배타적 사건 (카드)
hearts = 13 # 하트 무늬 카드의 수
face_cards = 12 # 페이스 카드(J,Q,K)의 수
heart_face_cards = 3 # 하트 무늬이면서 페이스 카드인 카드의 수
total_cards = addition_principle_non_disjoint(hearts, face_cards, heart_face_cards)
print(f"하트 무늬이거나 페이스 카드인 카드의 수: {total_cards}") # 출력: 22
순열(Permutation)
전체 순열
- (n = r)인 경우 : n개의 원소를 모두 선택하여 나열하는 방법의 수
- 모든 원소를 사용하여 만들 수 있는 모든 순서를 의미
- 공식 : nPn = n!
- (n-n)! = 0! = 1이므로, n! / (n-n)! = n! / 1 = n!
- 여기서 n!은 n 팩토리얼: n! = n × (n-1) × (n-2) × ... × 2 × 1
- 팩토리얼 : "n개의 서로 다른 물건을 나열하는 방법의 수" 주어진 숫자부터 시작하여 1까지 모든 자연수를 곱하는 연산
- 예시 : 4명의 학생을 일렬로 세우는 방법 4P4 = 4! = 24가지
- 예시 : 5개 글자로 만들 수 있는 모든 배열(애너그램) : 5P5 = 5! = 120가지
- 예시 : 카드 8장을 한 줄로 배열하는 방법 : 8P8 = 8! = 40,320가지
import math
def full_permutation(n):
"""n개 원소의 전체 순열 (n = r)"""
return math.factorial(n)
# 예시: 4명을 일렬로 세우는 방법
print(f"4명을 일렬로 세우는 방법: {full_permutation(4)}가지") # 출력: 24
# itertools로 모든 전체 순열 생성하기
from itertools import permutations
names = ['Alice', 'Bob', 'Charlie', 'David']
all_arrangements = list(permutations(names)) # r을 지정하지 않으면 전체 순열
print(f"첫 3가지 배열: {all_arrangements[:3]}")
부분 순열
- (n ≠ r인 경우, 일반적으로 n > r )인 경우 : n개의 원소 중 r개만 선택하여 나열하는 방법의 수
- 일부 원소만 선택하여 순서대로 배열
- 공식 : nPr = n!(n−r)!
- n > r일 때 적용
- 예시 : 10명 중 3명을 선발하여 금, 은, 동메달 수여 : 10P3 = 10! /7! = 720가지
- 예시 : 7개 색상 중 3개를 선택하여 순서대로 배치 : 7P3 = 7! / 4! = 210가지
- 예시 : 26개 알파벳 중 4개를 선택하여 비밀번호 생성 : 26P4 = 26! / 22! = 358,800가지
import math
def partial_permutation(n, r):
"""n개 중 r개를 선택하는 부분 순열 (n ≠ r)"""
if n < r:
raise ValueError("n은 r보다 크거나 같아야 합니다.")
return math.factorial(n) // math.factorial(n - r)
# 예시: 10명 중 금,은,동메달 수여 방법
print(f"10명 중 3개 메달 수여 방법: {partial_permutation(10, 3)}가지") # 출력: 720
# itertools로 부분 순열 생성하기
from itertools import permutations
colors = ['Red', 'Blue', 'Green', 'Yellow', 'Purple', 'Orange', 'Pink']
color_arrangements = list(permutations(colors, 3)) # 7개 중 3개 선택
print(f"가능한 배치 수: {len(color_arrangements)}가지") # 출력: 210
print(f"첫 3가지 색상 배치: {color_arrangements[:3]}")
중복 순열(Permutation with Reptition)
- 중복 순열은 n개의 원소 중에서 중복을 포함해 r개를 선택하여 특정한 순서로 나열하는 것을 의미한다.
- 각 위치에서 항상 n개의 모든 원소 중에서 선택 가능
- 이전에 선택한 원소도 다시 선택 가능
- r개의 각 위치에 대해 독립적으로 n개의 선택지가 있음
- 공식 : nΠr = nr
- 예시 : 주사위 던지기
- 주사위 3번 던지기
- 6Π3 = 63 = 216가지
- 예 : (1,1,1), (1,1,2), (1,1,3) ..., (6,6,6)
import itertools
def repeated_permutation(n, r):
"""nΠr: n개 중 r개를 선택하는 중복 순열의 수"""
return n ** r
# 예시: 3개 원소에서 2개 선택하는 중복 순열
n, r = 3, 2
count = repeated_permutation(n, r)
print(f"{n}개 원소에서 {r}개 선택하는 중복 순열의 개수: {count}") # 출력: 9
# 모든 중복 순열 나열하기
elements = ['A', 'B', 'C'] # 3개 원소
all_repeated_perms = list(itertools.product(elements, repeat=r))
print(f"가능한 모든 중복 순열: {all_repeated_perms}")
print(f"총 개수: {len(all_repeated_perms)}") # 출력: 9
- 곱의 법칙과의 차이점
- 곱의 법칙 : 더 일반적인 원리, 각 단계마다 선택지의 수가 다를 수 있음
- 중복 순열 : 모든 단계에서 동일한 n개의 선택지가 있는 특수한 경우
조합(Combination)
- 순서가 중요하지 않은 n개에서 r개를 선택하는 방법의 수
- 선택된 요소의 집합만 중요하고, 순서는 고려하지 않는다.
- 공식 : nCr = n!r!(n−r)!
- 순열에서는 ABC와 ACB를 다른 경우로 봄
- 조합에서는 ABC와 ACB를 같은 경우로 봄
- 조합은 순열을 r!로 나눈 값과 같음(순서를 고려하지 않으니)
- 예시 : 위원회 구성 : 15명 중 5명을 선택하여 위원회 구성
- 15C5 = 15! / (5! × 10!) = 3,003가지
- 예시 : 복권 당첨 : 45개 숫자 중 6개 선택(로또)
- 45C6 = 45! / (6! × 39!) = 8,145,060가지
- 예시 : 카드 게임 : 52장의 카드 중 5장 뽑기 (포커 핸드)
- 52C5 = 52! / (5! × 47!) = 2,598,960가지
import math
def combination(n, r):
"""nCr: n개 중 r개를 선택하는 방법의 수 (순서 무관)"""
return math.factorial(n) // (math.factorial(r) * math.factorial(n - r))
# 예시
print(f"15명 중 5명 위원회 구성 방법: {combination(15, 5)}") # 출력: 3003
print(f"로또(45개 중 6개 선택) 가능한 조합: {combination(45, 6)}") # 출력: 8145060
# 파이썬 itertools 라이브러리 사용
from itertools import combinations
# 모든 조합 생성 예시
students = ['Alice', 'Bob', 'Charlie', 'David', 'Eve']
committee_size = 3
# 가능한 모든 위원회 조합
possible_committees = list(combinations(students, committee_size))
print(f"가능한 위원회 구성 수: {len(possible_committees)}") # 출력: 10
print("가능한 위원회 구성:")
for i, committee in enumerate(possible_committees):
print(f"{i+1}. {', '.join(committee)}")
중복 조합(Combination with Reptition)
- 중복 조합은 서로 다른 n개에서 중복을 포함해 순서를 고려하지 않고 r개를 뽑는 것을 의미
- 같은 원소를 여러 번 선택 가능
- 순서는 중요하지 않음, 중복 조합은 n개의 원소와 r-1개의 구분자를 일렬로 배열하는 조합으로 생각 가능
- 공식 : n+r−1Cr
- 예시 : 동전 분배
- 4종류의 동전 (10원, 50원, 100원, 500원)으로 1000원 만들기
- 각 종류마다 여러 개 사용 가능, 순서는 중요하지 않음
- 이 문제는 음이 아닌 정수 x₁, x₂, x₃, x₄에 대해 10x₁ + 50x₂ + 100x₃ + 500x₄ = 1000 해 찾기
- 예시 : 다중집합에서 부분집합 선택
- {a,a,a,b,b,c}라는 다중집합에서 3개의 원소 선택 (중복 있음)
- 원소 종류는 3개(a,b,c), 선택할 개수는 3개
- 3H3 = (3+3-1)C3 = 5C3 = 10가지
import math
from itertools import combinations_with_replacement
def combination_with_repetition(n, r):
"""nHr: n개 중 r개를 선택하는 중복 조합의 수"""
return math.comb(n+r-1, r)
# 예시: 3개 원소에서 5개 선택하는 중복 조합
n, r = 3, 5
count = combination_with_repetition(n, r)
print(f"{n}개 원소에서 {r}개 선택하는 중복 조합의 개수: {count}") # 출력: 21
# 모든 중복 조합 나열하기
elements = ['바닐라', '초콜릿', '딸기']
all_combinations = list(combinations_with_replacement(elements, r))
print(f"가능한 모든 중복 조합 수: {len(all_combinations)}") # 출력: 21
print("첫 5가지 중복 조합:")
for i, combo in enumerate(all_combinations[:5]):
print(f"{i+1}. {combo}")
확률(Probability)
- 표본 공간(sample space) S에서 사건 X가 일어날 확률
- 사건 X 가 일어날 확률은 -> P(X)=n(X)n(S)
- P(X)는 사건 X가 일어날 확률
- n(X)는 사건 X에 포함된 경우의 수
- n(S)는 표본 공간 S의 전체 경우의 수
고전적 확률(Classical Probability)
- 모든 결과가 동등하게 발생할 수 있을 때 사용
- 공식: P(X)= 사건 X의 경우의 수전체 경우의 수
통계적 확률 (Statistical Probability)
- 예 : 1000번의 동전 던지기에서 앞면이 나온 횟수가 498번이면, 앞면이 나올 확률 ≈
- 4981000 = 0.498
- 시행 횟수가 많아질수록 실제 확률에 가까워짐 (큰 수의 법칙)
AI 활용 확률과 경우의 수 딥러닝/머신러닝 활용
확률 기반 머신러닝 알고리즘
- 분류와 예측 모델
- 나이브 베이즈(Naive Bayes) : 조건부 확률을 사용하여 텍스트 분류, 스팸 필터링 등 수행
- 로지스틱 회귀 : 입력 특성의 선형 조합을 시그모이드 함수에 적용하여 확률 출력
# 나이브 베이즈 분류기 예시 코드
from sklearn.naive_bayes import MultinomialNB
model = MultinomialNB()
model.fit(X_train, y_train)
# P(class|features) 확률에 기반한 예측
predictions = model.predict_proba(X_test)
- 생성 모델
- VAE(Variational Autoencoder) : 잠재 공간의 확률 분포를 학습하여 새로운 데이터 생성
- GAN(Generative Adversarial Network) : 생성자와 판별자의 확률적 경쟁을 통한 데이터 생성
- 확률적 학습 방법
- SGD(Stochastic Gradient Descent) : 무작위 샘플링을 통한 확률적 최적화
- 드롭아웃(Dropout) : 학습 과정에서 뉴런을 확률적으로 비활성화하여 과적합 방지
# SGD 최적화 예시
optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
model.compile(optimizer=optimizer, loss='categorical_crossentropy')
model.add(tf.keras.layers.Dropout(0.5)) # 50% 확률로 뉴런 비활성화
경우의 수와 AI 모델 설계
- 하이퍼파라미터 최적화
- 그리드 서치 : 가능한 모든 하이퍼파라미터 조합을 시험(곱의 법칙 적용)
- 앙상블 학습
- 랜덤 포레스트 : 여러 의사결정 트리의 조합을 통한 예측
- 배깅과 부스팅 : 다양한 모델 조합을 통한 성능 향상
- 특성 선택 : 최적의 특성 부분집합 찾기(조합 개념 활용)
- 신경망 아키텍처 탐색
- NAS(Neural Architecture Search) : 다양한 계층 구성과 연결 방식 탐색
- AutoML : 최적의 모델 아키텍처를 자동으로 찾는 프로세스
요약 및 추가 학습 자료
- 확률과 경우의 수는 AI와 딥러닝의 근간을 이루는 수학적 개념으로, 다음과 같은 측면에서 핵심적인 역할을 합니다:
- 확률 모델링: AI 시스템은 본질적으로 불확실성을 다루며, 확률은 이를 수학적으로 표현하는 도구입니다.
- 학습 알고리즘: 확률적 최적화 기법이 딥러닝의 학습 과정에 광범위하게 사용됩니다.
- 예측과 추론: AI 모델의 출력은 종종 확률 분포 형태로 표현되어 불확실성을 정량화합니다.
- 모델 설계: 경우의 수 계산은 하이퍼파라미터 최적화, 앙상블 방법, 아키텍처 설계 등에 활용됩니다.
- 일반화 능력: 확률적 요소(드롭아웃, 데이터 증강 등)는 과적합을 방지하고 모델의 일반화 능력을 향상시킵니다.
728x90