目的
AHP (Analytic Hierachy Process) による評価を行う。
使用法
AHP(x, y, labels.x=NULL, labels.y=NULL)
print.AHP(obj, digits=5)
plot.AHP(obj, xlab="Score", main="AHP (Analytic Hierachy Process)",file="")
引数
x 評価基準の重要度(対角成分を含まない下三角行列を列順で用意する。使用例参照)
y 代替案の重要度(対角成分を含まない下三角行列を列順で用意する。使用例参照)
labels.x 評価基準の名称ベクトル
labels.y 代替案の名称ベクトル
obj AHP が返すオブジェクト
digits 結果の表示桁数
xlab 軸の名称(デフォルトでは Score)
main グラフのタイトル(デフォルトでは AHP (Analytic Hierachy Process))
file 結果の画像を出力するファイル名(デフォルトでは空文字列で,ファイル出力しない)
ソース
インストールは,以下の 1 行をコピーし,R コンソールにペーストする
source("http://aoki2.si.gunma-u.ac.jp/R/src/AHP.R", encoding="euc-jp")
# AHP (Analytic Hierachy Process) による評価を行う
AHP <- function( x, # 評価基準の重要度(下三角行列をベクトルで用意)
y, # 代替案の評価(各行列の下三角行列を列とする行列で用意)
labels.x=NULL, # 評価基準のラベル
labels.y=NULL) # 代替案のラベル
{
items <- function(n) # 下三角行列の要素数から行列サイズを求める
{
retval <- (1+sqrt(1+8*n))/2
return(if (retval!=floor(retval)) Inf else retval)
}
make.matrix <- function(x) # 正方行列から重みベクトルを求める
{
n <- items(length(x)) # 行列のサイズ
mat <- diag(n) # 三角行列を表すベクトルから行列を生成
mat[lower.tri(mat, diag=FALSE)] <- x
mat <- t(mat)+mat
mat[upper.tri(mat)] <- 1/mat[upper.tri(mat)]
diag(mat) <- 1
result <- eigen(mat) # 固有値・固有ベクトルを求める
val <- as.numeric(result$values[1])
vec <- as.numeric(result$vectors[,1])
weight <- vec/sum(vec) # 固有ベクトルを和が 1 になるように標準化したものが重み
ci <- (val-n)/(n-1)
cr <- ci/c(0,0,0.58,0.9,1.12,1.24,1.32,1.41,1.45,1.49,1.51,1.53)[n]
if (ci > 0.1 || cr > 0.1) {
cat("\nC.I.=", ci, ", C.R.=", cr, "\n", sep="")
print(mat)
W <- outer(weight, weight, "/")
print(W)
print(mat-W)
}
return(list(lambda=val, vec=vec, weight=weight, ci=ci, cr=cr))
}
if (is.null(labels.x)) { # ラベルが与えられていないときは A, B, ...
labels.x <- LETTERS[1:items(length(x))]
}
ans.x <- make.matrix(x)
weight.x <- ans.x$weight # 評価基準の重要度
names(weight.x) <- labels.x
nitems.y <- items(nrow(y))
if (is.null(labels.y)) { # ラベルが与えられていないときは a, b, ...
labels.y <- letters[1:nitems.y]
}
ans.y <- matrix(unlist(apply(y, 2, make.matrix)), 3+2*nitems.y)
weight.y <- ans.y[(2+nitems.y):(1+2*nitems.y),] # 代替案の評価
rownames(weight.y) <- labels.y
colnames(weight.y) <- labels.x
score <- rowSums(t(weight.x*t(weight.y))) # スコア
return(structure(list(weight.x=weight.x, weight.y=weight.y, score=score, sorted.score=sort(score)), class="AHP"))
}
# print メソッド
print.AHP <- function( obj, # AHP の返すオブジェクト
digits=5) # 結果の表示桁数
{
cat("\n評価基準の重み\n\n")
print(round(obj$weight.x, digits=digits))
cat("\n代替案の評価結果\n\n")
print(round(obj$weight.y, digits=digits))
cat("\nスコア\n\n")
print(round(obj$score, digits=digits))
cat("\nソートされたスコア\n\n")
print(round(obj$sorted.score, digits=digits))
}
# plot メソッド
plot.AHP <- function( obj, # AHP の返すオブジェクト
xlab="Score", # 結果グラフの横軸名
main="AHP (Analytic Hierachy Process)", # 結果グラフの表題
file="") # 結果グラフをファイル出力するときにファイル名
{
if (file != "") pdf(file, width=540/72, height=160/72, onefile=FALSE)
score <- obj$score
plot(score, rep(0, length(score)), pch=19, xlab=xlab, main=main, xaxt="n",
xlim=range(pretty(score)), ylab="", yaxt="n", ylim=c(0,0.2),
bty="n", xpd=TRUE)
text(score, 0.0, names(score), pos=3)
axis(1, pos=0)
if (file != "") dev.off()
}
使用例
# 評価基準の重要度
値段 燃費 乗り心地 車格
値段 1 3 5 7
燃費 1/3 1 5 7
乗り心地 1/5 1/5 1 3
車格 1/7 1/7 1/3 1
# 評価基準の重要度の下三角行列(対角要素は含まない)を列順にベクトルとして表す
> x <- c(1/3, 1/5, 1/7, 1/5, 1/7, 1/3) # 分数で書いて良い
# 代替案の評価
4項目の評価基準において,3つの代替案の評価をする
値段
A車 B車 C車
A車 1 2 3
B車 1/2 1 2
C車 1/3 1/2 1
燃費
A車 B車 C車
A車 1 1/5 1/2
B車 5 1 7
C車 2 1/7 1
乗り心地
A車 B車 C車
A車 1 3 2
B車 1/3 1 1/2
C車 1/2 2 1
車格
A車 B車 C車
A車 1 1/2 1/2
B車 2 1 1
C車 2 1 1
# 評価基準ごとの評価結果を以下のような行列としてまとめる
[,1] [,2] [,3] [,4]
[1,] 0.5000000 5.0000000 0.3333333 2
[2,] 0.3333333 2.0000000 0.5000000 2
[3,] 0.5000000 0.1428571 2.0000000 1
# 各列は,代替案の評価の下三角行列(対角要素は含まない)を列順に記載する
> y <- matrix(c(1/2,1/3,1/2, 5,2,1/7, 1/3,1/2,2, 2,2,1), 3, 4) # 分数で書いて良い
> AHP(x, y, labels.x=c("値段", "燃費", "乗り心地", "車格"), labels.y=c("A 車", "B 車", "C 車"))
C.I.=0.05947573, C.R.=0.1025444 # 結果を print メソッドで表示
評価基準の重み
値段 燃費 乗り心地 車格
0.543736 0.310926 0.097453 0.047885
代替案の評価結果
値段 燃費 乗り心地 車格
A 車 0.53961 0.10564 0.53961 0.2
B 車 0.29696 0.74446 0.16342 0.4
C 車 0.16342 0.14990 0.29696 0.4
スコア
A 車 B 車 C 車
0.38842 0.42802 0.18356
ソートされたスコア
C 車 A 車 B 車
0.18356 0.38842 0.42802
> plot(a) # 結果を plot メソッドで描画