Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

여유로움

[11.28 일] 빅데이터 분석기사 실기 - Machine Learning (10~12강) 회귀분석, 파생변수 생성, 스케일러 사용 본문

셀프스터디/빅데이터 분석기사

[11.28 일] 빅데이터 분석기사 실기 - Machine Learning (10~12강) 회귀분석, 파생변수 생성, 스케일러 사용

티로즈 2021. 11. 28. 19:34

[개념복습]

회귀 분석 (지도학습)

: 독립변수(X)와 종속변수(Y) 간 관계를 분석하는 모델

선형 회귀(Linear Regression) 로지스틱 회귀(Logistic Regression)
[개념] 변수 feature 간의 선형 관계로 예측 값 추측.
실제 값과 가장 오차가 작은 유일한 직선을 찾음
X, Y가 이항분포를 이룰 때
종속변수가 범주형(선형회귀와 다른 특징)
[활성화 함수] 선형 함수 시그모이드 함수(0 또는 1 출력)_이진 로지스틱 회귀
소프트맥스(결과 값 합이 1)_여러 개를 분류할 때
(독립변수 1개) 단순 선형회귀,
(독립변수 2개 이상) 다중 선형회귀 
다항 로지스틱 회귀(범주가 2개 이상일 때)
[관련개념] 최소 제곱법(일차함수 기울기, 절편을 알아냄)
경사하강법(해당 함수의 최소값 위치를 찾기 위해 비용(손실)함수의 기울기 반대 방향으로 정의한 step size를 가지고 조금씩 움직여가면서 최적의 파라미터를 찾으려는 방법)
[관련개념] 최대 우도 측정법(시그모이드 함수를 최적화 하는 방법)

회귀모델 성능평가 지표

  • MSE(Mean Squared Error, 평균 제곱 오차) : 실제 값과 예측 값 사이의 차이를 제곱하여 더한 값
  • RMSE(Root MSE)

1. 이항분류

  • 합격/불합격 판정
  • 3과목의 평균 60점 이상 합격, 과락 40점미만
# 사용할 라이브러리 import 
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
# sample로 사용할 DataSet을 생성하는 함수 작성
# X: 국어, 영어, 수학 점수
# Y: 합격여부 (X의 평균 60이상, 과락 40점 미만)

# seedno : 랜덤 수 생성 규칙
# size : 랜덤 수 생성 행의 수
# step=0 (균형), step=다른수 (불균형)
seedno = 1234
size = 20000
colnames=['국어','영어','수학']
np.random.seed(seedno)
A = np.random.randint(0,101,(size,3))
df = pd.DataFrame(A, columns=colnames)
df['합격여부'] = (df.mean(axis=1) >= 60) & (df.min(axis=1)>=40)
df['합격여부'].value_counts()
F, T = df['합격여부'].value_counts()

B = np.random.randint(60,101,(F-T,3))
df2 = pd.DataFrame(B, columns=colnames)
df2['합격여부'] = True

df = pd.concat([df, df2])

df['합격여부'].value_counts()
df.index = pd.RangeIndex(len(df))
df['합격여부'] = df['합격여부'].replace({True:1False:0})
df #합/불합 비율이 같은 테스트set 완성
# 균형 데이터
data = make_sample(12341000)
data['합격여부'].value_counts()
# 불균형 데이터
data = make_sample(12341000, step=1)
data['합격여부'].value_counts()
#1) X, Y 데이터 분리

Y = data['합격여부']
X = data.drop(columns=['합격여부']) #합격여부(결과값=Y)만 제외한 모든 컬럼을 사용할 때 사용

#2) 학습, 평가 데이터로 분리
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, stratify=Y, random_state=0)

#3) 분리된 데이터의 shape 출력
print([x.shape for x in [x_train, x_test, y_train, y_test]])

#4) 학습 모델 선택 및 학습
model = LogisticRegression(max_iter=1000#반복횟수 1000번
model.fit(x_train, y_train) 

#5) 성능 평가 (과대적합 여부 확인)
print('train 성능: ', model.score(x_train, y_train))
print('test 성능; ', model.score(x_test, y_test))

 

2. 데이터의 중요성 : 충분한 데이터가 중요한 이유

# 균형 데이터   # 1234, 1225, 1245
for no in [123412251245] :
    model1 = LogisticRegression(max_iter=1000)
    data = make_sample(seedno=no, size=20000)
    ModelTrain(model1, data)

# 불균형 데이터
for no in [123412251245] :
    model2 = LogisticRegression(max_iter=1000)
    data = make_sample(seedno=no, size=32000, step=1)
    ModelTrain(model2, data)

# 부족한, 불균형 데이터 # 1234, 1225, 1245
for no in [123412251245] :
    model4 = LogisticRegression(max_iter=1000)
    data = make_sample(no, 60, step=1)
    ModelTrain(model4, data)

 

3. 파생변수 생성 및 사용

  • 합격/불합격 여부를 결정하는 평균, 과락에 관련된 파생변수를 추가하여 봅니다.
# 데이터 생성
data = make_sample(seedno=1245, size=20000)
data.head(2)

# 파생변수 생성/추가
data['평균'] = data[['국어''영어''수학']].mean(axis=1)
data['최저'] = data[['국어''영어''수학']].min(axis=1)
data.head(2)

for no in [123412251245] :
    model5 = LogisticRegression(max_iter=1000)
    data = make_sample(seedno=no, size=20000)
    data['평균'] = data[['국어''영어''수학']].mean(axis=1)
    data['최저'] = data[['국어''영어''수학']].min(axis=1)
    ModelTrain(model5, data)

# 모든 값을 사용한 예측 결과
def make_all():
    colnames = ['국어''영어''수학']
    data = [[kor, eng, mat] for kor in range(101for eng in range(101for mat in range(101)]
    data = pd.DataFrame(data, columns=colnames)
    data['평균'] = data[['국어''영어''수학']].mean(axis=1)
    data['최저'] = data[['국어''영어''수학']].min(axis=1)
    data['합격여부'] = (data['평균'] >=60) & (data['최저'] >= 40)
    data['합격여부'] = data['합격여부'].replace({True:1False:0})  # 합격:1, 불합격:0
    return data

data = make_all()
X1 = data.iloc[:, :3]
X2 = data.drop(columns=['합격여부'])
Y = data['합격여부']
print(Y.value_counts())

for x in model1, model2, model3, model4:
    print(x.score(X1, Y))
print(model5.score(X2, Y)) 

 

4. 스케일러 사용

for no in [123412251245] :
    model6 = LogisticRegression(max_iter=1000)
    data = make_sample(seedno=no, size=20000)
    data['국어'] *= 500
    data['수학'] *= 1000
    ModelTrain(model6, data)
# StancardScaler 사용하여 정규 분포 만들기
from sklearn.preprocessing import StandardScaler

for no in [123412251245]:
    model7 = LogisticRegression(max_iter=1000) #모델 생성(로지스틱 회귀)
    data = make_sample(seedno=no, size=20000)
    data['국어'] *= 500
    data['수학'] *= 1000    
    X = data[['국어''영어''수학']]
    Y = data['합격여부']
    scaledX = StandardScaler().fit_transform(X)
    scaledX = pd.DataFrame(scaledX, columns=['국어''영어''수학'])
    data = pd.concat([scaledX, Y], axis=1)
    ModelTrain(model7, data)