在《体彩历险记》中,我介绍了一些对体育彩票的数据分析以及购买思考,在文章结尾提到这只是个开始,我是计划伴随着继续购买彩票的经历,写一系列的体彩相关的文章的。从写上一篇到现在,抛去春节期间淘宝彩票未提供服务,我依然增加了一个月的购买经验。最深的感受是体彩水也真的很深,只靠先前的一些分析思考很难长期立足,这一个月的战绩是小赔。这期间我对NBA比赛有了一些新感受,思考了一些新的购买方案,还有一个自己觉得很赞的想法在孵化。但是这想法还没有成型,也需要数据和实战去验证。所以我想先写一些过渡性的文章,将这个系列进行下去。
上篇文章中,我用数据把所有球队放在一块展示了不少结果,但是当我们真的要购买NBA体彩的时候,我们通常面对的是一天8,9场的比赛对阵。要看每场比赛的双方的数据对比,不管是从自己计算的整体结果里找,还是到彩票网站上去看,无疑都是费神的体力活。所以既然是要长期从事这个“事业”,就肯定希望每次能自动地展示所有场次的最新的数据对比。
auto_vs.R是我写的一个自动展示明日NBA各场次数据对比的R脚本,在R交互行里允许source("auto_vs.R")
即可获得如下的数据展示:
展示结果中值为NaN
的地方表示此球队(行)最近20天没有主场或客场比赛(列)。上图中最后对2014-02-21的NBA3场比赛分别做了数据对比,从主客场胜率到主客场输赢分差,到是否背靠背,共对比了14个字段。last
表示最近连胜或连败情况,负值表示连败;is-back-to-back
表示明日的比赛是否是背靠背(即是否是两天内的第二场比赛),1表示是背靠背。选取计算明天的场次是因为NBA体彩只能在前一天购买第二天的比赛。需要说明的是,auto_vs.R所需要的3个文件数据nba.txt,latest.txt,matches.txt(都已分享在百度网盘)都是从chrome的console直接抓取,每次更新数据需要手动粘贴代码运行。如果采用爬虫程序,就能只用一个脚本完成数据的更新和上述计算结果的展示了。
附:auto_vs.R脚本
print(date())
#比赛结果数据
nba <- read.table("../resources/nba/nba.txt", sep="\t", header=T, as.is=c(T,F,T,T,T,F))
nba <- na.omit(nba)
nba$date <- as.Date(nba$date)
nba$win[nba$diff < 0] <- -1 #主场赢
nba$win[nba$diff > 0] <- 1 #客场赢
#各球队最近连胜或连败情况
latest <- read.table("../resources/nba/latest.txt", sep="\t", row.names=1, header=F, as.is=T)
#NBA赛程,包括未来的比赛
matches <- read.table("../resources/nba/matches.txt", sep="\t", header=T, as.is=T)
matches$date <- as.Date(matches$date)
#原始数据分差有误,重新计算分差:客场-主场
nba$diff <- sapply(strsplit(nba$score, ":"), FUN=function(x){return(as.integer(x[1])-as.integer(x[2]))})
#设置使用数据的日期段限制,以便计算的数据能更好地预测
period <- 20 #自由选择,一般选最近20天的数据进行下面的计算
nba <- nba[nba$date >= (max(nba$date)-period),]
print(paste("最近", period, "天的数据如下:"))
#计算主场胜率排行和客场胜率排行榜
win.lose.zhu <- table(nba$zhudui, nba$win)
win.rate.zhu <- sort(win.lose.zhu[,"-1"]/rowSums(win.lose.zhu), decreasing=T) #主场胜率排行榜
win.rate.zhu <- as.data.frame(win.rate.zhu)
win.lose.ke <- table(nba$kedui, nba$win)
win.rate.ke <- sort(win.lose.ke[,"1"]/rowSums(win.lose.ke), decreasing=T) #客场胜率排行榜
win.rate.ke <- as.data.frame(win.rate.ke)
#计算胜率总排行榜
win.rate.all <- (win.lose.ke[,"1"]+win.lose.zhu[,"-1"])/(rowSums(win.lose.ke)+rowSums(win.lose.zhu))
win.rate.all <- sort(win.rate.all, decreasing=T)
win.rate.all <- as.data.frame(win.rate.all)
win.all <- cbind(win.rate.all, win.rate.zhu[row.names(win.rate.all),], win.rate.ke[row.names(win.rate.all),])
names(win.all) <- c("all", "zhu", "ke")
win.all$diff <- win.all$zhu - win.all$ke
print("胜率总情况")
print(win.all)
#提取一只球队的战绩数据
schedule.oneteam <- function(team){
schedule.zhu <- nba[nba$zhudui==team, c("date", "kedui", "diff", "win")]
schedule.zhu$diff <- -schedule.zhu$diff
schedule.zhu$win <- -schedule.zhu$win
names(schedule.zhu)[2] <- "rival"
schedule.ke<- nba[nba$kedui==team, c("date", "zhudui", "diff", "win")]
names(schedule.ke)[2] <- "rival"
schedule <- rbind(schedule.zhu, schedule.ke)
schedule$zhuke <- c(rep("主场", nrow(schedule.zhu)), rep("客场", nrow(schedule.ke)))
return(schedule[order(schedule$date),])
}
#计算一个球队的连胜或连败记录
streak <- function(team, lose=T){
schedule <- schedule.oneteam(team)
lose.str <- paste(schedule$win, collapse="")
lose.str <- gsub("-1", "0", lose.str)
split <- if(lose) "1+" else "0+"
type <- if(lose) "连败" else "连胜"
lose.counts <- nchar(unlist(strsplit(lose.str, split)))
lose.max <- max(lose.counts)
max.num <- sum(lose.counts %in% lose.max)
return(c(lose.max, max.num))
}
#按照胜率总排行计算各球队的连胜或连败记录
streak.lose <- sapply(row.names(win.rate.all), streak)
streak.win <- sapply(row.names(win.rate.all), FUN=function(x,lose=F)streak(x, lose))
streak.all <- cbind(t(streak.lose), t(streak.win))
streak.all <- as.data.frame(streak.all)
names(streak.all) <- c("lose.max", "lose.max.num", "win.max", "win.max.num")
cat("\n\n")
print("各球队的连胜连败记录")
print(streak.all)
#计算各球队主客场赢输分差
diff.zhu.win <- sapply(row.names(win.rate.zhu), function(x)return(-mean(nba$diff[nba$zhudui==x & nba$diff<0])))
diff.ke.win <- sapply(row.names(win.rate.ke), function(x)return(mean(nba$diff[nba$kedui==x & nba$diff>0])))
diff.zhu.lose <- sapply(row.names(win.rate.zhu), function(x)return(-mean(nba$diff[nba$zhudui==x & nba$diff>0])))
diff.ke.lose <- sapply(row.names(win.rate.ke), function(x)return(mean(nba$diff[nba$kedui==x & nba$diff<0])))
diff.all <- cbind(diff.zhu.win, diff.zhu.lose, diff.ke.win, diff.ke.lose)
diff.all <- diff.all[row.names(win.rate.all),]
cat("\n\n")
print("各球队主客场赢输分差")
print(diff.all)
#自动展示某日的所有场次比赛双方数据对比
match.predict <- function(kedui, zhudui, date) {
wa <- win.all[c(kedui, zhudui),]
da <- diff.all[c(kedui, zhudui),]
sa <- streak.all[c(kedui, zhudui),]
last <- latest[c(kedui, zhudui),]
#计算是否背靠背
before.ke <- matches$date[matches$kedui==kedui | matches$zhudui==kedui]
back.ke <- as.numeric((as.Date(date)-max(before.ke[before.ke<date]))==1)
before.zhu <- matches$date[matches$kedui==zhudui | matches$zhudui==zhudui]
back.zhu <- as.numeric((as.Date(date)-max(before.zhu[before.zhu<date]))==1)
back <- cbind(back.ke, back.zhu)
vs <- as.data.frame(rbind(t(wa), t(da), t(sa), last, back))
rownames(vs)[nrow(vs)] <- "is-back-to-back"
vs[,1] <- as.numeric(vs[,1])
vs[,2] <- as.numeric(vs[,2])
return(vs)
}
#展示明天的比赛VS数据
tomorrow <- Sys.Date()+1
result <- apply(matches[matches$date==tomorrow, c("kedui","zhudui")], 1, FUN=function(x){match.predict(x[1], x[2], tomorrow)})
cat("\n\n")
print(paste(tomorrow, "比赛VS数据:"))
print(result)
网友评论