KT에이블스쿨 5기/DX컨설턴트

머신러닝/딥러닝을 이용한 데이터분석 프로젝트 프로세스

ryuming 2024. 4. 22. 17:07

[KT에이블스쿨 5기 DX] 머신러닝/딥러닝을 이용한 데이터분석 프로젝트 프로세스 

 

오늘은 KT에이블스쿨 DX 5차 미니프로젝트에 시작하기 앞서

일반적인 데이터분석 프로젝트에서의 흐름을 

자주쓰이는 코드와 함께 소개해드리려고합니다 !!



1. 주제에 대한 도메인 지식 검색

예를들어 '개인별 토익성적 데이터를 활용한 토익점수 상승 솔루션' 이라는 주제로 프로젝트를 진행한다고 합시다.

이때 토익 시험이 어떤 시험인지조차 모르고 데이터 분석을 한다면, 과연 유의미한 결과를 도출해낼 수 있을까요?

추후에 도메인 지식을 더 알아보더라도 최소한 프로젝트의 주제와 각각의 변수가 무엇을 의미하는 정도는 알 수 있어야합니다. 도메인이 지식이 중요한 더 자세한 이유는 제가 이전에 포스팅한 글을 첨부하겠습니다.

 

2024.04.10 - [KT에이블스쿨 5기/DX컨설턴트] - 프로젝트 성공을 위한 필수 요소 '도메인지식' , 그리고 중요성

 

프로젝트 성공을 위한 필수 요소 '도메인지식' , 그리고 중요성

프로젝트 성공을 위한 필수 요소 '도메인지식' , 그리고 중요성 어제 드디어 KT에이블스쿨 5기 DX과정의 3번째 미니프로젝트가 끝났습니다~~!! 프로젝트를 진행하면 진행할수록 뼈저리게 느끼는

cattower.tistory.com

 


2. 필요한 라이브러리 설치 및 로딩

!pip install numpy pandas matplotlib seaborn scikit-learn tensorflow
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import StandardScaler, LabelEncoder
from tensorflow import keras

 

일반적으로 많이 쓰이는 라이브러리 이정도는 외워서 치기 😉

난 아직 못외움..

 


 

3. 데이터 로딩 및 확인

df = pd.read_csv('your_data.csv')
df.head()
df.tail() 
df.shape #행/열을 튜플형태로 반환
df.info() #정보(컬럼정보, Null 여부, 타입,데이터수)
df.index #인덱스 ()는 꼭 빼기
df.columns #구성하는 칼럼명
df.dtypes #데이터형태와 종류
df.values #값
df.describe() #요약통계량 .T 옵션으로 경우에 따라 더 편하게 보기 가능
df.isna().sum() # NULL값의 합 확인
df['컬럼이름'] #특정컬럼보기
df['컬럼이름'].value_counts() #특정컬럼의 데이터별 건수

#컬럼명 변경
df=df.rename(columns = {'이전컬럼명':'바꿀컬럼명','이전컬럼명2':'바꿀컬럼명2')

#정렬
df=df.sort_values(by = '기준컬럼', ascending=False) #ascending=True는 오름차순

 

데이터를 로딩하고 이정도는 필수적으로 확인해줍시다 

구조와 타입에 따라 후에 분석방법이 달라지니까요!

 

(추가) 데이터 저장방법 
#csv로 저장
df.to_csv('저장할이름.csv', index=False) 

#엑셀로저장
df.to_excel('processed_data.xlsx', index=False) 

#데이터베이스에 저장
import sqlite3
conn = sqlite3.connect('my_data.db')
df.to_sql('processed_data', conn, if_exists='replace', index=False)

#파이썬 객체로 저장 (Pickle)
import pickle
with open('model.pkl', 'wb') as file:
    pickle.dump(df, file)

 


 

4.데이터 결측치 처리 

결측치처리에 따라 추후 결과값이 아예 다르게 나와버리기때문에 매우매우 중요합니다

결측치 처리 방법에 앞서 데이터를 선택할때 많이 사용하는 loc와 iloc의 차이를 간단하게 표로 보여드리겠습니다(아래 코드에는 안썼습니다)

loc(location) iloc(integer location)
데이터프레임의 행이나 열에 대해 레이블로 접근 데이터프레임의 행이나 열에 인덱스 값으로 접근
인덱스 및 칼럼명을 통해 지정하는 방법 인덱스를 활용해 지정하는 방법
설정한 인덱스를 그대로 사용 0 based index로 사용

 

#의미없는 '_'와 같은 값이 많은 컬럼은 삭제 (ex : '_'값이 40%이상인 컬럼 삭제)
df.drop(columns=['컬럼1','컬럼2'],inplace=True) #방법1
df = [col for col in df.columns if (df[col] == '_').mean() >= 0.5] #방법2

#40%이하는 NULL으로 변경
df.replace('_', np.nan) 

#NULL값 최빈값으로 대체
f_value =df['컬럼명'].mode()[0]
print(f_value) #확인
df = df.fillna({'컬럼명': f_value}) #inplace=True로 바로 저장되게도 가능

#NULL값 중앙값으로 대체
m_value =df['컬럼명'].median()
print(m_value) #확인
df = df.fillna({'컬럼명': m_value})
df['컬럼명'] = df['컬럼명'].astype(int) #필요한경우 데이터타입 변경

 

보통 결측치는 삭제나 대체로 처리합니다

 


 

5.라벨인코딩/원핫인코딩

범주형 데이터를 모델이 처리할 수 있는 수치형 데이터로 변환하는 기법

라벨 인코딩은 각 범주를 숫자로 변환하고, 원핫 인코딩은 범주를 바이너리 벡터로 변환합니다.

이 과정을 하는 이유는 머신러닝 알고리즘들이 주로 숫자데이터를 기반으로 작동하기 때문입니다.

 

▼ 라벨 인코딩(Label Encoding)과 원핫 인코딩(One-Hot Encoding) 자세히 알아보기

더보기

라벨 인코딩

라벨 인코딩은 각 범주를 유일한 정수로 매핑합니다. 예를 들어, 범주형 특성이 ['red', 'blue', 'green'] 세 가지 값을 가질 때, 이를 [0, 1, 2]로 변환할 수 있습니다.

  • 장점:
    • 변환된 숫자 크기가 작아 메모리를 효율적으로 사용합니다.
    • 범주의 수가 많지 않을 때 간단하고 효율적인 방법이 될 수 있습니다.
  • 단점:
    • 숫자는 자연스럽게 크기나 순서를 가지고 있기 때문에, 모델이 이 숫자들 사이에 수학적인 순서나 크기를 잘못 해석할 수 있습니다. 이로 인해 모델 성능에 부정적인 영향을 줄 수 있습니다.
  • 적합한 사용 경우:
    • 순서가 있는 범주형 데이터(예: 낮음, 중간, 높음)에 적합합니다.
    • 결정 트리와 같은 특정 알고리즘에서는 라벨 인코딩이 유용하며, 이 알고리즘은 숫자의 크기를 분할 기준으로 사용할 수 있습니다.

원핫 인코딩

원핫 인코딩은 범주 각각을 벡터로 변환하며, 해당 범주에 해당하는 위치만 1이고 나머지는 0인 바이너리 벡터를 생성합니다. 위의 예에서 'red', 'blue', 'green'은 각각 [1, 0, 0], [0, 1, 0], [0, 0, 1]로 변환됩니다.

  • 장점:
    • 수치적 크기나 순서가 없으므로, 모델이 잘못된 가중치를 부여하는 문제를 방지할 수 있습니다.
    • 특히 로지스틱 회귀, 신경망과 같이 숫자의 크기를 중요하게 고려하는 알고리즘에 적합합니다.
  • 단점:
    • 변환된 특성의 수가 범주의 수만큼 증가하기 때문에, 범주의 수가 많을 때 차원의 저주를 야기할 수 있고 메모리 사용량이 크게 증가합니다.
  • 적합한 사용 경우:
    • 순서가 없는 범주형 데이터에 적합합니다.
    • 대부분의 선형 모델이나 신경망 모델에서 더 나은 성능을 제공합니다.
from sklearn.preprocessing import LabelEncoder

# object 타입인 컬럼 선택
o_cols = df.select_dtypes(include=['object']).columns
print(o_cols)

# 특정컬럼에 LabelEncoder 적용
le = LabelEncoder()
df['특정컬럼'] = le.fit_transform(df['특정컬럼'])


# 나머지 컬럼에 One-Hot-Encoding 
df = pd.get_dummies(df, columns=['컬럼명1','컬럼명2','컬럼명3'], drop_first=True)
df.info() #확인

 


 

6. X,Y 데이터 분리

독립 변수와 종속 변수를 분리

from sklearn.model_selection import train_test_split

target = '타겟컬럼'
X = df.drop('target', axis=1)
Y = df.loc[:, target]

#X, Y 값을 가지고 8:2 비율로 Train , Test Dataset으로 나누기
#조건 :y 클래스 비율에 맞게 분리, y 값은 'taget컬럼명', random_state는 42)
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, stratify=Y, random_state=42)

 


 

7. 데이터 정규화/표준화

모델의 성능을 최적화하기 위해 데이터의 스케일을 조정

from sklearn.preprocessing import StandardScaler

# StandardScaler 객체 생성
scaler = StandardScaler()

# 훈련 데이터셋에 대해 정규분포화(fit_transform)
X_train = scaler.fit_transform(X_train)

# 테스트 데이터셋에 대해 표준화(transform)
X_test = scaler.transform(X_test)

 

훈련데이터셋은 정규분포화(fit_transform)하고 테스트 데이터셋은 표준화(transform)

 

 

정규화(Normalization)하고 표준화(Standardization) 자세히 알아보기 

더보기

정규화 (Normalization)

정규화는 데이터를 특정 범위(예: 0과 1 사이)로 스케일을 조정합니다. 이 방법은 각 특성(feature)의 최소값과 최대값을 사용합니다.

  • 공식:
  • 목적:
    • 모든 특성의 스케일을 같게 하여, 한 특성이 모델에 더 큰 영향을 미치는 것을 방지합니다.
    • 특히 거리 기반 알고리즘에서 중요한 역할을 합니다. 예를 들어, k-최근접 이웃(k-NN)과 같은 알고리즘은 각 특성의 스케일이 모델의 성능에 크게 영향을 미칩니다.
  • 장점:
    • 모든 데이터 포인트를 동일한 스케일로 조정하므로, 작은 숫자 범위의 특성이 다른 특성에 의해 지배당하지 않습니다.
  • 단점:
    • 이상치(outliers)가 있을 경우, 다른 모든 값들이 매우 좁은 범위에 모일 수 있습니다. 즉, 이상치의 영향을 크게 받습니다.

 

표준화 (Standardization)

표준화는 데이터의 평균을 0, 표준편차를 1로 조정합니다. 이 방법은 데이터의 평균과 표준편차를 사용하여, 데이터를 가우시안 분포(정규 분포)에 가깝게 만듭니다.

  • 공식:
    • 여기서 𝜇는 특성의 평균이고, 𝜎는 표준편차입니다.
  • 목적:
    • 특성 간의 스케일 차이를 줄여 모델의 성능을 향상시키고, 수렴 속도를 빠르게 합니다.
    • 선형 회귀, 로지스틱 회귀, 신경망 등에서 가중치를 더 효율적으로 학습시킬 수 있습니다.
  • 장점:
    • 이상치에 덜 민감하며, 많은 머신러닝 알고리즘에서 요구되는 조건을 충족시킵니다.
  • 단점:
    • 모든 데이터를 정규 분포로 가정하는 것이 항상 적합하지 않을 수 있습니다. 특히, 원래 데이터가 정규 분포를 따르지 않을 때 비효율적일 수 있습니다. 

 


 

8. 머신러닝 모델링 및 모델 성능 평가  +시각화

- 로지스틱 회귀 (LogisticRegression, 분류)

from sklearn.linear_model import LogisticRegression

# Logistic Regression 모델 생성
logistic_model = LogisticRegression(C=10, max_iter=2000)
#규제강도C는 10으로 설정, 계산에 사용할 작업수 max_iter는 2000으로 설정

# 모델 학습
logistic_model.fit(X_train, Y_train)

#성능평가
from sklearn.metrics import confusion_matrix, classification_report
import seaborn as sns
import matplotlib.pyplot as plt

# 테스트 데이터셋을 사용하여 y값 예측
y_pred = logistic_model.predict(X_test)

# Confusion Matrix 계산
cm = confusion_matrix(y_test, y_pred)

# Heatmap 그래프로 시각화
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', annot_kws={"size": 16})
plt.xlabel('Predicted Labels')
plt.ylabel('True Labels')
plt.title('Confusion Matrix')
plt.show()

# Classification Report 출력
print(classification_report(y_test, y_pred))

 

-  DecisionTree 

from sklearn.tree import DecisionTreeClassifier

# DecisionTree 모델 생성
tree_model = DecisionTreeClassifier(max_depth=10, random_state=42)

# 모델 학습
tree_model.fit(X_train, Y_train)
tree_model.score(X_test, Y_test)

 

-RadomForest

from sklearn.ensemble import RandomForestClassifier

# RandomForest 모델 생성
random_forest_model = RandomForestClassifier(n_estimators=100, random_state=42)

# 모델 학습
random_forest_model.fit(X_train, Y_train)
random_forest_model.score(X_test, Y_test)

 

- XGBoost

from xgboost import XGBClassifier

# XGBoost 모델 생성
xgb_model = XGBClassifier(n_estimators=5)

# 모델 학습
xgb_model.fit(X_train, Y_train)
xgb_model.score(X_test, Y_test)

 

- Light BGM

from lightgbm import LGBMClassifier

# LightGBM 모델 생성
lgb_model = LGBMClassifier(n_estimators=3)

# 모델 학습
lgb_model.fit(X_train, Y_train)
lgb_model.score(X_test, Y_test)

 

- Linear Regression 모델을 연습으로 만들고 학습 해보기

#예시데이터
x_data = np.array([1.6, 2.3, 3.5, 4.6]).reshape(-1,1)
y_data = np.array([3.3, 5.5, 7.2, 9.9])


from sklearn.linear_model import LinearRegression

# 데이터 준비
x_data = np.array([1.6, 2.3, 3.5, 4.6]).reshape(-1, 1)
y_data = np.array([3.3, 5.5, 7.2, 9.9])

# Linear Regression 모델 생성
linear_model = LinearRegression()

# 모델 학습
linear_model.fit(x_data, y_data)
linear_model.score(X_test, Y_test)
linear_model.predict([[5]])

 


 

9. 딥러닝 모델링 및 모델 성능 평가  +시각화

복잡한 패턴을 학습할 수 있는 강력한 머신러닝 기법 중 하나

 

예시 가이드 
  • 첫번째 Hidden Layer : unit 64 , activation='relu'
  • 두번째 Hidden Layer : unit 32 , activation='relu'
  • 세번째 Hidden Layer : unit 16 , activation='relu'
  • 각 Hidden Layer 마다 Dropout 0.2 비율로 되도록 하세요.
  • EarlyStopping 콜백을 적용하고 ModelCheckpoint 콜백으로 validation performance가 좋은 모델을 h5 모델로 저장하세요.
  • batch_size는 10, epochs는 10으로 설정하세요.
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint

# 딥러닝 모델 구성
model = Sequential([
    Dense(64, activation='relu', input_shape=(X_train.shape[1],)),
    Dropout(0.2),
    Dense(32, activation='relu'),
    Dropout(0.2),
    Dense(16, activation='relu'),
    Dropout(0.2),
    Dense(1, activation='softmax')
])

# EarlyStopping 콜백 설정
early_stopping = EarlyStopping(monitor='val_loss', patience=4, mode='min', verbose=1)

# ModelCheckpoint 콜백 설정
checkpoint = ModelCheckpoint('best_model.keras', monitor='val_loss', save_best_only=True, verbose=1)

# 모델 컴파일
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

# 모델 훈련
history = model.fit(X_train, Y_train,
					validation_data=(X_test, Y_test), 
                    epochs=10, 
                    batch_size=10, 
                    callbacks=[early_stopping, checkpoint])

 

  • Y_train,Y_test를 원핫 인코딩 후 다중 분류하는 딥러닝 모델
from keras.utils import to_categorical
y_train_ohe = to_categorical(Y_train)
y_test_ohe = to_categorical(Y_test)

model = Sequential()
model.add(Dense(64,activation='relu',input_shape=(X_train.shape[1],)))
model.add(Dropout(0.2))
model.add(Dense(32,activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(16,activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(2,activation='softmax'))

model.compile(optimizer='adam', loss='categorical_crossentropy',metrics=['acc'])

history = model.fit(X_train, y_train_ohe, batch_size=10, epochs=10, callbacks=[es,mc], validation_data=(X_test, y_test_ohe), verbose=1)

model.save('voc_model.h5')

 

  • 모델 성능평가 그래프 (학습 정확도와 검증정확도)
import matplotlib.pyplot as plt

################################방법1#################################

# 학습과 검증 정확도 가져오기
train_accuracy = history.history['accuracy']
val_accuracy = history.history['val_accuracy']

# 그래프로 표현
plt.plot(range(1, len(train_accuracy) + 1), train_accuracy, label='Train')
plt.plot(range(1, len(val_accuracy) + 1), val_accuracy, label='Validation')

# 그래프 제목과 축 레이블 설정
plt.title('Model Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()

# 그래프 표시
plt.show()


################################방법2#################################

plt.figure(figsize=(10,5))
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('Model Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend(['Train','Validation'], loc='lower right')

 

  • 모델 성능평가 그래프 (학습손실과 검증손실)
import matplotlib.pyplot as plt

################################방법1#################################

# 학습과 검증 손실 가져오기
train_loss = history.history['loss']
val_loss = history.history['val_loss']

# 그래프로 표현
plt.plot(range(1, len(train_loss) + 1), train_loss, label='Train Loss')
plt.plot(range(1, len(val_loss) + 1), val_loss, label='Validation Loss')

# 그래프 제목과 축 레이블 설정
plt.title('Model Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()

# 그래프 표시
plt.show()


################################방법2#################################
plt.figure(figsize=(10,5))
plt.plot(history.history['loss'], 'b', label='Train Loss')
plt.plot(history.history['val_loss'], 'y', label='validaton Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()

 

  • Y값을 예측하고 정확도 출력
# 테스트 데이터에 대한 예측 수행
y_test_pred_prob = model.predict(X_test,batch_size=10, verbose=1)

y_test = np.argmax(y_test_ohe, axis=1)
y_test_pred = np.argmax(y_test_pred, axis=1)

# 정확도 계산
from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y_test, y_test_pred)
print("정확도:", accuracy)

 


 

KT에이블스쿨 DX과정에서 배운 것을

총정리하는 느낌으로 올려봤습니다

요기에 안썼지만 자주쓰이는 방법들은 추후에 포스팅하겠습니다

 

다들.. 빠이팅

❤️