ASSO 대비

source
type 📌 개발노트
topics 100-데이터분석 & AI 101 머신러닝
index 자격증
tags

!pip install seaborn
인덱스,시리즈,데이터프레임
loc,iloc
apply
DataFrame 데이터 접근 방법

보통 axis 가 0이면 가로 , 1일면 세로임
기본 함수들 : https://ordo.tistory.com/37

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

1. 데이터 불러오기 및 구성 확인

기본

import pandas as pd

# <span id="불러오기"></span>불러오기
df = pd.read_csv("경로")
"""
index_col=0**: 첫 번째 컬럼을 인덱스로 사용
index_col='컬럼이름'**: 해당 컬럼을 인덱스로 사용
"""

# <span id="확인-상하위-5개"></span>확인 상하위 5개
df.head()
df.tail()

# <span id="데이터프레임-정보출력"></span>데이터프레임 정보출력
df.info() # 컬럼, not-null 개수, dtype 

# <span id="각컬럼의-통계-요약-count는-결측치가-아닌-것의-개수"></span>각컬럼의 통계 요약, count는 결측치가 아닌 것의 개수
# <span id="일반적으론-수치형만"></span>일반적으론 수치형만
df.describe() # count, mean, std, min, 25%, 50%, 75%, max
# <span id="범주형object"></span>범주형(object)
df.describe(include="O") 
# <span id="count-값의-개수결측치-제외"></span>count: 값의 개수(결측치 제외)
#unique: 고유값 개수
#top: 가장 많이 나온 값(최빈값)
#freq: 최빈값의 빈도수


# <span id="행을-식별하는-라벨-보통-인덱스라고-부름"></span>행을 식별하는 라벨 ( 보통 인덱스라고 부름)
# <span id="행의-길이와-같음-기본적으론-rangeindex가-부여"></span>행의 길이와 같음, 기본적으론 rangeindex가 부여
df.index

# <span id="열을-식별하는-라벨"></span>열을 식별하는 라벨

# <span id="각-열에-어떤-값이-있는지"></span>각 열에 어떤 값이 있는지
df[].values # 데이터프레임에서도 사용가능
df[].unique() #데이터프레임에서는 사용불가

# <span id="df-에서-각-열의-타입"></span>df 에서 각 열의 타입
df.dtypes
# <span id="시리즈에서의-타입-"></span>시리즈에서의 타입 
df.dtype

# <span id="행열-개수-반환"></span>행열 개수 반환
df.shape # 결과 : (행,열)

# <span id="행열-바꾸기-"></span>행열 바꾸기 
df.T

# <span id="정렬"></span>정렬
s_sorted = s.sort_index() # 인덱스 기준 정렬
s_sorted = s.sort_values() # 값 기준 정렬

시각화

https://diane-space.tistory.com/128
시본시각화

import matplotlib.pyplot as plt
# <span id="원형차트로-벨류의-비율을-보여주고픔"></span>원형차트로 벨류의 비율을 보여주고픔
plt.figure(figsize = (8, 5))
df['voc_trt_perd_itg_cd'].value_counts().plot(kind = 'pie', autopct = '%.2f%%')
plt.show() 

# <span id="특정-컬럼의-값의-데이터를-10개의-구간으로-나눠-히스토그램으로"></span>특정 컬럼의 값의 데이터를 10개의 구간으로 나눠 히스토그램으로
plt.hist(wine['alcohol'], bins=10)

# <span id="산점도"></span>산점도
# <span id="아래-둘다-같음"></span>아래 둘다 같음
wine.plot.scatter(x='rat_ca', y='quality')
plt.scatter(wine['rat_ca'], wine['quality'])

# <span id="선그래프"></span>선그래프
plt.plot(range(1, 51), accs) # 순서대로 x, y 값
# <span id="여러-옵션들"></span>여러 옵션들
plt.title('Accuracy')
plt.xlabel('epochs')
plt.ylabel('accuracy')
plt.legend()
plt.grid(True)

# <span id="막대그래프-"></span>막대그래프 
df.plot.bar() 
# <span id="박스플롯-"></span>박스플롯 
df.plot.box()

# <span id="시본-버전"></span>시본 버전
import seaborn as sns
# <span id="산점도"></span>산점도
tips = sns.load_dataset("tips")
sns.scatterplot(x="total_bill", y="tip", data=tips)

# <span id="막대그래프"></span>막대그래프
sns.barplot(x="day", y="total_bill", data=tips)

# <span id="히스토그램"></span>히스토그램
sns.histplot(x="total_bill", data=tips, bins=20, kde=True)

# <span id="페어플롯-여러-변수-간-관계-시각화"></span>페어플롯 (여러 변수 간 관계 시각화)
iris = sns.load_dataset("iris")
sns.pairplot(data=iris, hue="species")


함수 주요 용도 대표 시각화
kdeplot 연속형 데이터 분포 밀도곡선
pairplot 다변량 변수간 관계, 분포 산점도/히스토그램
countplot 범주형 데이터 빈도 막대그래프
heatmap 2D 데이터의 값 크기/패턴 색상 행렬
boxplot 수치형 데이터 분포/이상치 상자수염그림

2. 데이터 정제

1) 결측치 확인

# <span id="각-컬럼별-결측치가-몇개-존재하는지-"></span>각 컬럼별 결측치가 몇개 존재하는지 
df.isnull().sum() 
df.isna().sum() # 이두개 완전히같음
# <span id="notna나-notnull의-경우-결측값이면-false를-반환합니다"></span>`notna`나 `notnull`의 경우 결측값이면 `False`를 반환합니다.

# <span id="특정값이-몇개-존재하는-지-"></span>특정값이 몇개 존재하는 지 
(df['column명'] == '특정').sum()
df2=df1.replace('_',None)

# <span id="특정열-value의-개수를-확인"></span>특정열 value의 개수를 확인
# <span id="시리즈를-반환"></span>시리즈를 반환
df["열이름"].value_counts()

# <span id="특정열-드록"></span>특정열 드록
df5=df5.drop(columns=['new_date','opn_nfl_chg_date','cont_fns_pam_date'])
value_counts 옵션들

https://zzinnam.tistory.com/entry/pandas-valuecounts-%ED%95%A8%EC%88%98

옵션 설명 기본값
normalize 비율로 반환할지 여부 False
sort 결과를 정렬할지 여부 True
ascending 오름차순 정렬 여부 False
dropna 결측치(NaN)를 제외할지 여부 True

2) 결측치 처리

결측치 제거

50퍼가넘는건 제거

# <span id="결측치가-50-이상인-컬럼을-드롭-"></span>결측치가 50% 이상인 컬럼을 드롭 
threshold = len(df) * 0.5 
df_cleaned = df.loc[:, df.isnull().sum() < threshold]
# <span id="같은의미의-코드들-thresh-결측치가-몇개-이상이면-드롭"></span>같은의미의 코드들 thresh 결측치가 몇개 이상이면 드롭
# <span id="subset-dropna메서드를-수행할-레이블을-지정합니다"></span>`subset` : `dropna`메서드를 수행할 레이블을 지정합니다.
df.dropna(axis=1, thresh=int(len(df)*0.5)+1)
df.loc[:, df.isnull().mean() < 0.5]

# <span id="dropna-axis-기본-0-행"></span>dropna axis 기본 0 (행)
df.dropna() # 결측치잇는 행제거
# <span id="결측치-있는-특정컬럼-행제거"></span>결측치 있는 특정컬럼 행제거
df = train.dropna(subset=['country','workclass'])

결측치 replace

# <span id="결측치를-중앙값으로-변환"></span>결측치를 중앙값으로 변환
df4 = df3.fillna({'age_itg_cd':df3['age_itg_cd'].median()})
# <span id="최빈값으로"></span>최빈값으로
df5=df5.fillna({'cust_dtl_ctg_itg_cd':df5['cust_dtl_ctg_itg_cd'].mode()[0]})

3) 데이터 형변환

  • astype:
    모든 값이 지정한 타입으로 변환 가능해야 하며, 불가능하면 에러가 납니다.

  • to_numeric:
    변환 불가능한 값이 있어도 옵션(errors='coerce')을 주면 NaN으로 처리해 더 유연하게 작동합니다

# <span id="astype"></span>astype
df4['age_itg_cd']=df4['age_itg_cd'].astype(int)

# <span id="시리즈"></span>시리즈
pd.to_numeric(s, errors='coerce')
# <span id="데이터프레임"></span>데이터프레임
df_numeric = df.apply(pd.to_numeric, errors='coerce')

4) 특정 데이터타입 선택

# <span id="예-object문자열-타입-컬럼만-선택"></span>예: object(문자열) 타입 컬럼만 선택
object_cols = df.select_dtypes(include=['object']).columns
# <span id="예-object-타입-컬럼을-float으로-변환"></span>예: object 타입 컬럼을 float으로 변환
df[object_cols] = df[object_cols].astype('float')
# <span id="특정타입의-컬럼을-선택해서-이렇게-형변환도-가능"></span>특정타입의 컬럼을 선택해서 이렇게 형변환도 가능

5) 분류 인코딩

분류를 인코딩하는데는 라벨인코딩과 원핫인코딩이있음
라벨은 value가 a,b,c,d 이러면 이걸걍 숫자로 단순 변환
원핫은 value가 a,b,c,d 이러면 컬럼_a이렇게 새로 컬럼을 만듬
원핫은 값이 0 아니면 1임ㅋㅋ

구분 라벨 인코딩 원핫 인코딩
변환 방식 각 범주를 정수로 매핑 각 범주를 별도 열로 만들고 0/1로 표시
사용 상황 순서 없는 범주, 트리 계열 모델, 목표변수 순서 없는 범주, 대부분의 모델, 입력 변수
장점 간단, 변수 수 증가 없음 순서/크기 정보 왜곡 없음, 대부분 모델에 안전
단점 숫자 간 순서 오해 가능 변수(열) 수 증가, 희소 행렬
# <span id="안보고-한번에-오브젝트-확인하려면-아래방법쓰면됨"></span>안보고 한번에 오브젝트 확인하려면 아래방법쓰면됨
cols = train.select_dtypes(include='object').columns cols = train.columns[train.dtypes == object]

# <span id="라벨-인코딩"></span>라벨 인코딩
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
df5['cust_clas_itg_cd'] = le.fit_transform(df5['cust_clas_itg_cd'])
# <span id="만약-분리후에햇고-위의-인코딩방식이랑-같게-인코딩하려면"></span>만약 분리후에햇고 위의 인코딩방식이랑 같게 인코딩하려면
le.transform(test[col])
# <span id="r-g-b-가-가각-012-로-라벨인코딩되엇을때-"></span>R, g, b 가 가각 0,1,2 로 라벨인코딩되엇을때 
# <span id="transform은-그기준에-맞춰서-라벨인코딩해줌"></span>transform은 그기준에 맞춰서 라벨인코딩해줌
# <span id="traintest-분리-전에-fit_transform을-하면-안-되는-이유"></span>train/test 분리 전에 fit_transform을 하면 안 되는 이유
# <span id="test-데이터의-정보를-미리-알고-학습하는-것과-같음"></span>test 데이터의 정보를 미리 알고 학습하는 것과 같음

# <span id="원핫인코딩-판다스의-함수임"></span>원핫인코딩 , 판다스의 함수임
df6=pd.get_dummies(df5,columns = cat_cols.drop('cust_clas_itg_cd'))

3. 데이터 변환

test,val,train데이터 분할

  • train(학습 데이터): 모델을 학습시키는 데 사용
  • validation(검증 데이터): 하이퍼파라미터 튜닝, 모델 선택 등에 사용 (학습에는 사용하지 않음)
  • test(테스트 데이터): 최종적으로 모델의 성능을 평가하는 데 사용 (학습과 검증에 모두 사용하지 않음)
from sklearn.model_selection import train_test_split
# <span id="xy-분할"></span>x,y 분할
X = df6.drop(target, axis=1) # axis 기본row 삭제
y = df6[target]
# <span id="아래처럼-처리도-가능-단-원본이-수정됨"></span>아래처럼 처리도 가능 단 원본이 수정됨
y = train.pop("income")
x = train
# <span id="traintest-분리"></span>train,test 분리
# <span id="stratify-비율-유지"></span>stratify : 비율 유지
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42)
# <span id="traintest-분리"></span>train,test 분리
X_train, X_valid, y_train, y_valid = train_test_split(X_train, y_train, test_size=0.2, random_state=2021, stratify=y_train)

스케일링

데이터 정규화 (스케일링, 인코딩)

표준화(정규분포화)

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train) # 평균0 표편 1
# <span id="fit하지않음"></span>fit하지않음
X_test = scaler.transform(X_test) # 이건 X_train에서 계산 한 평균,표편을 사용해서 표준화

정규화

from sklearn.preprocessing import MinMaxScaler 
scaler = MinMaxScaler() 
df_normalized = scaler.fit_transform(df)

로버트: 중앙값과 사분위값활용, 이산치영향최소화

from sklearn.preprocessing import RobustScaler
scaler = RobustScaler()
train[col] = scaler.fit_transform(train[col])
test[col] = scaler.transform(test[col])

4. 학습

일반 머신러닝

분류

# <span id="로지스틱"></span>로지스틱
from sklearn.linear_model import LogisticRegression
lr_model = LogisticRegression(C=10, max_iter = 2000)
lr_model.fit(X_train, y_train)

# <span id="knn"></span>knn
from sklearn.neighbors import KNeighborsClassifier 
model = KNeighborsClassifier(n_neighbors=) 

# <span id="결정트리"></span>결정트리
from sklearn.tree import DecisionTreeClassifier 
model = DecisionTreeClassifier(max_depth=, random_state=) 

# <span id="랜덤포레스트"></span>랜덤포레스트
from sklearn.ensemble import RandomForestClassifier 
model = RandomForestClassifier(n_estimators=, random_state=) 

# <span id="xgboost-트리이용"></span>xgboost 트리이용
from xgboost import XGBClassifier 
model = XGBClassifier(n_estimators= ) 

# <span id="lightgbm-트리이용"></span>lightgbm 트리이용
from lightgbm import LGBMClassifier 
model = LGBMClassifier(n_estimators=)

회귀

from sklearn.linear_model import LinearRegression
model = LinearRegression(  )

from sklearn.neighbors import KNeighborsRegressor
moedel = KNeighborsRegressor(n_neighbors=)

from sklearn.tree import DecisionTreeRegressor
model = DecisionTreeRegressor()

from sklearn.ensemble import RandomForestRegressor
model = RandomForestRegressor()

from xgboost import XGBRegressor
model = XGBRegressor( )

from lightgbm import LGBMRegressor
model = LGBMRegressor()

딥러닝

회귀는 출력레이가 하나 분류는 출력레이어가 두개

개념

  • Activation Function (활성화 함수)
    • 역할: 뉴런의 출력에 비선형성을 추가해 복잡한 패턴 학습 가능.
    • 주요 함수:
      • relu: 은닉층에서 주로 사용 (음수는 0, 양수는 그대로).
      • sigmoid: 이진 분류의 출력층에서 사용 (0~1 확률 출력).
      • softmax: 다중 분류의 출력층에서 사용 (클래스별 확률 합 1).
      • linear: 회귀 문제의 출력층에서 사용 (연속값 예측).
    • 분류 vs 회귀:
      • 분류: 출력층에 sigmoid(이진), softmax(다중).
      • 회귀: 출력층에 활성화 함수 없음.
  • Optimizer (최적화 알고리즘)
    • 역할: 손실 함수를 최소화하는 가중치 업데이트 방향 결정.
    • 주요 옵티마이저:
      • adam: Adaptive Moment Estimation (기본 추천).
      • sgd: Stochastic Gradient Descent (학습률 조절 필요).
      • rmsprop: RNN에 적합.
    • 분류 vs 회귀: 문제 유형과 무관하게 동일하게 사용 가능.
  • Loss Function (손실 함수)
    • 역할: 예측값과 실제값의 오차를 계산.
    • 주요 손실 함수:
      • 분류:
        • binary_crossentropy: 이진 분류 (출력층 sigmoid와 함께 사용).
        • categorical_crossentropy: 다중 분류 (출력층 softmax와 함께 사용).
        • sparse_categorical_crossentropy :다중분류
          • 원핫인코딩안됏으면 이거사용
      • 회귀:
        • mse(Mean Squared Error): 연속값 예측.
        • mae(Mean Absolute Error): 이상치에 덜 민감.
    • 분류 vs 회귀:
      • 분류: 크로스 엔트로피 계열 사용.
      • 회귀: MSE/MAE 사용.
  • EarlyStopping
    • 역할: 검증 데이터의 손실(val_loss)이 개선되지 않을 때 학습을 조기 중단.
    • 주요 파라미터:
      • monitor: 모니터링할 지표 (예: val_loss).
      • patience: 개선이 없을 때 몇 epoch까지 기다릴지 (예: 4).
      • mode: 최소화(min) 또는 최대화(max) 방향 설정.
  • ModelCheckpoint
    • 역할: 모델의 가중치를 파일로 저장 (예: best_model.keras).
    • 주요 파라미터:
      • monitor: 저장 기준 지표 (예: val_loss).
      • save_best_only: 가장 좋은 모델만 저장.
      • verbose: 저장 시 로그 출력.

신경망에서의원핫인코딩 > to_categorical

from keras.utils import to_categorical
y_train_ohe = to_categorical(y_train)
y_test_ohe = to_categorical(y_test)
구분 to_categorical pd.get_dummies
주 용도 정답 레이블(타깃) 인코딩 입력 데이터(피처) 인코딩
입력 1차원 정수 배열 시리즈/데이터프레임(범주형)
출력 넘파이 배열(2D) 판다스 데이터프레임
대상 보통 y(정답) 보통 X(입력 피처)
다중 컬럼 지원 X O
문자열 지원 X (정수만) O
사용 예시 딥러닝 분류 레이블 머신러닝 피처 전처리

구현

  • 첫번째 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가 좋은 모델을 best_model.keras 모델로 저장하세요.
  • batch_size는 10, epochs는 10으로 설정하세요.
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.models import Sequentia, load_model
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(32,activation='sigmoid')# 출력층 
    # 출력시 분류면 featurer개수, 회귀면 1
    # activation 함수는 분류(이중:sigmoid,다중:softmax) 회귀면없어도됨
    
])

model.compile(
    optimizer = 'adam',
    loss = 'binary_crossentropy',
    # 분류 categorical_crossentropy binary_crossentropy
    # 분륜데 원핫 레이블 되지 않았으면 : sparse_categorical_crossentropy
    # 회귀 : mse or mae
    metrics = ['acc']  # 평가지표로 acc(정확도르 사용할것임)
    # 분류 'acc', 'AUC'
    # 보통 회귀 : 'mae', 'mse'
)
es = EarlyStopping(monitor='val_loss', patience=4, mode='min', verbose=1)

mc = ModelCheckpoint('best_model.keras', monitor='val_loss', save_best_only=True, verbose=1)

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

# <span id="ohe는-원핫인코딩한데이터"></span>ohe는 원핫인코딩한데이터
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)

# <span id="구녕조정"></span>구녕조정
model.save('voc_model.keras')

5. 결과 확인및 시각화

분류

값 예측 잘하나확인

원핫인코딩 되었을땐 각클래스에 맞는 확률을 리턴하기에 argmax를이용해야함
가장 높게 예측한걸 예측한클래스로 생각한다는 말임

from sklearn.metrics import confusion_matrix, classification_report
import seaborn as sns

y_lr_predict = lr_model.predict(X_test)
cm = confusion_matrix(y_test,y_lr_predict)
sns.heatmap(
    cm,
    annot =True # 각 셀에 값 표시
    fmt = 'd', # 정수형으로 표시
    cmap = 'Blues' # 색상
)
plt.xlabel('Predicted')
plt.ylabel('Actual')

classification_report(y_test, y_lr_predict)

## <span id="원핫인코딩되어서"></span>원핫인코딩되어서
y_test_pred = 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_score(y_test, y_test_pred)
ASSO 대비-1745563235224.png
  • macro avg : 각 클래스의 정밀도, 재현율, F1-score의 단순 평균(여기선 모두 1.00).
  • weighted avg: 각 클래스의 support(데이터 개수)로 가중평균(여기선 모두 1.00).

    loss 확인 - history이용함

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')

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()

딥러닝


회귀

from sklearn.metrics import mean_squared_error, mean_absolute_error,r2_score

y_pred = model.predict(x_test)

#결과
print(mean_squared_error(y_test, y_pred, squared=False)) # RMSE를 반환
print(mean_absolute_error(y_test, y_pred))
print(r2_score(y_test, y_pred))


# <span id="회귀계수-가중치-확인-"></span>회귀계수 = 가중치 확인 : 
model.coef_

# <span id="편향y절편-"></span>편향(y절편) = 
model.intercept_