原文地址
https://www.r-bloggers.com/analytic-hierarchy-process-ahp-with-the-ahp-package/
Tom Dick and Harry problem
问题描述
以下内容来自维基百科
This example describes the use of the AHP in choosing a leader for a company whose founder is about to retire. There are several competing candidates and several competing criteria for choosing the most suitable one. By using the AHP, the board of directors is able to choose the best candidate in a rational, transparent way that can be examined and understood by all concerned.
简单理解:公司领导人退休,需要选举新的领导人。为了使选举结果公开透明、使人信服,需要一定的方法。这里选择的是AHP(analytic hierarchy process层次分析法)。
- 目标是选择公司领导人;
- 评价的标准教育背景Education,Experience经验,Charisma领导力,Age
- 3个候选人Tom,Dick,Harry
AHP层次分析法
AHP is a method for multi-criteria decision making that breaks the problem down based on decision criteria, subcriteria, and alternatives that could satisfy a particular goal. The criteria are compared to one another, the alternatives are compared to one another based on how well they comparatively satisfy the subcriteria, and then the subcriteria are examined in terms of how well they satisfy the higher-level criteria. The Tom-Dick-Harry problem is a simple hierarchy: only one level of criteria separates the goal (“Choose the Most Suitable Leader”) from the alternatives (Tom, Dick, or Harry):
上面这段话自己还看不太明白,反正大体的意思就是运用这个方法可以帮你选出最合适的领导人。
R语言里有一个现成的包可以来做这个事情ahp
安装方法
devtools::install_github("gluc/ahp", build_vignettes = TRUE)
安装过程有时候会报错cannot remove prior installation of package ‘Rcpp’
,删掉旧的包,手动安装一遍就可以了
但是准备输入文件太麻烦,要求的是YAML格式。下面是ahp包中提供的示例文件
Version: 2.0
#########################
# Alternatives Section
#
Alternatives: &alternatives
# Here, we list all the alternatives, together with their attributes.
# We can use these attributes later in the file when defining
# preferenceFunctions. The attributes can be quantitative or
# qualitative.
Accord Sedan:
price: 20360
mpg: 31
passengers: 5
cargo: 14
curb weight: 3289
safety class: Midsize Car
crash rating: 4 in Side Impact Front
residual value: 0.52
Accord Hybrid:
price: 31090
mpg: 35
passengers: 5
cargo: 14
curb weight: 3501
safety class: Midsize Car
crash rating: 4 in Side Impact Front
residual value: 0.46
Pilot:
price: 27595
mpg: 22
passengers: 8
cargo: 87.6
curb weight: 4264
safety class: Midsize SUV
crash rating: 4 in Rollover
residual value: 0.4
CR-V:
price: 20700
mpg: 27
passengers: 5
cargo: 72.9
curb weight: 3389
safety class: Small SUV
crash rating: 4 in Rollover
residual value: 0.55
Element:
price: 18980
mpg: 25
passengers: 4
cargo: 74.6
curb weight: 3433
safety class: Small SUV
crash rating: 3 in Rollover
residual value: 0.48
Odyssey:
price: 25645
mpg: 26
passengers: 8
cargo: 147.4
curb weight: 4385
safety class: Minivan
crash rating: All 5 Stars
residual value: 0.48
#
# End of Alternatives Section
#####################################
#####################################
# Goal Section
#
Goal:
# The goal spans a tree of criteria and the alternatives
name: Buy Car
description: >
This is a classic single decision maker problem. It models
the situation facing by a family that wants to buy a new car.
author: unknown
preferences:
# preferences are typically defined pairwise
# 1 means: A is equal to B
# 9 means: A is highly preferrable to B
# 1/9 means: B is highly preferrable to A
pairwise:
- [Cost, Safety, 3]
- [Cost, Style, 7]
- [Cost, Capacity, 3]
- [Safety, Style, 9]
- [Safety, Capacity, 1]
- [Style, Capacity, 1/7]
children:
Cost:
preferences:
pairwise:
- [Purchase Price, Fuel Cost, 2]
- [Purchase Price, Maintenance Cost, 5]
- [Purchase Price, Resale Value, 3]
- [Fuel Cost, Maintenance Cost, 2]
- [Fuel Cost, Resale Value, 2]
- [Maintenance Cost, Resale Value, 1/2]
children:
Purchase Price:
preferences:
pairwise:
- [Accord Sedan, Accord Hybrid, 9]
- [Accord Sedan, Pilot, 9]
- [Accord Sedan, CR-V, 1]
- [Accord Sedan, Element, 1/2]
- [Accord Sedan, Odyssey, 5]
- [Accord Hybrid, Pilot, 1]
- [Accord Hybrid, CR-V, 1/9]
- [Accord Hybrid, Element, 1/9]
- [Accord Hybrid, Odyssey, 1/7]
- [Pilot, CR-V, 1/9]
- [Pilot, Element, 1/9]
- [Pilot, Odyssey, 1/7]
- [CR-V, Element, 1/2]
- [CR-V, Odyssey, 5]
- [Element, Odyssey, 6]
children: *alternatives
# We don't need to retype the alternatives here. Instead
# we can simply make a reference to the alternatives anchor
# defined in the alternatives section of the file.
Fuel Cost:
# Alternatively to the pairwise preferences, you
# can define a preference function. This function
# is in R syntax, and needs to have two arguments.
# The Calculate method will pass all combinations
# of alternatives to this function, and the function
# is expected to return the pairwise preference, i.e.
# a number between 1/9 and 9.
preferences:
pairwiseFunction:
function(a1, a2) min(9, max(1/9, a2$mpg/a1$mpg))
children: *alternatives
Maintenance Cost:
preferences:
pairwise:
- [Accord Sedan, Accord Hybrid, 1.5]
- [Accord Sedan, Pilot, 4]
- [Accord Sedan, CR-V, 4]
- [Accord Sedan, Element, 4]
- [Accord Sedan, Odyssey, 5]
- [Accord Hybrid, Pilot, 4]
- [Accord Hybrid, CR-V, 4]
- [Accord Hybrid, Element, 4]
- [Accord Hybrid, Odyssey, 5]
- [Pilot, CR-V, 1]
- [Pilot, Element, 1.2]
- [Pilot, Odyssey, 1]
- [CR-V, Element, 1]
- [CR-V, Odyssey, 3]
- [Element, Odyssey, 2]
children: *alternatives
Resale Value:
preferences:
pairwiseFunction: >
GetResalePreference <- function(a1, a2) {
if (a1$`residual value` < a2$`residual value`) return (1/GetResalePreference(a2, a1))
ratio <- a1$`residual value` / a2$`residual value`
if (ratio < 1.05) return (1)
if (ratio < 1.1) return (2)
if (ratio < 1.15) return (3)
if (ratio < 1.2) return (4)
if (ratio < 1.25) return (5)
return (5)
}
children: *alternatives
Safety:
preferences:
pairwise:
- [Accord Sedan, Accord Hybrid, 1]
- [Accord Sedan, Pilot, 5]
- [Accord Sedan, CR-V, 7]
- [Accord Sedan, Element, 9]
- [Accord Sedan, Odyssey, 1/3]
- [Accord Hybrid, Pilot, 5]
- [Accord Hybrid, CR-V, 7]
- [Accord Hybrid, Element, 9]
- [Accord Hybrid, Odyssey, 1/3]
- [Pilot, CR-V, 2]
- [Pilot, Element, 9]
- [Pilot, Odyssey, 1/8]
- [CR-V, Element, 2]
- [CR-V, Odyssey, 1/8]
- [Element, Odyssey, 1/9]
children: *alternatives
Style:
preferences:
pairwise:
- [Accord Sedan, Accord Hybrid, 1]
- [Accord Sedan, Pilot, 7]
- [Accord Sedan, CR-V, 5]
- [Accord Sedan, Element, 9]
- [Accord Sedan, Odyssey, 6]
- [Accord Hybrid, Pilot, 7]
- [Accord Hybrid, CR-V, 5]
- [Accord Hybrid, Element, 9]
- [Accord Hybrid, Odyssey, 6]
- [Pilot, CR-V, 1/6]
- [Pilot, Element, 3]
- [Pilot, Odyssey, 1/3]
- [CR-V, Element, 7]
- [CR-V, Odyssey, 5]
- [Element, Odyssey, 1/5]
children: *alternatives
Capacity:
preferences:
pairwise:
- [Cargo Capacity, Passenger Capacity, 1/5]
children:
Cargo Capacity:
preferences:
pairwiseFunction: >
CargoPreference <- function(a1, a2) {
if (a1$cargo < a2$cargo) return (1/CargoPreference(a2, a1))
ratio <- a1$cargo / a2$cargo
if (ratio < 3) return (1)
if (ratio < 8) return (2)
return (3)
}
children: *alternatives
Passenger Capacity:
preferences:
pairwise:
- [Accord Sedan, Accord Hybrid, 1]
- [Accord Sedan, Pilot, 1/2]
- [Accord Sedan, CR-V, 1]
- [Accord Sedan, Element, 3]
- [Accord Sedan, Odyssey, 1/2]
- [Accord Hybrid, Pilot, 1/2]
- [Accord Hybrid, CR-V, 1]
- [Accord Hybrid, Element, 3]
- [Accord Hybrid, Odyssey, 1/2]
- [Pilot, CR-V, 2]
- [Pilot, Element, 6]
- [Pilot, Odyssey, 1]
- [CR-V, Element, 3]
- [CR-V, Odyssey, 1/2]
- [Element, Odyssey, 1/6]
children: *alternatives
#
# End of Goal Section
#####################################
准备这个输入文件应该是非常麻烦,如何将我们自己的数据整理成这种格式可能得费一番功夫了!
#########################
# Alternatives Section
# THIS IS FOR The Tom, Dick, & Harry problem at
#
Alternatives: &alternatives
# 1= not well; 10 = best possible
# Your assessment based on the paragraph descriptions may be different.
Tom:
age: 50
experience: 7
education: 4
leadership: 10
Dick:
age: 60
experience: 10
education: 6
leadership: 6
Harry:
age: 30
experience: 5
education: 8
leadership: 6
#
# End of Alternatives Section
#####################################
# Goal Section
#
Goal:
# A Goal HAS preferences (within-level comparison) and HAS Children (items in level)
name: Choose the Most Suitable Leader
preferences:
# preferences are defined pairwise
# 1 means: A is equal to B
# 9 means: A is highly preferable to B
# 1/9 means: B is highly preferable to A
- [Experience, Education, 4]
- [Experience, Charisma, 3]
- [Experience, Age, 7]
- [Education, Charisma, 1/3]
- [Education, Age, 3]
- [Age, Charisma, 1/5]
children:
Experience:
preferences:
- [Tom, Dick, 1/4]
- [Tom, Harry, 4]
- [Dick, Harry, 9]
children: *alternatives
Education:
preferences:
- [Tom, Dick, 3]
- [Tom, Harry, 1/5]
- [Dick, Harry, 1/7]
children: *alternatives
Charisma:
preferences:
- [Tom, Dick, 5]
- [Tom, Harry, 9]
- [Dick, Harry, 4]
children: *alternatives
Age:
preferences:
- [Tom, Dick, 1/3]
- [Tom, Harry, 5]
- [Dick, Harry, 9]
children: *alternatives
#
# End of Goal Section
#####################################
接下来用这个文件来做AHP分析
myAhp<-Load("../Desktop/AHP_practice.txt.txt")
遇到了报错
Error in value[[3L]](cond) :
Could not load ahp model. Exception caught when converting into a data.tree: Error in doTryCatch(return(expr), name, parentenv, handler): Could not load ahp model. Could not find Version
In addition: Warning message:
In readChar(ahpFile, file.info(ahpFile)$size) :
can only read in bytes in a non-UTF-8 MBCS locale
暂时还不知道如何解决
重复ahp报自带的例子
devtools::install_github("gluc/ahp")
library(ahp)
myAhp<-Load("../Desktop/AHP_practice.txt.txt")
??LoadFile
ahp::Load()
ahpFile<-system.file("extdata","car.ahp",package="ahp")
carAhp<-Load(ahpFile)
Calculate(carAhp)
Visualize(carAhp)
Analyze(carAhp)
AnalyzeTable(carAhp)
输出结果
输出结果竟然是图片形式展示表格!!!
结果里好像也没有给出最终的决策结果呀!可能是有其他函数实现的吗?
结果里给出了各个变量的权重
本篇文章的目的:知道有这么个方法,知道有这个R包可以实现!研究研究如何将自己的数据转化为输入文件的格式!
欢迎大家关注我的公众号 小明的数据分析笔记本