Rの{e1071}パッケージの関数 tune.svm() を利用して、C-SVM(ソフトマージンSVM)のパラメータ C をグリッドサーチでチューニングする際のグリッドサーチ結果の作図について
{e1071}パッケージのtune.svm()
を利用して、C-SVM(ソフトマージンSVM)の C 値のチューニングをグリッドサーチにかけて見つけようとしているのですが、グリッドサーチ結果の図がうまく作成出来ません。
tune.svm()
を利用してのグリッドサージ結果の作図をご教示して頂けると助かりますm(__)m
<170305追記>
尚、作成したいグラフは以下のような種類のグラフです
tune.svm()
を含む Wrapper Functions のヘルプ
https://www.rdocumentation.org/packages/e1071/versions/1.6-8/topics/tune.wrapper
<170317追記>
参考サイト
http://d.hatena.ne.jp/hoxo_m/20110325/p1
https://bi.biopapyrus.net/machine-learning/svm/e1071.html
以下作成中のコードです。
#install.packages("kernlab")
#install.packages("e1071")
# expand lib on memory
library( MASS ) # MASS package
library( kernlab ) # use C-SVM function
library( e1071 ) # grid serch of C-SVM
############################
# set Pima data #
############################
# Pima data expand on memory
data( Pima.tr )
data( Pima.te )
# copy data from Pima data
lstPimaTrain <- list(
numNoDiabetes = 0, # 糖尿病未発症人数(0で初期化)
numDiabetes = 0, # 糖尿病発症人数(0で初期化)
glu = Pima.tr$glu,
bmi = Pima.tr$bmi,
bResult = rep(0, length(Pima.tr$glu)) # 糖尿病か否か?(FALSE:糖尿病でない、TRUE:糖尿病)
)
# Pima.tr$type のデータ(Yes,No)を符号化[encoding]
for ( i in 1:length(Pima.tr$type) )
{
if(Pima.tr$type[i] == "Yes" )
{
lstPimaTrain$numDiabetes <- (lstPimaTrain$numDiabetes + 1)
lstPimaTrain$bResult[i] <- 1
}
else if( Pima.tr$type[i] == "No" )
{
lstPimaTrain$numNoDiabetes <- (lstPimaTrain$numNoDiabetes + 1)
lstPimaTrain$bResult[i] <- 0
}
else{
# Do Nothing
}
}
# sort Pima data
lstPimaTrain$glu <- lstPimaTrain$glu[ order(lstPimaTrain$bResult) ]
lstPimaTrain$bmi <- lstPimaTrain$bmi[ order(lstPimaTrain$bResult) ]
lstPimaTrain$bResult <- lstPimaTrain$bResult[ order(lstPimaTrain$bResult) ]
# split data to class C1 and C2
lstPimaTrain_C1 <- list(
glu = lstPimaTrain$glu[1:lstPimaTrain$numNoDiabetes],
bmi = lstPimaTrain$bmi[1:lstPimaTrain$numNoDiabetes],
bResult = rep( 0, lstPimaTrain$numNoDiabetes ), # 糖尿病か否か?(FALSE:糖尿病でない、TRUE:糖尿病)
vec_u = matrix( 0, nrow = 2, ncol = 1 ),
mat_S = matrix( 0, nrow = 2, ncol = 2 )
)
lstPimaTrain_C2 <- list(
glu = lstPimaTrain$glu[(lstPimaTrain$numNoDiabetes+1):(lstPimaTrain$numNoDiabetes+lstPimaTrain$numDiabetes)],
bmi = lstPimaTrain$bmi[(lstPimaTrain$numNoDiabetes+1):(lstPimaTrain$numNoDiabetes+lstPimaTrain$numDiabetes)],
bResult = rep( 1, lstPimaTrain$numDiabetes ), # 糖尿病か否か?(FALSE:糖尿病でない、TRUE:糖尿病)
vec_u = matrix( 0, nrow = 2, ncol = 1 ), # 変数1(glu)の平均値、変数2(BMI)の平均値
mat_S = matrix( 0, nrow = 2, ncol = 2 ) # 共分散行列
)
# sort class C1,C2 data
lstPimaTrain_C1$glu <- lstPimaTrain_C1$glu[ order(lstPimaTrain_C1$glu) ]
lstPimaTrain_C1$bmi <- lstPimaTrain_C1$bmi[ order(lstPimaTrain_C1$glu) ]
lstPimaTrain_C2$glu <- lstPimaTrain_C2$glu[ order(lstPimaTrain_C2$glu) ]
lstPimaTrain_C2$bmi <- lstPimaTrain_C2$bmi[ order(lstPimaTrain_C2$glu) ]
# release memory
rm( Pima.tr )
rm( Pima.te )
# set class C1 data
lstPimaTrain_C1$vec_u <- matrix( # クラス1(糖尿病発症なし)の平均ベクトル
c( mean( lstPimaTrain_C1$glu ), mean( lstPimaTrain_C1$bmi ) ),
nrow = 2, ncol = 1
)
lstPimaTrain_C1$mat_S[1,1] <- sqrt( var( lstPimaTrain_C1$glu, lstPimaTrain_C1$glu ) )
lstPimaTrain_C1$mat_S[1,2] <- sqrt( var( lstPimaTrain_C1$glu, lstPimaTrain_C1$bmi ) )
lstPimaTrain_C1$mat_S[2,1] <- sqrt( var( lstPimaTrain_C1$bmi, lstPimaTrain_C1$glu ) )
lstPimaTrain_C1$mat_S[2,2] <- sqrt( var( lstPimaTrain_C1$bmi, lstPimaTrain_C1$bmi ) )
# set class C2 data
lstPimaTrain_C2$vec_u <- matrix( # クラス2(糖尿病発症なし)の平均ベクトル
c( mean( lstPimaTrain_C2$glu ), mean( lstPimaTrain_C2$bmi ) ),
nrow = 2, ncol = 1
)
lstPimaTrain_C2$mat_S[1,1] <- sqrt( var( lstPimaTrain_C2$glu, lstPimaTrain_C2$glu ) )
lstPimaTrain_C2$mat_S[1,2] <- sqrt( var( lstPimaTrain_C2$glu, lstPimaTrain_C2$bmi ) )
lstPimaTrain_C2$mat_S[2,1] <- sqrt( var( lstPimaTrain_C2$bmi, lstPimaTrain_C2$glu ) )
lstPimaTrain_C2$mat_S[2,2] <- sqrt( var( lstPimaTrain_C2$bmi, lstPimaTrain_C2$bmi ) )
#--------------------------
# normalize Pima data
#--------------------------
lstNormPimaTrain_C1 <- lstPimaTrain_C1
lstNormPimaTrain_C2 <- lstPimaTrain_C2
lstNormPimaTrain_C1$glu <- scale( lstNormPimaTrain_C1$glu )
lstNormPimaTrain_C1$bmi <- scale( lstNormPimaTrain_C1$bmi )
lstNormPimaTrain_C2$glu <- scale( lstNormPimaTrain_C2$glu )
lstNormPimaTrain_C2$bmi <- scale( lstNormPimaTrain_C2$bmi )
############################
# C-SVM #
############################
# SVM用のデータ作成
dat_CsvmForm <- c( lstNormPimaTrain_C1$bResult, lstNormPimaTrain_C2$bResult)
df_CsvmData <- data.frame(
glu = c( lstNormPimaTrain_C1$glu, lstNormPimaTrain_C2$glu ),
bmi = c( lstNormPimaTrain_C1$bmi, lstNormPimaTrain_C2$bmi ),
bResult = dat_CsvmForm
)
#----------------------------
# C-SVMモデル構築
#----------------------------
result <- ksvm(
dat_CsvmForm ~ .,
data = df_CsvmData, #
type = "C-bsvc", # 分類方法を指定
kernel = "rbfdot", # 利用するカーネル関数を指定
kpar = list(sigma = 0.2), # カーネル関数のパラメーターを指定
C = 5, # Cパラメーター
cross = 3,
prob.model = TRUE # 予測時に予測確率を出力するためにTRUEに設定
)
print(result)
#----------------------------
# パラメータのチューニング
#----------------------------
# グリッドサーチの範囲
gamma_lim <- 10^( seq(from = -5, to = 5, by = 0.1) ) # 階乗
cost_lim <- 10^( seq(from = -1, to = 1, by = 0.1) )
以下のコードでエラーが発生します。
resTune <- tune.svm(
dat_CsvmForm ~ .,
data = df_CsvmData,
# gamma = gamma_lim, # gammaパラメーターをgamma.limの範囲で移動させる
# cost = cost_lim, # costパラメーターをcost.limの範囲で移動させる
tunecontrol = tune.control( sampling = "cross", cross = 5 ) # 5-cross validation
)
Error in model.frame.default(formula, data) : 変数 ('glu' に基づく)
の長さが異なります
以下コードの続きです。
print(resTune)
############################
# set graphics parameters #
############################
# 軸に関してのデータリスト
lstAxis <- list(
xMin = 0.0, xMax = 1.0, # x軸の最小値、最大値
yMin = 0.0, yMax = 1.0, # y軸の最小値、最大値
zMin = 0.0, zMax = 1.0, # z軸の最小値、最大値
xlim = range( c(0.0, 1.0) ),
ylim = range( c(0.0, 1.0) ),
zlim = range( c(0.0, 1.0) ),
mainTitle = "mainTitle", # 図のメインタイトル(図の上)
subTitle = "subTitle", # 図のサブタイトル(図の下)
xlab = "x", # x軸の名前
ylab = "y", # y軸の名前
zlab = "z" # z軸の名前
)
lstAxis$xMin <- 0
lstAxis$xMax <- 200
lstAxis$yMin <- 0
lstAxis$yMax <- 50
lstAxis$zMin <- 0
lstAxis$zMax <- 1
lstAxis$xlim = range( c(lstAxis$xMin, lstAxis$xMax) )
lstAxis$ylim = range( c(lstAxis$yMin, lstAxis$yMax) )
lstAxis$zlim = range( c(lstAxis$zMin, lstAxis$zMax) )
lstAxis$xlab <- "glu"
lstAxis$ylab <- "BMI"
lstAxis$mainTitle <- "Pima.tr の散布図\n[row data]"
lstAxis$subTitle <- "row data"
# plot frame only
par(new=F)
plot.new() # clear
plot( c(), type='n',
main = lstAxis$mainTitle,
xlim=lstAxis$xlim, ylim=lstAxis$ylim,
xlab=lstAxis$xlab, ylab=lstAxis$ylab
)
grid() #グリッド線を追加
############################
# Draw figure #
############################
# 変換前の散布図
par(new=T)
plot(
lstPimaTrain_C1$glu, lstPimaTrain_C1$bmi,
type='p',
col = "red",
pch = 1,
main = lstAxis$mainTitle,
xlim=lstAxis$xlim, ylim=lstAxis$ylim,
xlab=lstAxis$xlab, ylab=lstAxis$ylab
)
par(new=T)
plot(
lstPimaTrain_C2$glu, lstPimaTrain_C2$bmi,
type='p',
col = "blue",
pch = 2,
main = lstAxis$mainTitle,
xlim=lstAxis$xlim, ylim=lstAxis$ylim,
xlab=lstAxis$xlab, ylab=lstAxis$ylab
)
# 凡例の追加
legend(
x = 0, y = 15,
legend = c("糖尿病発症無し","糖尿病発症有り"),
col = c("blue","red"),
pch = c(2,1),
text.width = 60
)
#----------------------
# 標準化後のの散布図
#-----------------------
lstAxis$xMin <- -5
lstAxis$xMax <- 5
lstAxis$yMin <- -5
lstAxis$yMax <- 5
lstAxis$zMin <- 0
lstAxis$zMax <- 1
lstAxis$xlim = range( c(lstAxis$xMin, lstAxis$xMax) )
lstAxis$ylim = range( c(lstAxis$yMin, lstAxis$yMax) )
lstAxis$zlim = range( c(lstAxis$zMin, lstAxis$zMax) )
lstAxis$mainTitle <- "Pima.tr の散布図\n[normalized data]"
plot(
lstNormPimaTrain_C1$glu, lstNormPimaTrain_C1$bmi,
type='p',
col = "red",
pch = 1,
main = lstAxis$mainTitle,
xlim=lstAxis$xlim, ylim=lstAxis$ylim,
xlab=lstAxis$xlab, ylab=lstAxis$ylab
)
grid()
par(new=T)
plot(
lstNormPimaTrain_C2$glu, lstNormPimaTrain_C2$bmi,
type='p',
col = "blue",
pch = 2,
main = lstAxis$mainTitle,
xlim=lstAxis$xlim, ylim=lstAxis$ylim,
xlab=lstAxis$xlab, ylab=lstAxis$ylab
)
# 凡例の追加
legend(
x = 0, y = 15,
legend = c("糖尿病発症無し","糖尿病発症有り"),
col = c("blue","red"),
pch = c(2,1),
text.width = 60
)