必要なパッケージを読み込む。
::p_load(tidyverse,
pacman
rsample,
gmodels,
OneR, RWeka)
次に、ggplot2のテーマとフォントの設定を行う。自分好みの設定がある場合は自由に変えてよい。
if (.Platform$OS.type == "windows") {
if (require(fontregisterer)) {
<- "Yu Gothic"
my_font else {
} <- "Japan1"
my_font
}else if (capabilities("aqua")) {
} <- "HiraginoSans-W3"
my_font else {
} <- "IPAexGothic"
my_font
}
theme_set(theme_gray(base_size = 9,
base_family = my_font))
2021年10月31日に実施された衆議院議員総選挙のデータを使って実習を行う。このページ にある小選挙区のデータをダウンロードする。
download.file(
url = "https://yukiyanai.github.io/jp/resources/data/hr2021_districts.csv",
dest = "data/hr2021_districts.csv"
)
データを読み込む。
<- read_csv("data/hr2021_districts.csv") HR2021
実習用に整形する。
<- HR2021 %>%
myd select(win_smd, age, party, status, previous, duplicate) %>%
mutate(win_smd = factor(win_smd,
levels = 0:1,
labels = c("Lose", "Win")),
party = factor(party),
status = factor(status),
duplicate = factor(duplicate,
levels = 0:1,
labels = c("No", "Yes"))) %>%
rename(dual = duplicate) %>%
mutate_if(is.double, scale)
データを訓練データと検証データに分割する。
set.seed(2021-11-03)
<- initial_split(myd)
myd_split <- training(myd_split)
myd_train <- testing(myd_split) myd_test
ルールを一切決めず、全員を「落選 (Lose)」に分類する。
<- nrow(myd_test)
N <-rep("Lose", N) yhat_0R
混同行列を作る。
CrossTable(x = myd_test$win_smd,
y = yhat_0R,
dnn = c("実際の結果", "分類結果"),
prop.r = FALSE,
prop.c = FALSE,
prop.t = TRUE,
prop.chisq = FALSE)
##
##
## Cell Contents
## |-------------------------|
## | N |
## | N / Table Total |
## |-------------------------|
##
##
## Total Observations in Table: 215
##
##
## | yhat_0R
## myd_test$win_smd | Lose | Row Total |
## -----------------|-----------|-----------|
## Lose | 124 | 124 |
## | 0.577 | |
## -----------------|-----------|-----------|
## Win | 91 | 91 |
## | 0.423 | |
## -----------------|-----------|-----------|
## Column Total | 215 | 215 |
## -----------------|-----------|-----------|
##
##
正解率は57.7%である。
1Rアルゴリズムで分類してみよう。OneRパッケージのOneR()
を使う。 RWekaパッケージにも同じ名前の関数があるので、パッケージ名と一緒に指定する。
<- OneR::OneR(win_smd ~ .,
m1r data = myd_train)
分類結果を確認する。
m1r
##
## Call:
## OneR.formula(formula = win_smd ~ ., data = myd_train)
##
## Rules:
## If party = N党 then win_smd = Lose
## If party = れい then win_smd = Lose
## If party = 公明 then win_smd = Win
## If party = 共産 then win_smd = Lose
## If party = 国民 then win_smd = Lose
## If party = 無所 then win_smd = Lose
## If party = 社民 then win_smd = Lose
## If party = 立憲 then win_smd = Lose
## If party = 維新 then win_smd = Lose
## If party = 自民 then win_smd = Win
## If party = 諸派 then win_smd = Lose
##
## Accuracy:
## 502 of 642 instances classified correctly (78.19%)
所属政党 (party) によって分類されていることがわかる。 「party = 自民」と「party = 公明」が当選(Win)、それ以外が落選(Lose)に分類されている。
このルールに従って、検証データの分類を行おう。
<- ifelse(myd_test$party %in% c("自民", "公明"), "Win", "Lose") yhat_1R
混同行列を作る。
CrossTable(x = myd_test$win_smd,
y = yhat_1R,
dnn = c("実際の結果", "分類結果"),
prop.r = FALSE,
prop.c = FALSE,
prop.t = TRUE,
prop.chisq = FALSE)
##
##
## Cell Contents
## |-------------------------|
## | N |
## | N / Table Total |
## |-------------------------|
##
##
## Total Observations in Table: 215
##
##
## | 分類結果
## 実際の結果 | Lose | Win | Row Total |
## -------------|-----------|-----------|-----------|
## Lose | 106 | 18 | 124 |
## | 0.493 | 0.084 | |
## -------------|-----------|-----------|-----------|
## Win | 25 | 66 | 91 |
## | 0.116 | 0.307 | |
## -------------|-----------|-----------|-----------|
## Column Total | 131 | 84 | 215 |
## -------------|-----------|-----------|-----------|
##
##
正解率は、80.0% である。ZeroR よりも正解率が22ポイント上昇した。
続いて、RIPPERアルゴリズムによる分類ルール学習を実行しよう。 RWekaパッケージのJRip()
を使う。
<- JRip(win_smd ~ .,
m_ripper data = myd_train)
分類結果を確認する。
m_ripper
## JRIP rules:
## ===========
##
## (status = 前) and (previous >= 0.975881) => win_smd=Win (102.0/28.0)
## (status = 前) and (previous >= 0.288109) and (age <= 0.226462) => win_smd=Win (77.0/24.0)
## (party = 自民) and (age <= -0.405126) => win_smd=Win (26.0/10.0)
## (party = 自民) and (previous <= -0.399662) => win_smd=Win (17.0/7.0)
## => win_smd=Lose (420.0/45.0)
##
## Number of Rules : 5
5つのルールを学習したことがわかる。最初のルールでは当選(Win)を分類しているが、102の観測点は実際に当選、28の観測点は実際には落選である。
この学習結果を利用して、検証データを分類しよう。
<- predict(m_ripper, newdata = myd_test) yhat_rip
混同行列を作る。
CrossTable(x = myd_test$win_smd,
y = yhat_rip,
dnn = c("実際の結果", "分類結果"),
prop.r = FALSE,
prop.c = FALSE,
prop.t = TRUE,
prop.chisq = FALSE)
##
##
## Cell Contents
## |-------------------------|
## | N |
## | N / Table Total |
## |-------------------------|
##
##
## Total Observations in Table: 215
##
##
## | 分類結果
## 実際の結果 | Lose | Win | Row Total |
## -------------|-----------|-----------|-----------|
## Lose | 105 | 19 | 124 |
## | 0.488 | 0.088 | |
## -------------|-----------|-----------|-----------|
## Win | 21 | 70 | 91 |
## | 0.098 | 0.326 | |
## -------------|-----------|-----------|-----------|
## Column Total | 126 | 89 | 215 |
## -------------|-----------|-----------|-----------|
##
##
正解率は81.4%である。分類性能はOneRと大差なさそうだ。
実習課題