얼마전에 로또분석에 관해 김태영님께서 포스팅한 딥러닝 글을 보게되었습니다. 평소에 로또나 주식에 관심이 많았기에 기존 분석방법을 고도화 하고 싶어 김태영님의 코드를 참고하였고, 이를 R버전으로 포스팅해보겠다. 물론 현재 이 외에 다양한 시도를 해보는 중이다.
참고 : 김태영님의 블로그
로또 자료 생성
로또 자료 생성의 경우 멀티 코어를 활용하였다. 또한 패키지 로드가 귀찮아 만들었던 개인 패키지를 활용하였다.
library(devtools)
if(!require(lotto))install_github('qkdrk777777/lotto')
if(!require(DUcj))install_github('qkdrk777777/DUcj')
# 개인 패키지
library(DUcj)
# DUcj::package 는 if(!require(패키지))install.packages('패키지')를 동시에 진행해주는 함수
package('progress')
package('XML')
package('stringr')
package('rvest')
package(parallel)
package(foreach)
package(rvest)
package(xml2)
url<-'https://search.naver.com/search.naver?sm=tab_hty.top&where=nexearch&query=%EB%A1%9C%EB%98%90&oquery=%EB%A1%9C%EB%98%90&tqi=TmrKidpVuFdsssc0EvVssssssUd-075322'
line<-read_html(url,encoding="UTF-8")
p1<-html_nodes(line,css='._lotto-btn-current em')%>%html_text()
last=as.numeric(substr(p1,1,3))
last
spec=detectCores()
spec
cl=makeCluster(spec)
data=NULL
try({url<-paste0('https://search.naver.com/search.naver?sm=tab_drt&where=nexearch&query=',last:1,'%ED%9A%8C%EB%A1%9C%EB%98%90')
c=data.frame(t(parApply(cl,MARGIN=1,data.frame(url),function(x){
(as.numeric(strsplit(stringr::str_trim(
rvest::html_text(rvest::html_nodes(xml2::read_html(x,encoding='UTF-8'),css='.num_box'))),split=' ')[[1]][1:6]))})))
data=cbind(num=last:1,c)},silent = T)
stopCluster(cl)
Sys.sleep(3)
# 멀티코어로 크롤링을 실패한 경우 다음과 같이 진행
if(is.null(data)){
url<-paste0('https://search.naver.com/search.naver?sm=tab_drt&where=nexearch&query=',last:1,'%ED%9A%8C%EB%A1%9C%EB%98%90')
data=NULL;t=0
for( i in url){t=t+1
data=rbind(data,data.frame(num=(last:1)[t],t(as.numeric(strsplit(stringr::str_trim(
rvest::html_text(rvest::html_nodes(xml2::read_html(i,encoding = 'UTF-8'),css='.num_box'))),split=' ')[[1]][1:6]))))
message(t/last*100)
}
}
분석용 데이터 생성
library(plyr)
rm(list=setdiff(ls(),c('data','data2')))
data2<-matrix(0,ncol=45,nrow=nrow(data));colnames(data2)=1:45
for(i in 1:nrow(data2)){
for(j in 2:7){
for(k in 1:45){
if(data[i,j]==k)data2[i,k]<-1}}}
rownames(data2)<-nrow(data2):1
library(keras)
library(tensorflow)
library(reticulate)
delete=data2
train=data.matrix(delete[-1,])
train=array(train,dim=c(1,nrow(train),ncol(train)))
target=data.matrix(delete[-nrow(data),])
모델 생성
model=keras_model_sequential()%>%
layer_cudnn_lstm(units=128,batch_input_shape=c(1,1,dim(train)[3]),return_sequences = F,stateful = T)%>%
layer_dense(units=45,activation = 'sigmoid')
model %>% compile(
optimizer = "adam",
loss = 'binary_crossentropy')
M_train_loss=c()
M_val_loss=c()
for(epoch in 1:150){
model$reset_states()
train_loss=c()
for (i in 1:700){
xs=train[,i,,drop=F]
ys=target[i,,drop=F]
train_loss=c(loss,model$train_on_batch(xs,ys))}
val_loss=c()
for( i in 700:800){
xs=train[,i,,drop=F]
ys=target[i,,drop=F]
val_loss=c(loss,model$test_on_batch(xs,ys))}
M_train_loss=c(M_train_loss,mean(train_loss))
M_val_loss=c(M_val_loss,mean(val_loss))
print(epoch)
}
matplot(cbind(M_train_loss,M_val_loss),type='l')
ls=list()
for(i in 1:800){
source('./MC_test.R')
}
ls1=ls
ls=list()
for(i in (800:(nrow(data)-1))){
source('./MC_test.R')
}
ls2=ls
table(rep(names(unlist(ls1)),unlist(ls1)))
table(rep(names(unlist(ls2)),unlist(ls2)))
i=dim(train)[2]
ball_list=c()
for(j in 1:10){
xs=train[,i,,drop=F]
pred=model$predict_on_batch(xs)
ball_box=rep(1:45,as.integer(pred*100+1))
selected_balls=c()
while(T){
if (length(selected_balls)==6) break
ball=sample(ball_box,1)
if (!(ball %in% selected_balls)) selected_balls=c(selected_balls,ball)
}
ball_list=rbind(ball_list,sort(selected_balls))
}
source 코드로 사용된 MC_test.R 코드
검증 코드는 편의상 2등을 생략하였는데 크롤링으로 데이터 생성할 때부터 보너스번호를 고려하여 짜면 될거 같다.
rank=c()
for(j in 1:10){
xs=train[,i,,drop=F]
pred=model$predict_on_batch(xs)
ball_box=rep(1:45,as.integer(pred*100+1))
selected_balls=c()
while(T){
if (length(selected_balls)==6) break
ball=sample(ball_box,1)
if (!(ball %in% selected_balls)) selected_balls=c(selected_balls,ball)
}
selected_balls
temp=length(intersect(selected_balls,data[i+1,-1]))
rank=c(rank,ifelse(temp==6,'1등',ifelse(temp==5,'3등',ifelse(temp==4,'4등',ifelse(temp==3,'5등',NA)))))
}
# print(i)
ls[[i]]=table(rank)
참고 : loss function 을 커스터마이징하여 분석을 진행할때 활용한 코드
lossfunction <- function(y, t) {
k_binary_crossentropy(y,t)
}
model %>% compile(
optimizer = "adam",
loss = function(y_true, y_pred)
lossfunction(y_true, y_pred)
)
'R' 카테고리의 다른 글
automap::autoKrige fit.method 의존성 문제 (0) | 2020.07.18 |
---|---|
R 스케줄링 (0) | 2020.01.19 |
[ggplot2] 시각화 정리 (0) | 2019.12.08 |
[R][SQL] RMariaDB 외부 접속 설정하기 (0) | 2019.11.29 |
[공간정보오픈플렛폼]위경도 변환, 주소 변환 (0) | 2019.11.27 |