Project/ML-파이썬 주식 종목 예측
머신러닝 모델 만들기 및 테스트
CoderHan
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차원 필터 여러개를 통해 정제된 데이터를 얻었다는 점에서 내가 만든 모델과 차이가 있다... 그래서 나는 학습데이터의 부족함이라고 판단하고 데이터 양을 늘려서 시험해봐야겠다
반응형