python实现CD图的绘制
所需包:Orange
可以直接使用pip或conda安装
pip install orange3 # or
conda install orange3
以下为一段实例代码:
import Orange
# import orngStat
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
# Adam-LDL-SCL x^2
names = ['alg1', 'alg2', 'alg3', 'alg4', 'alg5', 'alg6', 'alg7', 'alg8', 'alg9']
avranks = [5.48, 6.52, 6.92, 3.44, 4.24, 5.6, 6.44, 4.68, 1.68]
#tested on 25 datasets
cd = Orange.evaluation.compute_CD(avranks, 25, alpha='0.05', test='bonferroni-dunn')
print('cd=', cd)
Orange.evaluation.graph_ranks(avranks, names, cd=cd, width=8, cdmethod=8, reverse=True)
# reverse表示按照算法平均排名从左到右依次增大的顺序绘图
# cdmethod 为控制算法的索引,如果不指定则每个算法都会标出其CD范围
plt.show()
结果如下所示:
但是有些时候我们可能需要另一种形式的,形如下图:
而Orange这个包并没有这种图的参数,此时就可以通过修改源码的方式来实现。
if cdmethod < 0 or cdmethod > len(names) - 1:
raise ValueError('cdmethod 小于0或者超出范围')
def get_lines(sums, hsd):
# get all pairs
lsums = len(sums)
allpairs = [(i, j) for i, j in mxrange([[lsums], [lsums]]) if j > i]
# remove not significant
notSig = [(i, j) for i, j in allpairs
if abs(sums[i] - sums[j]) <= hsd]
# keep only longest
def no_longer(ij_tuple, notSig):
i, j = ij_tuple
for i1, j1 in notSig:
if (i1 <= i and j1 > j) or (i1 < i and j1 >= j):
return False
return True
longest = [(i, j) for i, j in notSig if no_longer((i, j), notSig)]
return longest
lines = get_lines(ssums, cd)
cd_lines = []
for temp_line in lines:
if cdmethod >= temp_line[0] and cdmethod <= temp_line[1]:
cd_lines.append(temp_line)
def draw_lines(lines, side=0.05, height=0.1):
start = cline + 0.2
for l, r in lines:
line([(rankpos(ssums[l]), start),
(rankpos(ssums[r]), start)],
linewidth=2.5)
# start += height
draw_lines(cd_lines)
print(lines[-1])
将上述代码粘贴到orange包下的scoring.py文件内(在本人电脑上为
D:\Software\Python\Miniconda3\envs\pytorch\lib\site-packages\Orange\ evaluation\scoring.py)
的以下部分,将源代码部分替换掉
elif cd:
# 源代码
begin = rankpos(avranks[cdmethod] - cd)
end = rankpos(avranks[cdmethod] + cd)
line([(begin, cline), (end, cline)],
linewidth=2.5)
line([(begin, cline + bigtick / 2),
(begin, cline - bigtick / 2)],
linewidth=2.5)
line([(end, cline + bigtick / 2),
(end, cline - bigtick / 2)],
linewidth=2.5)
# of 源代码
即可得到另一种形式的CD图。
如果有高人知道更简单的方法,期待您的指导:-D。