728x90
반응형

분류 앙상블 모델

🍇 앙상블 모델

  • tree구조(결정트리)를 기반으로 만들어진 모델
  • 여러개의 트리 모델을 이용해서 훈련하는 모델을 앙상블 모델이라고 칭한다.

🍇 앙상블 모델 분류

  • 회귀와 분류에서 모두 사용한 모델들 이다
  • sklearn 패키지 모델은 모두 가능
  • xgb도 가능

🍇 배깅(Bagging)과 부스팅(Boosting) 방식

  • 앙상블 모델은 여러개의 트리를 사용하기 때문에 훈련 데이터를 여러 모델(여러 트리)에 적용하는 방식에 따라서 배깅과 부스팅 방식으로 구분한다.

🍇 배깅(Bagging)

  • 사용되는 여러개의 모델(여러 트리)들은 서로 독립적을 사용 된다.(연관성 없음)
  • 훈련데이터는 여러 모델에 랜덤하게 적용되며, 중복되는 데이터가 있을 수 도 있다.
  • 훈련데이터를 사용 후에는 반환하는 방식을 사용한다
    → 반환 후에 다시 랜덤하게 추출하여 여러 모델(여러 트리)에 적용한다
  • 대표적인 배깅 앙상블 모델은 랜덤포레스트 모델이 있다.
  • 배깅 앙상블 모델 : 랜덤 포레스트, 엑스트라트리
  • 예측 : 회귀에서는 평균값을 이용하며, 분류에서는 과반수(확률)에 따라 결정 된다.
  • 과적합을 해소하는 모델로 주로 사용된다.

🍇 부스팅(Boosting)

  • 사용되는 여러개의 모델(여러 트리)들은 서로 연관성을 가진다.
  • 이전 모델(이전 트리)의 오차를 보완하여 다음 모델(다음 트리)에서 이어서 훈련이 진행되는 방식
  • 훈련 데이터는 랜덤하게 추출되어 사용되지만, 이전 모델 훈련에서 오차가 크게 발생했던 훈련데이터에 가중치를 부여하여 사용하게 된다.
  • 대표적인 부스팅 앙상블 모델로 그레디언트 부스팅 모델이 있다.
  • 모델 : 그래디언트 부스팅, 히스트그레디언트 부스팅, 엑스지부스팅
  • 정확도를 높이는 모델로 주로 사용된다.

 🍇실제 모델 적용 순서

  • 분류시 최초에는 주로 랜덤포레스트 모델을 이용해서 수행한다.
     정확도가 높은 모델로 유명했다. 지금은 부스트 모델이 우수한 편이다.
  • 최종 모델 선정시에는 분류모델 전체 사용하여 선정한다.

Randomforest(랜덤포레스트)

 🍇 데이터 불러들이기

import pandas as pd
wine = pd.read_csv("./data/08_wine.csv")
wine


🍇 와인종류 분류하기

  • 와인종류 : 레드와인(0), 화이트와인(1)
  • 훈련에 사용할 데이터
    - 독립변수 : Alcohol(알콜), Sugar(설탕, 당도), pH(수소이온농도; 산성 또는 염기성)
    - 종속변수 : class(와인종류; 0또는 1, 0은 레드와인, 1은 화이트와인)

🍇 독립변수와 종속변수로 데이터 분리하기

'''독립변수'''
data = wine[["alcohol", "sugar", "pH"]].to_numpy()

'''종속변수'''
target = wine["class"].to_numpy()

data.shape, target.shape

 

🍇 훈련 테스트데이터로 분리하기(8:2)

'''
사용변수 : train_input, test_input, train_target, test_target
'''
from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(data, target, test_size=0.2, random_state=42)

print(f"train_input={train_input.shape} / train_target={train_target.shape}")
print(f"test_input={test_input.shape} / test_target={test_target.shape}")

 

🍇 데이터 스케일링(정규화 또는 표준화)

  • 서로 다른 변수(특성)의 값의 범위(단위)를 일정한 수준으로 맞추는 작업을 의미함
  • 수치형 변수(특성, 퓨터, 항목, 컬럼 같은 용어)에만 적용된다
  • 스케일링 방법 3가지 (아래 3가지는 구분만 될 뿐 의미는 모두 스케일링이다)
    1. 정규화 : StandardScaler → 분류 또는 회귀에서 사용가능하며, 주로 분류에서 사용됨
    2. 정규화 : RobustScaler → 분류 및 회귀 모두 사용가능
    3. 표준화 : MinMaxScaler → 분류 또는 회귀에서 사용가능 하며, 주로 회귀에서 사용됨(최대 및 최소 범위 내에서 처리되는 방식)

1. 정규화 : StandardScaler  

'''
훈련데이터 정규화 변수 : train_std_scaler
테스트데이터 정규화 변수 : test_std_scaler
'''

from sklearn.preprocessing import StandardScaler

''' 정규화 클래스 생성하기 '''
ss = StandardScaler()

''' 정규화 패턴 찾기 : 훈련데이터만 사용 '''
ss.fit(train_input)

''' 훈련 및 테스트 독립변수 변환하기 '''
train_std_scaler = ss.transform(train_input)
test_std_scaler = ss. transform(test_input)
train_std_scaler.shape, test_std_scaler.shape

 

2. 정규화 : RobustScaler 

''' 
훈련데이터 정규화 변수 : train_rbs_scaler
테스트데이터 정규화 변수 : test_rbs_scaler
'''
from sklearn.preprocessing import RobustScaler

''' 정규화 클래스 생성하기 '''
rbs = RobustScaler()

''' 정규화 패턴 찾기 : 훈련데이터만 사용 '''
rbs.fit(train_input)

''' 훈련 및 테스트 독립변수 변환하기 '''
train_rbs_scaler = rbs.transform(train_input)
test_rbs_scaler = rbs. transform(test_input)
train_rbs_scaler.shape, test_rbs_scaler.shape

 

3. 표준화 : MinMaxScaler  

'''
훈련데이터 표준화 변수 : train_mm_scaler
테스트데이터 표준화 변수 : test_mm_scaler
'''
from sklearn.preprocessing import MinMaxScaler

''' 표준화 클래스 생성하기 '''
mm = MinMaxScaler()

''' 표준화 패턴 찾기 : 훈련데이터만 사용 '''
mm.fit(train_input)

''' 훈련 및 테스트 독립변수 변환하기 '''
train_mm_scaler = mm.transform(train_input)
test_mm_scaler = mm. transform(test_input)
train_mm_scaler.shape, test_mm_scaler.shape

 

 🍇 훈련하기

''' 훈련모델 생성하기 '''
from sklearn.ensemble import RandomForestClassifier

''' 모델(클래스) 생성하기
 - cpu의 코어는 모두 사용, 랜덤값은 42번을 사용하여 생성하기
 - 모델 변수의 이름은 rf 사용
'''
rf = RandomForestClassifier(random_state=42, n_jobs=-1)

''' 모델 훈련 시키기 '''
rf.fit(train_std_scaler, train_target)

''' 훈련 및 검증(테스트) 정확도(score) 확인하기 '''
train_score = rf.score(train_std_scaler, train_target)
test_score = rf.score(test_std_scaler, test_target)
print(f"훈련 = {train_score} / 검증 = {test_score}")

 

728x90
반응형
728x90
반응형

🍡 선형회귀모델 (LR; Liner Regression Model)

 

### 모델 라이브러리 불러들이기
from sklearn.linear_model import LinearRegression
### 사용할 데이터
train_input, train_target, test_input, test_target
### 모델(클래스 생성하기)
lr = LinearRegression()

### 모델 훈련 시키기
lr.fit(train_input, train_target)

### 훈련 정확도
train_r2 = lr.score(train_input, train_target)

### 테스트(검증) 정확도
test_r2 = lr.score(test_input, test_target)

print(f"훈련={train_r2} / 테스트={test_r2}")

### (해석)
# - 결정계수 확인 결과, 훈련 결정계수 > 테스트 결정계수이므로 과소적합은 일어나지 않았으나,
# - 두 계수의 차이가 0.12로 과대적합이 의심됨

 

🍡임의 데이터로 예측하기

  • KNN에서는 1033g을 예측했었음
lr.predict([[50]])

 

🍡추세선 그리기

  • 추세선(예측선 이라고도 함)를 그리기 위한 계수값 추출하기
  • 직선의 방정식 y = a * x + b
  •  coef_ : 기울기(계수) → a
  • intercept_ : y절편 → b
lr.coef_, lr.intercept_

### 훈련데이터 산점도
plt.scatter(train_input, train_target)

### 예측값 산점도
plt.scatter(50, 1241.839, marker='^')

### 추세선
plt.plot([15, 50], [lr.coef_ * 15 + lr.intercept_,
                   lr.coef_ * 50 + lr.intercept_])

plt.grid()
plt.show()

# 선으로부터 떨어진 거리 = 오차 값(MAE)

 

  • 추세선 시작값을 0으로 설정
### 훈련데이터 산점도
plt.scatter(train_input, train_target)

### 예측값 산점도
plt.scatter(50, 1241.839, marker='^')

### 추세선
plt.plot([0, 50], [lr.coef_ * 0 + lr.intercept_,
                   lr.coef_ * 50 + lr.intercept_])

plt.grid()
plt.show()

 

해석

 - 임의 값 예측 시 KNN보다는 성능이 좋은 예측이 가능하며, 과적합이 발생하지 않는 일반화된 모델로 보여지나, y절편의 값이 음수로 예측시 음수의 데이터가 예측 될 가능성이 있는 모델로 보여짐
 - 종속변수 무게의 값은 0이하로 나올 수 없기에 이상치를 예측할 수 있는 모델로 현재 사용하는 데이터를 예측하기에는 부적합한 모델로 여겨짐

 

 

 

🧁 다항회귀모델

 

  • 데이터의 분포가 선형이면서 곡선을 띄는 경우에 사용됨
  • 곡선(포물선)의 방정식이 적용되어 있음
  • y = (a * x^2) + (b * x) +c
  • 독립변수는 2개가 사용됨 : x^2값과 x값

🧁 훈련 및 테스트데이터의 독립변수에 x^2값 추가하기

# - 훈련 독립변수
train_poly = np.column_stack((train_input**2, train_input))

# - 테스트 독립변수
test_poly = np.column_stack((test_input**2, test_input))

train_poly.shape, test_poly.shape

 

🧁 모델 훈련 및 예측

### 모델 생성하기
# - 선형, 다형, 다중 회귀모델은 하나의 모델(클래스) 사용
# - 직선, 곡선에 대한 구분은 독립변수의 갯수로 모델이 알아서 구분해준다. 
lr = LinearRegression()

### 모델 훈련 시키기
lr.fit(train_poly, train_target)

### 훈련 정확도 확인하기
train_r2 = lr.score(train_poly, train_target)

### 테스트 정확도 확인하기
test_r2 = lr.score(test_poly, test_target)

### 과적합 여부 확인(해석)
# - 0.007 정도의 과소적합(훈련 < 검증)이 발생

print(f"훈련 결정계수 = {train_r2} / 테스트 결정계수 = {test_r2}")

### 임의 값 길이 50으로 예측하기
pred = lr.predict([[50**2, 50]])
print(f"길이 50 예측 결과 : {pred}")

 

🧁 추세선 그리기

  • 추세선을 그리기 위해서는 곡선의 방정식에 사용할 계수 a,b와 절편 c를 알아야 함
print(f"계수 = {lr.coef_} / 절편 = {lr.intercept_}")

a = lr.coef_[0]
b = lr.coef_[1]
c = lr.intercept_
print(f"a = {a} / b = {b} / c = {c}")

 

plt.scatter(train_input, train_target)
plt.scatter(50, pred[0], marker='^')

# 추세선
# - 추세선이 사용할 x축값 지정(0~50까지의 순차적인 값 사용)
point = np.arange(0, 51)
plt.plot(point, a*point**2 + b*point + c)

plt.grid()
plt.show()


해석
 - 선형회귀모델의 경우에는 음의 절편값이 나타나는 모델이었으나, 다항회귀모델의 경우에는 이를 해소할 수 있었음
 - 단, 길이(x)가 10이하의 독립변수는 사용하면 안됨
 - 다항회귀모델의 훈련 및 테스트 결정계수의 결과 미세한 과소적합을 보이고 있으나, 사용가능한 모델로 판단됨
 - 선형회귀모델에 비하여 독립변수들이 전체적으로 추세선에 가깝게 위치하고 있기에 오차가 적은 모델이라고 분석 됨


 

🧁 과소 / 과대 적합을 해소하기 위한 방법

  • 데이터 양(row 데이터, 행)을 늘릴 수 있는지 확인
  • 분석 모델이 좀 더 집중해서 훈련할 수 있도록 특성(독립변수)을 추가하는 방법 확인
    → 특성을 추가(늘리는)하는 방법은 "특성공학" 개념을 적용
    → 특성을 늘려서 사용하는 모델로 다중회귀모델이 있음
    → 특성을 늘린다는 의미는 훈련의 복잡도를 증가시킨다고 표현하며, 복잡도가 증가되면, 훈련의 집중력이 강해지게 됨
  • 복잡도를 늘리는 방법으로는 "규제" 방법이 있음
    → "규제"를 하는 하이퍼파라미터 속성을 이용하는 방식으로 릿지와 라쏘 회귀모델 방식이 있음
  • 이외 다른 회귀모델을 사용하여 비교
  •  특성 → 컬럼, 필드, 퓨처 모두 같은 의미
  • 데이터 처리 분야에서는 컬럼 또는 필드라고 칭하며, 머신러닝에서는 특성이라고 칭하며, 딥러닝에서는 퓨처라고 칭함

💎 다중회귀모델(Multiple Regression)

 

  • 여러개의 특성을 사용한 회귀모델
  • 특성이 많을수록 복잡도가 증가됨(훈련 시간이 오래걸림, 시스템 성능에 따라 빠를 수도 있음)
  • 다중회귀모델 공식
    y = a*x1 + b*x2 + c*x3 + ... + y절편 (x의 값은 3개 이상)

💎 데이터 불러들이기

  • 사용할 데이터프레임 변수
import pandas as pd
df = pd.read_csv("./data/03_농어의_길이_높이_두께_데이터.csv")

 

💎 농어의 길이, 두께 높이 값을 이용해서 무게 예측하기

  • 독립변수 : 길이, 두께, 높이
  • 종속변수 : 무게
  • 독립변수 생성하기
    → 데이터프레임의 특성 중에 독립변수로 사용할 특성들을 2차원의 리스트 또는 배열 형태로 만들어아야 한다.
    → to_numpy() : 행렬 데이터 형태를 리스트 배열 형태로 바꿈
perch_full = df.to_numpy()
perch_full.shape

  • 종속변수 생성하기
import numpy as np
### 농어 무게
perch_weight = np.array(
    [5.9, 32.0, 40.0, 51.5, 70.0, 100.0, 78.0, 80.0, 85.0, 85.0, 
     110.0, 115.0, 125.0, 130.0, 120.0, 120.0, 130.0, 135.0, 110.0, 
     130.0, 150.0, 145.0, 150.0, 170.0, 225.0, 145.0, 188.0, 180.0, 
     197.0, 218.0, 300.0, 260.0, 265.0, 250.0, 250.0, 300.0, 320.0, 
     514.0, 556.0, 840.0, 685.0, 700.0, 700.0, 690.0, 900.0, 650.0, 
     820.0, 850.0, 900.0, 1015.0, 820.0, 1100.0, 1000.0, 1100.0, 
     1000.0, 1000.0]
     )
perch_weight.shape

 

💎 훈련 및 테스트 데이터로 분류하기

  •  분류 기준 : 테스트 데이터를 30%로
from sklearn.model_selection import train_test_split

train_input, test_input, train_target, test_target = train_test_split(perch_full,
                                                                      perch_weight,
                                                                     test_size=0.3,
                                                                     random_state=42)

print(f"{train_input.shape} : {train_target.shape}")
print(f"{test_input.shape} : {test_target.shape}")

 

💎 모델 훈련 및 평가

from sklearn.linear_model import LinearRegression

### 모델 생성하기
lr = LinearRegression()

### 모델 훈련시키기
lr.fit(train_input, train_target)

### 훈련 정확도 및 검증(테스트) 정확도 확인하기
train_r2 = lr.score(train_input, train_target)
test_r2 = lr.score(test_input, test_target)

print(f"훈련 = {train_r2} / 테스트 = {test_r2}")

  • 과적합 여부 판단하기
    - 훈련과 검증(테스트) 결정계수의 결과로 볼 때 과소적합은 발행하지 않았다. 또한, 0.07 ~ 0.08 정도로 과대적합 또한 일어나지 않은 일반화 된 모델로 볼 수 있음
    - 다만, 검증(테스트) 정확도가 0.8대에서 0.9대로 올릴 수 없을지 고민해 본다.
    - 특성공학을 적용하여 특성 늘리는 방법으로 집중도를 강화하는 방식을 사용해서 성능 향상이 되는지 확인한다.
  • 특성을 생성하는 라이브러리
    - 사용 패키지 : sklearn.preprocessing
    - 사용 클래스 : PolynomialFeatures(변환기라고 보통 칭한다)
    - 사용 함수 : fit(훈련 독립변수에서 생성할 특성의 패턴 찾기), transform(찾은 패턴으로 특성 생성하기)
    - 종속변수는 사용되지 않는다.

💎 테스트 데이터로 예측하기

test_pred = lr.predict(test_input)
test_pred

 

💎 평균절대오차(MAE) 확인하기

from sklearn.metrics import mean_absolute_error

mae = mean_absolute_error(test_target, test_pred)
mae

💎 특성공학

 

💎 특성공학 적용하기

  • 패키지 정의하기
from sklearn.preprocessing import PolynomialFeatures
  • 클래스 생성하기
    - 특성을 생성 시킬 때 y절편값도 생성을 함께 시킨다.
    - 특성만 있으면 되기 때문에 y절편은 생성에서 제외시키기 위해서 include_bias(y절편) = False로 설정한다.
poly = PolynomialFeatures(include_bias = False)
  • sample 데이터로 어떤 특성들이 만들어지는지 확인하기
temp_data = [[2, 3, 4]]
temp_data

  • 특성을 만들 패턴 찾기
poly.fit(temp_data)

  • 찾은 패턴으로 특성 생성하기
poly.transform(temp_data)

 

💎 실제 독립변수를 이용해서 특성 생성하기

  • 클래스 생성하기
  • degree = 2
    - 차원을 의미하며 2는 제곱승을 의미함
    - 3을 넣으면 2의 제곱, 3의 제곱을 수행
    - 4를 넣으면 2의 제곱, 3의제곱, 4의 제곱승을 수행함
    - 기본값은 2 (생략하면 2의 제곱승이 적용됨)
poly = PolynomialFeatures(degree=2, include_bias=False)

  • 패턴 찾기
    - 훈련 독립변수 사용
poly.fit(train_input)

  • 특성 생성하기
### 훈련 독립변수에 특성 추가하기
train_poly = poly.transform(train_input)

### 테스트 독립변수에 특성 추가하기
test_poly = poly.transform(test_input)

train_poly.shape, test_poly.shape

  • 사용된 패턴 확인하기
poly.get_feature_names_out()

 

💎 모델 생성 / 훈련 / 예측 / 평가

### 모델 생성하기
lr = LinearRegression()

### 모델 훈련시키기
lr.fit(train_poly, train_target)

### 훈련 정확도 및 검증(테스트) 정확도 확인하기
train_r2 = lr.score(train_poly, train_target)
test_r2 = lr.score(test_poly, test_target)

### 예측 하기
test_pred = lr.predict(test_poly)

### 모델 평가하기(MAE)
mae = mean_absolute_error(test_target, test_pred)

print(f"훈련 = {train_r2} / 테스트 = {test_r2} / 오차 = {mae}")

해석
- 특성공학을 적용하지 않은 모델은 검증(테스트) 정확도가 다소 낮았으며, 오차가 50g 정도 있으나- 특성공학을 적용하여 특성을 추가하여 훈련 집중도를 높였을 때는 훈련 및 검증(테스트) 정확도 모두 높아졌으며, 과적합이 발생하지 않은 일반화 모델로 오차는 30g정도의 매우 우수한 모델로 판단 됨
- 이 모델을 사용하려면, 독립변수의 특성 길이, 높이, 두께 3개의 특성을 사용해야 하고 특성 생성 시 degree 2를 적용한 특성을 사용해야 함

💎규제

 

💎 규제

  • 과대 또는 과소 적합 중에 주로 과대적합이 발생 했을 때 사용된다.
  • 훈련의 정확도가 다소 낮아지는 경향이 있으나. 검증(테스트) 정확도를 높이는 효과가 있음
  • 훈련모델을 일반화하는데 주로 사용되는 방법임
  • 규제 개념을 적용한 향상된 모델 : 릿지(Ridge)와 라쏘(Lasso)가 있다.

💎 규제 순서

  1. 정규화(단위(스케일)을 표준화 시키는 방식)
  2. 규제가 적용된 모델 훈련 / 검증

💎 훈련 및 테스트 독립변수 정규화 하기

  • 정규화를 위한 라이브러리
from sklearn.preprocessing import StandardScaler

 

  • 정규화 순서
     1. 정규화 클래스 생성
     2. fit() : 정규화 패턴 찾기(훈련 독립변수 사용)
     3. transform() : 찾은 패턴으로 정규화 데이터로 변환(훈련 및 테스트 독립변수 변환)
''' 1. 정규화 클래스 생성 '''
ss = StandardScaler()

''' 2. 정규화 패턴 찾기 '''
ss.fit(train_poly)

''' 3. 찾은 패턴으로 훈련 및 테스트 독립변수 변환 생성하기 '''
train_scaled = ss.transform(train_poly)
test_scaled = ss.transform(test_poly)

print(f"{train_scaled.shape} / {test_scaled.shape}")

 

릿지(Ridge) 모델

from sklearn.linear_model import Ridge

''' 모델 생성하기'''
ridge = Ridge()

''' 모델 훈련시키기 '''
ridge.fit(train_scaled, train_target)

''' 훈련 및 검증(테스트) 정확도 확인하기 '''
train_r2 = ridge.score(train_scaled, train_target)
test_r2 = ridge.score(test_scaled, test_target)

train_r2, test_r2

''' 예측하기 '''
test_pred = ridge.predict(test_scaled)

''' 평가하기(MAE) '''
mae = mean_absolute_error(test_target, test_pred)

print(f"훈련 = {train_r2} / 테스트 = {test_r2} / 오차 = {mae}")

해석
- 과적합 여부를 확인한 결과, 과소적합은 발생하지 않았으며- 기존 특성공학을 적용한 우수한 모델보다는 훈련 정확도는 0.005정도 낮아 졌지만 검증(테스트) 정확도는 0.013 정도 높아졌음
- 또한, 평균절대오차(MAE)도 1g 낮아졌음
- 따라서, 일반화되고, 오차가 적은 Ridge 모델은 매우 우수한 모델로 판단됨

 

라쏘(Lasso) 모델

### 사용할 패키지
from sklearn.linear_model import Lasso

### 모델 생성하기
lasso = Lasso()

''' 모델 훈련시키기 '''
lasso.fit(train_scaled, train_target)

''' 훈련 및 검증(테스트) 정확도 확인하기 '''
train_r2 = lasso.score(train_scaled, train_target)
test_r2 = lasso.score(test_scaled, test_target)

train_r2, test_r2

''' 예측하기 '''
test_pred = lasso.predict(test_scaled)

''' 평가하기(MAE) '''
mae = mean_absolute_error(test_target, test_pred)

print(f"훈련 = {train_r2} / 테스트 = {test_r2} / 오차 = {mae}")

해석
- 0.0002 정도의 과소적합이 있는 것으로 보임
- 오차값도 3g정도 작아졌음

- 과소적합이 미세한 차이이기 때문에 릿지 모델과 비교 했을 때 나쁜 모델은 아니지만, 사용하기에는 미흡한 부분으로 판단 됨

 

💎 하이퍼파라미터 튜닝하기 (규제 적용)

  • 릿지(Ridge) 모델 규제 튜닝하기
    • alpha : 규제강도 값
    • 값의 범위 0.001 ~ 100 사이의 값
    • 값이 작을 수록 훈련 정확도는 낮아지면서, 과적합에 도움을 주게 됨
    • 값이 커질 수록 훈련 정확도는 높아짐, 과적합에는 도움이 되지 읺을 수도 있음
    • 기본 값은 = 1
ridge = Ridge(alpha=1)
ridge.fit(train_scaled, train_target)
ridge.score(train_scaled, train_target), ridge.score(test_scaled, test_target)
# 규제강도 1 (0.9849041294689239, 0.9845173591615219)
# 0 (0.9898271546307025, 0.971377160062062)
# 0.1 (0.9882780161390031, 0.9868237771849514) best!!
# 0.01 (0.9882780161390031, 0.9868237771849514)
# 0.001 (0.9891665643761299, 0.9844479791505587)
# 0.0001 (0.9897131221945868, 0.9790469305992887)

 

  • 라쏘(Lasso) 모델 규제 튜닝하기
lasso = Lasso(alpha=0.1)
lasso.fit(train_scaled, train_target)
lasso.score(train_scaled, train_target), lasso.score(test_scaled, test_target)

 

# 0.1 (0.9883448062768178, 0.9857016019582314)

 

728x90
반응형
728x90
반응형

🎈KNN 회귀모델

 

데이터 입력과 훈련 - 농어의 길이와 무게

### 농어 길이
perch_length= np.array(
    [8.4, 13.7, 15.0, 16.2, 17.4, 18.0, 18.7, 19.0, 19.6, 20.0, 
     21.0, 21.0, 21.0, 21.3, 22.0, 22.0, 22.0, 22.0, 22.0, 22.5, 
     22.5, 22.7, 23.0, 23.5, 24.0, 24.0, 24.6, 25.0, 25.6, 26.5, 
     27.3, 27.5, 27.5, 27.5, 28.0, 28.7, 30.0, 32.8, 34.5, 35.0, 
     36.5, 36.0, 37.0, 37.0, 39.0, 39.0, 39.0, 40.0, 40.0, 40.0, 
     40.0, 42.0, 43.0, 43.0, 43.5, 44.0]
     )

### 농어 무게
perch_weight = np.array(
    [5.9, 32.0, 40.0, 51.5, 70.0, 100.0, 78.0, 80.0, 85.0, 85.0, 
     110.0, 115.0, 125.0, 130.0, 120.0, 120.0, 130.0, 135.0, 110.0, 
     130.0, 150.0, 145.0, 150.0, 170.0, 225.0, 145.0, 188.0, 180.0, 
     197.0, 218.0, 300.0, 260.0, 265.0, 250.0, 250.0, 300.0, 320.0, 
     514.0, 556.0, 840.0, 685.0, 700.0, 700.0, 690.0, 900.0, 650.0, 
     820.0, 850.0, 900.0, 1015.0, 820.0, 1100.0, 1000.0, 1100.0, 
     1000.0, 1000.0]
     )

 

🎈 농어의 길이로, 무게 예측하기

  • 독립변수 : 길이
  • 종속변수 : 무게(연속)
perch_length.shape, perch_weight.shape

 

🎈 산점도 그리기

import matplotlib.pyplot as plt

plt.scatter(perch_length, perch_weight)
plt.xlabel("length")
plt.ylabel("weight")
plt.show()


해석
- 초반에는 곡선을 띄는 듯하다가, 중반부부터는 직선의 형태를 나타내고 있음
- 종속변수가 연속형 데이터이며, 선형 분포를 나타내기에 회귀모델을 사용함

 

 

 


 

🎈 훈련 및 테스트 데이터 분류하기

  • 훈련 : 테스트 = 75 : 25로 구분
  • 사용변수 : train_input, train_target, test_input, test_target
from sklearn.model_selection import train_test_split

train_input, test_input, train_target, test_target = train_test_split(perch_length,
                                                                      perch_weight,
                                                                     test_size=0.25,
                                                                     random_state=42)

print(f"{train_input.shape} : {train_target.shape}")
print(f"{test_input.shape} : {test_target.shape}")

 

🎈 훈련 및 테스트의 독립변수를 2차원으로 만들기

### 훈련 독립변수 2차원 만들기
# -1 : 전체를 의미함
train_input = train_input.reshape(-1, 1)

### 테스트 독립변수 2차원 만들기
test_input = test_input.reshape(-1, 1)

print(f"{train_input.shape} / {test_input.shape}")

 

🎈 모델 훈련하기

from sklearn.neighbors import KNeighborsRegressor

### 모델(클래스 생성하기)
knr = KNeighborsRegressor()

### 모델 훈련시키기
knr.fit(train_input, train_target)

### 훈련 정확도 확인하기
train_r2 = knr.score(train_input, train_target)

### 검증 정확도 확인하기
test_r2 = knr.score(test_input, test_target)

print(f"훈련={train_r2} / 테스트={test_r2}")

 

해석
- 훈련 및 테스트 정확도는 매우 높게 나타난 성능 좋은 모델로 판단됨
- 그러나 과적합 여부를 확인한 결과, 훈련 정확도가 테스트 정확도보다 낮게 나타난 것으로 보아 과소 적합이 발생하고 있는 것으로 판단됨
- 이는 데이터의 갯수가 적거나, 튜닝이 필요한 경우로 이후 진행을 하고자 함

 

모델 평가하기 : 평균절대오차(MAE)

🎈 평균절대오차(MAE; Mean Absolute Error)

  •  회귀에서 사용하는 평가방법
  • 예측값과 실제값의 차이를 평균하여 계산한 값
  • 즉, 사용된 이웃들과의 거리차를 평균한 값
  • 라이브러리
from sklearn.metrics import mean_absolute_error

 

🎈 예측하기

  • 5개 이웃의 평균 값이 나옴
test_pred = knr.predict(test_input)
test_pred

 

🎈 평가하기

  • mean_absolute_error(실제 종속변수, 예측 종속변수)
mae = mean_absolute_error(test_target, test_pred)
mae

 

해석
- 해당 모델을 이용해서 예측을 할 경우에는

- 평균적으로 → 약 19.157g 정도의 차이(오차)가 있는 결과를 얻을 수 있음

- 즉, 예측결과는 약 19.157g 정도의 차이가 있다

 

하이퍼파라미터 튜닝

🎈 과소적합을 해소하기 위하여 튜닝을 진행해 보기

  • 이웃의 갯수 → 기본값 사용
### KNN 모델의 이웃의 갯수(하이퍼파리미터)를 조정해보기

### 이웃의 갯수 -> 기본값 사용
knr.n_neighbors = 5

### 하이퍼파라미터 값 수정 후 재훈련 시켜서 검증해야 한다.
knr.fit(train_input, train_target)

### 훈련정확도 확인
train_r2 = knr.score(train_input, train_target)

### 테스트(검증) 정확도 확인
test_r2 = knr.score(test_input, test_target)

print(f"훈련={train_r2} / 테스트={test_r2}")

 

해석

- 과적합 여부 확인 결과 과소적합이 발생하여, 훈련모델로 적합하지 않음

- 과소적합 해소 필요


  • 이웃의 갯수 조정
### KNN 모델의 이웃의 갯수(하이퍼파리미터)를 조정해보기
knr.n_neighbors = 3

### 하이퍼파라미터 값 수정 후 재훈련 시켜서 검증해야 한다.
knr.fit(train_input, train_target)

### 훈련정확도 확인
train_r2 = knr.score(train_input, train_target)

### 테스트(검증) 정확도 확인
test_r2 = knr.score(test_input, test_target)

print(f"훈련={train_r2} / 테스트={test_r2}")

 

해석

- 과소적합 해소를 위해 이웃의 갯수를 조정하여 하이퍼파라미터 튜닝을 진행한 결과
- 과소적합을 해소할 수 있었음
- 또한, 훈련 정확도와 테스트 정확도의 차이가 크지 않기에 과대적합도 일어나지 않았음
- 다만, 테스트 정확도는 다소 낮아진 반면 훈련정 확도가 높아졌음
- 이 모델은 과적합이 발생하지 않은 일반화된 모델로 사용가능

 

🎈 가장 적합한 이웃의 갯수 찾기(하이퍼파리미터 튜닝)

### 1보다 작은 가장 좋은 정확도일 때의 이웃의 갯수 찾기
### 모델(클래스 생성)
kn = KNeighborsClassifier()
### 훈련시키기
kn.fit(train_input, train_target)

# - 반복문 사용 : 범위는 3 ~ 전체 데이터 갯수

### 정확도가 가장 높을 떄의 이웃의 갯수를 담을 변수
nCnt = 0
###정확도가 가장 높을때의 값을 담을 변수
nScore = 0

for n in range(3, len(train_input), 2):
    kn.n_neighbors = n
    score = kn.score(train_input, train_target)
    print(f"{n} / {score}")

    ### 1보다 작은 정확도인 경우
    if score < 1 :
        ### nScore의 값이 score보다 작은 경우 담기
        if nScore < score : 
            nScore = score
            nCnt = n

print(f"nCnt = {nCnt} / nScore = {nScore}")

 

임의 값으로 예측하기

🎈 길이 50으로 무게 예측하기

pred = knr.predict([[50]])
pred

 

🎈 사용된 이웃의 인덱스 확인

dist, indexes = knr.kneighbors([[50]])
indexes

 

🎈 산점도 그리기 (이웃포함)

plt.scatter(train_input, train_target, c="blue", label="bream")
plt.scatter(50, pred[0], marker='^', c="green", label="pred")
plt.scatter(train_input[indexes], train_target[indexes], c="red", label="test")
plt.xlabel("length")
plt.ylabel("weight")
plt.legend()
plt.show()


🎈 길이 100으로 무게 예측하기

pred = knr.predict([[100]])
pred

 

🎈 사용된 이웃의 인덱스 확인

dist, indexes = knr.kneighbors([[50]])
indexes

 

🎈 산점도 그리기 (이웃포함)

plt.scatter(train_input, train_target, c="blue", label="bream")
plt.scatter(100, pred[0], marker='^', c="green", label="pred")
plt.scatter(train_input[indexes], train_target[indexes], c="red", label="test")
plt.xlabel("length")
plt.ylabel("weight")
plt.legend()
plt.show()

 

💧KNN의 한계

 가장 가까운 이웃을 이용해서 예측을 수행하는 모델이기에, 예측하고자 하는 독립변수의 값이 기존 훈련데이터의 독립변수가 가지고 있는 범위를 벗어나는 경우에는 값이 항상 동일하게 나옴(가까운 거리의 이웃이 항상 동일해짐)
 따라서, 다른 회귀모델을 사용해야 함.

 

 


 

 

🎈 회귀모델 종류

  • 선형회귀모델(직선 한개), 다항회귀모델(곡선), 다중회귀모델(직선 여러개), 릿지, 라쏘 : 회귀에서만 사용
  • 랜덤포레스트, 그레디언트부스트, 히스토그램그래디언트부스트, XGBoost, 기타 등등 : 회귀 또는 분류 모두 사용 가능
  • 주로 많이 사용되는 회귀모델 : 릿지, 히스토그램그래디언트부스트, XGBoost
728x90
반응형
728x90
반응형

🧤 훈련 및 테스트 데이터 분류하기

🧤 훈련, 검증, 테스트, 데이터 분류시 주로 사용되는 변수명

  • 정의된 변수 이름은 없음
  • 훈련데이터 : 훈련(fit)에 사용되는 데이터
                 : (훈련 독립변수) train_input, train_x, X_train
                 : (훈련 종속변수) train_target, train_y, y_train
  • 검증데이터 : 훈련 정확도(score)에 사용되는 데이터
                 : (검증 독립변수) val_input, val_x, X_val
                 : (검증 종속변수) val_target, val_y, y_val
  • 테스트데이터 : 예측(predict)에 사용되는 데이터
                   : (테스트 독립변수) test_input, test_x, X_test
                   : (테스트 종속변수) test_target, test_y, y_test

🧤  데이터 분류 순서

  1. 훈련과 테스트를 비율로 먼저 나누기
    → 훈련과 테스트 비율 : 주로 7 : 3을 사용, 또는 7.5 : 2.5 또는 8 : 2
  2. 훈련과 검증 데이터를 나누기
    → 훈련과 검증 비율 : 주로 4 : 2 또는 6 : 2를 사용
  3. 가장 많이 사용되는 훈련
    → 검증 : 테스트 비율 대략 => 6 : 2 : 2

사용할 데이터 정의하기

fish_length = [25.4, 26.3, 26.5, 29.0, 29.0, 29.7, 29.7, 30.0, 30.0, 30.7, 31.0, 31.0, 
                31.5, 32.0, 32.0, 32.0, 33.0, 33.0, 33.5, 33.5, 34.0, 34.0, 34.5, 35.0, 
                35.0, 35.0, 35.0, 36.0, 36.0, 37.0, 38.5, 38.5, 39.5, 41.0, 41.0, 9.8, 
                10.5, 10.6, 11.0, 11.2, 11.3, 11.8, 11.8, 12.0, 12.2, 12.4, 13.0, 14.3, 15.0]

fish_weight = [242.0, 290.0, 340.0, 363.0, 430.0, 450.0, 500.0, 390.0, 450.0, 500.0, 475.0, 500.0, 
                500.0, 340.0, 600.0, 600.0, 700.0, 700.0, 610.0, 650.0, 575.0, 685.0, 620.0, 680.0, 
                700.0, 725.0, 720.0, 714.0, 850.0, 1000.0, 920.0, 955.0, 925.0, 975.0, 950.0, 6.7, 
                7.5, 7.0, 9.7, 9.8, 8.7, 10.0, 9.9, 9.8, 12.2, 13.4, 12.2, 19.7, 19.9]

 

🧤 훈련에 사용할 2차원 데이터 형태로 만들기

  • 독립변수 정의하기
fish_data = [[l, w]for l, w in zip(fish_length, fish_weight)]
print(fish_data)
len(fish_data)

  • 종속변수 정의하기
  • 도미 : 빙어 = 1 : 0 -> 찾고자 하는 값을 1로 설정
  • 이진분류에서는 찾고자 하는 값을 1로 정의하는 것이 일반적 개념
  • 다만, 어떤 값을 사용하여도 무관
fish_target = [1]*35 + [0]*14
print(fish_target)
len(fish_target)

 

훈련 및 테스트 데이터로 분류하기

🧤 훈련데이터(train)

# - 훈련 독립변수
train_input = fish_data[ : 35]

# - 훈련 종속변수
train_target = fish_target[ : 35]

print(len(train_input), len(train_target))

 

🧤 테스트 데이터(test)

# - 훈련 독립변수
test_input = fish_data[35 : ]

# - 훈련 종속변수
test_target = fish_target[35 : ]

print(len(test_input), len(test_target))

 

모델 생성하기

from sklearn.neighbors import KNeighborsClassifier

 

🧤모델(클래스) 생성

  • 이웃의 갯수는 기본값 사용
kn = KNeighborsClassifier()
kn

 

🧤 모델 훈련 시키기

  • 훈련데이터 적용
kn.fit(train_input, train_target)

 

🧤 훈련 정확도 확인하기

# - 훈련 데이터 사용
train_score = kn.score(train_input, train_target)

### 검증하기 
# - 테스트 데이터 사용
test_score = kn.score(test_input, test_target)

train_score, test_score

 

 

 

해석
- 훈련 정확도가 1 이기 때문에 과대적합이 발생하였으며, 검증 정확도가 0으로 나타났음

- 따라서, 이 훈련 모델은 튜닝을 통해 성능 향상을 시켜야 할 필요성이 있음

 

원인분석
- 데이터 분류시 : 35개의 도미값으로만 훈련을 시켰기 때문에 발생한 문제

- 즉, 검증데이터가 0이 나왔다는 것은, 또는 매우 낮은 정확도가 나온 경우 데이터에 편향이 발생하였을 가능성이 있다고 의심해 본다.

- 샘플링 편향 : 특정 데이터에 집중되어 데이터가 구성되어 훈련이 이루어진 경우 발생하는 현상
- 샘플링 편향 해소방법 : 훈련 / 검증 / 테스트 데이터 구성시에 잘 섞어야 한다. (셔플)

 

샘플링 편향 해소하기(셔플)

🧤 numpy의 셔플링 함수 사용

import numpy as np

 

🧤 넘파이 배열 형태로 변형하기

input_arr = np.array(fish_data)
tayget_arr = np.array(fish_target)
input_arr

 

🧤 데이터 갯수 확인하기

  • shape : 차원을 확인하는 넘파이 속성(행의 갯수, 열의 갯)
input_arr.shape, tayget_arr.shape

 

🧤 랜덤하게 섞기

  • 랜덤 규칙 지정하기
  • random.seed(42) : 데이터를 랜덤하게 생성할 때 규칙성을 띄도록 정의, 숫자 값은 의미없는 값으로 규칙을 의미함
np.random.seed(42)

 

  • index 값 정의하기
index = np.arange(49)
index

 

  • index 값 셔플로 섞기
np.random.shuffle(index)
index

 

🧤 훈련 및 테스트 데이터 분류하기

train_input = input_arr[index[ : 35]]
train_target = tayget_arr[index[ : 35]]

test_input = input_arr[index[35 : ]]
test_target = tayget_arr[index[35 : ]]

print(train_input.shape, train_target.shape)
print(test_input.shape, test_target.shape)

 

🧤 산점도 그리기

### 라이브러리
import matplotlib.pyplot as plt

plt.scatter (train_input[:, 0], train_input[:, 1], c="red", label="train")
plt.scatter(test_input[:, 0], test_input[:, 1], c="blue", label="test")
plt.xlabel("length")
plt.ylabel("weight")
plt.legend()
plt.show()

 

🧤 모델 생성 및 훈련

### 모델 생성하기
kn = KNeighborsClassifier()

### 훈련시키기
kn.fit(train_input, train_target)

### 훈련 정확도 확인하기
train_score = kn.score(train_input, train_target)

### 테스트 정확도 확인하기
test_score = kn.score(test_input, test_target)
train_score, test_score

 

🧤 예측하기

test_pred = kn.predict(test_input)
print(f"predict : {test_pred}")
print(f"실제값 : {test_target}")

 

🧤 하이퍼파라미터 튜닝

### 1보다 작은 가장 좋은 정확도일 때의 이웃의 갯수 찾기
### 모델(클래스 생성)
kn = KNeighborsClassifier()
### 훈련시키기
kn.fit(train_input, train_target)

# - 반복문 사용 : 범위는 3 ~ 전체 데이터 갯수

### 정확도가 가장 높을 떄의 이웃의 갯수를 담을 변수
nCnt = 0
###정확도가 가장 높을때의 값을 담을 변수
nScore = 0

for n in range(3, len(train_input), 2):
    kn.n_neighbors = n
    score = kn.score(train_input, train_target)
    print(f"{n} / {score}")

    ### 1보다 작은 정확도인 경우
    if score < 1 :
        ### nScore의 값이 score보다 작은 경우 담기
        if nScore < score : 
            nScore = score
            nCnt = n

print(f"nCnt = {nCnt} / nScore = {nScore}")

 

🧤 데이터 섞으면서 분류하기

  • 2차원 데이터 생성하기
fish_data = np.column_stack((fish_length,fish_weight))
fish_data

 

  • 1차원 데이터 생성하기
fish_target = np.concatenate((np.ones(35), np.zeros(14)))
fish_target

 

🧤 train_test_split

  • 머신러닝, 딥러닝에서 사용하는 데이터 분류기 함수
  • 랜덤하게 섞으면서 두개(훈련 : 테스트)의 데이터로 분류함
  • 첫번째 값 : 독립변수
  • 두번째 값 : 종속변수
  • test_size = 0.3 : 분류 기준(훈련 : 테스트 = 7 : 3)
  • random_state : 랜덤 규칙
  • stratify=fish_target : 종속변수의 범주 비율을 훈련과 테스트의 비율대비 편향 없이 조정시킴
### 라이브러리
from sklearn.model_selection import train_test_split

train_input,test_input, train_target, test_target = train_test_split(fish_data, fish_target, test_size=0.3, random_state=42)
print(f"{train_input.shape}, {train_target.shape} / {test_input.shape}, {test_target.shape}")

첫번째 결과값 : 훈련 독립변수
두번째 결과값 : 테스트 독립변수
세번째 결과값 : 훈련 종속변수
네번째 결과값 : 테스트 종속변수

 

🧤 모델 생성 및 훈련

### 모델(클래스 생성하기)
kn = KNeighborsClassifier(n_neighbors=5)

### 모델 훈련시키기
kn.fit(train_input, train_target)

### 훈련 정확도 확인하기
train_score = kn.score(train_input, train_target)

### 검증 정확도 확인하기
test_score = kn.score(test_input, test_target)

train_score, test_score

 

정확도 해석

  • 과대적합 : 훈련 > 검증 또는 훈련이 1인 경우
  • 과소적합 : 훈련 < 검증 또는 검증이 1인 경우
  • 과소적합이 일어나는 모델은 사용할 수 없음
  • 과대적합 중에 훈련 정확도가 1인 경우의 모델은 사용할 수 없음
  • 과대적합이 보통 0.1 이상의 차이를 보이면 정확도의 차이가 많이난다고 의심해 볼 수 있음

모델 선정 기준

  •  과소적합이 일어나지 않으면서, 훈련 정확도가 1이 아니고 훈련과 검증의 차이가 0.1 이내인 경우

  • 선정된 모델을 "일반화 모델"이라고 칭한다.
  • 다만, 추가로 선정 기준 중에 평가기준이 있음

  • 가장 바람직한 결과는 훈련 > 검증> 테스트
  • (훈련 > 검증 < 테스트인 경우도 있음)

 

🧤 하이퍼파라미터 튜닝

### 1보다 작은 가장 좋은 정확도일 때의 이웃의 갯수 찾기
### 모델(클래스 생성)
kn = KNeighborsClassifier()
### 훈련시키기
kn.fit(train_input, train_target)

# - 반복문 사용 : 범위는 3 ~ 전체 데이터 갯수

### 정확도가 가장 높을 떄의 이웃의 갯수를 담을 변수
nCnt = 0
###정확도가 가장 높을때의 값을 담을 변수
nScore = 0

for n in range(3, len(train_input), 2):
    kn.n_neighbors = n
    score = kn.score(train_input, train_target)
    print(f"{n} / {score}")

    ### 1보다 작은 정확도인 경우
    if score < 1 :
        ### nScore의 값이 score보다 작은 경우 담기
        if nScore < score : 
            nScore = score
            nCnt = n

print(f"nCnt = {nCnt} / nScore = {nScore}")

 

🧤 임의로 테스트 하기 (for문 돌리지 않기)

kn.predict([[25, 150]])

 

🧤 산점도 그리기

plt.scatter(train_input[:, 0], train_input[:, 1], c="red", label="bream")
plt.scatter(25, 150, marker='^', c="green", label="pred")
plt.xlabel("length")
plt.ylabel("weight")
plt.legend()
plt.show()

 

🧤 사용된 이웃 확인하기

  • kneighbors(이웃과의 거리, index 위치값)
dist, indexes = kn.kneighbors([[25, 150]])
indexes

 

  • 이웃을 포함하여 산점도 그리기
plt.scatter(train_input[:, 0], train_input[:, 1], c="red", label="bream")
plt.scatter(25, 150, marker='^', c="green", label="pred")
plt.scatter(train_input[indexes, 0], train_input[indexes, 1], c="blue", label="nei")
plt.xlabel("length")
plt.ylabel("weight")
plt.legend()
plt.show()

 

분석

- 예측 결과는 빙어로 확인되었으나, 시각적으로 확인하였을 때는 도미에 더 가까운 것으로 확인 됨
- 실제 이웃을 확인한 결과 빙어쪽 이웃을 모두 사용하고 있음
- 이런 현상이 발생한 원인 : 스케일(x축과 y축의 단위)이 다르기 때문에 나타나는 현상 → "스케일이 다르다" 라고 표현 한다.

- 해소 방법 : 데이터 정규화 전처리를 수행해야 함

 

 

 

 

 

 

🧤 정규화 하기

현재까지 수행 순서

1. 데이터 수집
2. 독립변수 2차원과 종속변수 1차원 데이터로 취합
3. 훈련, 검증, 테스트 데이터로 섞으면서 분리
4. 훈련, 검증, 테스트 데이터 중에 독립변수에 대해서만 정규화 전처리 수행
5. 훈련모델 생성
6. 모델 훈련 시키기
7. 훈련 및 검증 정확도 확인
8. 하이퍼파라미터 튜닝
9. 예측

 

정규화

🧤 정규화 → 표준점수화 하기

  • 표준점수 = (각 데이터 - 데이터 전체 평균) / 데이터 전체 표준편차
  • 표준점수 : 각 데이터가 원점(0)에서 표준편차 만큼 얼마나 떨어져 있는지를 나타내는 값

🧤 데이터 전체 평균 구하기

mean = np.mean(train_input, axis=0)
mean

 

🧤 데이터 전체 표준편차 구하기

std = np.std(train_input, axis=0)
std

 

🧤정규화(표준점수) 처리하기

train_scaled = (train_input - mean) / std
train_scaled

 

🧤 이웃을 포함하여 산점도 그리기

plt.scatter(train_scaled[:, 0], train_scaled[:, 1], c="red", label="bream")
plt.scatter(25, 150, marker='^', c="green", label="pred")
plt.scatter(train_input[indexes, 0], train_input[indexes, 1], c="blue", label="nei")
plt.xlabel("length")
plt.ylabel("weight")
plt.legend()
plt.show()

 

🧤 예측하고자 하는 값들도 모두 정규화 처리해야 함

new = ([25, 150] - mean) / std
new

 

🧤 이웃을 포함하여 산점도 그리기

plt.scatter(train_scaled[:, 0], train_scaled[:, 1], c="red", label="bream")
plt.scatter(new[0], new[1], marker='^', c="green", label="pred")
plt.scatter(train_scaled[indexes, 0], train_scaled[indexes, 1], c="blue", label="nei")
plt.xlabel("length")
plt.ylabel("weight")
plt.legend()
plt.show()

 

 

모델 훈련시키기

### 모델(클래스 생성하기)
kn = KNeighborsClassifier()

### 모델 훈련시키기
kn.fit(train_scaled, train_target)

### 훈련 정확도 확인하기
train_score = kn.score(train_scaled, train_target)

train_score

 

🧤 테스트 데이터로 검증하기

  • 검증 또는 테스트 데이터를 스케일링 정규화 처리
  • 이때는 훈련에서 사용한 mean과 std 그대로 사용해야 함
test_scaled = (test_input - mean) / std
test_score = kn.score(test_scaled, test_target)
test_score

 

🧤 예측하기

kn.predict([new])

 

🧤 예측에 사용된 이웃 확인하고 시각화 하기

dist , indexes = kn.kneighbors([new])
indexes

 

🧤 이웃을 포함하여 산점도 그리기

plt.scatter(train_scaled[:, 0], train_scaled[:, 1], c="red", label="bream")
plt.scatter(new[0], new[1], marker='^', c="green", label="pred")
plt.scatter(train_scaled[indexes, 0], train_scaled[indexes, 1], c="blue", label="nei")
plt.xlabel("length")
plt.ylabel("weight")
plt.legend()
plt.show()

728x90
반응형
728x90
반응형

🐟 생선구분하기_K최근접이웃모델

데이터 처리

  • 빙어와 도미 데이터
  • 생선의 종류를 분류(구분)하기 위한 모델 생성을 위해 독립변수와 종속변수로 데이터를 가공해야함
  • 독립변수(x) : 길이, 무게
  • 종속변수(y) : 생선종류(빙어 또는 도미)

🐟 라이브러리

import matplotlib.pyplot as plt

 

🐟 데이터 불러오기

# - 도미 길이(cm)
bream_length = [25.4, 26.3, 26.5, 29.0, 29.0, 29.7, 29.7, 30.0, 
                30.0, 30.7, 31.0, 31.0, 31.5, 32.0, 32.0, 32.0, 
                33.0, 33.0, 33.5, 33.5, 34.0, 34.0, 34.5, 35.0, 
                35.0, 35.0, 35.0, 36.0, 36.0, 37.0, 38.5, 38.5, 
                39.5, 41.0, 41.0]

# - 도미 무게(g)
bream_weight = [242.0, 290.0, 340.0, 363.0, 430.0, 450.0, 500.0, 
                390.0, 450.0, 500.0, 475.0, 500.0, 500.0, 340.0, 
                600.0, 600.0, 700.0, 700.0, 610.0, 650.0, 575.0, 
                685.0, 620.0, 680.0, 700.0, 725.0, 720.0, 714.0, 
                850.0, 1000.0, 920.0, 955.0, 925.0, 975.0, 950.0]
                
# - 빙어 길이(cm)
smelt_length = [9.8, 10.5, 10.6, 11.0, 11.2, 11.3, 11.8, 11.8, 12.0, 12.2, 12.4, 13.0, 14.3, 15.0]

# - 빙어 무게(g)
smelt_weight= [6.7, 7.5, 7.0, 9.7, 9.8, 8.7, 10.0, 9.9, 9.8, 12.2, 13.4, 12.2, 19.7, 19.9]

 

데이터 분포 확인하기

🐟 도미 데이터 산점도 그래프 그리기 : scatter()

  • x축에는 길이, y축에는 무게
  • 길이가 길어질수록, 무게가 커질까?
plt.scatter (bream_length, bream_weight)
plt.xlabel("length")
plt.ylabel("weight")
plt.show()

 

해석

- 길이가 길어질수록 무게가 커지는 특징을 가지고 있음
- 분포의 방향은 양(+)의 상관관계를 나타내고 있음
- 양(+)의 상관관계를 우상향 분포라고 칭함

- 우상향 분포를 선형 형태라고도 칭함
- 모델을 분석하는 입장에서는 선형 형태를 나타낸다고 해석하     며, 선형형태에 대한 분석은 회귀분석을 사용한다.


 

 

  • 선형형태 = 회귀분석
    • 도미와 생선을 구분하기 위한 모델 사용
    • 구분 = 분류
    • 분류 모델을 이용해서 진행
    • 알고 있는 정보 : 길이, 무게, 생선 이름

🐟 빙어 데이터 산점도 그래프 그리기 : scatter()

  • x축에는 길이, y축에는 무게
  • 길이가 길어질수록, 무게가 커질까?
plt.scatter(smelt_length, smelt_weight)
plt.xlabel("length")
plt.ylabel("weight")
plt.show()

 

 

 

 

 

 

 

 

 

 

 

 

 

 

🐟 도미와 빙어의 분포 확인하기(산점도 그리기)

plt.scatter (bream_length, bream_weight, c="red", label="bream")
plt.scatter(smelt_length, smelt_weight, c="blue", label="smelt")
plt.xlabel("length")
plt.ylabel("weight")
plt.legend()
plt.show()

 

도미와 빙어 비교 해석
- 도미와 빙어 모두 우상향 분포를 나타내고 있음
- 도미 데이터는 경사가 급한 반면,  빙어 데이터는 경사가 완만하게 분포되어 있음

 

 

 


 

 

 

 

생선 분류하기(도미와 빙어 구분하기)

🐟 회귀분석의 분류모델을 사용

  • K최근접이웃 모델 사용
  • KNN : K최근접이웃모델
    • 머신러닝에서 가장 간단한 모델
    • 비교용으로 주로 사용되는 모델(실제 사용되기에는 성능이 약한 모델)
  • KNN 처리 방법 : 예측하고자 하는 값과 가장 가까운 이웃 갯수의 비율(또는 평균)을 이용하여, 비율이 가장 많은 쪽(다수결의 원칙을 따름)의 값으로 판단하는 방식

🐟 데이터 통합하기

  • 도미와 빙어 데이터를 각각 하나의 길이와 무게 데이터로 통합하기
# - 길이(length)
length = bream_length + smelt_length

# - 무게(weight)
weight = bream_weight + smelt_weight

len(length), len(weight)

 

🐟 데이터를 2차원 형식으로 변형

  • 이전의 length, weight는 1차원

  • 머신러닝에서 사용하는 데이터 차원은 2차원
  • 독립변수(길이와 무게) → 독립변수는 2차원 데이터 형태
  • 종속변수(생선 이름) → 종속변수는 1차원 데이터 형태

🐟 독립변수(길이와 무게) 생성하기

  • 2차원으로 생성 : [[길이, 무게], [길이, 무게], ...]
fish_data = [[l, w]for l, w in zip(length, weight)]
print(fish_data)
len(fish_data)

 

🐟 종속변수(생선이름) 생성하기

  • 1차원으로 생성 : ["도미", "도미", ..., "빙어"]
  • 종속변수로 사용하는 데이터 형태 : 정수형을 주로 사용
  • 범주 값의 갯수에 따라 : 0 ~ n 값을 사용
  • 이진분류 : 0 또는 1 사용
  • 다중분류 : 0 ~ n개 사용
  • (이진분류)도미 : 빙어 = 1 : 0
  • 이진분류에서는 찾고자 하는 값을 1로 정의하는 것이 일반적 개념
  •  다만, 어떤 값을 사용하여도 무관
fish_target = [1]*35 + [0]*14
print(fish_target)
len(fish_target)

 

모델 생성하기

from sklearn.neighbors import KNeighborsClassifier

 

🐟 분류모델(클래스) 생성시키기

kn = KNeighborsClassifier()
kn

 

모델 훈련(학습) 시키기

  • KNN은 지도학습 모델 : 독립변수와 종속변수 모두 사용
  • 훈련(학습) 시키는 함수 : fit()
kn.fit(fish_data, fish_target)

 

모델 정확도 확인하기

🐟 모델 훈련(학습)이 잘 되었는지 확인하는 절차

  • score() 정확도 확인하는 함수
  • 첫번째 값 : 예측하고자하는 값
  • 두번째 값 : 실제 정답
  • score()함수는 첫번째 값만 이용해서 훈련모델의 패턴에 적용하여 예측결과를 추출
  • 추출된 예측결과와 두번째 값(실제 정답)과 비교하여 얼마나 잘 맞추었는지 비교
kn.score(fish_data, fish_target)

 

해석

분류에서의 정확도 : 0 ~ 1 사이의 값이 출력됨

0 ~ 1 : 0% ~ 100%의 정확도를 의미함

💡(훈련에 사용한 데이터를 이용해서) 정확도를 확인 했을 때 1.0의 정확도는 과대적합이라고 칭함

 

🐟 예측 : 임의값으로 예측하기

  • 예측 : predict() 함수 사용
  • 예측 시에는 정답은 알려주지 않고, 문제만 넣어준다
  • 즉, 문제는 독립변수에 속하며, 2차원 데이터를 사용해야 한다.
  • 훈련에 사용된 독립변수 형태 그대로 사용해야 한다. await
kn.predict([[30, 600]])

 

1 = 도미로 예측

 

 

🐟 산점도 그리기

plt.scatter (bream_length, bream_weight, c="red", label="bream")
plt.scatter(smelt_length, smelt_weight, c="blue", label="smelt")
plt.scatter(30, 600,marker='^', c="green", label="pred")
plt.xlabel("length")
plt.ylabel("weight")
plt.legend()
plt.show()

 

해석

- 임의 예측 데이터가 분포한 위치를 통해서 시각적으로 확인가능

- 모델(클래스)이 사용하는 기본 이웃의 값은 5개를 기준으로 한다.

 

 

 


 

 

 

하이퍼파라메터 튜닝

🐟 하이퍼파라메터 튜닝

  • 모델 성능을 향상시키기 위한 방법
  • 과대적합 또는 과소적합이 일어난 경우 튜닝 진행

🐟 하이퍼파라메터

  • 모델(클래스)의 속성 중에 사람이 직접 값을 지정해 주어야하는 변수들을 통칭 한다.

🐟 KNN 모델 생성하기

  • n_neighbors : 이웃의 갯수(하이퍼파라메터 속성)
kn20 = KNeighborsClassifier(n_neighbors=20)

 

🐟 모델 훈련시키기

kn20.fit(fish_data, fish_target)

 

🐟 훈련 정확도 확인하기

kn20.score(fish_data, fish_target)

 

매우 좋은 성능을 보이는 모델이다라고 표현

 

🐟 예측하기

kn20.predict([[30, 600]])

 

🐟 튜닝 계속 진행

  • 방법1 : 이미 훈련은 되어있고 이웃의 갯수만 바꿔서 진행
# 1
kn20.n_neighbors = 40
kn20.score(fish_data, fish_target)

# 2 
kn20.n_neighbors = 15
kn20.score(fish_data, fish_target)

# 3
kn20.n_neighbors = 5
kn20.score(fish_data, fish_target)

 

  • 방법2 : 반복문 사용하여 1보다 작은 가장 좋은 정확도일 때의 이웃의 갯수 찾기
### 모델(클래스 생성)
kn = KNeighborsClassifier()
### 훈련시키기
kn.fit(fish_data, fish_target)

### 정확도가 가장 높을 떄의 이웃의 갯수를 담을 변수
nCnt = 0
###정확도가 가장 높을때의 값을 담을 변수
nScore = 0

# - 반복문 사용 : 범위는 3 ~ 전체 데이터 갯수
for n in range(3, len(fish_data), 2):
    kn20.n_neighbors = n
    score = kn20.score(fish_data, fish_target)
    print(f"{n} / {score}")

 

19일 때 가장 높은 정확도를 가짐

동일한 정확도일 때 이웃 갯수가 많을수록 PC과부하

그러므로 가장 갯수가 적은 19를 선택

 

 

 

 

 

 


for n in range(3, len(fish_data), 2):
    kn20.n_neighbors = n
    score = kn20.score(fish_data, fish_target)
    #print(f"{n} / {score}")

    ### 1보다 작은 정확도인 경우
    if score < 1 :
        ### nScore의 값이 score보다 작은 경우 담기
        if nScore < score : 
            nScore = score
            nCnt = n

print(f"nCnt = {nCnt} / nScore = {nScore}")

 

해석 : 모델의 성능이 가장 좋은 시점의 이웃의 갯수를 추출하기 위한 하이퍼파리메터 튜닝 결과, 이웃의 갯수 19개를 사용하였을 때가장 좋은 성능을 발휘하는 것으로 확인 됨

 

🐟 최종 모델 검증

kn.n_neighbors = nCnt
kn.score(fish_data, fish_target)

kn.predict([[10, 30]])

728x90
반응형
728x90
반응형

🎄 Machine Learning 개요

🎄 Machine Learning이란?

  • 알고리즘(algorithms) : 어떠한 문제를 해결하기 위한 일련의 절차나 방법
  • 유튜브는 개인이 유튜브 영상을 보는 패턴에 대해 학습하는 프로그램(머신러닝)을 만든 다음 그 패턴(알고리즘)에 맞게 다음 영상을 계속 추천해 준다.
  • 머신러닝을 통해 데이터를 훈련시켜서 패턴을 파악한다. 그 후 파악되는 패턴을 통해 미래를 예측하는 방법을 사용한다.
  • 머신러닝이 필수인가? 데이터를 분석할 때 머신러닝을 사용하는 회사가 존재한다.
    • 설문조사(리서치) 회사 - 탐색적 데이터 분석을 통해 데이터의 인사이트 도출,  파이썬을 통해 예측
    • 데이터 분석 및 예측  회사 - 데이터의 흐름을 가지고 미래 예측. 예를 들어, 기상청은 지형지물에 대한 영상을 보고 어떠한 형태인지 파악 후 미래 날씨 예측
    • 영상에서 통해 수집되는 행위분석(이미지분석) 회사 - 딥러닝, CCTV를 통해 물건을 훔치는 모션이 정보로 들어오면 스스로 신고하게하는 행위

  • 인공지능 :  스스로 학습하고 스스로 판단하게 하는 능력을 가지는 것으로 인공지능으로 가려면 데이터 분석이 필요하다.
  • ICBMS : 4차 산업을 이끄는 핵심기술 (IoT / Cloud / Big Data / Mobile / Security)
  • 사이킷런(scikit-learn) : 머신러닝 프레임워크, 실제 머신러닝 모델을 생성하고 데이터에 적용할 수 있도록 도와주는 도구

  • 머신러닝(machine learning) : 기계가 패턴을 학습하여 자동화하는 알고리즘, 데이터를 컴퓨터에 학습 시켜 그 패턴과 규칙을 컴퓨터가 스스로 학습하도록 만드는 기술
    • 이전에는 사람이 지식을 직접 데이터베이스화한 후 컴퓨터 가 처리하도록 프로그램으로 만듦
    • 머신러닝은 데이터를 분류하는 수학적 모델을 프로그래밍 하여, 데이터만 입력하면 이미 만들어진 수학 모델이 규칙으로 적용되어 여러 문제를 풀 수 있음
  • 딥러닝(deep learning) : 머신러닝 기법 중 신경망(neural network)을 기반으로 사물이나 데이터를 군집화하거나 분류하는데 사용하는 기술
  • 인공지능 ⊃ 머신러닝 ⊃ 딥러닝

 

 

🎄머신러닝의 학습 프로세스와 종류

 

  • 모델과 알고리즘
    •  ‘모델’은 ‘수식’이나 ‘통계 분포’, ‘알고리즘’은 모델을 산출하기 위해 규정화된 과정(훈련과정 = 학습)
    • 보통 하나의 모델은 다양한 알고리즘으로 표현할 수 있다
    • 때때로 ‘알고리즘’은 하나의 ‘수식’으로 표현 가능하다

  • 그림 1 : 모델을 훈련시킨다.
    • 원천데이터 전처리 가공 후 머신러닝이라는 알고리즘에 넣어줌(라이브러리 활용, 라이브러리에는 계산 공식이 들어 있음 ) > 넣어준 데이터를 가지고 훈련시킴 > 훈련을 통해 가장 정확한 것 같은 패턴을 파악 
    • 선형예측, 회귀예측, 분류예측

  • 머신러닝의 종류(데이터 종류)
    • 지도학습(supervised learning) : 문제와 답을 함께 학습
    • 비지도학습(unsupervised learning) : 조력자의 도움 없 이 컴퓨터 스스로 학습. 컴퓨터가 훈련 데이터를 이용 하여 데이터들 간의 규칙성을 찾아냄
    • 실제 답(ground truth) 의 존재 여부에 따라 구분

x = 넣어준 데이터(문제, 독립변수)

y = 문제에 대한 답으로 구성된 데이터(정답, 종속변수)

x와 y 사이의 패턴 파악
새로운 x값을 넣어주면, 스스로 y값을 도출해냄


  • 회귀(regression)
    • 독립변수 x와 종속변수 y의 관계를 함수식으로 설명
    • 추세선을 표현하는 수학적 모델을 만드는 기법
    • 사용하는 데이터 : 연속형 데이터(나이, 키, 몸무게)


우상향, 선형
x(키), y(몸무게) 값을 넣어줌.
a, b를 대표하는 값을 찾아내기 위해 컴퓨터를 훈련시킴.
빨간색 = 추세선 알아내고 x 값을 넣었을 때 y값을 도출해냄

 


  • 분류(classification)
    • 데이터를 어떤 기준(패턴)에 따라 나눔
    • 이진분류(binary classification) : 2개의 값 중 1개를 분류 
    • 다중분류(multi-class classification) : 3개 이상 분류 실행
    • 사용하는 데이터 : 범주형 데이터(성별, 형태를 구분하는 것)


x(키), y(몸무게)의 패턴값을 확인해서 분포를 확인.
스스로 학습하여 확률적으로 패턴확인.
그리고 구분선(빨간색)을 그려 분류하고 성별을 분류하여 알아냄 

 


 

  • 군집(clustering)
    • 기존에 모여 있던 데이터에 대해 따로 분류 기준을 주지 않고 모델이 스스로 분류 기준을 찾아 집단을 모으는 기법
    • 비슷한 수준의 농구팀 3개 만들기
    • 사용하는 데이터 : 연속형 / 범주형 데이터
    • 비지도 학습은 분류를 하기 위해 사용하기 때문에 대부분 범주형 데이터를 주로 사용

 

집단을 나누는 것.

집단의 갯수는 따로 지정할 수 있음.

갯수에 대한 범주를 스스로 만들어 군집을 만들어 냄

중복되는 부분(이상데이터)은 해소시켜줘야 함

     > 데이터를 제거? 추가? 추가한다면 어느 군집으로 넣을 것인가? 


 

 

🐟 Machine Learning 실습

🐟 생선구분하기_K최근접이웃모델

  • 데이터 처리
    • 빙어와 도미 데이터
    • 생선의 종류를 분류(구분)하기 위한 모델 생성을 위해 독립변수와 종속변수로 데이터를 가공해야함
    • 독립변수(x) : 길이, 무게
    • 종속변수(y) : 생선종류(빙어 또는 도미)

 

  • 훈련모델 처리 절차
    1. 데이터 전처리
    2. 데이터 정규화
    3. 훈련 : 검증 : 테스트 데이터로 분류 (또는 훈련 : 테스트 데이터로 분류)
      >>  6 : 2 : 2 또는 7 : 2 : 1, 데이터가 적은 경우에는 8 : 2 또는 7 : 3 정도로 분류
    4. 모델 생성
    5. 모델 훈련(fit) (훈련 데이터와 검증 데이터 사용, 또는 테스트 데이터)
    6. 모델 평가 (모델 선정, 검증데이터)
    7. 하이퍼파라미터 튜닝
    8. 5번 ~ 6번 진행
    9. 최종 테스트(예측, predict) (테스트 데이터 또는 새로운 데이터로 사용)

 

 

I want to be good at machine learning!

 

728x90
반응형

+ Recent posts