環境
OS : Windows
R : Microsoft R Open 3.2.5
CPU : intel core i7-8550U 4コア8スレッド
メモリ : 8GB
これからやること
前回(https://qiita.com/gaborotta/items/65b6150e85b150491993) ランキング20位以内に入る動画かどうかを判定するモデルを何となく作成して、説明変数のパラメータを見てみたけど、そもそもモデルの精度はどないなの?
ということで、今回はちょっと精度を上げる方向で頑張ってみました。
前回、5分動画、10分動画、フォロワー数多い、動画数多いのダミー変数を作成するとき、適当に閾値を決めていたのですが、ここをちゃんと求めていきます。
そもそもの目的を考える
今回は、ある種のマーケティング的分析になります。
モデルの精度を上げることも大事ですが、それよりも大事なのは各説明変数が目的変数に対してどの程度影響するのか、有意な変数であるのかです。
つまりは、どのくらいの動画時間が適切なのか、何時に投稿すると20位以内に入りやすいのか等を見ていきます。
SVMとかニューラルネットワークを使うと精度は上がるけれども、各説明変数の影響度合いが分かりにくいので、モデルはロジットモデルのままにします。
ただ、モデルの精度が低いと本来であれば有意なものも有意でなかったり、その逆も生じうるので、精度を高める努力をします。
前回のモデルの精度
前回はざっくりと20位以内に入る動画かどうかの判定結果が合っているか、そうでないかで見ていました。
そうではなくて、20位以外の動画がどのくらい20位以外と判定されて、以内の動画がどれだけ以内と判定されたかに着目します。
以下の、RATE00は以外の動画が以外と判定された割合。RATE11は以内の動画が以内と判定された割合を示しています。
両者の平均を取ると、0.651程度の判定精度であることが分かります。
これを高めれるような各閾値を見つけていきます。
[1] "Calc Fit Rate"
RATE00 RATE01 RATE10 RATE11
1: 0.9270558 0.0729442 0.6243017 0.3756983
> (0.9270558+0.3756983)/2
[1] 0.6513771
方法と前処理
5分動画、10分動画、フォロワー数多い、動画数多いのダミー変数を作成するための閾値、計6変数について最適値を求めます。
glmの結果から得たモデルの精度を目的変数として、これを最大化する各変数の値を求めます。
それぞれの変数の値はある程度の範囲内に収まるようにするので、制約条件付きということになります。
で、非線形制約条件付非線形最適化問題用のパッケージ、Rsolnpのgosolnp関数を使用します。
そのために、閾値を入力したらglmの結果精度を返す関数を作成し、gosolnpに突っ込みます。
今回の制約条件は非線形ではないので、optim関数とかでも最適化できるのですが、
gosolnp関数は複数の最適解が存在する場合のために、初期値を何度も繰り返し変更して最適値を求める機能と、並列化処理が行えるようになっているので、今回はこれを使います。
閾値の関係ない部分の処理
閾値が関係ない部分、投稿時間やニコニコVer、タグ名等はあらかじめ処理してCSVで出力しておきます。
もちろんデータベースに書き込みでもOK。
### 共通前処理###
# Divide data within 20th place and others
videoData <- videoData %>% mutate(isOver20 = ifelse( MAX_RANK <= 20, 1, 0)) %>% mutate(isOver20=factor(isOver20))
# 不要データの削除
videoData0<-videoData%>%filter(USER_ID!=0,FOLLOWER_NUM>0,VIDEO_NUM>0,DATE!="",LENGTH!="")
# 投稿時間のダミー変数化
videoData0<-mutate(videoData0,DATE=as.character(DATE))
videoData0<-separate(videoData0,DATE,into = c("day", "time"),sep = "T",extra = "drop")
videoData0<-separate(videoData0,time,into = c("PUSH_HOUR", "minute","second"),sep = ":",extra = "drop")
videoData0<-videoData0%>%select(-minute,-second)%>%mutate(PUSH_HOUR=factor(PUSH_HOUR))
# 動画時間のダミー変数化
videoData0<-videoData0 %>% separate(LENGTH,into = c("minute"),sep = c("秒"),extra = "drop")
videoData0<-videoData0 %>% separate(minute,into = c("minute", "second"),sep = c("分"),extra = "drop")
videoData0<-videoData0 %>% separate(minute,into = c("hour", "minute"),sep = c("時間"),extra = "drop",fill="left")
videoData0<-videoData0 %>% mutate(hour=as.numeric(hour),minute=as.numeric(minute),second=as.numeric(second))
videoData0[is.na(videoData0)]<-0
videoData0<-videoData0 %>% mutate(time=hour*3600+minute*60+second)%>%select(-hour,-minute,-second)
# ニコニコ動画Ver、投稿者名のダミー変数化
videoData0<-videoData0%>%mutate(NICO_VER=factor(NICO_VER),NAME=factor(NAME))
# データ整形
videoData0<-videoData0%>%select(-URL.x,-URL.y,-USER_ID,-day,-MAX_RANK)
# 動画タグのダミー変数化
tag_name<-group_by(videoTagData,TAG_NAME)
tag_name<-tag_name%>%summarise(count=n())%>%filter(count>=100)%>%setorder(-count)
tag_name<-videoTagData%>%inner_join(tag_name,by="TAG_NAME")
tag_name<-tag_name%>%mutate(TAG_NAME=factor(TAG_NAME))
df_dummy <- dummyVars(~.,data=tag_name)
df_dummy<- data.table(predict(df_dummy, tag_name))
head(df_dummy)
df_dummy_tag<-df_dummy%>%group_by(VIDEO_ID)%>%summarise_each(funs(sum), starts_with("TAG_NAME"))#%>%mutate_each(funs(factor),starts_with("TAG_NAME"))
head(df_dummy_tag)
# サンプルデータ化
sample<-inner_join(videoData0,df_dummy_tag,by=c("ID"="VIDEO_ID"))
# データ保存
write.csv(sample,"sample.csv",row.names=FALSE)
閾値処理部分とモデル構築・精度計算の関数化
最適化する関数を作成します。
glm関数は、より処理速度の速いspeedglmパッケージのspeedglmを使用します。
summaryが見れなかったりと、色々問題があるっぽいですが、パラメータ推定はしっかりとしてくれるのでOK。
ちなみにfitted関数も使えないので、predict関数で推定結果を計算しています。
モデル構築・精度計算関数の引数には、最適値を求めたい変数をベクトルで与えれるようにします。
また、Rsolnpは関数の最小値を求める仕様なので、返り値には-1を掛けて負の値にしています。
### 閾値処理###
# 時間帯区分の作成
setDummy<-function(sample_data,m5_min,m5_max,m10_min,m10_max,follower_min,video_min){
#時間帯ダミー
sample_data<-sample_data%>%mutate(TIME_RANGE=
if_else(time>=m5_min&time<=m5_max,"TIME_5m",
if_else(time>=m10_min&time<=m10_max,"TIME_10m","other")))
sample_data<-sample_data%>%mutate(TIME_RANGE=factor(TIME_RANGE))
#フォロワー数と動画投稿数のダミー変数化
sample_data<-sample_data%>%mutate(FOLLOWER_RANGE=if_else(FOLLOWER_NUM>=follower_min,"MANY","FEW"))%>%mutate(FOLLOWER_RANGE=factor(FOLLOWER_RANGE))
sample_data<-sample_data%>%mutate(VIDEO_RANGE=if_else(VIDEO_NUM>=video_min,"MANY","FEW"))%>%mutate(VIDEO_RANGE=factor(VIDEO_RANGE))
#不要列の削除
sample_data<-sample_data%>%select(-time,-FOLLOWER_NUM,-VIDEO_NUM,-ID,-NAME)
sample_data<-sample_data%>%mutate_all(funs(factor))
return(sample_data)
}
getFitRate<-function(value,sample_data){
#データ読み込み
value<-value
m5_min<-value[1]
m5_max<-value[2]
m10_min<-value[3]
m10_max<-value[4]
follower_min<-value[5]
video_min<-value[6]
#時間区間の整合を取るためのearly returm
if(!m5_min<m5_max){return(0)}
if(!m10_min<m10_max){return(0)}
if(!m5_max<m10_min){return(0)}
cat(sprintf("%1.6f : %1.6f : %1.6f : %1.6f : %1.6f : %1.6f\n",m5_min,m5_max,m10_min,m10_max,follower_min,video_min))
#サンプル作成
print("Make Sample")
sample_data<-setDummy(sample_data,m5_min,m5_max,m10_min,m10_max,follower_min,video_min)
#モデル化
#一般化線形モデル 二項ロジットモデル
print("Make Model")
result <- speedglm(isOver20 ~., data=sample_data, family=binomial(link="logit"))
#適合度
print("Calc Fit Rate")
sample_data<-sample_data%>%mutate(fit=predict(result,sample_data,type="response"))
sample_data<-sample_data%>%mutate(isOver20_Simu=if_else(fit>=0.5,1,0))
re<-sample_data%>%group_by(isOver20,isOver20_Simu)%>%summarise(count=n())
re_sum<-re%>%group_by(isOver20)%>%summarise(sum=sum(count))
re<-re%>%right_join(re_sum,by="isOver20")%>%mutate(rate=count/sum)
result<-data.table(RATE00=re$rate[1],RATE01=re$rate[2],RATE10=re$rate[3],RATE11=re$rate[4])
print(result)
res<- -1*mean(c(re$rate[1],re$rate[4]))
cat(sprintf("\n#Result\n################################################\n", res))
cat(sprintf("%1.6f : %1.6f : %1.6f : %1.6f : %1.6f : %1.6f",m5_min,m5_max,m10_min,m10_max,follower_min,video_min))
cat(sprintf("\n########### Fit Rate : %1.6f #################\n#\n\n", res))
return(res)
}
Rsolnp
https://cran.r-project.org/web/packages/Rsolnp/Rsolnp.pdf
こちらを参考にgosolnp関数を使用します。
gosolnp(pars = NULL, fixed = NULL, fun, eqfun = NULL, eqB = NULL, ineqfun = NULL,
ineqLB = NULL, ineqUB = NULL, LB = NULL, UB = NULL, control = list(),
distr = rep(1, length(LB)), distr.opt = list(), n.restarts = 1, n.sim = 20000,
cluster = NULL, rseed = NULL, ...)
で、gosolnp関数の中でsolnp関数を使っているのですが、LB,UBをsolnp関数で指定すると値が収束しない事態が発生。
というわけでgosolnp関数の中身を少しいじります。
以下の部分で、solnp関数呼び出し時の引数指定部分を[#LB = LB, UB = UB,]という感じでコメントアウトして消します。
これで準備OK。
if( !is.null(cluster) )
{
clusterExport(cluster, c("gosolnp_rndpars"), envir = environment())
solution = parLapply(cluster, as.list(1:n.restarts), fun = function(i) {
xx = gosolnp_rndpars[i,]
names(xx) = gosolnp_parnames
ans = try(solnp(pars = xx, fun = fun, eqfun = eqfun,
eqB = eqB, ineqfun = ineqfun,
ineqLB = ineqLB, ineqUB = ineqUB,
#LB = LB, UB = UB,
control = control, ...), silent = TRUE)
if(inherits(ans, "try-error")){
ans = list()
ans$values = 1e10
ans$convergence = 0
ans$pars = rep(NA, length(xx))
}
return( ans )
})
} else {
solution = lapply(as.list(1:n.restarts), FUN = function(i){
xx = gosolnp_rndpars[i,]
names(xx) = gosolnp_parnames
ans = try(solnp(pars = xx, fun = fun, eqfun = eqfun,
eqB = eqB, ineqfun = ineqfun,
ineqLB = ineqLB, ineqUB = ineqUB,
#LB = LB, UB = UB,
control = control, ...), silent = TRUE)
if(inherits(ans, "try-error")){
ans = list()
ans$values = 1e10
ans$convergence = 0
ans$pars = rep(NA, length(xx))
}
return( ans )
})
}
最適化
先ほども言ったとおり、CPUでの並列化処理が出来るのでそれを利用。
parallelパッケージでクラスターを作成し、gosolnp関数に引き渡します。
クラスターに計算で必要な自作関数やパッケージを渡すことを忘れずに。
n.restarts とn.simの値を変えることで試行回数を変えれます。
より精度の高いものを探したいときや計算時間を短くしたいときにいじりましょう。
library(parallel)
library(Rsolnp)
# パラメータ最適化
# Rsolnpの使用。
# 並列化クラスターの作成
cl <- makeCluster(detectCores())
clusterEvalQ(cl, date())
clusterExport(cl, c("setDummy"))
clusterEvalQ(cl,library(speedglm))
clusterEvalQ(cl,library(data.table))
clusterEvalQ(cl,library(dplyr))
## LB,UBで各閾値の範囲を指定
value0<-c(300,360,540,660,2000,50)
LB = c(240,300,480,600,1000,25)
UB = c(300,360,600,720,10000,1000)
# 制約付き最適化実行
# solution<-solnp(value0,fun = getFitRate,control = ctrl,sample_data=sample0)
# solution<-gosolnp(value0,fun = getFitRate,LB = LB, UB = UB,n.sim=1,sample_data=sample0)
solution<-gosolnp(value0,fun = getFitRate,LB = LB, UB = UB,n.restarts = 4,n.sim=128,cluster = cl,sample_data=sample0)
solution
# クラスター停止
stopCluster(cl)
結果
精度は0.6981463となりました。前回より少し良くなったくらい。
やはりこれらの閾値をいじるよりは、タグ名をもっといじった方がいいかもしれない...。
ちなみに計算時間は2.065873 minsだったらしいです。結構早い。
> solution
$`pars`
[1] 273.6193 307.5727 591.9196 644.0166 5457.5306 435.5165
$convergence
[1] 0
$values
[1] -0.6981463 -0.6981463
$lagrange
[1] 0
$hessian
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 0 0 0 0 0
[2,] 0 1 0 0 0 0
[3,] 0 0 1 0 0 0
[4,] 0 0 0 1 0 0
[5,] 0 0 0 0 1 0
[6,] 0 0 0 0 0 1
$ineqx0
NULL
$nfuneval
[1] 37
$outer.iter
[1] 1
$elapsed
Time difference of 2.065873 mins
$vscale
[1] 1 1 1 1 1 1 1
$start.pars
[1] 273.6193 307.5727 591.9196 644.0166 5457.5306 435.5165
$rseed
[1] 1552287014
求めた閾値を使ってモデル化とパラメータ分析
以下の閾値を使うと良いみたいなので、これらを使ってモデルを構築します。
summaryを使いたいのでglmで。
$`pars`
[1] 273.6193 307.5727 591.9196 644.0166 5457.5306 435.5165
# モデル再構築
para<-solution$pars
sample1<-setDummy(sample0,para[1],para[2],para[3],para[4],para[5],para[6])
result <- glm(isOver20 ~., data=sample1, family=binomial(link="logit"))
# 説明変数のパラメータ分析
smma<-summary(result)
coe<-data.table(rownames(smma[["coefficients"]]),smma[["coefficients"]])
g1 <- ggplot(coe, aes(x = V1, y = Estimate, fill = V1))
g1 <- g1 + geom_bar(stat = "identity")+theme(legend.position = 'none')+theme(axis.text.x = element_text(angle = 90, hjust = 1))
plot(g1)
説明変数のパラメータ推定結果
以下の結果になりました。
TIME_RANGETIME_5mが有意になったのが大きな違いかなと。
しかし、TIME_RANGETIME_10m(10分動画ダミー)もTIME_RANGETIME_5m(5分動画ダミー)もVIDEO_RANGEMANY(動画投稿数多ダミー)も負のパラメータになってる。
それぞれがマイナスの効果があるということです。
FOLLOWER_RANGEMANYは2.025796とかなり正の効果があるみたいですが、閾値が5457.5人以上となると、それもそうだろうなという感じです。
投稿時間ダミーも有意なものが少なく、負の値をとっているものが多い印象。
結局、自分の裁量でコントロールできるのは動画に付けるタグ名くらいでしょうか。
しかし、有意なタグ名を見てみると、有名な投稿者固有のタグが多かったりと、なかなか難しいところ...。
> summary(result)
Call:
glm(formula = isOver20 ~ ., family = binomial(link = "logit"),
data = sample1)
Deviance Residuals:
Min 1Q Median 3Q Max
-2.3937 -0.6582 -0.4715 0.6759 3.1719
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -0.047188 0.313004 -0.151 0.880167
PUSH_HOUR 01 0.259993 0.133570 1.946 0.051596 .
PUSH_HOUR 02 -0.141452 0.180764 -0.783 0.433908
PUSH_HOUR 03 -0.052578 0.190628 -0.276 0.782689
PUSH_HOUR 04 -0.122043 0.215344 -0.567 0.570896
PUSH_HOUR 05 0.260182 0.152361 1.708 0.087699 .
PUSH_HOUR 06 0.133817 0.133717 1.001 0.316950
PUSH_HOUR 07 0.201381 0.124525 1.617 0.105838
PUSH_HOUR 08 0.121390 0.136277 0.891 0.373058
PUSH_HOUR 09 0.193378 0.139644 1.385 0.166116
PUSH_HOUR 10 -0.089508 0.139130 -0.643 0.520005
PUSH_HOUR 11 -0.015087 0.145357 -0.104 0.917332
PUSH_HOUR 12 -0.014727 0.129500 -0.114 0.909455
PUSH_HOUR 13 0.097830 0.143322 0.683 0.494866
PUSH_HOUR 14 -0.037632 0.149846 -0.251 0.801708
PUSH_HOUR 15 -0.002069 0.142839 -0.014 0.988441
PUSH_HOUR 16 -0.121307 0.149667 -0.811 0.417643
PUSH_HOUR 17 0.019366 0.115909 0.167 0.867308
PUSH_HOUR 18 -0.009163 0.101801 -0.090 0.928280
PUSH_HOUR 19 -0.010974 0.102863 -0.107 0.915038
PUSH_HOUR 20 -0.046665 0.106898 -0.437 0.662443
PUSH_HOUR 21 -0.375577 0.118766 -3.162 0.001565 **
PUSH_HOUR 22 -0.302255 0.118470 -2.551 0.010732 *
PUSH_HOUR 23 -0.251901 0.119603 -2.106 0.035192 *
NICO_VERGINZA 0.398252 0.094754 4.203 2.63e-05 ***
NICO_VERQ -0.140898 0.127051 -1.109 0.267436
NICO_VERRC 0.476952 0.107401 4.441 8.96e-06 ***
NICO_VERRC2 0.090231 0.126745 0.712 0.476521
NICO_VERSP1 0.183192 0.115726 1.583 0.113426
NICO_VERZero -0.195233 0.153208 -1.274 0.202558
NICO_VERβ 0.508500 0.137474 3.699 0.000217 ***
NICO_VERββ 0.068100 0.113801 0.598 0.549564
NICO_VERγ 0.212291 0.098648 2.152 0.031396 *
NICO_VERく -0.507283 0.305239 -1.662 0.096529 .
NICO_VER夏 0.106267 0.183170 0.580 0.561812
NICO_VER原宿 0.030278 0.111730 0.271 0.786399
NICO_VER秋 -0.606862 0.209268 -2.900 0.003732 **
NICO_VER冬 -9.862609 118.769947 -0.083 0.933820
TAG_NAME.1080p1 0.160840 0.248021 0.648 0.516666
TAG_NAME.7_days_to_die1 1.208152 0.239430 5.046 4.51e-07 ***
TAG_NAME.7DTD1 0.968477 0.387982 2.496 0.012554 *
TAG_NAME.biimシステム1 -0.095128 0.107522 -0.885 0.376303
TAG_NAME.biimシステムpart1リンク1 0.515764 0.235913 2.186 0.028797 *
TAG_NAME.biimシステム単発リンク1 0.661741 0.225245 2.938 0.003305 **
TAG_NAME.biim兄貴リスペクト1 -0.093930 0.111879 -0.840 0.401148
TAG_NAME.CeVIO実況プレイ1 -0.376221 0.207542 -1.813 0.069872 .
TAG_NAME.dbd1 0.393003 0.220581 1.782 0.074803 .
TAG_NAME.DbD1 -0.023230 0.205982 -0.113 0.910207
TAG_NAME.Dead_by_Daylight1 0.171259 0.167195 1.024 0.305691
TAG_NAME.EDF51 -0.428958 0.318459 -1.347 0.177987
TAG_NAME.Fate1 -0.288294 0.287496 -1.003 0.315969
`TAG_NAME.fate/go`1 -0.704759 0.330039 -2.135 0.032730 *
`TAG_NAME.Fate/go`1 -0.488844 0.292199 -1.673 0.094330 .
`TAG_NAME.Fate/Grand_Order`1 -0.525222 0.211856 -2.479 0.013170 *
`TAG_NAME.fate/grandorder`1 -0.715436 0.302069 -2.368 0.017863 *
TAG_NAME.FGO1 1.213573 0.202763 5.985 2.16e-09 ***
TAG_NAME.FGO宝具1 0.618836 0.328584 1.883 0.059654 .
TAG_NAME.gdgdゆっくりーず1 -0.196947 0.258756 -0.761 0.446579
TAG_NAME.Hearthstone1 -0.216777 1.034106 -0.210 0.833958
TAG_NAME.IA実況プレイ1 1.058210 0.323585 3.270 0.001074 **
TAG_NAME.Kenshi1 0.292255 0.161487 1.810 0.070331 .
TAG_NAME.MHW1 -0.276378 0.249613 -1.107 0.268195
TAG_NAME.MikuMikuDance1 -0.716278 0.439008 -1.632 0.102767
TAG_NAME.Minecraft1 -0.152270 0.148267 -1.027 0.304420
TAG_NAME.MMD艦これ1 0.504474 0.451249 1.118 0.263589
TAG_NAME.MO1 0.105158 0.651779 0.161 0.871826
TAG_NAME.moco781 0.720227 0.346544 2.078 0.037681 *
TAG_NAME.MTG1 -1.536401 0.608057 -2.527 0.011513 *
TAG_NAME.MUGEN1 0.084485 0.129660 0.652 0.514664
TAG_NAME.Nintendo_Switch1 1.270724 0.340176 3.735 0.000187 ***
TAG_NAME.nintendoswitch1 -1.429824 0.258295 -5.536 3.10e-08 ***
TAG_NAME.ONE実況プレイ1 -0.155773 0.319968 -0.487 0.626372
TAG_NAME.PCゲーム1 0.365634 0.188442 1.940 0.052343 .
`TAG_NAME.PLAYERUNKNOWN'S_BATTLEGROUNDS`1 0.458753 0.193998 2.365 0.018043 *
TAG_NAME.PS41 0.252164 0.152477 1.654 0.098172 .
TAG_NAME.pubg1 1.532021 0.233270 6.568 5.11e-11 ***
TAG_NAME.PUBG1 0.690207 0.169720 4.067 4.77e-05 ***
TAG_NAME.RimWorld1 -0.245892 0.238116 -1.033 0.301766
TAG_NAME.RTA1 0.398713 0.118406 3.367 0.000759 ***
TAG_NAME.Skyrim1 0.666482 0.315151 2.115 0.034447 *
TAG_NAME.Splatoon21 -0.394265 0.383188 -1.029 0.303524
TAG_NAME.steam1 1.055859 0.169756 6.220 4.98e-10 ***
TAG_NAME.Steam1 0.158280 0.091618 1.728 0.084058 .
TAG_NAME.TAS1 0.251597 0.160374 1.569 0.116692
TAG_NAME.TRPG1 -1.002298 0.262317 -3.821 0.000133 ***
TAG_NAME.VOICEROID1 -0.826668 0.290136 -2.849 0.004382 **
`TAG_NAME.VOICEROID+_琴葉_茜・葵`1 0.246586 0.185319 1.331 0.183319
TAG_NAME.VOICEROID実況プレイ1 -0.094359 0.079768 -1.183 0.236843
TAG_NAME.VOICEROID実況プレイPart1リンク1 -0.082289 0.117594 -0.700 0.484069
TAG_NAME.VOICEROID実況プレイ最終回リンク1 0.843028 0.220955 3.815 0.000136 ***
TAG_NAME.VOICEROID実況プレイ単発リンク1 -0.015591 0.251040 -0.062 0.950479
TAG_NAME.VOICEROID遊劇場1 0.966438 0.181935 5.312 1.08e-07 ***
TAG_NAME.World_of_Tanks1 -0.438180 0.478921 -0.915 0.360228
TAG_NAME.WoT1 0.287695 0.524738 0.548 0.583511
TAG_NAME.アニメ1 0.279109 0.245935 1.135 0.256421
TAG_NAME.ガンオン1 0.554031 0.674575 0.821 0.411473
TAG_NAME.ガンダムオンライン1 0.008805 0.624008 0.014 0.988742
TAG_NAME.クトゥルフ神話TRPG1 -0.556290 0.167748 -3.316 0.000912 ***
TAG_NAME.クトゥルフ神話TRPG第一話リンク1 -0.369064 0.347916 -1.061 0.288788
TAG_NAME.ゲーム1 -2.038489 0.286456 -7.116 1.11e-12 ***
TAG_NAME.ゲームPV1 -0.373859 0.240050 -1.557 0.119371
TAG_NAME.ゲームエフェクト集1 -0.458957 0.375571 -1.222 0.221699
TAG_NAME.ゲーム実況1 0.359370 0.207812 1.729 0.083754 .
TAG_NAME.さとうささら実況プレイ1 0.233984 0.243585 0.961 0.336761
TAG_NAME.サムネホイホイ1 0.695787 0.224030 3.106 0.001898 **
TAG_NAME.シノビガミ1 -1.044803 0.265922 -3.929 8.53e-05 ***
TAG_NAME.スパロボ1 1.005571 0.295541 3.402 0.000668 ***
TAG_NAME.スプラトゥーン21 -0.166390 0.382367 -0.435 0.663447
TAG_NAME.スマブラ1 0.788843 0.360824 2.186 0.028799 *
TAG_NAME.スマブラSP1 -0.035971 0.497249 -0.072 0.942332
TAG_NAME.とらねずの人1 2.184961 0.174580 12.516 < 2e-16 ***
TAG_NAME.どんたこす1 -2.242428 0.829237 -2.704 0.006847 **
TAG_NAME.ニンテンドースイッチ1 -0.295350 0.332353 -0.889 0.374184
TAG_NAME.ネタが多すぎてタグに困る動画1 0.426963 0.224717 1.900 0.057433 .
TAG_NAME.ハースストーン1 -1.457225 0.991546 -1.470 0.141657
TAG_NAME.バーチャルYouTuber1 -0.155331 0.184461 -0.842 0.399741
TAG_NAME.パワプロ1 -0.380305 0.453424 -0.839 0.401615
TAG_NAME.パワプロ20181 -0.905581 0.617246 -1.467 0.142340
TAG_NAME.ヒテッマンリスペクト1 -1.156956 0.393889 -2.937 0.003311 **
TAG_NAME.ファミコン1 -0.234405 0.255449 -0.918 0.358819
TAG_NAME.プレイ動画1 -0.100732 0.273865 -0.368 0.713010
`TAG_NAME.ボイロ×mtg`1 0.139737 0.630545 0.222 0.824615
`TAG_NAME.ボイロ×MTG`1 0.583082 0.573894 1.016 0.309625
TAG_NAME.ポケモン1 0.131194 0.225869 0.581 0.561349
TAG_NAME.ポケモンUSM1 -0.833034 0.396087 -2.103 0.035452 *
TAG_NAME.ポケモンusm対戦リンク1 -0.731593 0.303751 -2.409 0.016017 *
TAG_NAME.ポケモンUSM対戦リンク1 -1.177651 0.451623 -2.608 0.009118 **
TAG_NAME.ポケモン手描き実況リンク1 -0.434473 0.473677 -0.917 0.359020
TAG_NAME.マインクラフト1 0.304791 0.197881 1.540 0.123494
`TAG_NAME.モダン(mtg)`1 -1.662943 0.780492 -2.131 0.033119 *
TAG_NAME.もっと評価されるべき1 -0.534603 0.178160 -3.001 0.002694 **
TAG_NAME.モンスターハンターワールド1 0.807143 0.288766 2.795 0.005188 **
TAG_NAME.ゆづきず実況プレイ1 -0.555896 0.311298 -1.786 0.074142 .
TAG_NAME.ゆっくりTRPG1 -0.248221 0.166781 -1.488 0.136671
TAG_NAME.ゆっくりTRPG第一話リンク1 -0.025580 0.298620 -0.086 0.931736
TAG_NAME.ゆっくり解説1 0.295452 0.160543 1.840 0.065720 .
TAG_NAME.ゆっくり実況1 -0.290321 0.166443 -1.744 0.081114 .
TAG_NAME.ゆっくり実況プレイ1 -0.130657 0.060732 -2.151 0.031447 *
TAG_NAME.ゆっくり実況プレイPart1リンク1 0.245563 0.156746 1.567 0.117201
TAG_NAME.ゆっくり実況プレイ最終回リンク1 0.871286 0.216123 4.031 5.54e-05 ***
TAG_NAME.ゆっくり実況プレイ単発リンク1 0.425052 0.279950 1.518 0.128935
TAG_NAME.リアルタイムアタックpart1リンク1 0.609255 0.292495 2.083 0.037255 *
TAG_NAME.リアルタイムアタックPart1リンク1 0.734352 0.255164 2.878 0.004003 **
TAG_NAME.リターン1 1.879221 0.339732 5.531 3.18e-08 ***
TAG_NAME.レトロゲーム1 0.374493 0.193776 1.933 0.053284 .
TAG_NAME.嘘字幕シリーズ1 -0.829040 0.323168 -2.565 0.010307 *
TAG_NAME.音街ウナ実況プレイ1 0.046827 0.184003 0.254 0.799119
TAG_NAME.課金観戦リンク1 0.123193 0.284114 0.434 0.664576
TAG_NAME.艦これ1 -0.043088 0.289364 -0.149 0.881628
TAG_NAME.艦隊これくしょん1 -0.123972 0.304083 -0.408 0.683500
TAG_NAME.京町セイカ実況プレイ1 -0.223476 0.196860 -1.135 0.256291
TAG_NAME.琴葉葵1 0.474266 0.222964 2.127 0.033412 *
TAG_NAME.琴葉葵実況プレイ1 0.209340 0.117913 1.775 0.075837 .
TAG_NAME.琴葉茜1 0.171419 0.214782 0.798 0.424809
`TAG_NAME.琴葉茜・葵実況プレイ`1 0.191001 0.079187 2.412 0.015864 *
TAG_NAME.琴葉茜実況プレイ1 0.177687 0.115650 1.536 0.124437
TAG_NAME.琴葉姉妹実況プレイ1 -0.731662 0.214243 -3.415 0.000638 ***
TAG_NAME.結月ゆかり1 -0.360281 0.211387 -1.704 0.088312 .
TAG_NAME.結月ゆかり実況プレイ1 0.052924 0.075270 0.703 0.481982
TAG_NAME.弦巻マキ実況プレイ1 0.034138 0.090287 0.378 0.705352
TAG_NAME.字幕プレイ動画1 -1.492686 0.410286 -3.638 0.000275 ***
TAG_NAME.字幕プレイ動物園1 -1.718669 0.787777 -2.182 0.029134 *
TAG_NAME.実況プレイ動画1 -0.062351 0.095336 -0.654 0.513104
TAG_NAME.衝撃のラスト1 0.562057 0.256005 2.195 0.028128 *
TAG_NAME.神回1 0.529662 0.175132 3.024 0.002492 **
TAG_NAME.声優1 0.382531 0.294647 1.298 0.194195
TAG_NAME.千年戦争アイギス1 -2.095605 0.716195 -2.926 0.003433 **
TAG_NAME.多人数VOICEROID実況プレイ1 0.787613 0.211162 3.730 0.000192 ***
TAG_NAME.大乱闘スマッシュブラザーズSPECIAL1 -0.822664 0.502273 -1.638 0.101447
TAG_NAME.地球防衛軍51 -0.176956 0.254391 -0.696 0.486675
TAG_NAME.刀剣乱舞1 0.176855 0.339195 0.521 0.602090
TAG_NAME.刀剣乱舞偽実況1 -1.503234 0.546751 -2.749 0.005971 **
TAG_NAME.東北きりたん1 0.068430 0.182699 0.375 0.707994
TAG_NAME.東北きりたん実況プレイ1 0.031866 0.084987 0.375 0.707697
TAG_NAME.東北ずん子1 0.039800 0.288668 0.138 0.890340
TAG_NAME.東北ずん子実況プレイ1 -0.143002 0.120965 -1.182 0.237137
TAG_NAME.東北姉妹実況プレイ1 -0.059597 0.243441 -0.245 0.806602
TAG_NAME.日本語読めない卓1 0.839175 0.241132 3.480 0.000501 ***
TAG_NAME.任天堂1 0.430196 0.307432 1.399 0.161716
TAG_NAME.任天堂ゲーム配信1 0.414397 0.248255 1.669 0.095070 .
TAG_NAME.縛りプレイ1 -0.003862 0.167907 -0.023 0.981650
TAG_NAME.裏影P1 2.479544 0.427647 5.798 6.71e-09 ***
TAG_NAME.紲星あかり1 0.307995 0.179995 1.711 0.087056 .
TAG_NAME.紲星あかり実況プレイ1 0.020426 0.102522 0.199 0.842078
TIME_RANGETIME_10m -0.026314 0.083485 -0.315 0.752615
TIME_RANGETIME_5m -0.383133 0.176199 -2.174 0.029673 *
FOLLOWER_RANGEMANY 2.025796 0.048353 41.896 < 2e-16 ***
VIDEO_RANGEMANY -1.304770 0.089128 -14.639 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 21458 on 18254 degrees of freedom
Residual deviance: 16673 on 18067 degrees of freedom
AIC: 17049
Number of Fisher Scoring iterations: 11
結論
一連の分析の中で、ランキング20位以内に入る動画の要因を分析してみたのですが、
結論としては人気な人が人気。
とは言ってもモデル自体の精度がそんなに良くないので、そこまで気にすることでもないかと。
RATE10(20位以内だけど20位以外と判定されたもの)の割合が約0.51だったので、あまり気にしないでいいかと。
面白い動画がランクインする!それだけが真実です。
> res<-getFitRate(para,sample0)
273.619336 : 307.572748 : 591.919615 : 644.016639 : 5457.530632 : 435.516484
[1] "Make Sample"
[1] "Make Model"
[1] "Calc Fit Rate"
RATE00 RATE01 RATE10 RATE11
1: 0.9066677 0.09333233 0.5103751 0.4896249
# Result
################################################
273.619336 : 307.572748 : 591.919615 : 644.016639 : 5457.530632 : 435.516484
########### Fit Rate : -0.698146 #################
#
まとめ
統計的な基礎集計からモデル構築、機械学習的手法によるパラメータ推定まで行いました。
一連の統計分析の流れを実践できたかなと思います。
とりあえずこのシリーズはこれで終了の予定です。