Rで何かをしたり、読書をするブログ

政府統計の総合窓口のデータや、OECDやUCIやのデータを使って、Rの練習をしています。ときどき、読書記録も載せています。

UCI Machine Learning RepositoryのLetter Recognitionのデータの分析2 - RのglmnetでA, B, Cを識別するモデル

 

www.crosshyou.info

の続きです。前回はUCIのLetter RecognitionのデータをRに取り込みました。これから、文字認識のモデルを作成していきます。

とはいうものの、26文字全てを認識するモデルを作るのは私にはできないので、今回は、A, B, Cの3文字を識別するモデルをつくります。

なので、A, B, Cだけのデータフレームをつくります。

ファクターのレベルを確認しましょう。

ファクターのレベルが、B, A, Cの順番になっているので、A, B, Cの順番に直します。

A, B, Cの順番になりましたね。

A, B, Cの数を確認します。

3分の1ずつですね。

では、glmnetパッケージのfamily = "multinomial"でモデルを作ってみます。

パッケージの読み込みをします。

glmnetはx, yとマトリックス型が必要なのでx, yを作ります。

トレーニング用のインデックスを作成します。

alpha = 0.5として、Elastic-Net回帰でモデルを作成してみます。

モデルの係数を確認します。

plot()関数でλとMultinomial Devianceのグラフを描きます。

テストデータで予測します。

type = "response" にすると確率、type = "class" にすると、A, B, Cが返ります。

混合行列(Confusion Matrix)をだしてみます。

confusion.glmnet()関数を使う方法と、table()関数を使う方法でやってみました。どちらも同じ混合行列が出てきます。正解率が99.13%です!これはいい結果ですね。

今回は以上です。

はじめから読むには、

www.crosshyou.info

です。

今回のコードは以下になります。

#
# A, B, Cだけのデータフレームを作る
df <- df_raw |> 
  filter(V1 %in% c("A", "B", "C")) |> 
  mutate(V1 = as_factor(V1)) |> 
  as_tibble()
#
# ファクターのレベル
levels(df$V1)
#
# ファクターのレベルをA, B, Cに変える
df$V1 <- factor(df$V1, levels = c("A", "B", "C"))
levels(df$V1)
#
# A, B, Cの数
df |> 
  count(V1) |> 
  mutate(prop = n / nrow(df))
#
# glmnetのfamily = "multinomial"
# パッケージの読み込み
library(glmnet)
#
# x, y を作成
x <- df |> select(-V1) |> makeX()
y <- df |> select(V1) |> pull()
#
# トレーニング用のインデックスを作成
set.seed(29)
idx <- sample(1:nrow(x), nrow(x) * 0.7, replace = FALSE)
#
# Elastic-Net回帰(alpha = 0.5)
set.seed(63)
elnet <- cv.glmnet(x[idx, ], y[idx], family = "multinomial",
                   alpha = 0.5)
#
# モデルの係数
coef(elnet, s = "lambda.min")
#
# モデルのプロット
plot(elnet)
#
# テストデータで予測, 確率
elnet_prob <- predict(elnet, newx = x[-idx, ],
                      s = "lambda.min", type = "response")
#
# テストデータで予測, クラス
elnet_class <- predict(elnet, newx = x[-idx, ],
                       s = "lambda.min", type = "class")
#
# Confusion Matrix
confusion.glmnet(elnet, newx = x[-idx, ], y[-idx],
                 s = "lambda.min", family = "multinomial")
#
table(elnet_class, y[-idx])
(249 + 227 + 206) / length(y[-idx])
#

 

(冒頭の画像は Bing Image Creator で生成しました。プロンプトは Red and Pink Rose flowers landscape photograph, under the blue sky and white clouds, fall season, photo です。)