커플성사예측

2025. 1. 3. 19:40데이터 분석/딥러닝(인공신경망)

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

df = pd.read_csv("./train.csv")
df.head()

df["match"]
df["match"].value_counts()

from imblearn.under_sampling import RandomUnderSampler
from imblearn.under_sampling import NearMiss
import pandas as pd

x = df.iloc[:, 0:21] # x
y = df.iloc[:, 21] # y


from imblearn.under_sampling import RandomUnderSampler
from collections import Counter

# 언더샘플링을 수행하는 함수
def balanced_under_sampling(x, y, strategy='auto'):
    """
    언더샘플링을 통해 클래스 비율을 균형 있게 맞추는 함수
    strategy: 'auto' (기본값) 또는 수동으로 비율을 설정 가능
    """
    # 샘플링 전략을 'auto'로 두면 소수 클래스를 다수 클래스 수에 맞게 줄입니다.
    undersampler = RandomUnderSampler(sampling_strategy=strategy, random_state=42)
    # sampling_strategy : 샘플링 비율 설정/auto면 소수 클래스를 다수 클래스 수에 맞추어 줄임
    
    x_resampled, y_resampled = undersampler.fit_resample(x, y)
    
    # 언더샘플링 후 클래스 비율 출력
    print("언더샘플링 후 클래스 비율:")
    print(Counter(y_resampled))
    
    return x_resampled, y_resampled

# 데이터 준비: x, y는 이전의 데이터셋 (X, Y 변수)
x_resampled, y_resampled = balanced_under_sampling(x, y, strategy='auto')

# 언더샘플링 후 클래스 비율 확인
print("언더샘플링 후 클래스 비율:")
print(y_resampled.value_counts())


from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from imblearn.over_sampling import SMOTE
from keras.models import Sequential
from keras.layers import Dense, Dropout, BatchNormalization, LeakyReLU
from keras.callbacks import EarlyStopping
from sklearn.metrics import classification_report

# Train-Test 분리
x_train, x_test, y_train, y_test = train_test_split(
    x_resampled, y_resampled, test_size=0.2, random_state=42, stratify=y_resampled
)

# 데이터 스케일링
ss = StandardScaler()
x_train_scaled = ss.fit_transform(x_train)
x_test_scaled = ss.transform(x_test)


# 모델 설계
model = Sequential([
    Dense(128, input_dim=x_train_scaled.shape[1]),
    LeakyReLU(alpha=0.1),  # 음수값도 죽지않는다
    BatchNormalization(),
    Dropout(0.3),
    
    Dense(64),
    LeakyReLU(alpha=0.1),
    BatchNormalization(),
    Dropout(0.3),
    
    Dense(32),
    LeakyReLU(alpha=0.1),
    BatchNormalization(),
    Dropout(0.3),
    
    Dense(1, activation='sigmoid')
])


model.compile(optimizer="adam", loss="binary_crossentropy", metrics=["accuracy"])

# 학습
early_stopping = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)
# patience : 모델 학습이 더 이상 개선되지 않는 경우 몇 번의 epoch동안 기다릴 것이냐!?
# restore_best_weights=True : 학습이 중지된 후, 가장 성능이 좋았던 시점의 가중치로 복원!
# val_loss+66.93 : 모니터링하면 더 빠르게 성능 저하를 감지하고 종료할 수 있다.
# val_accuracy+70.31

history = model.fit(
    x_train_scaled, y_train, 
    epochs=100, batch_size=128, 
    validation_split=0.2, verbose=2, 
    callbacks=[early_stopping]
)

# 평가
score = model.evaluate(x_test_scaled, y_test)
print(f"Test Accuracy: {score[1]*100:.2f}%")

# 상세 지표
y_pred = model.predict(x_test_scaled)
y_pred_classes = (y_pred > 0.5).astype(int)
print(classification_report(y_test, y_pred_classes))


from sklearn.metrics import roc_auc_score

auc = roc_auc_score(y_test, y_pred)
print(f"AUC-ROC Score: {auc:.2f}")


import pandas as pd
import numpy as np

# 새로운 데이터 불러오기
new_data = pd.read_csv("test.csv")

new_x = new_data.iloc[:, 0:21]

# 새로운 데이터 전처리
new_x_scaled = ss.transform(new_x)

# 예측 생성 (0.5 기준으로 1, 0으로 분류)
predictions = model.predict(new_x_scaled)  # 예측 결과는 (n_samples, 1) 형태의 배열

# 예측 결과를 1D 배열로 변환하고, 0.5 기준으로 1과 0으로 변환
predictions = (predictions.reshape(-1) > 0.5).astype(int)

# 새로운 테스트 데이터에 추가하고 파일로 저장
new_data['match'] = predictions
new_data.to_csv('test.csv', index=False)