一日一膳(当社比)

RとJavaと時々数学

基本情報技術者試験まであと一週間を切りました

(この行を消して、ここに「迷い」と「決断」について書いてください)

#「迷い」と「決断」

りっすん×はてなブログ特別お題キャンペーン〜りっすんブログコンテスト2019「迷い」と「決断」〜 Sponsored by イーアイデム

基本情報技術者試験とは

基本情報技術者試験とは,情報処理に関する知識を有することを示す国家資格です.毎年2回(4月と10月)開催される試験であり,この試験に合格すると 日曜日の朝に早起きできる能力 を客観的に示すことが出来ます.

合格率の推移

基本情報技術者試験の合格率は,大体20%~30%の間で推移しています. (基本情報技術者試験ドットコムより,統計を拝借しました) 以下,直近14回の応募者, 受験者, 合格者の情報です.

開催 応募者 受験者 合格者
24年春期 75,085人 52,582人 12,437人
24年秋期 79,674人 58,905人 15,987人
25年春期 66,667人 46,416人 10,674人
25年秋期 76,020人 55,426人 12,274人
26年春期 65,141人 46,005人 11,003人
26年秋期 74,577人 54,874人 12,950人
27年春期 65,570人 46,874人 12,174人
27年秋期 73,221人 54,347人 13,935人
28年春期 61,281人 44,184人 13,418人
28年秋期 75,095人 55,815人 13,173人
29年春期 67,784人 48,875人 10,975人
29年秋期 76,717人 56,377人 12,313人
30年春期 73,581人 51,377人 14,829人
30年秋期 82,347人 60,004人 13,723人

f:id:kimigayoseishou:20190414212151p:plain
基本情報技術者試験合格率推移

次回の合格率をブラウン運動モデル予測してみる

合格率をモデリングしてみます.  t回目の合格率を p_tとして,これが次のようなモデルで表されるとします.

 \displaystyle{{\rm logit}(p_t) =  {\rm logit}(p_{t - 1})  + \epsilon_t \quad ( \epsilon_t \sim N(0, \sigma ^2))}

ただし,ここで {\rm logit}(x) := \log \Bigl( \frac{x}{1-x} \Bigr)とおいた.

要は ブラウン運動 ですね.

以下Rパッケージの{dlm}で推定するコードです.


FE_stats_csv <- read.csv('FE_stats.csv', encoding = 'utf-8')
View(FE_stats_csv)

開催 <- paste("H",gsub("年秋期", "-10", gsub("年春期", "-04",FE_stats_csv$開催)))
受験者 <- as.numeric(gsub(",", "",gsub("人", "", FE_stats_csv$受験者)))
合格者 <- as.numeric(gsub(",", "",gsub("人", "", FE_stats_csv$合格者)))

FE_stats <- data.frame(開催 = 開催, 受験者 = 受験者, 合格者 = 合格者)

df <- data.frame(t = FE_stats$開催,success_rate = FE_stats$合格者 / FE_stats$受験者)
g <- ggplot(df, aes(x = t, y = success_rate, group = 1))+
    geom_line(colour = 'darkblue')+
    ylim(0.10, 0.40)
plot(g)

lgt <- function(p) {
    return(log(p/(1-p)))
}

invlgt <- function(x) {
    return(exp(x) / (1 + exp(x)))
}

lgt_suc_rat <- data.frame(t = FE_stats$開催, val = lgt(df$success_rate))
g <- ggplot(lgt_suc_rat, aes(x = t, y = val, group = 1))+
    geom_line(colour = 'darkorange')+
    ylim(-2.0, -0.0)
plot(g)

#autp correlation plot
lgt_suc_rat_acf <- acf(lgt_suc_rat$val, plot = FALSE)
acf_data <- data.frame(lag = lgt_suc_rat_acf$lag, acf = lgt_suc_rat_acf$acf)
acf_plot <- ggplot(acf_data, aes(x = lag, y = acf))+
    geom_hline(aes(yintercept = 0))+
    geom_segment(mapping = aes(xend = lag, yend = 0))
plot(acf_plot)
#Brown_motion_fitting###########################################################
#Brownian Motion
brownian_motion <- function(theta) {
    dlmModPoly(order = 1, dV = 0
               ,dW = exp(theta[1]), m0 = theta[2], C0 = exp(theta[3]))
}

fit_Brown_motion <- function(path, model) {
    
    fit <- dlmMLE(path, parm = rep(0, 3), build=model)
    
    llik <- - dlmLL(path, brownian_motion(fit$par))
    
    return(list(fit = fit, llik = llik))
}

fit.brown_motion <- fit_Brown_motion(lgt_suc_rat$val, brownian_motion)
mod.brown_motion <- brownian_motion(fit.brown_motion$fit$par)

#smoothing
smooth.brown_motion <- dlmSmooth(lgt_suc_rat$val, mod.brown_motion)

#forecast
T_Ahead <- 3
forecast <- dlmForecast(mod.brown_motion, nAhead = T_Ahead)

forecast.val <- append(dropFirst(smooth.brown_motion$s), forecast$a)
forecast.sd <- append(rep(0, 14), sqrt(as.numeric(forecast$R)))

#lower & upper bound of 90% C.I.
q <- qnorm(0.90)
upper_bd <- forecast.val + forecast.sd * q
lower_bd <- forecast.val - forecast.sd * q

df_forecast <- data.frame(t = seq(1, 17, length = 17)
                          , observed = append(lgt_suc_rat$val, forecast$a)
                          , val = forecast.val
                          , upper_CI = upper_bd
                          , lower_CI = lower_bd)

plot_forecast <- ggplot(df_forecast, aes(x = t)) + 
    geom_line(aes(y=val), colour="darkblue") + 
    geom_ribbon(aes(ymin=lower_CI, ymax=upper_CI), alpha=0.3)

plot(plot_forecast)

#inv_logit
df_forecast_sucrat <- data.frame(t = append(開催, c("H 31-04", "R 1-10", "R 1-10"))
                                 , sucrat = invlgt(forecast.val)
                                 , upper_CI = invlgt(upper_bd)
                                 , lower_CI = invlgt(lower_bd))

#次回(H 31 -04)合格率の予測値
df_forecast_sucrat$sucrat[15]
#0.2365265  

#19.4%~28%(0.90CI)
plot_forecast_sucrat <- ggplot(df_forecast_sucrat, aes(x = t, group = 1)) + 
    geom_line(aes(y=sucrat), colour="darkblue") + 
    geom_ribbon(aes(ymin=lower_CI, ymax=upper_CI), alpha=0.3)

plot(plot_forecast_sucrat)

平成最後の基本情報技術者試験の合格率推定結果は...
0.2365265 (= 23.6%)となりました.(ただ,90%Confidence Intervalは19.4%~28%とだいぶ幅がありますね.)以下は,推定結果のプロットです(灰色の部分は90%Confidence Interval).

f:id:kimigayoseishou:20190414214410p:plain
基本情報技術者試験合格率予測(3回先まで)

最後に

基本情報技術者試験を今回受ける方,頑張ってください╭( ・ㅂ・)و ̑̑ グッ