본문 바로가기

Study/class note

머신러닝 / 앙상블

88 앙상블

다양한 전문가 팀을 만드는 것과 유사한 원리를 활용하는 메타학습 방법을 앙상블이라고 함. 모든 앙상블 방법은 약한 학습자 여러개를 결합하면 강한 학습자가 만들어진다는 아이디어를 기반으로 함.

앙상블 모형은 여러개의 분류모형 또는 수치예측모델을 같이 사용하여 한꺼번에 평가하는 모형을 말함.

 

실습1. 정확도가 60% 밖에 되지 않는 분류기 모형들이 즐비한데 이 모형들을 최소한 몇개를 써야 정확도를 90% 를 능가하게 만들수 있을까 ?

ret_err <- function(n,err) {
  sum <- 0 
  
  for(i in floor(n/2):n) { 
    sum <- sum + choose(n,i) * err^i * (1-err)^(n-i)
  }
  sum
}
for(j in 1:60) {
  err <- ret_err(j , 0.4)
  cat(j,'--->',1-err,'\n') 
  if(1-err >= 0.9) break
}

 

ㅇ앙상블 기법은 무엇인가?

여러개의 모델이 같이 앙상블로 실행된 후,

1. 분류 > 다수결

2. 수치예측 > 평균값

으로 결과를 출력함

 

ㅇ앙상블을 이용했을때의 장점?

다양한 모델의 결과를 종합하여 전반적으로 오류를 줄여주어 정확도는 높여줌.

모델별로 다양한 bias를 종합하여 결과를 생성하게 되어 오버피팅을 줄여줌.

 

ㅇ앙상블 기법의 종류 2가지

1. 배깅(bagging) : 훈련 데이터에서 데이터를 샘플링하여 각각의 같은 머신러닝 모델로 학습하여 결과를 평균 또는 투표로 출력하는 앙상블 알고리즘

 

2. 부스팅(boosting) : 배깅을 개선한 앙상블 알고리즘으로 데이터를 샘플링할 때 잘못 분류한 데이터에 대해서 가중치를 주어 좀 더 많이 샘플링하여 학습할 수 있도록 하는 알고리즘.

 

 

89 배깅

1. 앙상블을 사용하지 않고 의사결정트리 단독으로 모델을 생성했을 때

#1. 데이터 로드
iris <- read.csv("c:\\data\\iris2.csv", stringsAsFactors = TRUE)
head(iris)

#2. 훈련 데이터, 테스트 데이터 분리
library(caret)
set.seed(1)
k <- createDataPartition(iris$Species, p = 0.9, list = F)
iris_train <- iris[k,]
iris_test <- iris[-k,]

nrow(iris_train) #135
nrow(iris_test) #15

#3. 모델 생성 및 훈련
library(C50)
set.seed(1)
model <- C5.0(Species ~., data = iris_train, trials = 100)

#4. 모델 예측
result <- predict(model, iris_test)
result

#5. 모델 평가
sum(iris_test$Species == result) / length(iris_test$Species)  # 0.9333333

 

2. 앙상블의 bagging으로 모델 생성했을 때

#1. 데이터 로드
iris <- read.csv("c:\\data\\iris2.csv", stringsAsFactors = TRUE)

#2. 훈련데이터, 테스트데이터 분리
library(caret)
set.seed(1)
k <- createDataPartition(iris$Species, p = 0.9, list = F)
iris_train <- iris[k, ]
iris_test <- iris[-k, ]

nrow(iris_train)  #135
nrow(iris_test)  #15

#3. 모델 생성
library(ipred)
set.seed(1)
my_bag <- bagging(Species ~., data = iris_train, nbagg = 25)  # bag의 갯수

#4. 모델 예측
p_bag <- predict(my_bag, iris_test[,-5])
p_bag

#5. 모델평가
sum(iris_test$Species == p_bag) / length(iris_test$Species)  # 1

앙상블을 사용했더니 정확도 100%의 모델이 생성되었음.

 

 

90 부스팅

#1. 데이터 로드
iris <- read.csv("c:\\data\\iris2.csv", stringsAsFactors = TRUE)

#2. 훈련데이터, 테스트데이터 분리
library(caret)
set.seed(1)
k <- createDataPartition(iris$Species, p = 0.9, list = F)
iris_train <- iris[k, ]
iris_test <- iris[-k, ]

nrow(iris_train)  #135
nrow(iris_test)  #15

#3. 모델 생성 및 훈련
install.packages("adabag")
library(adabag)
set.seed(1)
m_adaboost <- boosting(Species ~., data = iris_train)

#4. 모델 예측
p_adaboost <- predict(m_adaboost, iris_test[, -5])
p_adaboost

#5. 모델 평가
sum(iris_test[,5] == p_adaboost$class) / length(iris_test[,5])  # 1

부스팅 모델의 정확도도 100% 

 

 

ㅇ 파이썬으로 앙상블 구현하기

1. 앙상블을 사용하지 않고 단독 의사결정트리로만 했을 때

#1. 데이터 로드
import pandas as pd

iris = pd.read_csv("c:\\data\\iris2.csv")
iris.head()

#3. 정규화 작업
x = iris.iloc[:,:-1]
y = iris.iloc[:,-1]

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
x_scaled = scaler.fit_transform(x)

#2. 훈련데이터 테스트 데이터 분리
from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(x_scaled, y, test_size = 0.1, random_state = 1)

print(x_train.shape, x_test.shape, y_train.shape, y_test.shape)  #(135, 4) (15, 4) (135,) (15,)


#4. 의사결정트리 모델 생성
from sklearn.tree import DecisionTreeClassifier

model = DecisionTreeClassifier(criterion = 'entropy', max_depth = 20, random_state = 1)

#5. 모델 훈련
model.fit(x_train, y_train)

#6. 모델 예측
result = model.predict(x_test)
result

#7. 모델 평가
print( sum(result == y_test) / len(y_test))  #1.0

 

2. 앙상블을 사용했을 때(배깅)

#1. 데이터 로드
import pandas as pd

iris = pd.read_csv("c:\\data\\iris2.csv")
iris.head()

#3. 정규화 작업
x = iris.iloc[:,:-1]
y = iris.iloc[:,-1]

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
x_scaled = scaler.fit_transform(x)

#2. 훈련데이터 테스트 데이터 분리
from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(x_scaled, y, test_size = 0.1, random_state = 1)

print(x_train.shape, x_test.shape, y_train.shape, y_test.shape)  #(135, 4) (15, 4) (135,) (15,)

#4. 모델 생성
#의사결정트리 모델 생성
from sklearn.tree import DecisionTreeClassifier

model2 = DecisionTreeClassifier(criterion = 'entropy', max_depth = 20, random_state = 1)

from sklearn.ensemble import BaggingClassifier

bagging_model = BaggingClassifier(model2, max_samples = 0.9, max_features = 0.5, random_state = 1)
#max_samples = 0.9는 bag에 데이터를 담을 때 훈련 데이터의 90% 샘플링하겠다는 것
#max_features = 0.5는 하나의 예측기가 가져갈 수 있는 최대 컬럼의 갯수를 50%만 쓰겠다는 것

#5. 모델 훈련
bagging_model.fit(x_train, y_train)

result2 = bagging_model.predict(x_test)

#6. 모델 평가
print(sum(result2 == y_test) / len(y_test))  #1.0

 

3. 앙상블을 사용했을 때 (부스팅)

#1. 데이터 로드
import pandas as pd

iris = pd.read_csv("c:\\data\\iris2.csv")
iris.head()

#3. 정규화 작업
x = iris.iloc[:,:-1]
y = iris.iloc[:,-1]

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
x_scaled = scaler.fit_transform(x)

#2. 훈련데이터 테스트 데이터 분리
from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(x_scaled, y, test_size = 0.1, random_state = 1)

print(x_train.shape, x_test.shape, y_train.shape, y_test.shape)  #(135, 4) (15, 4) (135,) (15,)

#4. 모델 생성
from sklearn.ensemble import GradientBoostingClassifier

model3 = GradientBoostingClassifier(n_estimators = 300, random_state = 1)

#5. 모델 훈련
model3.fit(x_train, y_train)

#6. 모델 예측
result3 = model3.predict(x_test)
result3

#7. 모델 평가
print(sum(result3 == y_test) / len(y_test))  # 1.0

 

+) 부스팅 방법 참고 블로그

https://m.blog.naver.com/gdpresent/221717318894

 

 

위에서 수행한 배깅과 부스팅은 의사결정트리 모델을 여러개로 만들어서 구현한 것이고, 우리가 이론 수업에서 배웠던 것처럼 여러개의 머신러닝 모델을 가지고 수치예측하기

 

#1. 데이터 로드
import pandas as pd

iris = pd.read_csv("c:\\data\\iris2.csv")
iris.head()

#3. 정규화 작업
x = iris.iloc[:,:-1]
y = iris.iloc[:,-1]

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
x_scaled = scaler.fit_transform(x)

#2. 훈련데이터 테스트 데이터 분리
from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(x_scaled, y, test_size = 0.1, random_state = 1)

print(x_train.shape, x_test.shape, y_train.shape, y_test.shape)  #(135, 4) (15, 4) (135,) (15,)

#4. 앙상블 모델 생성
from sklearn.naive_bayes import GaussianNB  #나이브베이즈
from sklearn.linear_model import LogisticRegression #로지스틱회귀
from sklearn.ensemble import RandomForestClassifier #랜덤포레스트
from sklearn.ensemble import VotingClassifier  #여러개의 분류모델을 앙상블로 쓰기 위한 모듈

r1 = GaussianNB()  #약자 gnb
r2 = LogisticRegression()  #약자 lr
r3 = RandomForestClassifier()  #약자 rf

eclf1 = VotingClassifier(estimators = [('gnb', r1), ('lr',r2), ('rf', r3)], voting = 'hard' )

#5. 모델 훈련
eclf1.fit(x_train, y_train)

#6. 모델 예측
result4 = eclf1.predict(x_test)

#7. 모델 평가
print(sum(result == y_test) / len(y_test))  #1.0

 

문제438. (점심시간 문제) 위의 앙상블 조합을 다른 조합으로 변경하고 수행하시오.

변경전 변경후
from sklearn.naive_bayes import GaussianNB  #나이브베이즈
from sklearn.linear_model import LogisticRegression #로지스틱회귀
from sklearn.ensemble import RandomForestClassifier #랜덤포레스트

from sklearn.naive_bayes import GaussianNB  #나이브베이즈
from sklearn.linear_model import LogisticRegression #로지스틱회귀
from sklearn.ensemble import RandomForestClassifier #랜덤포레스트

from sklearn.neural_network import MLPclassifier  #신경망
#1. 데이터 로드
import pandas as pd

iris = pd.read_csv("c:\\data\\iris2.csv")
iris.head()

#2. 훈련데이터 테스트 데이터 분리
x = iris.iloc[:,:-1]
y = iris.iloc[:,-1]

from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(x_scaled, y, test_size = 0.1, random_state = 1)

print(x_train.shape, x_test.shape, y_train.shape, y_test.shape)  #(135, 4) (15, 4) (135,) (15,)


#3. 정규화 작업
from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
scaler.fit(x_train)
x_train_scaled = scaler.transform(x_train)
x_test_scaled = scaler.transform(x_test)


#4. 앙상블 모델 생성
from sklearn.naive_bayes import GaussianNB  #나이브베이즈
from sklearn.linear_model import LogisticRegression #로지스틱회귀
from sklearn.ensemble import RandomForestClassifier #랜덤포레스트
from sklearn.neural_network import MLPClassifier #신경망

from sklearn.ensemble import VotingClassifier  #여러개의 분류모델을 앙상블로 쓰기 위한 모듈

r1 = GaussianNB()  #gnb
r2 = LogisticRegression()  #lr
r3 = RandomForestClassifier()  #rf
r4 = MLPClassifier() #mlp

eclf1 = VotingClassifier(estimators = [('gnb', r1), ('lr',r2), ('rf', r3), ('mlp', r4)], voting = 'hard' )

#5. 모델 훈련
eclf1.fit(x_train_scaled, y_train)

#6. 모델 예측
result4 = eclf1.predict(x_test_scaled)

#7. 모델 평가
print(sum(result == y_test) / len(y_test))  #1.0

 

+) votingclassifier 약어 정리

 

ㅇ voting = 'hard'와 voting = 'soft'의 차이

voting = 'hard'는 다수결에 의해 분리하는 것이고, voting = 'soft'는 확률의 평균값으로 분류하는 것

 

 

ㅇ앙상블을 이용해서 수치예측 모델 만들기 실습

"보스톤 집값 데이터를 예측하는 모델 만들기"

1. 선형회귀 모델로 집값 예측(장 : 오버피팅 작음 / 단 : 성능이 떨어짐 = 상관계수가 작음)

2. 랜덤 포레스트 모델로 집값 예측(장 : 성능이 좋음 = 상관계수가 큼 / 단 : 오버피팅)

3. 위의 두 개를 결합한 앙상블 모델로 집값 예측

 

#1. 선형회귀 모델 집값 예측

#1. 데이터로드
from sklearn import datasets

boston = datasets.load_boston()
x = boston.data
y = boston.target

#2. 훈련 데이터 테스트 데이터 분리
from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.1, random_state = 1)

print(x_train.shape, x_test.shape, y_train.shape, y_test.shape)  #(455, 13) (51, 13) (455,) (51,)

#3. 선형회귀모델 생성
from sklearn.linear_model import LinearRegression

r1 = LinearRegression()

#4. 모델 훈련
r1.fit(x_train, y_train)

#5. 모델 예측
train_result = r1.predict(x_train) # 훈련데이터에 대한 예측
test_result = r1.predict(x_test)  # 테스트데이터에 대한 예측

#6. 모델 성능 평가
import numpy as np
 
print(np.corrcoef(y_train, train_result))  #0.85727551
print(np.corrcoef(y_test, test_result))  #0.88901603

 

#2. 랜덤포레스트 모델로 집값 예측

#1. 데이터로드
from sklearn import datasets

boston = datasets.load_boston()
x = boston.data
y = boston.target

#2. 훈련 데이터 테스트 데이터 분리
from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.1, random_state = 1)

print(x_train.shape, x_test.shape, y_train.shape, y_test.shape)  #(455, 13) (51, 13) (455,) (51,)

#3. 랜덤 포레스트 모델 생성
from sklearn.ensemble import RandomForestRegressor

r2 = RandomForestRegressor()

#4. 모델 훈련
r2.fit(x_train, y_train)

#5. 모델 예측
train_result2 = r2.predict(x_train)
test_result2 = r2.predict(x_test)

#6. 모델 평가
print(np.corrcoef(y_train, train_result2))  # 0.99209092
print(np.corrcoef(y_test, test_result2))  #0.96937062

 

#3. 앙상블

#1. 데이터로드
from sklearn import datasets

boston = datasets.load_boston()
x = boston.data
y = boston.target

#2. 훈련 데이터 테스트 데이터 분리
from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.1, random_state = 1)

print(x_train.shape, x_test.shape, y_train.shape, y_test.shape)  #(455, 13) (51, 13) (455,) (51,)

#3. 모델 2개를 결합한 앙상블 모델 생성
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor
from sklearn.ensemble import VotingRegressor

r1 = LinearRegression()
r2 = RandomForestRegressor(n_estimators = 10, random_state = 1)

er = VotingRegressor([('lr', r1), ('rf', r2)])

#4. 모델 훈련
er.fit(x_train, y_train)

#5. 모델 예측
result_train_er = er.predict(x_train)
result_test_er = er.predict(x_test)

#6. 모델 평가
print(np.corrcoef(y_train, result_train_er))  # 0.95853412
print(np.corrcoef(y_test, result_test_er))  #0.95623851

> 앙상블 모형으로 만들었더니 성능도 우수하고 오버피팅도 발생하지 않음.

 

반응형