ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 머신러닝 모델 만들기 및 테스트
    Project/ML-파이썬 주식 종목 예측 2023. 6. 9. 11:11
    반응형
    # import scipy as sp
    import pandas as pd
    import numpy as np
    #konlpy : 형태소 분석기
    from konlpy.tag import Kkma        
    from konlpy.tag import Hannanum  
    from konlpy.tag import Okt 
    from konlpy.tag import *
    import nltk
    import pickle
    
    from wordcloud import WordCloud, STOPWORDS
    from PIL import Image
    #머신러닝에 필요한 라이브러리
    from sklearn.feature_extraction.text import CountVectorizer
    from sklearn.feature_extraction.text import TfidfVectorizer 
    from sklearn.linear_model import LogisticRegression
    from sklearn.pipeline import Pipeline 
    from sklearn.metrics import accuracy_score
    from sklearn.model_selection import train_test_split
    
    %matplotlib inline
    import os
    import matplotlib.pyplot as plt
    import seaborn as sns
    import graphviz
    from sklearn.tree import export_graphviz
    
    import matplotlib.font_manager as fm
    plt.rc('font', family='NanumGothic')
    
    import matplotlib as mpl
    mpl.rcParams['axes.unicode_minus'] = False
    
    import warnings
    warnings.filterwarnings('ignore')
    plt.rc('font', family='NanumBarunGothic')

     

    필요한 모듈들을 임포트해줬다

    news_df = pd.read_csv('네이버_뉴스타이틀.csv')
    
    title_list = news_df.뉴스제목.values.tolist()
    title_text = ''
    for each_line in title_list:
        title_text = title_text + each_line + '\n'
    title_text
    
    tokens_ko = t.morphs(title_text)
    ko = nltk.Text(tokens_ko)
    print(len(ko.tokens))          # 토큰 전체 개수
    print(len(set(ko.tokens)))
    
    stop_words = ['\n',"'",'…',',','[',']','(',')','"','주','에','코스닥','특징','종목','·','장','코스피','증시','-','적',\
                  '도','기술','분석','마감','‘','`','요약','가','’','의','이','오전','★','은','“','대','”','한','B','로',\
                  '?','3','선','A','오후','는','5','!','"…','상','들','1','만에','제','2','…"','20','일','서','명',"'…",'기',\
                  '···','10','소','등','으로','자','전','률','미','...','50','세','시','안','폭',"…'",'만','9','VI','까지',\
                  '눈','더','e','량','고','인','52','성','띄네','1%','부터','다','감','을','지','4','에도','수','7','것','째',\
                 '체크','기','···','중','계','관련','왜','1억원','총','내','과','젠','또','연','엔','차','굿모닝','할','8','.',\
                 '보다','새','주간','전망','추천','이슈','플러스','사','개월','때','..','임','속','’…','G','나','개','원','에서',\
                 '하는','이유','달','→','권','?…','단독','간','배','30','K','저','와','하','/','1조','6','두','해야','분','형',\
                 '황','공','&','앞두고','보','문','이번','익','X','1억',']"','치','산','를','오','해','S','우리','그','된','준','▶',\
                 '건','재','반','라','10년','초','3분','월','신','p','급','조','줄','경','했다','구','진','이어','올','발','vs','강',\
                 '국','9억','1년','난','판','면','"(','`…','살','아','인데','번','텍','팜','8월','Q','메','2년','점','하고','10월',\
                 'D','비','됐다','채',"]'",'보니','손','확','종','동','팔','40','타','~','9월','2100','30%','땐','말','한다','요',\
                 "',",'스','…`','단','16','길','12','3억','회','될까','호','용','2조','번째','일까','듯','최']
    
    tokens_ko = [each_word for each_word in tokens_ko
               if each_word not in stop_words]
    ko = nltk.Text(tokens_ko)

     

    뉴스 제목을 형태소별로 쪼갠 뒤에 불용어에 해당하면 제외하고 아니면 포함하는 방식으로 해서

    tokens_ko와 ko를 만들어 주었다.

     

    def tokenizer(text):
        okt = Okt()
        return okt.morphs(text)
    
    def data_preprocessing():
        # 수집한 데이터 읽어오기
        news_df = pd.read_csv('네이버_뉴스타이틀.csv')
        # 학습셋, 테스트셋 분리
        title_list = news_df['뉴스제목'].tolist()
        price_list = news_df['주가변동'].tolist()
        # 데이터의 80%는 학습셋, 20%는 테스트셋
        title_train, title_test, price_train, price_test = train_test_split(title_list, price_list, test_size=0.2, random_state=0)
        return title_train, title_test, price_train, price_test
    
    def learning(x_train, y_train, x_test, y_test):
        # 전처리가 끝난 데이터를 단어 사전으로 만들고
        # 리뷰별로 나오는 단어를 파악해서 수치화 (벡터화)해서 학습
        # tfidf, 로지스틱 회귀 이용
        tfidf = TfidfVectorizer(lowercase=False, tokenizer=tokenizer) #빈도가 높으면 유의미한 단어가 아님을 분석해주는 도구
        # 로지스틱
        logistic = LogisticRegression(C=2, penalty='l2', random_state=0)     # C의 숫자가 너무 크면 과적합 (기본 1), penalty로 과적합 방지
        pipe = Pipeline([('vect',tfidf),('clf',logistic)])
        # 학습
        pipe.fit(x_train, y_train)
        # 학습 정확도 측정
        y_pred = pipe.predict(x_test)
        print(accuracy_score(y_test, y_pred))
        # 학습한 모델을 저장
        with open('pipe.dat', 'wb') as fp:     # 쓰기, 저장
            pickle.dump(pipe, fp)
        print('저장완료')     # 학습된 모델 저장 완료
    
    def using():
        # 객체를 복원, 저장된 모델 불러오기
        with open('pipe.dat','rb') as fp:     # 읽기
            pipe = pickle.load(fp)
        while True :
            text = input('뉴스 타이틀을 입력해주세요 : ')
            str = [text]
            # 예측 정확도
            r1 = np.max(pipe.predict_proba(str)*100)     # 확률값을 구해서 *100
            # 예측 결과
            r2 = pipe.predict(str)[0]     # 긍정('1'), 부정('0')
            if r2 == '1':
                print('삼성전자는 상승할 것으로 예상됩니다.')
            else: 
                print('삼성전자는 하락할 것으로 예상됩니다.')
            print('정확도 : %.3f' % r1)
            print('------------------------------------------------')

    이런식으로 함수를 구성했다

    함수를 쭉 살펴보면 tfidf로 유의미한 단어를 구분하고 유의미한 단어의 벡터값을 로지스틱 회귀를 통해 학습했다.

    로지스틱 회귀란 0~1사이로 결과를 출력해내는 애라고 간단하게 설명할 수 있는데 이 두 개를 파이프함수로 연결하여

    짧은 코드를 통해 효율적으로 학습시켰다.

    using함수는 .bat파일을 불러와서 text에 타이틀을 입력하면 예측정확도와 결과를 출력해준다.

    0.775
    저장완료
    뉴스 타이틀을 입력해주세요 : 삼성전자, HBM 8개 탑재 첨단 패키징 내년 양산
    삼성전자는 하락할 것으로 예상됩니다.
    정확도 : 82.135
    ------------------------------------------------
    뉴스 타이틀을 입력해주세요 : 비싸진 TSMC 3나노 공정에 엔비디아도 고민, 삼성전자 가격으로 승부볼까
    삼성전자는 하락할 것으로 예상됩니다.
    정확도 : 88.103
    ------------------------------------------------
    뉴스 타이틀을 입력해주세요 : 삼성전자, '중국 테크 세미나'서 TV·생활가전 신기술 공개
    삼성전자는 하락할 것으로 예상됩니다.
    정확도 : 77.112
    ------------------------------------------------
    뉴스 타이틀을 입력해주세요 : 삼성전자, 중국서 네오 QLED·OLED TV 선보여
    삼성전자는 하락할 것으로 예상됩니다.
    정확도 : 74.368
    ------------------------------------------------
    뉴스 타이틀을 입력해주세요 : '삼성페이 유료화설'…카드사, 애플페이 올라타나
    삼성전자는 하락할 것으로 예상됩니다.
    정확도 : 87.621
    ------------------------------------------------
    뉴스 타이틀을 입력해주세요 : SK하이닉스·삼성전자, 동시호가서 대량거래 터졌다…무슨 일이
    삼성전자는 하락할 것으로 예상됩니다.
    정확도 : 80.205
    ------------------------------------------------

    이건 실제로 학습시킨 후에 오늘(06.09)일자로 발행된 기사들을 넣어봤는데 전부 하락한다고 나온다...

    현 시각 기준으로 1.38%상승한 삼성전자 주가인데 학습데이터가 부족한 탓인지 전부 하락한다고 나와서 이를 다듬어보아야 할 것 같다...

    전체 데이터가 학습일 기준 일주일 전 주 거래일 총 5일의 기사만 데이터로 사용했다. 그 중 0.2를 test Set으로 사용했으니

    4일치의 학습 데이터밖에 없는 셈이다...5일만 사용한 이유는 내가 본 논문에서 일주일치의 뉴스기사를 사용했을 때 정확도가 가장 높다고 해서 그랬는데...좀 더 다듬어야겠다..물론 논문에서 만든 모델은 영어이기도 하고 300차원의 벡터를 64차원 필터 여러개를 통해 정제된 데이터를 얻었다는 점에서 내가 만든 모델과 차이가 있다... 그래서 나는 학습데이터의 부족함이라고 판단하고 데이터 양을 늘려서 시험해봐야겠다

    반응형

    댓글

Designed by Tistory.