本文へスキップ
からだにいいもの

Rのトピックスを中心に『まだ、まだ、知らない、役に立つ情報?』を発信します。

Rで解析:モデルの応答と残差を可視化できる「plotmo」パッケージの紹介

機械学習や統計モデルを構築後、各予測変数が予測値にどのように影響しているかを確かめたい場面があります。しかし、背景となる変数を固定しながら応答曲線を1つずつ描き、さらに残差の分布まで確認するには手間がかかります。

「plotmo」パッケージは、線形モデルや決定木、勾配ブースティングなど幅広いモデルを対象に、予測変数ごとの応答曲線と2変数の交互作用面を描画する機能を提供します。背景変数を中央値で固定する方法と、影響を平均化する部分依存プロットの両方に対応し、残差プロットや累積分布、QQプロットのプロットも可能です。また、勾配ブースティングモデルの学習曲線や、glmnetモデルの係数経路の描画も可能です。本パッケージの利用で、モデルの挙動を確認しながら解釈を進める作業ができるのではないかと考えます。

パッケージバージョンは3.7.1。Windows 11 x64 (build 26200)のR version 4.6.1で確認しています。

パッケージのインストール

下記コマンドを実行してください。

# パッケージのインストール
install.packages("plotmo")

# パッケージの読み込み
library("plotmo")

# 必要に応じて
install.packages("gbm")
install.packages("glmnet")

後半で扱うplot_gbmコマンドはgbmパッケージ、plot_glmnetコマンドはglmnetパッケージを利用します。いずれもplotmoの推奨パッケージのため、必要に応じてinstall.packages(“gbm”)、install.packages(“glmnet”)で別途導入してください。

スポンサーリンク

コマンド例

詳細はコメント、パッケージのヘルプを確認してください。

plotmoコマンドは、着目する予測変数だけを変化させ、それ以外の変数(背景変数)を代表値に固定して応答を描画します。既定では背景変数を中央値(因子は最頻カテゴリ)に固定しますが、pmethod=”partdep”を指定すると、背景変数の影響を全データで平均化した部分依存プロットになります。1つの変数の主効果を描いた図をdegree1プロット、2つの変数の交互作用を描いた面をdegree2プロットと呼びます。

共通データとして、京都府の宇治茶園を想定した架空の一番茶収量データを作成します。春季の平均気温、月あたりの日照時間、茶園の標高、窒素施肥量、栽培品種から、10アールあたりの収量(kg)を予測する構成です。

# 乱数の種を固定
set.seed(20260903)

# 標本サイズ
n <- 240

# 栽培品種(やぶきた・ごこう・さみどり)
hinshu <- factor(sample(c("yabukita", "gokou", "samidori"), n, replace = TRUE))

# 春季の平均気温(度)
kion <- round(runif(n, 11, 18), 1)

# 月あたりの日照時間(時間)
nissho <- round(runif(n, 110, 220))

# 茶園の標高(メートル)
hyoko <- round(runif(n, 30, 450))

# 窒素施肥量(10アールあたりkg)
hiryo <- round(runif(n, 18, 60))

# 品種ごとの収量への上乗せ量
hinshu_kou <- c(yabukita = 0, gokou = 14, samidori = 6)[as.character(hinshu)]

# 10アールあたりの収量(kg)を生成
shukaku <- 40 +
  6.0 * (kion - 14) -
  0.18 * (kion - 14)^2 +
  0.10 * (nissho - 165) +
  0.004 * (kion - 14) * (nissho - 165) -
  0.02 * (hyoko - 200) / 10 +
  0.9 * hiryo -
  0.010 * hiryo^2 +
  hinshu_kou +
  rnorm(n, 0, 6)

# データフレームにまとめる
chaen <- data.frame(shukaku, kion, nissho, hyoko, hiryo, hinshu)

予測変数ごとの応答曲線のプロット:plotmoコマンド

モデルオブジェクトを渡すと、予測変数ごとのdegree1プロットと、選ばれた組み合わせのdegree2プロットを1ページにまとめて描画します。pmethod=”partdep”で部分依存プロットに切り替えられます。

オプション意味初期値
objectモデルオブジェクトstop(“no ‘object’ argument”)
typepredictに渡す予測タイプ、既定はモデルに応じて自動選択NULL
nresponsepredictが複数列を返す場合に使用する列の番号または名前NA
pmethod描画方式、”plotmo”は背景変数を中央値で固定、”partdep”は部分依存、”apartdep”は近似部分依存“plotmo”
pt.col応答点の色、0で非表示0
jitterpt.col指定時に応答点へ加える散らばりの大きさ、0で無効0.5
smooth.col応答点を通す平滑線の色、0で非表示0
levelpredictが対応する場合に描く信頼区間・予測区間の水準、0で非表示0
func各図に重ねて描く関数func(x)NULL
inverse.func描画前に応答へ適用する関数、変換した応答を元の尺度へ戻す用途NULL
nrug図の下端に描くラグの本数、0で非表示、”density”で密度表示0
grid.coldegree1プロットの背景グリッドの色、0で非表示0
type2degree2プロットの種類、”persp”・”image”・”contour”のいずれか“persp”
degree1描画するdegree1プロットを選ぶ添字または変数名、0で非表示TRUE
all1TRUEでplotmoが通常選ぶ変数に限らず全予測変数を描画FALSE
degree2描画するdegree2プロットを選ぶ添字または変数名TRUE
all2TRUEで全ての予測変数の組を描画FALSE
do.par作図パラメータの設定方法、NULL・FALSE・TRUE・2のいずれかTRUE
clipTRUEで大きく外れた予測値を無視してylimを決めるTRUE
ylim全図で共通のY軸範囲、NULLで自動、NAで各図個別、c(ymin,ymax)で指定NULL
caption図全体の見出し、既定は自動生成、””で非表示NULL
trace実行時の情報表示の詳しさ、-1でplotmoの通常メッセージを抑制0
grid.func軸に無い変数を固定する値を求める関数、既定は中央値と最頻値NULL
grid.levels背景変数ごとに固定値を指定するリスト、grid.funcより優先NULL
extend各図で横軸を広げる割合、0で広げない0
ngrid1各degree1プロットで用いる等間隔なx値の個数50
ngrid2degree2プロットの格子の細かさ、ngrid2×ngrid2点を描画20
ndiscrete異なる値がこの個数以下の変数を階段状に描画5
npoints描画する応答点の個数、pt.col指定時のみ有効、TRUEまたは-1で全点3000
centerTRUEで描画する応答を中央化FALSE
xflipTRUEでX軸の向きを反転FALSE
yflipTRUEでdegree2プロットのY軸の向きを反転FALSE
swapxyTRUEでdegree2プロットのX軸とY軸を入れ替えFALSE
int.only.okTRUEで切片のみのモデルでも最初の予測変数で1枚だけ描画TRUE
plotやpersp、predictなどに渡すその他の引数なし
# 気温と日照の交互作用項を含む線形モデルを構築
lm_model <- lm(shukaku ~ kion * nissho + hyoko + hiryo + hinshu, data = chaen)
# 予測変数ごとの応答曲線と交互作用面を描画
plotmo(lm_model)
 plotmo grid:    kion nissho hyoko hiryo hinshu
                 14.1    166   254    39  gokou

# 背景変数の影響を平均化した部分依存プロットを描画
plotmo(lm_model, pmethod = "partdep", degree2 = FALSE)
calculating partdep for kion
calculating partdep for nissho
calculating partdep for hyoko
calculating partdep for hiryo
calculating partdep for hinshu

回帰モデルの残差のプロット:plotresコマンド

モデル図、残差の累積分布、予測値に対する残差、QQプロットの4枚を既定で描画します。whichで描く図を選び、info=TRUEで学習済み決定係数などの補足情報を重ねられます。

オプション意味初期値
objectモデルオブジェクトstop(“no ‘object’ argument”)
which描画する図の種類、既定の1:4はモデル図・累積分布・予測値に対する残差・QQプロット1:4
infoTRUEで残差分布や学習済み決定係数などの補足情報を表示FALSE
versus残差をプロットする対象、1で予測値、2で観測番号、3で応答、4でてこ比、文字列で予測変数1
standardizeTRUEで残差を標準化、一部のモデルのみ対応FALSE
deleverTRUEで残差をてこ比で補正、一部のモデルのみ対応FALSE
levelモデルが対応する場合に描く信頼区間・予測区間の水準、0で非表示0
id.nラベルを付ける残差の大きい順の個数、TRUEまたは-1で全件3
labels.id残差点に付けるラベル、id.nが正のときのみ使用NULL
smooth.col残差点を通す平滑線の色、0で非表示2
grid.col背景グリッドの色、0で非表示0
jitter残差点へ加える散らばりの大きさ、0で無効0
do.par作図パラメータの設定方法、NULL・FALSE・TRUE・2のいずれかNULL
caption図全体の見出し、既定は自動生成、””で非表示NULL
trace実行時の情報表示の詳しさ0
npoints描画する点の個数、大きい残差20点前後は必ず含む、TRUEまたは-1で全点3000
centerTRUEで残差プロットの横軸を中央に寄せ、分布の非対称を見やすくするTRUE
typeresidualsおよびpredictに渡すタイプ、既定は自動選択NULL
nresponseresidualsやpredictが複数列を返す場合に使用する列の番号または名前NA
object.nameエラーやトレース表示に用いるオブジェクト名quote.deparse(substitute(object))
plotmoやpredictなどに渡すその他の引数なし
# 残差の4種類の診断図を描画
plotres(lm_model)
# 学習済み決定係数などの補足情報を重ねて表示
plotres(lm_model, info = TRUE)

勾配ブースティングモデルの学習曲線のプロット:plot_gbmコマンド

gbmコマンドで構築した勾配ブースティングモデルについて、木の本数に対する学習誤差・検証誤差・交差検証誤差・OOB誤差の曲線を描画します。既定では最小点付近を拡大して表示し、各曲線の最小点における木の本数を戻り値として返します。

オプション意味初期値
objectgbmモデルstop(“no ‘object’ argument”)
smoothtrain・test・CV・OOBの各曲線を平滑化するかを表す4要素ベクトルc(0, 0, 0, 1)
coltrain・test・CV・OOBの各曲線の色を表す4要素ベクトル、0でその曲線を非表示c(1, 2, 3, 4)
ylimY軸範囲、”auto”で最小点付近を詳しく表示、NULLで曲線の全範囲“auto”
legend.x凡例のX位置、既定は自動配置、NAで凡例なしNULL
legend.y凡例のY位置NULL
legend.cex凡例の文字の大きさ0.8
grid.col背景グリッドの色、既定はグリッドなしNA
n.treesplotres用、残差計算に使った木の本数を示す縦線のX位置NA
col.n.treesplotres用、n.treesを示す縦線の色“darkgray”
plot関数に渡すその他の引数なし
# gbmパッケージの読み込み
library("gbm")
Loaded gbm 2.3.1
This version of gbm is no longer under development. Consider transitioning to gbm3, https://github.com/gbm-developers/gbm3

# 勾配ブースティングモデルを構築
gbm_model <- gbm(shukaku ~ ., data = chaen, distribution = "gaussian",
                 n.trees = 600, shrinkage = 0.05, interaction.depth = 3,
                 train.fraction = 0.8, verbose = FALSE)
# 学習曲線を描画し、最小点の木の本数を確認
plot_gbm(gbm_model)

glmnetモデルの係数経路のプロット:plot_glmnetコマンド

glmnetコマンドで推定した正則化回帰について、正則化パラメータの変化に対する各係数の推移を描画します。plot.glmnetコマンドと異なり、既定の横軸は減少するlog lambdaで、右側に表示する変数名の数をlabelで調整します。

オプション意味初期値
xglmnetモデルstop(“no ‘x’ argument”)
xvar横軸に取る量、”rlambda”で減少するlog lambda、”lambda”でlog lambda、”norm”で係数のL1ノルム、”dev”で説明された逸脱度の割合c(“rlambda”, “lambda”, “norm”, “dev”)
label図の右側に表示する変数名の数、FALSEで非表示、TRUEで全て10
nresponse多変量応答モデルでどの応答を描画するかNA
grid.col背景グリッドの色、既定はグリッドなしNA
splotres用、残差計算に使ったlambda sを示す縦線のX位置NA
plot.glmnetに渡すその他の引数なし
# glmnetパッケージの読み込み
library("glmnet")
Loading required package: Matrix
Loaded glmnet 5.0

# 因子を含む説明変数を数値行列へ変換
x <- model.matrix(~ kion + nissho + hyoko + hiryo + hinshu, data = chaen)[, -1]
# 目的変数のベクトル
y <- chaen$shukaku
# Lasso回帰の係数経路を推定
glmnet_model <- glmnet(x, y)
# 正則化パラメータに対する係数の推移を描画
plot_glmnet(glmnet_model)

この記事が誰かの役に立ちますように。

スポンサーリンク
価格および配送状況は変更される場合があります。購入時は商品ページをご確認ください。
当サイトに表示されている商品情報はAmazonから提供されたものであり、更新または削除される場合があります。
karada-goodはAmazonアソシエイトとして、適格販売により収入を得ています。