2장 간단한 분류 알고리즘 훈련
- 퍼셉트론
- 분류를 위한 초창기 머신 러닝 알고리즘
- 파이썬을 사용한 효율적인 구현 방법
- 적응형 선형 뉴런
- 기본적인 최적화
- 사이킷런 머신 러닝 라이브러리_강력한 분류 모델 사용의 기초
1. 인공 뉴런: 초기 머신 러닝의 간단한 역사
1943년 워렌 맥컬록(Warren McCulloch), 월터 피츠(Walter Pitts)
: 간소화된 뇌의 뉴런 개념 발표 = 맥컬록-피츠(MCP) 뉴런
*뉴런: 뇌의 신경 세포와 서로 연결 => 화학적/전기적 신호 처리, 전달
*신경 세포 -> 이진 출력을 내는 간단한 논리 회로
여러 신호 -> 수상 돌기 => 세포체 합쳐짐
합쳐진 신호 > 특정 임계 값 -> 출력 신호 생성 -> 축삭 돌기 이용하여 전달
프랑크 로젠블라트(Frank Rosenblatt)
MCP 뉴런 모델 기반 -> 퍼셉트론 학습 개념 발표
*퍼셉트론 규칙: 자동으로 최적의 가중치 학습 알고리즘 제안
*가중치: 뉴런의 출력 신호OX 결정 -> 입력 특성에 곱하는 계수
=> 새로운 데이터 포인트가 한 클래스에 속하는지 아닌지 예측
1) 인공 뉴런의 수학적 정의
인공 뉴런(artificial neuron) -> 2개 클래스(1(양성)/-1(음성)) O 이진 분류 작업
입력 값 x, 상응하는 가중치 벡터 w 선형 조합 -> 결정 함수(∅(x)) 정의
*결정 함수(∅(∙)): 단위 계단 함수(unit step function) 변형한 것
<예측>
- 특정 샘플 x^(i)의 최종 입력 > 사전에 정의된 임계 값 θ => 클래스 1
- 특정 샘플 x^(i)의 최종 입력 <= 사전에 정의된 임계 값 θ => 클래스 -1
식 변형(-> z 간단하게 쓸 수 있음)
: 임계 값 θ: 식 왼쪽으로 이동 -> w_0 = -θ, x_0 = 1 인 0번째 가중치 정의
*절편: 임수 임계 값 or 가중치 w_0 = -θ
- 퍼셉트론 결정 함수 -> 최종 입력 z = w^Tx가 이진 출력(-1 or 1)으로 압축되는 방법(L그림)
- 이를 사용 -> 선형 분리 가능한 2 개의 클래스 사이 구별하는 방법(R 그림)
2) 퍼셉트론 학습 규칙
MCP 뉴런, 로젠블라트의 임계 퍼셉트론 모델 <- 뇌의 뉴런 하나가 작동하는 방식 흉내(환원주의(reductionism) 접근 방식)
=> 출력 OX (2가지 경우만 존재) => 학습 규칙 매우 간단
<퍼셉트론 알고리즘>
- 가중치 -> 0 or 랜덤한 작은 값으로 초기화
- 각 훈련 샘플 x^(i)에서 다음 작업
- 출력 값 ŷ 계산
- 가중치 업데이트
*출력 값: 앞서 정의한 단위 계단 함수로 예측한 클래스 레이블
가중치 벡터 w에 있는 개별 가중치 w_j가 동시에 업데이트 되는 것
가중치 w_j에 대한 업데이트 값(or w_j의 변화량) Δw_j 값 -> 퍼셉트론 학습 규칙 따라 계산
- η: 학습률(learning rate)_일반적으로 0.0 ~ 1.0 사이 실수
- y^{(i)}: i번째 훈련 샘플의 진짜 클래스 레이블(true class label)
- ŷ^{(i)}: 예측 ㅋ ㅡㄹ래스 레이블(predicted class label)
가중치 벡터의 모든 가중치를 동시에 업데이트
= 모든 가중치가 각자의 업데이트 값 Δw_j에 의해 업데이트되기 전 예측 레이블 ŷ^{(i)}를 다시 계산X
2차원 데이터셋 업데이트
ex.
1. 퍼셉트론: 클래스 레이블 정확히 예측 -> 가중치 변경X 그대로 유지 => 업데이트 값 0
2. 퍼셉트론: 클래스 레이블 잘못 예측 -> 가중치 -> 양성 or 음성 타깃 클래스 방향으로 이동시킴
<곱셈 계수인 x_j^{(i)} 이해하기 위한 예시>
ex. 1
x_j^{(i)} = 0.5일 때 이 샘플을 -1로 잘못 분류
가중치 +1 -> 다음번 이 샘플 만날 경우 최종 입력 x_j^{(i)} * w_j 가 더 큰 양수가 됨
=> 단위 계단 함수의 임계 값보다 커져 샘플이 +1로 분류될 가능성 ↑
가중치 업데이트는 x_j^{(i)}에 비례
ex. 2
다른 샘플 x_j^{(i)} = 2를 -1로 잘못 분류
다음번 올바르게 분류 -> 더 ↑ 결정 경계 움직임
퍼셉트론: 두 클래스가 선형적으로 구분, 학습률 충분히 ↓ => 수렴 보장
if 두 클래스 -> 선형 결정 경계로 나눌 수 X
-> 훈련 데이터셋을 반복할 최대 횟수(에포크(epoch)) 지정, 분류 허용 오차 지정
=> 가중치 업데이트를 멈추기 위해
- 샘플 x -> 퍼셉트론에 입력 -> 가중치 w 연결 => 최종 입력 계산
- 최종 입력 -> 임계 함수로 전달 -> 샘플의 예측 클래스 레이블인 -1 or +1 이진 출력 만듦
학습 단계: 출력 사용 -> 예측 오차 계산, 가중치 업데이트
2. 파이썬으로 퍼셉트론 학습 알고리즘 구현
1) 객체 지향 퍼셉트론 API
객체 지향 방식 사용 -> 퍼셉트론 인터페이스 가진 파이썬 클래스 정의
Perceptron 객체 초기화 -> fit 메서드: 데이터에서 학습 -> 별도의 predict 메서드: 예측 만듦
*관례에 따라 객체의 초기화 과정에서 생성X, 다른 메서드 호출해서 만든 속성 -> 밑줄(_) 추가 (ex. self.w_)
퍼셉트론 구현
퍼셉트론 구현 사용 -> 학습률 eta, 에포크 횟수(: 훈련 데이터셋을 반복하는 횟수) n_iter
=> 새로운 Perceptron 객체 초기화
fit 메서드: self.w_ 가중치 -> 벡터 R^{m+1}로 초기화
*m: 데이터셋에 있는 차원(특성) 개수
벡터의 첫 번째 원소인 절편 위해 +1
*self.w_[0]: 벡터의 첫 번째 원소 = 앞서 언급한 절편
rgen.normal(loc=0.0, scale=0.01, size=1 + X.shape[1] 사용
-> 표준 편차가 0.01인 정규 분포에서 뽑은 랜덤한 작은 수 담음
*rgen: 넘파이 난수(random number) 생성기, 사용자가 지정한 랜덤 시드(seed)로 이전과 동일한 결과 재현O
- 가중치 0으로 초기화X 이유: 가중치가 0이 아니어야 학습률 η^{(eta)} -> 분류 결과 영향
- 가중치 0으로 초기화O -> 학습률 파라미터 eta는 가중치 벡터의 방향이 아닌 크기에만 영향
ex. 삼각법
벡터 v1 = [1 2 3] 있을 때 v1과 벡터 v2 = 0.5 * v1 사이 각 = 0
- np.arccos 함수: 역코사인 삼각 함수
- np.linalg.norm: 벡터 길이 계산하는 함수
넘파이 배열 인덱싱
1차원 배열의 넘파이 인덱싱(indexing) ~= 대괄호([]) 사용하는 파이썬 리스트
2차원 배열: 첫 번째 인덱스 -> 행 번호, 두 번째 인덱스 -> 열 번호
ex. X[2, 3]: 2차원 배열 X의 세 번째 행과 네 번째 열 선택
fit 메서드: 가중치 초기화 -> 훈련 데이터셋에 있는 모든 개개의 샘플 반복 순회 -> 퍼셉트론 학습 규칙 따라 가중치 업데이트
fit 메서드에서 훈련하는 동안 가중치 업데이트 위해 predict 메서드 호출 -> 클래스 레이블에 대한 예측
*predict 메서드: 모델 학습되고 난 후 새로운 데이터 클래스 레이블 예측하는 데 사용
에포크마다 self.errors_ 리스트에 잘못 분류된 횟수 기록
=> 훈련하는 동안 얼마나 퍼셉트론 잘 수행했는지 분석 가능
net_input 메서드에서 사용한 np.dot 함수: 벡터 점곱 w^Tx 계산
a.dot(b)나 np.dot(a, b)처럼 넘파이 사용하여 배열 a와 b 사이의 벡터 점곱 계산
-> 파이썬만 사용: sum([i * j for i, j in zip(a, b)])처럼 계산O
넘파이 사용 이점: 산술 연산 -> 벡터화
*벡터화(vectorization): 원소별 산술 연산이 자동으로 배열의 모든 원소에 적용
한 번에 원소 하나씩 연산 차례로 수행X, 하나의 산술 연산을 배열에 대한 연속적인 명령으로 구성
-> SIMD(Single Instruction, Multiple Data)를 지원하는 최신 CPU 구조의 장점 활용O
넘파이: C or 고도로 최적화된 라이브러리 사용
ex. 포트란으로 쓴 BLAS(Basic Linear Algebra Subprograms)와 LAPACK(Linear Algebra PACKage)
=> 벡터와 행렬의 점곱과 같은 기초적인 선형대수학 사용 -> 간결하고 직관적으로 코드 작성
2) 붓꽃 데이터셋에서 퍼셉트론 훈련
앞서 만든 퍼셉트론 구현 테스트 -> 2개 특성(차원)만 사용
퍼셉트론 규칙: 2차원 국한X But, 학습 목적 -> 산점도에 훈련 모델의 결정 경계 그리기 -> 꽃받침 길이, 꽃임 길이
+ 퍼셉트론: 이진 분류 => 붓꽃 데이터셋에서 2개의 꽃 Setosa와 Versicolor만 사용
But, 퍼셉트론 알고리즘 -> 다중 분류로 확장O
ex. 일대다(One-versus-All, OvA) 전략 사용
다중 클래스 분류를 위한 일대다 전략
OvR 기법 사용 => 이진 분류기 -> 다중 클래스 문제에 적용O
OvA 사용할 때 클래스마다 하나의 분류기 훈련
각 클래스(양성 클래스)/다른 클래스의 샘플(음성 클래스)
레이블X 새로운 데이터 샘플 분류 -> n개 분류기(= 클래스 레이블의 개수)
신뢰도 가장 ↑ 클래스 레이블 -> 분류하려는 샘플에 할당
퍼셉트론: OvA 사용 -> 최종 입력의 절대값 가장 ↑ 클래스를 레이블로 선택
pandas 라이브러리 사용 -> UCI 머신 러닝 저장소에서 붓꽃 데이터셋을 DataFrame 객체로 직접 로드(load)
50개의 Iris-setosa와 50개의 Iris-versicolor 꽃에 해당하는 처음 100개의 클래스 레이블 추출
클래스 레이블 -> 2개의 정수 클래스 1(versicolor)과 -1(setosa)로 변경 -> 벡터 y에 저장
판다스 DataFrame의 values 속성: 넘파이 배열 반환
100개의 훈련 샘플에서 첫 번째 특성 열(꽃받침 길이)과 세 번째 특성 열(꽃잎 길이) 추출
-> 특성 행렬 X에 저장, 2차 산점도(scatter plot)로 시각화
산점도 -> 붓꽃 데이터셋에 있는 샘플들이 꽃받침 길이와 꽃잎 길이 두 개의 특성 축을 따라 분포된 형태 보여줌
2차원 부분 공간에서는 선형 결정 경계로 Setosa와 Versicolor 꽃 구분O
=> 퍼셉트론 같은 선형 분류기가 완벽하게 분류
붓꽃 데이터셋에서 추출한 일부 데이터에서 퍼셉트론 알고리즘 훈련
에포크 대비 잘못 분류된 오차 -> 그래프 => 알고리즘이 수렴하여 두 붓꽃 클래스 구분하는 결정 경계 찾는지 확인
퍼셉트론은 여섯 번째 에포크 이후 수렴, 훈련 샘플 와녁하게 분류
간단한 함수 만들어 2차원 데이터셋의 결정 경계 시각화
colors와 markers 정의, ListedColormap 사용 -> colors 리스트에서 컬러맵 만듦
두 특성의 최솟값, 최댓값 찾고 이 벡터로 넘파이 meshgrid 함수로 그리드(grid) 배열 xx1과 xx2 쌍 만듦
두 특성 차원에서 퍼셉트론 분류기 훈련 -> 그리드 배열 펼치고 훈련 데이터와 같은 개수의 열 되도록 행렬 만듦
predict 메서드: 그리드 각 포인트에 대응하는 클래스 레이블 Z 예측
클래스 레이블 Z -> xx1, xx2 같은 차원의 그리드로 크기 변경 -> 맷플롯립의 contourf 함수: 등고선 그래프
그리드 배열에 대해 예측한 클래스 -> 다른 색으로 매핑 => 결정 영역 나타냄
=> 퍼셉트론이 학습한 결정 경계는 두 개의 붓꽃으로 구성된 데이터셋의 모든 샘플 완벽하게 분류
퍼셉트론의 수렴
2개의 붓꽃 클래스 완벽하게 분류 But, 문제: 수렴
프랑크 로젠블란트: 퍼셉트론 학습 규칙: 2개의 클래스가 선형적인 초평면으로 구분O -> 수렴
선형 결정 경계로 완벽하게 클래스 구분X -> 최대 에포크 지정X -> 가중치 업데이트 과정 멈추지X
3. 적응형 선형 뉴런과 학습의 뉴런
적응형 선형 뉴런(ADAptive LInear NDuron, ADALINE)
버나드 위드로우(Bernard Widrow), 테드 호프(Tedd Hoff)
아달린(Adaline) 발표
*아달린: 퍼셉트론의 향상된 버전
연속 함수/ 비용 함수 정의, 최소화
=> 고급 머신 러닝 모델과 회귀 모델 이해하는데 도움
ex. 로지스틱 회귀(logistic regression), 서포트 벡터 머신(support vector machine)
아달린 규칙(= 위드로우-호프 규칙) vs. 로젠블라트 퍼셉트론
: 가중치 업데이트하는 데 퍼셉트론처럼 단위 계단 함수 대신 선형 활성화 함수 사용하는 것
*선형 활성화 함수 ∅(z): 항등 함수(identity function)
가중치 학습에 사용되지만 최종 예측 만드는데 임계 함수 사용(~= 단위 계단 함수)
아달린 알고리즘: 진짜 클래스 레이블 vs. 선형 활성화 함수의 실수 출력 값
=> 모델의 오차 계산, 가중치 업데이트
퍼셉트론: 진짜 클래스 레이블 vs. 예측 클래스 레이블
1) 경사 하강법으로 비용 함수 최소화
지도 학습 알고리즘의 핵심 구성 요소 중 하나: 학습 과정 동안 최적화하기 위해 정의한 목적 함수(object function)
최소화하려는 비용 함수 -> 목적 함수
아달린: 계산된 출력과 진짜 클래스 레이블 사이 제곱 오차합(Sum of Squared Errors, SSE)
-> 가중치 학습하기 위한 비용 함수 J 정의
1/2 항: 가중치 파라미터에 대한 비용 함수 or 손실 함수의 그레디언트(gradient) 간소하게 만드려고 편의상 추가
단위 계단 함수 대신 연속적인 선형 활성화 함수 사용(+): 비용 함수 -> 미분 가능, 비용 함수(+): 볼록 함수
경사 하강법(gradient descet) 적용 -> 붓꽃 데이터셋의 샘플 분류하도록 비용 함수 최소화하는 가중치 찾을 수 있음
- 반복에서 경사의 반대 방향으로 진행
- 진행 크기 <- 경사의 기울기와 학습률
경사 하강법 사용 -> 비용 함수 J(w)의 그레이디언트 ∇J(w) 반대 방향으로 조금씩 가중치 업데이트 O
가중치 변화량 Δw: 음수의 그레이디언트*학습률 η
비용 함수의 그레이디언트 계산 -> 각 가중치 w_j에 대한 편도 함수 계산
=> 가중치 w_j의 업데이트 공식
모든 가중치 동시에 업데이트 => 아달린 학습 규칙
제곱 오차합의 도함수
j번째 가중치에 대한 SSE 비용 함수의 편도 함수 유도하는 과정
아달린 학습 규칙이 퍼셉트론 규칙과 동이랗게 보이지만 z^{(i)}=w^Tx^{(i)}인 ∅(z^{i)})는 정수 클레스 레이블X, 실수O
+ 훈련 데이터셋에 있는 모든 샘플을 기반으로 가중치 업데이트 계산(각 샘플마다 가중치 업데이트X)
=> 배치 경사 하강법(batch gradient descent)
2) 파이썬으로 아달린 구현
퍼셉트론 규칙 ~= 아달린
=> 퍼셉트론 구현에서 fit 메서드 바꿔 경사 하강법으로 비용 함수 최소화되도록 가중치 업데이트
퍼셉트론처럼 개별 훈련 샘플마다 평가한 후 가중치 업데이트X, 전체 훈련 데이터셋 기반 -> 그레이디언트 계산
절편(0번째 가중치): self.eta * errors.sum()
가중치 1에서 m까지: self.eta * X.T.dot(erros)
*X.T.dot(erros): 특성 행렬과 오차 벡터 간의 행렬-벡터 곱셈
activation 메서드: 단순한 항등 함수(identity function) => 영향X
단일층 신경망 ~> 정보가 어떻게 흘러가는지 일반적 개념 표시 -> (activation 메서드에서 계산되는) 활성화 함수 추가
입력 데이터의 특성: 최종 입력 -> 활성화 -> 출력
3장: 항등 함수X 비선형 활성화 함수 사용O -> 로지스틱 회귀 분류기
*로지스틱 회귀 모델: 활성화 함수와 비용 함수만 다르고 아달린과 매우 비슷
비용 -> self.cost_ 리스트에 모아 훈련이 끝난 후 알고리즘이 수렴하는지 확인
실전) 최적으로 수렴하는 좋은 학습률 η 찾기 위해 여러 번 실험
2개의 학습률 η = 0.1, η = 0.0001
에포크 횟수 대비 비용 함수의 값 -> 그래프 => 아달린 구현이 훈련 데이터에서 얼마나 잘 학습하는지 확인 가능
퍼셉트론 하이퍼파라미터
에포크 횟수(n_iter)와 학습률 η(eta): 퍼셉트론과 아달린 학습 알고리즘의 하이퍼파라미트(OR 튜닝 파라미터)
비용 함수 J를 최소화하려고 특정 가중치 값 바꾸었을 때 어떤 일이 일어나는지
- L: 적절하게 선택한 학습률 경우/ 비용 점차 ↓ -> 전역 최솟값의 방향으로 이동
- R: 너무 ↑ 학습률 -> 전역 최솟값 지나침
3) 특성 스케일을 조정하여 경사 하강법 결과 향상
경사 하강법: 특성 스케일 조정 -> 혜택O
표준화(standardization) 특성 스케일 방법: 데이터 평균 0, 단위 분산O 표준 정규 분포 성질 부여
-> 경사 하강법 학습이 더 빠르게 수렴되도록 도움
But, 원본 데이터셋 -> 정규 분포로 만듦 (X)
각 특성의 평균을 0에 맞추고 특성의 표준 편차를 1(단위 분산)로 만듦
ex. j번째 특성 표준화 -> 모든 샘플에서 평균 μ_j를 빼고 표준 편차 σ_j로 나눔
x_j: n개의 모든 훈련 샘플에서 j번째 특성 값을 포함한 벡터
표준화 기법 -> 데이터셋의 각 특성 j에 적용
표준화가 경사 하강법 학습에 도움되는 이유: 더 적은 단계 거쳐 최적/좋은 솔루션 찾음
2차원 분류 문제에서 모델의 가중치에 따른 비용 함수의 등고선
표준화 -> 넘파이 내장 함수 mean과 std로 간단하게 처리O
표준화 -> 아달린 모델 훈련 -> 학습률 η=0.01에서 몇 번의 에포크만에 수렴하는지 확인
결정 경계 그래프와 비용이 감소되는 그래프
학습률 η=0.01 사용, 표준화된 특성에서 훈련 => 아달린 모델 수렴
모든 샘플이 완벽하게 분류되더라도 SSE != 0
4) 대규모 머신 러닝과 확률적 경사 하강법
- 배치 경사 하강법
- : 전체 훈련 데이터셋에서 계산한 그레이디언트의 반대 방향으로 한 걸음씩 진행 -> 비용 함수 최소화
- 확률적 경사 하강법(stochastic gradient descent, = 온라인 경사 하강법)
- 배치 경사 하강법의 다른 대안
- 가중치 자주 업데이트 -> 수렴 속도 경사 하강법보다 ↑
- 그레디언트가 하나의 훈련 샘플을 기반으로 계산 -> 오차의 궤적: 배치 경사 하강법보다 어지러움
- 비선형 비용 함수 다룰 때 얕은 지역 최솟값 더 쉽게 탈출O
- 만족스러운 결과 -> 훈련 샘플 순서 무작위하게 주입 + 순환되지X 에포크마다 훈련 데이터셋 섞음
모든 샘플 x^{(i)}에 대해 누적된 오차 합 기반 -> 가중치 업데이트
각 훈련 샘플에 대해 조금씩 가중치 업데이트
훈련하는 동안 학습률 조정하기
확률적 경사 하강법 구현에서 종종 고정된 학습률 η를 시간이 지남에 따라 적응적 학습률로 대체
c_1과 c_2는 상수, 확률적 경사 하강법은 전역 최솟값에 도달X But, 매우 가까운 지역에 근접
적응적 학습률을 사용 -> 최솟값에 더욱 가깝게 다가갈 수 있음
확률적 경사 하강법 다른 장점: 온라인 학습(online learning)으로 사용O
온라인 학습: 모델은 새로운 훈련 데이터가 도착하는 대로 훈련, 훈련 데이터 양 ↑ -> 유용
ex. 고객 데이터 처리 웹 애플리케이션
온라인 학습 사용 -> 시스템은 변화에 즉시 적응
if 저장 공간 제약O -> 모델 업데이트 -> 훈련 데이터 버리기
미니 배치 경사 하강법
배치 경사 하강법과 확률적 경사 하강법 사이의 절충점: 미니 배치 학습(mini-batch learning)
훈련 데이터의 작은 일부분으로 배치 경사 하강법 적용
ex. 한 번에 32개의 샘플 사용
배치 경사 하강법에 비해 가중치 업데이트 자주 일어남 -> 수렴 속도 ↑
확률적 경사 하강법에서 훈련 샘플을 순회하는 for 반복 -> 선형대수 개념(ex. 점곱 ~> 가중치 합 계산)을 사용한 벡토화된 연산
-> 학습 알고리즘의 계산 효율성 ↑
요약
- 머신 러닝 알고리즘 직관적 이해
- 판다스, 넘파이, 맷플롯립 -> 데이터 읽기, 처리, 시각화
- 파이썬 -> 선형 분류 알고리즘 구현
지도학습_선형 분류기
퍼셉트론 구현
-> 경사 하강법 방식: 적응형 선형 뉴런 효율적으로 훈련하는 방법
-> 확률적 경사 하강법: 온라인 학습으로 훈련하는 방법
퍼셉트론, 아달린 알고리즘 구현에 사용한 객체 지향 방식
-> fit, prdict 메서드와 동일한 바탕으로 구현 => 사이킷런 API 이해하는 데 도움
- 클래스 확률 모델링 -> 로지스틱 회귀
- 비선형 결정 경계 -> 서포트 벡터 머신
- 지도 학습 알고리즘: 트리 기반 알고리즘_앙상블 분류기 사용
출처
https://github.com/rickiepark/python-machine-learning-book-3rd-edition
'Artificial Intelligence' 카테고리의 다른 글
[혼자 공부하는 머신러닝+딥러닝] Chapter 04 다양한 분류 알고리즘 (0) | 2024.07.25 |
---|---|
[혼자 공부하는 머신러닝+딥러닝] Chapter 03 회귀 알고리즘과 모델 규제 (0) | 2024.07.25 |
[밑바닥부터 시작하는 딥러닝] CHAPTER 2 퍼셉트론 (0) | 2023.03.30 |
[밑바닥부터 시작하는 딥러닝] CHAPTER 1 헬로 파이썬 (0) | 2023.03.28 |
[머신러닝 교과서 with 파이썬, 사이킷런, 텐서플로] 1장 컴퓨터는 데이터에서 배운다 (1) | 2023.03.16 |