多标准决策 (MCDM) 的 TOPSIS 方法
通过与理想解决方案相似的顺序偏好技术 (TOPSIS)于 1980 年代作为一种基于多标准的决策方法出现。 TOPSIS 选择与理想解的欧几里得距离最短和与负理想解的最大距离的备选方案。
为了简化这个定义,假设您想购买一部手机,您去一家商店根据 RAM、内存、显示屏尺寸、电池和价格分析 5 部手机。最后,看到这么多因素,你一头雾水,不知道该买哪款手机。 TOPSIS 是一种根据给定因素的权重和影响来分配等级的方法。
- 权重表示应考虑多少给定因素(所有因素的默认权重 = 1)。就像您希望 RAM 比其他因素权重更多,因此 RAM 的权重可以是 2,而其他因素可以是 1。
- 影响是指给定因素具有正面或负面影响。就像您希望电池尽可能大但手机的价格尽可能低一样,因此您将为电池分配“+”权重,为价格分配“-”权重。
该方法可用于根据相关性、R^2、准确性、均方根误差等各种因素对机器学习模型进行排名。 现在我们已经了解了 TOPSIS 是什么,以及我们可以在哪里应用它。让我们看看在给定的数据集上实现 TOPSIS 的过程是什么,由多行(如各种手机)和多列(如各种因素)组成。
数据集示例:
特定因子的给定数据值将被视为标准单位。始终对任何非数字数据类型进行LabelEncode 。
程序:
步骤 1:计算归一化矩阵和加权归一化矩阵。我们通过使每个值标准化:其中 m 是数据集中的行数,n 是列数。 I 沿行变化,j 沿列变化。
上述给定值的归一化矩阵将是:
然后我们将列中的每个值与给定的相应权重相乘。
# Arguments are dataset, number of columns, and weights of each column
def Normalize(dataset, nCol, weights):
for i in range(1, nCol):
temp = 0
# Calculating Root of Sum of squares of a particular column
for j in range(len(dataset)):
temp = temp + dataset.iloc[j, i]**2
temp = temp**0.5
# Weighted Normalizing a element
for j in range(len(dataset)):
dataset.iat[j, i] = (dataset.iloc[j, i] / temp)*weights[i-1]
print(dataset)
步骤 2:从理想最差和理想最好值计算每一行的理想最佳和理想最差以及欧几里德距离。首先,我们将找出理想的最佳值和理想的最差值:现在我们需要看到影响,即它是“+”还是“-”影响。如果 '+' 影响 一列的最理想是该列中的最大值,而理想最坏是该列中的最小值,反之亦然对于 '-' 影响。
# Calculate ideal best and ideal worst
def Calc_Values(dataset, nCol, impact):
p_sln = (dataset.max().values)[1:]
n_sln = (dataset.min().values)[1:]
for i in range(1, nCol):
if impact[i-1] == '-':
p_sln[i-1], n_sln[i-1] = n_sln[i-1], p_sln[i-1]
return p_sln, n_sln
现在我们需要计算所有行中元素从理想最好和理想最坏开始的欧几里德距离,这里d iw是计算出的第 i行的最差距离,其中t i,j是元素值, t w,j是理想值最坏的那个列。类似地,我们可以找到d ib ,即在第 i个上计算的最佳距离 排。
现在数据集看起来像这样,包括正距离和负距离。
第 3 步:计算 Topsis 分数和排名。现在我们有了正距离和负距离,让我们根据它们计算每行的 Topsis 分数。
每行的 TOPSIS 分数 = d iw / (d ib + d iw )
现在根据TOPSIS分数进行排名,即分数越高,排名越好
我们的数据集将按如下方式排序:
最后一部分的代码在这里!
# Calculating positive and negative values
p_sln, n_sln = Calc_Values(temp_dataset, nCol, impact)
# calculating topsis score
score = [] # Topsis score
pp = [] # distance positive
nn = [] # distance negative
# Calculating distances and Topsis score for each row
for i in range(len(temp_dataset)):
temp_p, temp_n = 0, 0
for j in range(1, nCol):
temp_p = temp_p + (p_sln[j-1] - temp_dataset.iloc[i, j])**2
temp_n = temp_n + (n_sln[j-1] - temp_dataset.iloc[i, j])**2
temp_p, temp_n = temp_p**0.5, temp_n**0.5
score.append(temp_n/(temp_p + temp_n))
nn.append(temp_n)
pp.append(temp_p)
# Appending new columns in dataset
dataset['distance positive'] = pp
dataset['distance negative'] = nn
dataset['Topsis Score'] = score
# calculating the rank according to topsis score
dataset['Rank'] = (dataset['Topsis Score'].rank(method='max', ascending=False))
dataset = dataset.astype({"Rank": int})
你可以在我的 Github Repo 上找到代码源:链接