AI 부트캠프 - 9일차

Cookie Baking·2024년 10월 14일

AI 부트 캠프 TIL

목록 보기
9/42

1. 머신러닝

컴퓨터가 명시작으로 프로그래밍 되지 않아도 데이터를 통해 예측할 수 있도록 하는 기능

머신러닝 구성요소

1. 데이터 셋

  • 80% -> 학습에 사용, 규칙을 뽑아냄 / 20% -> 테스트에 사용

2. Feature (특징)

  • 데이터에서 모델이 학습할 수 있는 개별 속성

3. 레이블

  • 예측하고자 하는 목표 변수
  • 지도학습 모델에서는 레이블이 있는 데이터셋을 이용하여 모델을 학습시킴

4. 모델

  • 데이터의 특징으로부터 정답(레이블)을 예측할 수 있는 지식을 학습할 수 있는 프로그램/함수
  • 입력데이터와 출력 데이터 간의 관계를 학습하여 새로운 데이터에 대한 예측 수행

5. 학습

  • 모델이 데이터를 통해서 패턴을 인식하고, 이를 기반으로 예측을 수행할 수 있도록 함수 내의 가중치를 조절하는 과정

머신러닝의 학습

데이터 수집 -> 데이터 전처리 -> 특징 선택 -> 모델 선택 -> 모델 훈련 -> 모델 평가 -> 모델 배포

모델 평가 후 성능을 높이기 위해 사이클적으로 개선하는 과정을 거치게 된다.
즉 계속해서 학습을 통해 개선되는 시스템임

학습 방법

  1. 지도 학습 (Supervised Learning)
    레이블 (정답)이 있는 데이터셋을 이용하여 모델을 학습시키는 방법
    회귀 : 연속적인 값을 예측하는 문제
    - ex. 주택 가격 예측, 주식 가격 예측
    분류 : 이산적인 값을 예측하는 문제

2. 비지도 학습
레이블 (정답)이 없는 데이터셋을 이용하여 모델을 학습시키는 방법

  • 군집화 (Clustering) : 데이터를 유사한 그룹으로 묶는 문제
  • 차원 축소 : 고차원 데이터를 저차원으로 변환

3. 앙상블 학습
여러개의 머신러닝 모델을 결합하여 더 나은 성능을 얻는 방법

  • 배깅 : 여러 모델을 독립적으로 학습시키고, 예측을 평균내거나 다수결 투표로 최종 예측
    - ex. 랜덤포레스트

  • 부스팅 : 여러 모델을 순차적으로 학습시키고, 이진 모델의 오차를 보완하여 최종 예측을 수행
    - ex. 그래디언트 부스팅, XGBoost

  • 스태킹 (Stacking) : 여러 모델을 학습시키고 예측 결과를 새로운 데이터로 사용하여 메타 모델을 학습

  • 여러 개의 지도 학습을 모아놓은 것도 앙상블 기법에 해당함


PREPARE

  1. 가상환경 준비 : conda 로 venv 실행

# 가상환경 만들기
conda create --name myenv
# 가상환경 활성화
conda activate myenv
# 필요 패키지 설치
conda install jupyter numpy pandas
# 가상환경과 Jupyter 연결
python -m ipykernel install --user --name={연결할 가상환경} --display-name "가상환경에서부를 이름"
  1. 라이브러리 설치 : pip로 가상환경 activated 상태에서 필요한 라이브러리 설치
  • Numpy 주요 기능 : 다차원 배열 객체를 생성하고 조작할 수 있음, 벡터와 연산을 가능하게 해줌, 수학 함수를 제공함

  • Pandas 주요 기능 : 데이터 프레임 (테이블) 형태의 데이터를 생성하고 조작할 수 있음, 데이터 불러오기 및 저장, 데이터 조작 (그룹화, 병합 등)

  • 근데 seaborn은 Jupyter Notebook에서 %pip install seaborn을 해야 함

# 데이터를 확인할 수 있는 유용한 코드 (데이터를 불러온 후에 사용하면 좋겠음)

# 1. 데이터 프레임의 첫 5행 출력
df.head()

# 2. 데이터 프레임의 컬럼명 확인
df.columns

# 3. 데이터 프레임의 데이터 타입 확인
df.dtypes

# 4. 데이터 프레임의 컬럼명 확인
df.columns

# 5. 특정 컬럼 선택
df['특정 컬럼명']
  • Scikit-learn 라이브러리 : 머신러닝을 위한 Python 라이브러리, 이미 내부적으로 알고리즘이 결정되어 있는 것이 특정 (머신러닝에 적합, 직접 구조화를 해야 하는 딥러닝에는 부적합)

  • Pandas는 데이터 전처리를 할 때 주로 사용하며, Scikit-learn은 ML에서의 전처리를 할 때 주로 사용한다. 즉, 둘 다 사용한다는 말이다.


데이터 로드 방법

1. Kaggle 사용한 방법

  1. Kaggle API 설치
pip install kaggle
  1. Kaggle API 키 설정
  • https://www.kaggle.com/settings Kaggle 계정에서 API 키 생성
  • 생성된 API키는 다운로드 디렉터리에 위치해 있는데 이를 ~/.kaggle 디렉터리 생성 후 하위로 옮긴다.
    - mkdir -p ~/.kaggle
  1. 데이터셋 다운로드
!kaggle datasets download -d <dataset-indentifier>

# 예시 데이터셋
!kaggle competitions download -c titanic

# 압축해제 + 데이터 해당 디렉터리로 옮기기 + 압축 전 zip 파일 삭제
# 그렇다면 해당 디렉터리 하위에 파일들이 생성된 것을 확인할 수 있다.
!mkdir target_directory && unzip titanic.zip -d target_directory && rm titanic.zip

2. seaborn 사용한 방법 (내장 데이터 셋 로드)

  • train 데이터와 test 데이터를 직접 나눠줄 필요가 있는지 확인해야 한다.
import seaborn as sns

# 데이터 로드
titanic = sns.load_dataset('titanic')

# 필요한 열 선택 및 결측값 처리
titanic = titanic[['survived', 'pclass', 'sex', 'age', 'sibsp', 'parch', 'fare', 'embarked']].dropna()

# 인코딩 (성별과 탑승한 곳) : 각자 다른 범위로 인코딩을 해주었기 때문에 나중에 문제가 생길 수도 있으니 주의할 것
titanic['sex'] = titanic['sex'].map({'male': 0, 'female' : 1})
titanic['embarked'] = titanic['embarked'].map({'C': 0, 'Q': 1, 'S': 2})

# 특성과 타겟 분리
# surivived를 예측할 종속변수이기 때문에 훈련할 데이터 셋인 X에서 분리를 한다
X = titanic.drop('survived', axis=1)
y = titanic['survived']


# 여기서부터는 모델 선택만 제외하고는 반복되는 부분이라고 생각하면 된다.
# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 데이터 스케일링
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# 회귀 모델 생성 및 학습
model = LogisticRegression()
model.fit(X_train, y_train)

# 예측 
y_pred = model.predict(X_test)

# 평가
print(f"Accuracy: {accuracy_score(y_test, y_pred)}")
print(f"Classification Report:\n{classification_report(y_test, y_pred)}")
print(f"Confusion Matrix:\n{confusion_matrix(y_test, y_pred)}")

데이터 전처리

결측치 처리
결측치는 데이터셋에 누락된 값을 의미함
결측치를 처리하지 않으면 모델의 성능이 저하될 수 있음

  • 삭제 : 결측치가 있는 행이나 열을 삭제함 -> 이는 결측치가 적을 때 유용하지만, 데이터 손실이 발생할 수 있음
  • 대체 : 평균, 중앙값, 최빈값 등으로 결측치를 대체함
  • 예측 : 다른 특성을 사용하여 결측치를 예측하고 채움
# 삭제 (dropna) : NaN이 포함되어 있는 행이 있을 때 삭제해버림 / 열 단위로 하고 싶다면 axis=1로 설정 
df_dropped_cols = df.dropna(axis=1)

# 대체 (fillna) : 평균 값으로 대체 / 주의해야 할 점은 바꾸려는 값의 type이 일치하는지 확인해야 한다는 점이다.
df_filled_mean = df.fillna(df.mean())
# 결측값을 각 열의 최빈값으로 대체
df_filled_mode = df.fillna(df.mode().iloc[0])

이상치 처리
이상치는 데이터에서 비정상적으로 크거나 작은 값을 의미함
이상치는 모델의 성능을 저하시킬 수 있음

  • 제거 : 이상치를 데이터셋에서 제거함
  • 변환 : 이상치를 다른 값으로 변환함 (ex. 상한선이나 하한선으로 대체)
  • IQR 방법 : IQR (Interquartile Range)을 사용하여 이상치를 탐지하고 처리함
    - 총 범위의 하위 25% 와 상위 75% 를 초과하는 범위를 이상치라고 판단하는 방법이라고 처리함
# 제거

# 중복된 행 확인
print(df.duplicated().sum())
# 중복된 행 제거
df_no_duplicates = df.drop_duplicates()

# 변환

# 평균으로 대체
mean_value = df['column_name'].mean()
df['column_name'] = df['column_name'].apply(lambda x: mean_value if x < lower_bound or x > upper_bound else x)

# 실제로는 타입변환보다는 인코딩을 사용한다고 함

# IQR
# 사용하는 실제 방법은 
# 1. lower_bound & upper_bound 확인
# 2. print
# 3. outlier 확인

Q1 = df['C'].quantile(0.25)
Q3 = df['C'].quantile(0.75)

IQR = Q3 - Q1

lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

print(lower_bound)
print(upper_bound)

outliers = df[(df['C'] < lower_bound) | (df['C'] > upper_bound)]
# print(outliers)

df_no_outliers = df[(df['C'] >= lower_bound) & (df['C'] <= upper_bound)]

df_no_outliers

데이터 정규화
정규화는 데이터를 일정한 범위로 스케일링하는 과정임
일반적으로 [0,1] 범위로 변환함

데이터 표준화
표준화는 데이터를 평균 0, 분산 1로 변환하는 과정임
-> 데이터가 안정된 상태에서 믿을 수 있는 범위에 있어서 머신러닝 모델이 학습이 잘되게 이끔
ex. z-점수 표준화

특성공학
특성 공학은 데이터로부터 새로운 유용한 특성을 생성하는 과정임

  • 특성 생성 : 기존 데이터를 기반으로 새로운 특성을 생성함
  • 특성 선택 : 모델 성능에 중요한 특성을 선택하고, 중요하지 않은 특성은 제거함

데이터 인코딩
비정형 데이터를 모델이 이해할 수 있는 형태로 변환함

  • 레이블 인코딩 : 범주형 데이터를 숫자로 변환함
  • 원/핫 인코딩 : 범주형 데이터를 이진벡터로 변환함

데이터 분할
데이터를 학습용(train), 검증용(validation), 테스트용(test) 으로 분할함
이를 통해 모델의 일반화 성능을 평가할 수 있음

  • 샘플링 : 데이터셋의 크기를 줄이거나 늘리는 과정을 말함, 데이터셋의 대표성을 유지하면서 데이터의 크기를 조절하는 데 사용 (전체에서 특정 %만을 뽑아내고 싶다면 frac 옵션을 이용할 것)
# 데이터셋에서 50% 샘플 추출
df_sampled = df.sample(frac=0.5)

# 데이터셋에서 100개의 샘플 추출
df_sampled_n = df.sample(n=100)

지도 학습

회귀 모델 : 연속적인 값을 예측하는 모델, 주로 숫자 값을 예측하는 데 사용됨

  • ex. 부동산 가격 예측, 자동차 연비 예측
    분류 모델 : 범주형 또는 이산적인 값을 예측하는 모델, 주로 클래스 (또는 라벨)를 예측하는 데 사용됨
  • ex. 질병 진단, 이미지 분류

회귀 모델

선형 회귀

  • 선형 회귀는 종속 변수와 하나 이상의 독립 변수 간의 선형 관계를 모델링하는 방법임
  • 독립 변수의 수에 따라 단순 선형회귀 (독립 변수의 수는 1개)와 다중 선형회귀 (독립 변수의 수가 2개 이상)으로 나뉨

선형 회귀 - 다항 회귀

  • 다항 회귀는 종속 변수와 독립 변수 간의 비선형 관계를 모델링하는 방법임
  • 독립변수의 다항식을 사용하여 관계를 모델링 함
  • 차수 선택 : 차수가 높을수록 복잡해지며 과적합이 발생할 가능성이 높아지게 됨

# 필요한 모듈
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
# 선형 회귀
from sklearn.linear_model import LinearRegression
# 모델 평가를 위함
from sklearn.metrics import mean_squared_error, r2_score

# 단순 선형 회귀 데이터 생성 
X = np.array([[1, 1], [2, 2], [3, 3], [4, 4], [5, 5],[6,6]])
y = np.array([1, 2, 3, 4, 5, 6])

# 데이터 분할 (훈련 데이터와 테스트 데이터)
# 독립 변수인 x는 대문자로 표기하고 종속 변수인 y는 소문자로 표시하는 것이 관습인 것 같음
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 선형 회귀 모델 생성 -> skikit - learn 을 이용함
model = LinearRegression()
# 모델 학습 : 독립변수 (X)와 종속 변수 (y)의 관계를 파악하는 것이 최종 목적임에 잊지 말자
model.fit(X_train, y_train)

# 예측 -> 독립변수를 인자로 넣어줘 그에 따른 종속 변수를 내뱉게 함
y_pred = model.predict(X_test)

# 모델 평가 -> pred한 값과 종속변수의 test 데이터와 비교함
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

print(f'Mean Squared Error: {mse}')
print(f'R^2 Score: {r2}')


# 다항 회귀

# 1. import 문에 다항 특징 생성을 위한 PolynomialFeatures import 
from sklearn.preprocessing import PolynomialFeatures

# 2. 다항 특징 생성 (차수 2)
poly = PolynomialFeatures(degree=2)
X_poly = poly.fit_transform(X)

# 데이터 분할 (X_poly로 해줘야...), 다항 회귀 모델 생성 및 학습, 예측, 모델 평가
# 선형 회귀 모델 생성 및 학습
# 예측
# 모델 평가
       

로지스틱 회귀

로지스틱 회귀는 데이터를 학습하여 각 데이터 포인트가 특정 클래스에 속할 확률을 예측함
예를 들어, 유방암 데이터에서는 환자가 암에 걸렸을 확률, 타이타닉 데이터에서는 승객이 생존할 확률을 예측함

비용 함수

  • 로지스틱 회귀의 비율 함수는 모델의 예측 확률과 실제 레이블 사이의 차이를 측정함
  • 로그 손실 함수 또는 크로스 엔트로피 손실함수라고 함
  • 확률이 1에 가까울 수록 잘 예측한 것임
  • 데이터 로드 및 전처리
import numpy as np
import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# 데이터 로드
data = load_breast_cancer()
X = data.data
y = data.target

# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 이러고 X_train과 X_test의 값들을 살펴보았는데
[[9.029e+00 1.733e+01 5.879e+01 ... 1.750e-01 4.228e-01 1.175e-01]
 [2.109e+01 2.657e+01 1.427e+02 ... 2.903e-01 4.098e-01 1.284e-01]
 [9.173e+00 1.386e+01 5.920e+01 ... 5.087e-02 3.282e-01 8.490e-02]
 ...
 [1.429e+01 1.682e+01 9.030e+01 ... 3.333e-02 2.458e-01 6.120e-02]
 [1.398e+01 1.962e+01 9.112e+01 ... 1.827e-01 3.179e-01 1.055e-01]
 [1.218e+01 2.052e+01 7.722e+01 ... 7.431e-02 2.694e-01 6.878e-02]]
[[1.247e+01 1.860e+01 8.109e+01 ... 1.015e-01 3.014e-01 8.750e-02]
 [1.894e+01 2.131e+01 1.236e+02 ... 1.789e-01 2.551e-01 6.589e-02]
 [1.546e+01 1.948e+01 1.017e+02 ... 1.514e-01 2.837e-01 8.019e-02]
 ...
 [1.152e+01 1.493e+01 7.387e+01 ... 9.608e-02 2.664e-01 7.809e-02]
 [1.422e+01 2.785e+01 9.255e+01 ... 8.219e-02 1.890e-01 7.796e-02]
 [2.073e+01 3.112e+01 1.357e+02 ... 1.659e-01 2.868e-01 8.218e-02]]
# 이 처럼 그 차이가 꽤나 있음을 확인할 -> Scaling으로 범위 차이를 줄어주어야 함


# 데이터 스케일링
scaler = StandardScaler()
# 학습 데이터에 한해서는 "학습"이 변환과 함께 들어가야 하기 때문에 fit_transform이 쓰인 것이고 
# 테스트 데이터에 한해서는 변환만 시도되어도 괜찮기 때문에 transform만 쓰이게 된다.
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# 회귀모델 학습
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix

# 모델 생성 및 학습
model = LogisticRegression()
model.fit(X_train, y_train)

# 예측
y_pred = model.predict(X_test)

# 평가
# accuracy_score : 정확도 계산
print(f"Accuracy: {accuracy_score(y_test, y_pred)}")
# classificaton_report : 분류 보고서 생성
# 정확도, 정밀도, 재현율 등의 매트릭을 포함한 보고서를 출력함 
print(f"Classification Report:\n{classification_report(y_test, y_pred)}")
# confusion_matrix : 혼동 행렬 생성 (실제 값과 예측 값 간의)
print(f"Confusion Matrix:\n{confusion_matrix(y_test, y_pred)}")

헷갈렸던 개념
Clustering? : 군집화를 말함
Scaling? : 범위가 다른 두 데이터를 범위를 맞춰주는 작업을 말함

  • 처음에는 학습과 테스트 데이터의 결과가 차이가 많이 날 때 사용하나 했으나 그게 아니라
    학습 데이터 내에서 이상치가 많은 경우일 때 많이 사용한다고 한다

0개의 댓글