AHP (Analytic Hierachy Process)     Last modified: Aug 21, 2009

目的

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 メソッドで描画

fig


・ 直前のページへ戻る  ・ E-mail to Shigenobu AOKI

Made with Macintosh