상세 컨텐츠

본문 제목

(3편) ChatGPT를 활용한 로또번호 예측하기 (앙상블 Model)

카테고리 없음

by 늦둥이아빠 2024. 5. 10. 09:39

본문

앙상블(Ensemble) 모델은 여러 개의 개별 모델을 결합하여 하나의 강력한 모델을 만드는 기법입니다. 이러한 방식은 여러 모델의 다양한 예측을 결합하여 단일 예측을 수행함으로써 개별 모델의 약점을 보완하고 성능을 향상시킵니다. 1편, 2편에 이어 로또 당첨번호 데이터를 train_data2.csv와 test_data2.csv의 파일을 80:20 비율로 하여 EnSemble Model를 활용하여 예측해 보도록 하겠습니다.

(3편) ChatGPT를 활용한 로또번호 예측하기 (앙상블 Model)

앙상블 모델

앙상블 모델은 단일 모델보다 더 뛰어난 일반화 성능을 제공하는 경우가 많습니다. 이는 여러 모델의 다양한 관점을 결합하여 더 강력하고 안정적인 예측을 가능하게 합니다. 하지만, 앙상블 모델은 계산 비용이 높고 설명 가능성이 낮을 수 있으며, 너무 많은 모델을 결합할 경우 과적합의 위험이 있습니다.

앙상블 모델은 주로 두 가지 방식으로 작동합니다

  • 배깅(Bagging): 배깅은 병렬적으로 여러 개의 모델을 생성하여 그들의 예측을 결합합니다.각 모델은 동일한 학습 알고리즘을 사용하지만 학습 데이터의 서브셋을 사용하여 학습합니다. 대표적인 예로는 랜덤 포레스트(Random Forest)가 있습니다.
  • 부스팅(Boosting): 부스팅은 순차적으로 여러 모델을 학습시켜 예측을 개선합니다.각 모델은 이전 모델의 오류를 보완하도록 학습됩니다. 대표적인 예로는 그래디언트 부스팅(Gradient Boosting)과 에이다부스트(AdaBoost)가 있습니다.

파일썬 설치하기

파일 읽어 들여 훈련을 통해 예측을 하려면 파일썬 프로그램을 설치하고, 실행을 해야 합니다.

파일썬 공식 홈페이지 접근하여 최신 버전을 다운로드 하시기 바랍니다.

파일썬 설치하기

윈도우용이라면, 아래의 다운로드 파일썬 3.12.3을 설치하시면 됩니다.

설치 마법사의 첫 번째 창에서 아래와 같이 "Add python.exe to PATH"에 체크하고, "Customize installation"을 선택합니다.

"Add python.exe to PATH"는 현재 설치할 파이썬 실행파일을 PATH 환경변수에 등록하는 옵션입니다. PATH 환경변수에 실행파일을 등록하면 현재 디렉토리 위치에 상관없이 명령 프롬프트(cmd) 어디에서든 파이썬을 실행할 수 있습니다. 이 옵션을 선택하면 파이썬 실행파일을 PATH 환경변수에 따로 등록하지 않아도 됩니다.

ChatGPT 질문하기

train_data2.csv 훈련용 데이터와 test_data2.csv 검증용 데이터를 읽고, 다음 회차를 예측할 수 있는 앙상블 모델 프로그램을 짜줘. 단, 예측결과는 1에서 45사이의 6자리 숫자로 이루어진 조합이어야 합니다.

ChatGPT 답변

아래는 train_data2.csv 훈련용 데이터와 test_data2.csv 검증용 데이터를 사용하여 다음 회차를 예측하는 앙상블 모델 프로그램입니다. 이 프로그램은 배깅(Bagging) 앙상블 방법 중 하나인 랜덤 포레스트(Random Forest)를 사용합니다. 코드를 실행하기 전에 scikit-learn 라이브러리가 설치되어 있어야 합니다.

ChatGPT 답변 프로그램

위의 코드를 복사한 후 IDLE (Python 3.12 64-bit)를 실행하여 File>New file를 선택하면 빈 화면이 하나 더 팝업됩니다. 이때 여기에 복사한 코드를 붙여넣기 하면 아래와 같이 복사가 됩니다. Ensemble.py로 저장합니다.

Python  IDLE (Python 3.12 64-bit)에 ChatGPT 프로그램 복사하여 파일 생성

 

Run메뉴> F5키를 선택하면 파일 저장버튼이 나타납니다. Ensemble.py로 저장하고 실행하면, 실행결과가 에러가 있으면 에러 화면이 나타납니다.

Python 실행결과 에러 발생하면 ChatGPT에서 와서 에러 수정해 달라고 입력하는 화면

 

파일썬에서 에러가 발생하면 에러 내용을 복사하여 ChatGPT에 넣은 다음, “에러 수정해줘” 라고 입력합니다.

프로그램이 train_data2.csv 파일을 찾을 수 없어 오류가 발생했네요. 파일 경로가 올바른지 확인하고, 파일이 프로그램이 실행되는 디렉토리에 있는지 다시 확인해주세요. 파일 경로가 정확하다면 파일 이름 뒤에 작은 따옴표가 누락되었거나 잘못된 문자가 있는지도 확인해보세요. 파일 경로를 올바르게 지정하여 코드를 수정해 보겠습니다.

그러면 위에서 했던 것처럼 계속 에러 수정을 요청하고, 내가 원하는 결과가 나올때까지 ChatGPT에게 요구를 하면 결국 내가 원하는 값을 얻을 수 있습니다.

다음은 앙상블 모델을 처음에 사용했던 랜덤 포레스트 모델도 최종적으로 KNN 모델+서치그리드모델의 하이퍼파라미터로 변경하면서 최종적으로 수정한 Ensemble_Hyperpramenter.py의 완성된 코드입니다. 예측 방법을 변경하면서 정확도를 높일 수 있도록 다양한 방법을 시도해 보시기 바랍니다.

import pandas as pd
import numpy as np
from sklearn.multioutput import MultiOutputRegressor
from sklearn.neighbors import KNeighborsRegressor
from sklearn.model_selection import GridSearchCV
# KNN 모델 훈련
def train_knn(X_train, y_train, n_neighbors=5):
    knn = KNeighborsRegressor(n_neighbors=n_neighbors)
    multi_knn = MultiOutputRegressor(knn)
    multi_knn.fit(X_train, y_train)
    return multi_knn
# 다음 회차의 조합 예측
def predict_next_draw(X_train, y_train, X_test, num_pairs=1):
    knn_model = train_knn(X_train, y_train)
    next_draws = knn_model.predict(X_test)
    # 1에서 45 사이의 정수로 변환
    next_draws = np.round(next_draws).astype(int)
    # 중복되지 않는 조합을 선택하기 위한 함수
    def unique_combination(draw):
        while True:
            first_pair = np.random.choice(draw[:6], size=np.random.randint(2, 6), replace=False)
            second_pair = list(first_pair)  # Include numbers from the first pair
            while len(second_pair) < 6:
                new_num = np.random.choice(45, size=1)[0] + 1
                if new_num not in first_pair:
                    second_pair.append(new_num)
            new_combination = tuple(sorted(second_pair))
            if new_combination not in predicted_pairs:  # Check for uniqueness
                return new_combination
    predicted_pairs = []
    for draw in next_draws:
        new_combination = unique_combination(draw)
        predicted_pairs.append(new_combination)
        if len(predicted_pairs) == num_pairs:
            break
    return predicted_pairs
# 메인 함수
def main(train_file, test_file):
    # CSV 파일에서 데이터 읽어오기
    train_data = pd.read_csv(train_file, header=None, skiprows=1, encoding='cp949').values
    test_data = pd.read_csv(test_file, header=None, skiprows=1, encoding='cp949').values
    # 훈련 데이터와 테스트 데이터에서 특성과 레이블 분리
    X_train, y_train = train_data[:, :-6], train_data[:, -6:]
    X_test = test_data[:, :-6]  # 테스트 데이터
    # 그리드 서치를 사용하여 최적의 하이퍼파라미터 찾기
    param_grid = {'estimator__n_neighbors': [3, 5, 7, 9, 11]}  # MultiOutputRegressor의 하이퍼파라미터
    knn_model = GridSearchCV(estimator=MultiOutputRegressor(KNeighborsRegressor()), param_grid=param_grid, cv=5)
    knn_model.fit(X_train, y_train)
    # 최적의 모델로 예측 수행
    best_model = knn_model.best_estimator_
    predicted_pairs = predict_next_draw(X_train, y_train, X_test, num_pairs=5)
    # 예측 결과 출력
    print("다음 회차의 예측 조합:")
    for pair in predicted_pairs:
        print(pair)
if __name__ == "__main__":
    # 파일 경로 설정
    train_file = "train_data2.csv"
    test_file = "test_data2.csv"
 
    main(train_file, test_file)

 

이 코드는 주어진 훈련 데이터로부터 KNN 모델을 훈련시키고, 테스트 데이터에 대해 해당 모델을 사용하여 다음 회차의 로또 번호를 예측합니다. 중요한 점은 중복된 예측을 피하기 위해 각 번호 쌍을 선택할 때 중복을 체크한다는 것입니다.

아래는 이 프로그램의 내용 해설입니다.

  • import 문: pandas, numpy와 scikit-learn 라이브러리의 필요한 모듈을 가져옵니다.
  • train_knn 함수: KNN 모델을 훈련시키는 함수입니다. KNeighborsRegressor 클래스를 사용하여 KNN 회귀 모델을 생성하고, MultiOutputRegressor로 감싸서 다중 출력을 지원합니다. X_train, y_train, n_neighbors 매개변수를 받아서 모델을 훈련하고 반환합니다.
  • predict_next_draw 함수: 다음 회차의 로또 번호 조합을 예측하는 함수입니다.
  • 테스트 데이터인 X_test에 대해 KNN 모델을 사용하여 다음 회차의 번호를 예측합니다. 예측된 번호를 1에서 45 사이의 정수로 변환하고, 중복을 피하기 위해 각 번호 쌍을 선택할 때 중복을 체크합니다. 예측된 번호 쌍을 반환합니다.
  • main 함수: 주요 실행 부분입니다.
  • 훈련 데이터와 테스트 데이터를 CSV 파일에서 읽어옵니다.
  • 그리드 서치를 사용하여 최적의 KNN 모델을 찾습니다. 이때, 이웃의 수를 조정합니다.
  • 최적의 모델을 사용하여 predict_next_draw 함수를 호출하여 다음 회차의 번호를 예측합니다.
  • 예측된 번호 쌍을 출력합니다.
  • __main__ 블록: 파일 경로를 설정하고, main 함수를 호출하여 프로그램을 실행합니다.

예측결과

다음은  Ensemble_Hyperpramenter.py실행 했을때, 5쌍의 예측결과를 출력하는 화면입니다. 

마치며

로또 예측은 일반적으로 머신러닝 모델로 매우 어려운 문제 중 하나입니다. 그 이유는 로또 번호가 무작위로 추출되기 때문에 이전 번호에서 유용한 패턴을 학습하기가 어렵기 때문입니다. 그러므로 로또 번호 예측에 머신러닝 모델을 사용하는 것은 보다 근본적인 한계에 직면하게 됩니다. 위 코드에서 사용된 KNN 모델은 주변 이웃들의 평균값을 예측하는 방식으로 동작합니다. 하지만 이러한 방법은 로또 번호 예측과 같은 문제에는 적합하지 않을 수 있습니다. 왜냐하면 로또 번호는 이전 번호와는 독립적으로 추출되며, 이전 번호들 사이에 유의미한 관계가 없기 때문입니다. 또한, KNN 모델은 특히 데이터가 매우 큰 경우에는 계산 비용이 높을 수 있습니다.

일반적으로 로또 번호 예측에 머신러닝 모델을 사용하는 것은 권장되지 않습니다. 대신에, 로또는 순수한 무작위성에 의해 결정되는 확률적인 이벤트로 간주되어야 합니다. 따라서 로또 번호를 예측하는 대신, 로또는 단순한 운빨이며 재미있는 활동이라고 생각하는 것이 합리적일 것입니다.