1. 광고 클릭률 예측의 개요

2. 범주형 특징을 수치형으로 변환: 원-핫 인코딩과 순서 인코딩

    2.1. 로지스틱 회귀를 이용한 데이터 분류

    2.2. 로지스틱 함수 시작하기

    2.3. 로지스틱 함수와 로지스틱 회귀

3. 로지스틱 회귀 모델 훈련

    3.1. 경사하강법을 이용한 로지스틱 회귀 모델 훈련

    3.2. 경사하강법 기반의 로지스틱 회귀를 이용한 광고 클릭률 예측

    3.3. 확률적 경사하강법을 이용한 로지스틱 회귀 모델 학습

    3.4. 정규화를 통한 로지스틱 회귀 모델 학습

    3.5. L1 정규화를 통한 특징 선택

4. 온라인 학습을 통한 대규모 데이터셋 훈련

5. 다중 클래스 분류

6. 텐서플로를 이용한 로지스틱 회귀 구현

7. 랜덤 포레스트를 이용한 특징 선택


1. 광고 클릭률 예측의 개요

온라인 디스플레이 광고는 텍스트, 이미지, 플래시로 구성하는 베너 광고와,

오디오, 비디어와 같은 리치 미디어(Rich Media)를 포함한 다양한 형식으로 전달한다.

 

이 온라인 디스플레이 광고는 머신 러닝을 활용하기 좋은 예 중 하나이다

특정 연령대 소비자가 제품에 관심을 가진 가능성, 특정 가계소득 고객이 광고 시청 후 제품을 구매할 가능성,

스포츠 사이트를 자주 방문하는 방문자가 광고 시청에 시간을 할애할 가능성 등이 해당한다.

광고의 효과를 측정하는 가장 일반적인 방법은 클릭률(CTR; Click Through Rate)이다.

 └ 클릭률 : 전체 조회수 대비 특정 광고를 클릭하는 비율

 

클릭률 예측은, 특정 광고를 특정 사용자가 클릭할지 여부를 이진 분류한다. 주로 3가지 특징을 이용한다.

ㆍ 광고 콘텐츠와 정보(범주, 위치, 텍스트, 형식 등)

ㆍ 페이지 내용과 게시자 정부(범주, 컨텍스트(문맥), 도메인 등)

ㆍ 사용자 정보(나이, 성별, 위치, 소득, 관심사, 검색 기록, 인터넷 사용 기록, 사용 기기 등)

 

훈련과 예측을 위한 광고 샘플

위의 표에서 볼 수 있듯이 특징들은 대부분 범주형 데이터이다.

하지만 실제(현실 세계) 데이터는 수치형이거나 범주형일 수 있는데, 이 변화는 다음 목차에서 살펴본다.

본 글에서는 로지스틱이 무엇인지, SGD는 무엇인지, 정규화, 그리고 예시들을 살펴본다.

 

2. 범주형 특징을 수치형으로 변환: 원-핫 인코딩과 순서 인코딩

    2.1. 로지스틱 회귀를 이용한 데이터 분류

원-핫 인코딩의 예시

k개의 가능한 값을 갖는 범주형 특징을 변환하는 가장 간단한 방법은 매핑이다.

예를 들어 [생물, 지리, 지리, 과학, 생물, 생물, 과학]은 [1, 2, 2, 3, 1, 1, 3]에 대응한다.

하지만 이때 과학이 생물보다 크고, 지리에 더 가깝다는 '순서(Ordinal) 속성'이 생긴다.

이러한 방식을 '순서 인코딩(Ordinal Encoding)'이라고 한다.

 

순서 인코딩이 아닌 원-핫 인코딩(One-Hot Encoding)을 하면 범주형 특징을 수치형 특징으로 변환할 수 있다.

그러면 범주형 특징에 제한받지 않고, 트리 기반 알고리즘에 적용할 수 있다. 

 

사이킷런의 OneHotEncoder를 이용해 문자열 행렬을 이진 행렬로 변환한다.

이때 효율적인 변환을 위해 DictVectorizer 모듈을 사용한다. 사전 객체를 원-핫 인코딩된 벡터로 변환해준다.

 

결과(print(X_encoded))는 위의 매핑 결과에 따라 변환이 되었음을 알 수 있다.

이러한 특징으로 결괏값에서 원래 특징으로 역변환도 가능하다.

한 가지 유의할 점은, 새로운 데이터에서 보지 못한 새로운 범주를 발견하면 이를 무시해야 한다는 것이다.

OneHotEncoder에서 ignore 매개변수를 지정하면 DictVertorizer가 자동으로 처리해준다.

 

대ㆍ중ㆍ소 혹은 호ㆍ불호같은 경우, 순서 인코딩을 사용하는 게 좋을 때도 있다.

이런 특징들은 학습할 때, 순서나 순위(ranking) 지식을 사용해야 하기 때문이다.

이러한 코딩은 pandas 라이브러리로 구현할 수 있다.

 

    2.2. 로지스틱 함수 시작하기

로지스틱 함수(Logistic Function) = sigmoid function

로지스틱 회귀는 기본적으로 수치형 특징만을 다루는 분류기이다.

위는 로지스틱 알고리즘의 핵심 함수인 '로지스틱 함수(Logistic function)'이다.

일반적으로는 시그모이드 함수(sigmoid function)이라고도 부른다.

S자 곡선을 통해 입력이 클수록 출력은 1에, 입력이 작을수록 출력은 0에 가까워진다.

 

    2.3. 로지스틱 함수와 로지스틱 회귀

로지스틱 회귀에서 함수 입력 z는 특징의 가중치 합이 된다.

n개의 특징(x1, x2, ..., xn)을 가진 데이터 샘플 x의 가중치가 주여졌을 때, z는 위의 식처럼 표현한다.

 └ x는 특징 벡터를, w는 벡터를 나타낸다.

 └ x = (x1, x2, ..., xn), w는 벡터 (w1, w2, ..., wn)으로 나타낸다.

 └ 가중치(Weight)는 계수(Coefficient)라고도 한다.

만약 절편(w0)이 있는 경우, 선형 관계식은 위의 식처럼 바뀐다.

 └ 절편은 편향(bias)라고도 한다.

 

알고리즘에서 출력 y(z)는 0에서 1 사이의 범위를 갖는다.

이는 목표가 1 또는 양성 클래스일 확률이 된다.

따라서 로지스틱 회귀는 나이브 베이즈 분류기와 유사한 확률적 분류기라고 할 수 있다.

 

양성 샘플은 가능한 1에 가깝게 예측하고 음성 샘플은 가능한 0에 가깝게 예측하도록 학습한다.

수학적 언어로는 '평균제곱오차'로 정의하는 비용을 최소화하도록 가중치를 훈련한다고 볼 수 있다.

 └ 평균 제곱 오차  :참값과 예측값 차이의 제곱에 대한 평균으로 계산하는 식

 

m개의 훈련 샘플 (x1, y1), (x2, y2), ..., (xi, yi), ..., (xm, ym)이 있다고 하자.

여기서 yi가 1 또는 0을 가질 때, 최적화할 가중치에 대한 비용 함수 J(w)는 위와 같이 표현한다.

 └ 비용 함수(cost function) : 예측값과 실젯값 사이의 오차를 계산하는 함수

이 비용 함수는 볼록하지 않으므로, 많은 국소 최적이 발견되고, 함수가 전역 최적값으로 수렴하지 못할 수 있다.

 

볼록(convex)과 비볼록(non-convex) 함수의 예시

볼록(convex)과 비볼록(non-convex) 함수 그래프 예시는 위와 같다.

볼록 함수 에서는 전역 최적값이 하나뿐이지만, 비볼록 함수에서는 최적값이 2개라고 볼 수 있다.

이러한 문제가 있기에 실제 비용 함수 J(w)는 다음과 같이 정의한다.

 

실제 정의한 비용 함수 J(w)
비용 함수에서 하나의 훈련 샘플 비용의 예시

정답 yi가 1일 때, 모델이 완벽하게 예측하면 샘플 비용 j는 0이 나온다.

비용 j는 예측 확률이 감소함에 따라 증가하다가, 양성 클래스(1)일 가능성이 없다고 판단하면 무한히 커진다.

 

y = 1일 때 로지스틱 회귀의 비용 함수(왼쪽), y = 0일 때 로지스틱 회귀의 비용 함수(오른쪽)

위의 상황, 즉 y의 값에 따른 비용 함수 그래프를 그리면 위와 같다.

로지스틱 회귀에서 사용하는 대체 비용 함수를 최소화하는 문제는, 실제 MSE 기반 비용 함수를 최소화하는 것과 같다.

MSE 대신 이 로지스틱 회귀의 비용 함수를 선택할 때의 이점은 다음과 같다.

ㆍ 볼록 함수이기에 최적의 모델 가중치를 찾을 수 있다.

ㆍ 가중치에 대한 예측값 또는 도함수를 간단하게 계산할 수 있다.

참고로 J(w)에는 로그(log) 함수가 있는데, 로그 함수로 인한 비용 함수를 '로그 손실(Logarithmic loss)'이라고 한다.

 

3. 로지스틱 회귀 모델 훈련

    3.1. 경사하강법을 이용한 로지스틱 회귀 모델 훈련

J(w)가 최소화하도록 하는 최적의 w를 얻는 방법을 구해야 한다.

이는 '경사하강법(gradient descent)'을 통해 구할 수 있다.

 └ 가장 가파른 하강법(steepest descent)라고도 한다.

 

학습률 식

경사하강법은 1차 반복 최적화(first-order iterative optimization)를 통해, 목적 함수를 최소화하는 절차이다.

반복할 때마다 현재 지점에서, 목적 지점의 음의 도함수에 비례하는 만큼 이동한다.

이 비율을 학습률(learning rate) 또는 단계 크기(step size)라고 하는데 식은 위와 같다.

좌변의 w는 훈련 후의 가중치 벡터이고, 우변의 w는 이동 전의 가중치 벡터이다.

η는 학습률이고 Δw는 기울기(1차 도함수)를 나타낸다.

 

기울기(도함수) 식
학습률에 기울기(도함수)를 적용한 식

J(w) = MSE 식을 미분 후 일반화하면 위와 같은 Δw 식이 나오는데, 이를 학습률 식에 대입한다.

그 후 w를 반복할 때마다 업데이트하는 과정을 거친다.

 

결정 임곗값의 기본값은 0.5지만, 다른 값으로 설정할 수 있다.

예를 들어 화재 경보를 예측할 때 거짓 음성(false negative)을 피하고자 한다면, 임곗값을 낮게 설정하면 된다.

다른 예로 품질 보증을 위해 양품을 예측할 때 거짓 음성(false negative)을 피하고자 한다면, 기준에 따라 설정하면 된다.

 

위에서 정리한 식들을 기반으로 로지스틱 회귀 알고리즘을 구현한다.

ㆍ compute_prediction() : 현재 가중치로 예측값 y(x)을 계산하는 함수

ㆍ update_weights_gd() : 경사하강법으로 가중치를 업데이트하는 함수

ㆍ compute_cost() : 비용 J(w)를 계산하는 함수

ㆍ train_logistic_regression() : 위에서 구현한 함수를 통합한 모델 훈련 함수

ㆍ predict() : 새로운 입력에 대한 결과를 예측하는 함수

 

    3.2. 경사하강법 기반의 로지스틱 회귀를 이용한 광고 클릭률 예측

샘플 10,000개를 편향있는 로지스틱 회귀 모델을 0.01의 학습률로 max_iter = 10000번 훈련한다.

이때 모델 최적화에 걸린 시간은 232초가 소요된다.

만일 100,000개의 훈련 샘플로 이 과정을 진행했다면, 5240초(약 1시간 20분)가 소요된다.

 

로지스틱 회귀 분류기는 대규모 데이터셋에 유용하다.

하지만 테스트 결과만을 살펴본다면 모순되는 상황이다. 이에 대한 효율적 처리는 다음 목차에서 설명한다.

 

    3.3. 확률적 경사하강법을 이용한 로지스틱 회귀 모델 학습

경사하강법 기반의 로지스틱 회귀 모델에서는 가중치 업데이틀 위해 모든 훈련 샘플을 사용한다.

따라서 훈련 샘플 수가 많아지면 전체 훈련 과정 시간이 오래 걸리고, 계산 비용이 많이 든다.

 

SGD 가중치 계산 식

각 가중치를 업데이트할 때 전체 훈련셋 대신 단 하나의 훈련 샘플만을 사용하는 쪽으로 수정하면 된다.

하나의 훈련 샘플로 계산한 오차를 기반으로 모델을 한 단계 이동하고, 모든 샘플을 사용하면 한 번 반복이 완료된다.

이런 방식을 '확률적 경사하강법(SGD; Stochastic Gradient Descnet)'이라고 한다.

SGD는 일반 경사하강법보다 훨씬 빠르게 수렴한다.

 

SGD를 사용하기 위해서는 update_weights_gd()와 train_logistic_regression() 함수를 약간만 수정하면 된다.

수정 후 100,000개의 훈련 샘플을 학습률 0.01로 10번 반복한다면, 40초만에 작업이 끝난다.

 

사이킷런의 SGDClassifier 모듈을 이용해서도 구현이 가능하다.

ㆍ loss 매개변수에 대한 log는 비용 함수가 로그 손실임을 나타낸다.

ㆍ penalty 매개변수는 과적합을 줄이기 위한 정규화 항을 나타낸다.

ㆍ max_iter 매개변수는 최대 반복 횟수를 나타낸다.

ㆍ learning_rate 매개변수의 기본값을 optimal로, 업데이트를 진행할수록 학습률이 약간 감소한다.

     └ 이 방법은 대규모 데이터셋에서 최적의 솔루션을 찾을 때 조금 더 유용하다.

 

    3.4. 정규화를 통한 로지스틱 회귀 모델 학습

SGDClassifier의 penalty 매개변수는 모델 '정규화'와 관련이 있다.

정규화에는 L1과 L2의 두 가지 기본 형식이 있는데, 둘 다 원래의 비용 함수에 추가하는 항이다.

 └ L1 정규화는 라소(Lasso)라고 한다.

 └ L2 정규화는 리지(Ridge)라고 한다.

 

L1 정규화 식

가장 우측에 있는 α는 정규화 항에 곱하는 상수이고, q는 1 또는 2인데 각각 L1과 L2 정규화를 나타낸다.

로지스틱 회귀 모델을 훈련하는 것은 비용(오차 = 가중치 w의 함수)을 줄여나가는 과정이다.

만약 wi, wj, wk와 같은 일부 가중치가 상당히 커지면, 이런 가중치가 전체 비용을 좌우한다.

이를 위해 정규화라는 과정이 존재한다. 즉, 정규화는 과적합을 없애주는 과정이다.

 

매개변수 α는 로그 손실과 일반화 간의 균형을 잡아준다.

α가 너무 작으면 큰 가중치를 줄일 수 없고 모델의 분산이 커지거나 과적합이 발생한다. = 과잉적합 문제

α가 너무 크면 모델이 과도하게 일반화되어 데이터를 제대로 fitting할 수 없어 성능이 저하한다. = 과소적합 문제

α는 정규화를 통해 최상의 로지스틱 회귀 모델을 얻을 때 조정하는 중요한 매개변수이다.

 

L1과 L2 정규화를 선택하는 차이는 '특징 선택'과 관련있다.

머신 러닝 '분류'에서 '특징 선택'은 더 나은 모델 구성에 중요한 특징의 부분집합을 선택하는 과정이다.

실제 데이터 특징 중 일부는 중복되거나, 관련이 없으므로 샘플을 구별하는데 유용하지 않다.

따라서 이런 특징들은 거의 손실 없이 버릴 수 있다.

결론적으로 로지스틱 회귀 분류기에서는 L1 정규화를 통해서만 특징 선택을 할 수 있다.

 

L1 정규화와 L2 정규화의 차이

가중치 벡터 w1 = (1, 0)과 가중치 벡터 w2 = (0.5, 0.5)가 있다고 가정해보자.

두 벡터의 로그 손실이 동일할 때, 각 가중치 벡터의 L1, L2 정규화 항은 위와 같다.

두 벡터의 L1 항은 동일하지만 L2 항은 값이 다르다.

L1 정규화는 상당히 작거나 큰 가중치도 일부 허용하여 계산할 수 있다(L2 정규화는 그렇지 않다).

이는 곧 L1 정규화는 특징을 선택할 수 있다는 의미이고, 일부 가중치를 0에 가깝거나 0이 되도록 줄여줄 수 있다는 뜻이다.

 

사이킷런에서 정규화 유형은 penalty 매개변수로 none, l1, l2, elasticnet(혼합) 중 선택할 수 있다.

정규화 항에 곱해주는 상수 α는 alpha 매개변수로 지정할 수 있다.

 

    3.5. L1 정규화를 통한 특징 선택

특징 선택을 위한 L1 정규화를 검토한다.

L1 정규화를 통해 SGD 로지스틱 회귀 모델을 초기화하고, 10000개 샘플로 모델을 훈련한다.

 

훈련한 모델을 이용해서 계수의 절댓값을 구한다.

 

크기순으로 하위 10개 계수와, 그에 해당하는 값들을 출력한다.

 

하위 10가지 특징들이 무엇인지 출력하여 확인하는 코드이다.

예를 들어 X_train 0열의 1001, 8열의 851897aa 등이다.

 

마찬가지로 상위 10개 계수와 그에 해당하는 값을 구하는 코드이다.

예를 들면 X_train 7열의 cef3e649, 3열의 7687a86e 등이다.

 

4. 온라인 학습을 통한 대규모 데이터셋 훈련

온라인 학습과 오프라인 학습 비교

300,000개 이하의 샘플에 관해 모델을 훈련했지만, 이보다 수가 많아지면 메모리 부족이 발생할 수 있다.

그 이상의 샘플을 훈련하기 위해서는 '온라인 학습(Online Learning)'을 통해 대규모 데이터셋을 학습해야 한다.

 

한 번에 전체 훈련셋을 사용하는 경사하강법과 달리, SGD는 개별 훈련 샘플로 모델을 순차적으로 업데이트한다.

한 번에 모든 데이터가 제공되는 오프라인과 달리, 온라인에서는 데이터가 순차적 혹은 실시간으로 제공된다.

훈련할 때 한 번에 작은 크기의 샘플을 로드하고 전처리하기 때문에, 메모리가 적게 든다.

온라인 학습은 계산이 효율적일 뿐만 아니라, 실시간 데이터 처리도 가능하고 최신 모델 유지도 가능하다.

 

오프라인 학습에서는 이전 데이터셋과 최근 데이터셋을 함께 사용하여 처음부터 다시 개발해야만 한다.

하지만 온라인 학습에서는 가장 최근의 가용 데이터셋만으로도 업데이트가 가능하다.

사이킷런의 SGDClaffifier 모듈은 partial_fit 방법으로 온라인 학습을 구현한다.

 

5. 다중 클래스 분류

앞서 설명한 모든 내용은 로지스틱 회귀를 이진 분류에 적용한 설명이다.

그렇다면 다중 클래스의 경우에도 적용 가능할까? 라는 의문이 생긴다. 물론 가능하다.

두 개 이상의 클래스에 대한 로지스틱 회귀를 '다항 로지스틱 회귀(Multinomial Logistic Regression)'라고 한다.

이는 '소프트맥스 회귀(Softmax Regression)'라고도 부른다.

 

이진 분류의 로지스틱 회귀

앞서 이야기했듯, 이진 분류에서 목표가 1일 확률 또는 양성 클래스일 확률은 위와 같다.

 

다중 클래스의 로지스틱 회귀

K개 클래스에 대한 모델은 K개의 가중치 벡터(w1, w2, ..., wk)로 표현한다.

이때 목표가 클래스 k일 확률은 위와 같다.

이때 분모항은 확률값 yk(k의 범위는 1에서 K)의 합이 1이 되도록 정규화한다.

 

이진 클래스의 비용 함수
다중 클래스의 비용 함수

위의 식은 3.4 목차에서 언급한 이진 클래스의 비용 함수이다.

아래 식은 다중 클래스의 비용 함수이다.

1{y^(i) = j} 함수 부분에서 y^(i) = j가 참인 경우에 1이고, 그렇지 않으면 0이다.

 

비용 함수를 정의하면 이진 사례에서 Δw를 유도한 것과 같은 방식으로 j 가중치 벡터에 대한 Δwj를 구한다.

 

유사한 방식으로 매 반복마다 모든 K 가중치 벡터를 업데이트한다.

충분히 반복한 후에, 학습한 가중치 벡터 w1, w2, ..., wk는 위의 방정식을 통해 새로운 샘플 x`를 분류할 때 사용한다.

 

6. 텐서플로를 이용한 로지스틱 회귀 구현

300,000개 샘플 중 90%는 훈련에, 10%는 테스트에 사용한다.

텐서플로를 import하고, X_train, Y_train 등의 데이터 샘플을 float32로 캐스팅(cast)한다.

하나의 샘플이나 전체 훈련셋 대신 '하나의 샘플 배치(one batch)'만을 사용해서 가중치를 업데이트 한다.

이 예제에서 배치 크기는 1000이다.

그후 현재 예측, 비용, 기울기, 계수 등을 계산하여 (6000 단계의 )훈련을 실시한다.

모델 훈련 중 500 단계마다 성능을 확인하고, 최종 훈련 후 테스트셋을 예측하고 AUC 지표를 계산한다.

 

7. 랜덤 포레스트를 이용한 특징 선택

L1 정규화 로지스틱 회귀로 특징을 선택하는 방법을 앞에서 살펴보았다.

중요하지 않은 특징의 가중치는 0에 가깝게 줄어들거나 0이 된다.

L1 정규화 로지스틱 회귀 외에도 특징 선택을 위해 사용하는 기술이 있는데, '랜덤 포레스트(Random Forest)'이다.

 

랜덤 포레스트는 개별 의사결정 트리의 집합이다.

각각의 트리는 각 노드에서 무작위로 선택한 특징의, 부분집합에 대해서 최상의 분할 지점을 찾는다.

의사결정 트리에서 중요한 특징만 트리 노드를 구성하는데 사용한다.

전체 트리 집합에 대해서 좀 더 자주 사용하는 트리 노드의 특징이, 더 중요한 특징이다.

즉 모든 트리에 걸쳐, 노드에서 분할에 사용하는 특징을 기준으로 중요도를 평가하고, 가장 중요한 특징을 선택할 수 있다.

 

사이킷런에서 제공하는 RandomForestClassifier 모듈에는 특징의 중요도를 나타내는 속성이 있다.

feature_importances_ 속성으로 트리 노드에서 발생하는 비율로 계산한다.

랜덤 포레스트 모델을 fitting한 후, 특징 중요도 점수를 계산한다.

 

하위 10개 특징 점수(왼쪽), 상위 10개 특징 점수(오른쪽)

각각의 코드에 따라 하위 10개, 상위 10개의 특징 점수를 출력한다.

각 특징 점수에 따른 가장 중요하지 않은 특징도 같이 살펴본다.

+ Recent posts