ELDB代码

算法主类的构建

代码中调用的其他类见

构造函数

def init(self,*,*)
ELDB类继承MIL类,在构造函数中调用MIL的构造函数

super(ELDB, self).__init__(data_path, save_home=save_home, bag_space=bag_space)
    def __init__(self, data_path, psi=0.9, alpha=0.75, batch=None, psi_max=100,
                 type_b2b="ave", mode_bag_init="g", mode_action="a", k=10,
                 type_classifier=None, type_performance=None, print_loop=False,
                 save_home="../Data/Distance/", bag_space=None):
        """
        构造函数
        :param
            data_path:              数据的存储路径
            psi:                    基础dBagSet的大小
            alpha:                  学习率,即基础dBagSet的大小与训练集的比值
                                     在算法中,$\alpha \times N$ 表示为T_d,余下作为$T_s$
            batch:                  批次大小,当指定为None为,将使用默认划分,将$T_s$二分
            psi_max:                基础dBagSet的最大容量
            type_b2b:               距离函数的类型
            mode_bag_init:          基础dBagSet的初始化模式
            mode_action:            算法的行为模式
            k:                      k折交叉验证
            type_classifier:        单实例分类器,默认None时将使用["knn", "svm", "j48"]
            type_performance:       性能度量类型,默认None时将使用["acc", "f1_score"]
            print_loop:             是否输出每一折的轮次
            save_home:
            bag_space:              参见MIL文件
        """
        super(ELDB, self).__init__(data_path, save_home=save_home, bag_space=bag_space)
        self._psi = psi
        self._alpha = alpha
        self._batch = batch
        self._psi_max = psi_max
        self._type_b2b = type_b2b
        self._mode_bag_init = mode_bag_init
        self._mode_action = mode_action
        self._k = k
        self._type_classifier = type_classifier
        self._type_performance = type_performance
        self._print_loop = print_loop
        self.__init_eldb()
初始化函数

初始化分类器、度量类型、距离矩阵、各分类结果存储变量
距离矩阵调用B2B类,MIL

self.dis = B2B(self.data_name, self.bag_space, self._type_b2b, self.save_home).get_dis()
    def __init_eldb(self):
        """
        ELDB的初始化函数
        """
        self._type_classifier = ["knn", "svm", "j48"] if self._type_classifier is None else self._type_classifier
        self._type_performance = ["accuracy", "f1_score"] if self._type_performance is None else self._type_performance
        # 距离矩阵
        self.dis = B2B(self.data_name, self.bag_space, self._type_b2b, self.save_home).get_dis()
        # 记录不同分类器不同分类性能的分类结果
        self.lab_predict = {}
        # 记录按照交叉验证顺利的真实标签
        self.lab_true = []
        # 记录分类性能
        self.val_performance = {}
获取映射结果函数

初始化操作
获取训练集、测试集索引
获取分类器、度量指标、重设纪律参数

对每一折的训练集和测试集:划分基础数据集和更新数据集(大小、索引)

  • 首先通过遍历获取每一折的训练集和数据集
  • 基准数据集 N T d N_{Td} NTd、更新数据集 N T s N_{Ts} NTs

模型初始化操作

  • 计算 Δ \Delta Δ矩阵
# 计算\Delta矩阵
            matrix_Delta = np.zeros((N_Td, N_Td), dtype=int)
            for i in range(N_Td):
                for j in range(N_Td):
                    # 这里使用最简单的设计,即标签相同设置为-1;反之为1
                    if self.bag_lab[idx_td[i]] == self.bag_lab[idx_td[j]]:
                        matrix_Delta[i, j] = -1
                    else:
                        matrix_Delta[i, j] = 1
  • 计算 Γ \Gamma Γ矩阵
    np.diag(x):创建以x为对角线的对角矩阵
matrix_Gamma = np.diag(np.sum(matrix_Delta, 1))
  • 计算判别矩阵 L L L
matrix_L = matrix_Gamma - matrix_Delta
  • 计算分数
score_t = np.dot(np.dot(mapping_bag, matrix_L), np.transpose(mapping_bag))

基本数据集中从大到小排序索引

arg_score_td = np.argsort(score_td)[::-1]

获得初始dBagset

score_dBagSet, idx_dBagSet = score_td[idx_dBagSet], [idx_td[idx_dBagSet].tolist()]
  • 更新操作
    将每一轮更新后的dBagset索引列表,添加到 idx_dBagSet
idx_dBagSet.append(idx_dBagSet_update)

替换更新,返回变化后的索引和分数

        def __dBagSet_update_r(para_idx_dBagSet, para_score_dBagSet, idx_cur, score_cur):
            """
            用于行为模式r的更新
            :param
                para_score_td:   T_d的得分拷贝
                score_cur:       当前包的得分
            :return
                返回更新后的score_td
            """
            for idx_find in np.arange(len(para_idx_dBagSet) - 1, -1, -1):
                if score_cur > para_score_dBagSet[idx_find]:
                    continue
                else:
                    idx_find += 1
                    idx_find = len(para_idx_dBagSet) - 1 if idx_find == len(para_idx_dBagSet) else idx_find
                    para_idx_dBagSet[idx_find + 1:] = para_idx_dBagSet[idx_find: -1]
                    para_score_dBagSet[idx_find + 1:] = para_score_dBagSet[idx_find: -1]
                    para_idx_dBagSet[idx_find], para_score_dBagSet[idx_find] = idx_cur, score_cur
                    break
            return para_idx_dBagSet, para_score_dBagSet
  • 构建带权集成模型
    使用每一轮的dBagset的映射集mapping_td和对应标签Y_d,训练模型;使用模型预测更新数据子集的映射集mapping_ts和Y_s进行预测得到性能值,加入权重列表Weight,与测试集预测标签Predict
# 获取映射
                mapping_td, mapping_ts = self.dis[idx_td, :][:, dBagSet], self.dis[idx_ts, :][:, dBagSet]
                # 获取迭代器
                data_iter = get_iter(mapping_td, Y_d, mapping_ts, Y_s)
                # 获取权重并记录
                Weight.append(classifier.test(data_iter))
data_iter = get_iter(mapping_tr, lab_tr, mapping_te, lab_te)
                classifier.test(data_iter)
                Predict.append(classifier.te_predict_arr)

np.vstack :垂直(按照行顺序)的把数组给堆叠起来

  • 处理预测结果
    1)对每一轮的权值,预测标签进行加权处理,其中每一轮内都包括不同的分类器、不同的性能度量指标”
    2)对每一个分类器下每一个分类指标权值下的累加加权后的预测标签
 # 处理每一个分类器和分类指标的预测结果
            for i, (predict, weight) in enumerate(zip(Predict, Weight)):
                # 对于每一个分类器
                for classifier_name in self._type_classifier:
                    # 对于每一个分类度量指标
                    weight_classifier = weight[classifier_name]
                    for j, metric in enumerate(weight_classifier):
                        # 加权
                        weight_predict = metric * np.array(predict[classifier_name])
                        te_predict_all[classifier_name + ' ' + self._type_performance[j]] = \
                            te_predict_all.get(classifier_name + ' ' + self._type_performance[j],
                                               np.zeros_like(weight_predict)) + weight_predict

3)最后te_predict_all字典存储了不同分类器不同度量指标下的测试集最终加权集成预测结果
4)将标签标准化

			# 计算分类阈值
            tau = len(Weight) / 2
            # 阈值函数
            def sign(arr):
                arr[arr > tau] = 1
                arr[arr != 1] = 0
                return arr

对于te_predict_all字典中,每一关键字下的预测内容都进行处理,得到测试集的预测标签字典lab_predict、测试集真实标签列表lab_true
5)计算每一个key下对应的度量指标值,得到存储字典val_performance

# 获取分类性能
        for key, val in self.lab_predict.items():
            key_temp = key.split()
            self.val_performance[key] = performance[key_temp[-1]](val, self.lab_true)

        return self.val_performance
  • 代码
import numpy as np
import warnings
from Code.ClassifyTool import Classify
from Code.Distance import B2B
from Code.Function import get_k_cv_idx, get_iter, get_performance
from Code.MIL import MIL
warnings.filterwarnings('ignore')

class ELDB(MIL):
    """
    ELDB算法主类
    """
    def __init__(self, data_path, psi=0.9, alpha=0.75, batch=None, psi_max=100,
                 type_b2b="ave", mode_bag_init="g", mode_action="a", k=10,
                 type_classifier=None, type_performance=None, print_loop=False,
                 save_home="../Data/Distance/", bag_space=None):
        """
        构造函数
        :param
            data_path:              数据的存储路径
            psi:                    基础dBagSet的大小
            alpha:                  学习率,即基础dBagSet的大小与训练集的比值
                                    在算法中,$\alpha \times N$ 表示为T_d,余下作为$T_s$
            batch:                  批次大小,当指定为None为,将使用默认划分,将$T_s$二分
            psi_max:                基础dBagSet的最大容量
            type_b2b:               距离函数的类型
            mode_bag_init:          基础dBagSet的初始化模式
            mode_action:            算法的行为模式
            k:                      k折交叉验证
            type_classifier:        单实例分类器,默认None时将使用["knn", "svm", "j48"]
            type_performance:       性能度量类型,默认None时将使用["acc", "f1_score"]
            print_loop:             是否输出每一折的轮次
            save_home:
            bag_space:              参见MIL文件
        """
        super(ELDB, self).__init__(data_path, save_home=save_home, bag_space=bag_space)
        self._psi = psi
        self._alpha = alpha
        self._batch = batch
        self._psi_max = psi_max
        self._type_b2b = type_b2b
        self._mode_bag_init = mode_bag_init
        self._mode_action = mode_action
        self._k = k
        self._type_classifier = type_classifier
        self._type_performance = type_performance
        self._print_loop = print_loop
        self.__init_eldb()

    def __init_eldb(self):
        """
        ELDB的初始化函数
        """
        self._type_classifier = ["knn", "svm", "j48"] if self._type_classifier is None else self._type_classifier
        self._type_performance = ["accuracy", "f1_score"] if self._type_performance is None else self._type_performance
        # 距离矩阵
        self.dis = B2B(self.data_name, self.bag_space, self._type_b2b, self.save_home).get_dis()
        # 记录不同分类器不同分类性能的分类结果
        self.lab_predict = {}
        # 记录按照交叉验证顺利的真实标签
        self.lab_true = []
        # 记录分类性能
        self.val_performance = {}

    def __reset_record(self):
        """
        重设记录相关的变量
        """
        self.lab_predict = {}
        self.lab_true = []
        self.val_performance = {}

    def __get_classifier(self):
        """
        获取分类器
        """
        return Classify(self._type_classifier, self._type_performance)

    def get_state(self):
        """
        获取使用的分类以及度量性能
        """
        return self._type_classifier, self._type_performance

    def get_mapping(self):
        """
        获取映射结果.
        """
        def __dBagSet_update_r(para_idx_dBagSet, para_score_dBagSet, idx_cur, score_cur):
            """
            用于行为模式r的更新
            :param
                para_score_td:   T_d的得分拷贝
                score_cur:       当前包的得分
            :return
                返回更新后的score_td
            """
            for idx_find in np.arange(len(para_idx_dBagSet) - 1, -1, -1):
                if score_cur > para_score_dBagSet[idx_find]:
                    continue
                else:
                    idx_find += 1
                    idx_find = len(para_idx_dBagSet) - 1 if idx_find == len(para_idx_dBagSet) else idx_find
                    para_idx_dBagSet[idx_find + 1:] = para_idx_dBagSet[idx_find: -1]
                    para_score_dBagSet[idx_find + 1:] = para_score_dBagSet[idx_find: -1]
                    para_idx_dBagSet[idx_find], para_score_dBagSet[idx_find] = idx_cur, score_cur
                    break
            return para_idx_dBagSet, para_score_dBagSet

        # 获取训练集和测试集的索引
        idxes_tr, idxes_te = get_k_cv_idx(self.N, self._k)
        # 正包标签
        lab_positive = np.max(self.bag_lab)
        # 获取单实例分类器
        classifier = self.__get_classifier()
        # 性能度量器
        performance = get_performance(self._type_performance)
        # 记录参数重设
        self.__reset_record()
        # 主循环
        for loop, (idx_tr, idx_te) in enumerate(zip(idxes_tr, idxes_te)):
            """步骤0:初始化操作"""
            if self._print_loop:
                print("第{}折交叉验证...".format(loop))
            # 计算训练集、基准数据集和更新数据集的大小
            N_T = len(idx_tr)
            N_Ts = int(N_T * (1 - self._alpha))
            # 计算批次大小
            batch = N_Ts // 2 if self._batch is None else self._batch
            # 计算最大更新次数
            n_l = N_Ts // batch
            N_Td = N_T - (n_l * batch)
            # 获取T_d和T_s的索引
            idx_td, idx_ts = np.array(idx_tr[:N_Td]), np.array(idx_tr[N_Td:])

            """步骤1:模型和参数初始化"""
            # 计算\Delta矩阵
            matrix_Delta = np.zeros((N_Td, N_Td), dtype=int)
            for i in range(N_Td):
                for j in range(N_Td):
                    # 这里使用最简单的设计,即标签相同设置为-1;反之为1
                    if self.bag_lab[idx_td[i]] == self.bag_lab[idx_td[j]]:
                        matrix_Delta[i, j] = -1
                    else:
                        matrix_Delta[i, j] = 1
            # 计算\Gamma矩阵
            matrix_Gamma = np.diag(np.sum(matrix_Delta, 1))
            # 计算L矩阵
            matrix_L = matrix_Gamma - matrix_Delta
            # 只需要保留L矩阵
            del matrix_Delta, matrix_Gamma
            # 基于整个T_d进行映射//得到训练包到基本数据集的距离矩阵,每一行表示一个训练包的映射向量
            mapping_bag = self.dis[idx_tr, :][:, idx_td]
            # 使用矩阵乘法加速
            score_t = np.dot(np.dot(mapping_bag, matrix_L), np.transpose(mapping_bag))
            # 对角元素即是包的得分
            score_t = np.diag(score_t)
            # 获取T_d和T_s中每一个包的得分
            score_td, score_ts = score_t[:N_Td], score_t[N_Td:]
            # 获取初始dBagSet的大小
            psi = int(min(self._psi_max, N_Td) * self._psi)
            arg_score_td = np.argsort(score_td)[::-1]
            # 获取dBagSet在训练集中的真实索引
            if self._mode_bag_init == 'g':
                idx_dBagSet = arg_score_td[:psi].tolist()
            else:
                idx_dBagSet = []
                count = 0
                for i in arg_score_td:
                    if count >= psi:
                        break
                    if self._mode_bag_init == 'p' and self.bag_lab[idx_td[i]] == lab_positive or\
                       self._mode_bag_init == 'n' and self.bag_lab[idx_td[i]] != lab_positive:
                        idx_dBagSet.append(i)
                    count += 1
            score_dBagSet, idx_dBagSet = score_td[idx_dBagSet], [idx_td[idx_dBagSet].tolist()]
            del score_t, arg_score_td
            # 记录最小得分的索引和得分
            tau, p = len(idx_dBagSet[-1]) - 1, score_dBagSet[-1]
            # 获取所有更新后的dBagSet
            for i in range(n_l):
                idx_dBagSet_update, score_dBagSet_update = idx_dBagSet[-1].copy(), score_dBagSet.copy()
                for j in range(batch):
                    # 分数小于等于的均不考虑;取等是因为两个包得分完全相等的概率很小
                    idx_temp = i * batch + j
                    if score_ts[idx_temp] <= p:
                        continue
                    # 行为”a“只需要添加即可
                    if self._mode_action == "a":
                        idx_dBagSet_update.append(idx_ts[idx_temp])
                    # 行为”r“需要不断替换操作
                    else:
                        idx_dBagSet_update, score_dBagSet = __dBagSet_update_r(
                            idx_dBagSet_update, score_dBagSet_update, idx_ts[idx_temp], score_ts[idx_temp])

                if idx_dBagSet_update == idx_dBagSet[-1]:
                    continue
                idx_dBagSet.append(idx_dBagSet_update)
            del idx_dBagSet_update, score_dBagSet, mapping_bag

            """步骤2:构建带权集成模型"""
            # 遍历每一个dBagSet
            Y_d, Y_s = self.bag_lab[idx_td], self.bag_lab[idx_ts]
            # 训练集和测试集标签
            lab_tr, lab_te = self.bag_lab[idx_tr], self.bag_lab[idx_te]
            Predict, Weight = [], []

            for i, dBagSet in enumerate(idx_dBagSet):
                # 获取映射
                mapping_td, mapping_ts = self.dis[idx_td, :][:, dBagSet], self.dis[idx_ts, :][:, dBagSet]
                # 获取迭代器
                data_iter = get_iter(mapping_td, Y_d, mapping_ts, Y_s)
                # 获取权重并记录
                Weight.append(classifier.test(data_iter))
                # 获取训练集和测试集
                mapping_tr, mapping_te = np.vstack([mapping_td, mapping_ts]), self.dis[idx_te, :][:, dBagSet]
                del mapping_td, mapping_ts
                # 模型重训练并预测
                data_iter = get_iter(mapping_tr, lab_tr, mapping_te, lab_te)
                classifier.test(data_iter)
                Predict.append(classifier.te_predict_arr)
            # 清理缓存
            del data_iter, mapping_tr, mapping_te, lab_tr, lab_te
            """步骤3:获取预测的标签向量"""
            # 记录预测结果
            te_predict_all = {}
            # 处理每一个分类器和分类指标的预测结果
            for i, (predict, weight) in enumerate(zip(Predict, Weight)):
                # 对于每一个分类器
                for classifier_name in self._type_classifier:
                    # 对于每一个分类度量指标
                    weight_classifier = weight[classifier_name]
                    for j, metric in enumerate(weight_classifier):
                        # 加权
                        weight_predict = metric * np.array(predict[classifier_name])
                        te_predict_all[classifier_name + ' ' + self._type_performance[j]] = \
                            te_predict_all.get(classifier_name + ' ' + self._type_performance[j],
                                               np.zeros_like(weight_predict)) + weight_predict
            # 计算分类阈值
            tau = len(Weight) / 2

            # 阈值函数
            def sign(arr):
                arr[arr > tau] = 1
                arr[arr != 1] = 0
                return arr
            for key, val in te_predict_all.items():
                if loop == 0:
                    self.lab_predict[key] = sign(val).tolist()
                else:
                    self.lab_predict[key].extend(sign(val).tolist())
            self.lab_true.extend(self.bag_lab[idx_te])

        # 获取分类性能
        for key, val in self.lab_predict.items():
            key_temp = key.split()
            self.val_performance[key] = performance[key_temp[-1]](val, self.lab_true)

        return self.val_performance

Main

构建ELDB主类
eldb = ELDB(data_path=data_path, psi=args.psi, alpha=args.alpha, psi_max=args.psi_max,
                type_b2b=args.type_b2b, mode_bag_init=args.mode_bag_init,
                mode_action=args.mode_action, k=args.k,
                type_performance=args.type_performance, print_loop=args.print_loop)
进行10次CV

每一次cv调用eldb.get_mapping()
将10次cv的结果存储到results字典中

# 获取完整的CV实验结果
    for i in range(10):
        result_temp = eldb.get_mapping()
        for classifier in classifier_type:
            for metric in metric_type:
                val_temp = float("{:.4f}".format(result_temp[classifier + ' ' + metric] * 100))
                if i == 0:
                    results[classifier + ' ' + metric] = [val_temp]
                else:
                    results[classifier + ' ' + metric].append(val_temp)
计算平均值以及标准差

np.std:
当ddof=0时,计算的为总体标准偏差,一般在拥有所有数据的情况下,计算所有数据的标准差时使用,即最终除以n。
当ddof = 1时,表示计算无偏样本标准差,最终除以n-1。
这个是统计学意义上的,日常使用时一般情况很难收集到所有样本,都应该使用ddof = 1

对每个metric指标下,找出最佳分类器、平均值、标准差

 # 计算平均值以及标准差
    for metric in metric_type:
        best_ave[metric] = 0
        for i, classifier in enumerate(classifier_type):
            key = classifier + ' ' + metric
            ave_temp = float("{:.4f}".format(np.average(results[key])))
            std_temp = float("{:.4f}".format(np.std(results[key], ddof=1)))

            # 记录最佳结果
            if ave_temp > best_ave[metric]:
                best_classifier[metric] = classifier
                best_ave[metric] = ave_temp
                best_std[metric] = std_temp
                results_save[metric] = results[key]
保存分类结果并输出最佳结果
# 如果是最佳结果则进行保存
    data_save_path = (args.save_path_classification_result + data_name + '_' +
                      args.mode_action + '_' + str(args.k) + ".npz")
    if not os.path.exists(data_save_path):
        np.savez(data_save_path, best_classifier=best_classifier, best_ave=best_ave, best_std=best_std,
                 results_save=results_save)
    best_results_load = np.load(data_save_path, allow_pickle=True)
    # 输出最佳分类结果
    print("最佳分类结果 (行为模式{}, {}折交叉验证):".format(args.mode_action, args.k))
    for metric in metric_type:
        if best_ave[metric] < eval(str(best_results_load["best_ave"]))[metric]:
            best_classifier[metric] = eval(str(best_results_load["best_classifier"]))[metric]
            best_ave[metric] = eval(str(best_results_load["best_ave"]))[metric]
            best_std[metric] = eval(str(best_results_load["best_std"]))[metric]
            results_save[metric] = eval(str(best_results_load["results_save"]))[metric]
        print("\t{:s}度量{:s}分类器结果:".format(metric, best_classifier[metric]))
        print("\tk次验证结果:", results_save[metric])
        print("\t平均分类精度及标准差:", best_ave[metric], best_std[metric])
    np.savez(data_save_path, best_classifier=best_classifier, best_ave=best_ave, best_std=best_std,
             results_save=results_save)

其中,多次运行同一个数据集,首先与原文件中的结果作比较:1)若原文件中的值更大,则使用原文件中的预测值,2)若最新预测结果最佳,则直接使用最新最佳结果,并在文件中保存最新的最佳结果

代码
import argparse
import numpy as np
import os
from Code.ELDB import ELDB


def get_parser():
    """默认参数设置"""
    ini = np.recfromtxt("../Data/Ini/parameter_ini.txt")
    print(ini)
    save_path_parameter_txt = (str(ini[1][-1], encoding="utf-8") + data_name + '_' +
                               mode_action + '_' + str(ini[2][-1], encoding="utf-8") + ".txt")
    if not os.path.exists(save_path_parameter_txt):
        print(save_path_parameter_txt)
        psi = 0.9
        type_b2b = "ave"
        mode_bag_init = 'g'
    else:
        parameters = np.recfromtxt(save_path_parameter_txt)
        psi = float(parameters[0][-1])
        type_b2b = str(parameters[1][-1], encoding="utf-8")
        mode_bag_init = str(parameters[2][-1], encoding="utf-8")

    parser = argparse.ArgumentParser(description="多示例学习ELDB算法的参数设置")
    parser.add_argument("--psi", default=psi, choices=np.arange(0.1, 1.1, 0.1), help="辨别包的选取比例")
    parser.add_argument("-alpha", default=0.75, type=float, help="学习率")
    parser.add_argument("--psi_max", default=100, type=int, help="最大选取包数")
    parser.add_argument("--type_b2b", default=type_b2b, help="距离度量")
    parser.add_argument("--mode_bag_init", default=mode_bag_init, help="初始dBagSet选取模式")
    parser.add_argument("--mode-action", default=mode_action, help="行为模式")
    parser.add_argument("--k", default=int(str(ini[2][-1], encoding="utf-8")))
    parser.add_argument("--type_performance", default=["f1_score"], type=list, help="性能度量指标")
    parser.add_argument("--save_path_classification_result", default=str(ini[0][-1], encoding="utf-8"),
                        help="分类结果保存路径")
    parser.add_argument("--print_loop", action="store_false", default=False, help="是否打印loop变化值")

    return parser.parse_args()


def main():
    """
    测试
    """
    args = get_parser()
    eldb = ELDB(data_path=data_path, psi=args.psi, alpha=args.alpha, psi_max=args.psi_max,
                type_b2b=args.type_b2b, mode_bag_init=args.mode_bag_init,
                mode_action=args.mode_action, k=args.k,
                type_performance=args.type_performance, print_loop=args.print_loop)
    results = {}
    results_save = {}
    classifier_type, metric_type = eldb.get_state()
    # 获取完整的CV实验结果
    for i in range(10):
        result_temp = eldb.get_mapping()
        for classifier in classifier_type:
            for metric in metric_type:
                val_temp = float("{:.4f}".format(result_temp[classifier + ' ' + metric] * 100))
                if i == 0:
                    results[classifier + ' ' + metric] = [val_temp]
                else:
                    results[classifier + ' ' + metric].append(val_temp)
    # 计算平均值以及标准差
    for metric in metric_type:
        best_ave[metric] = 0
        for i, classifier in enumerate(classifier_type):
            key = classifier + ' ' + metric
            ave_temp = float("{:.4f}".format(np.average(results[key])))
            std_temp = float("{:.4f}".format(np.std(results[key], ddof=1)))

            # 记录最佳结果
            if ave_temp > best_ave[metric]:
                best_classifier[metric] = classifier
                best_ave[metric] = ave_temp
                best_std[metric] = std_temp
                results_save[metric] = results[key]

    # 如果是最佳结果则进行保存
    data_save_path = (args.save_path_classification_result + data_name + '_' +
                      args.mode_action + '_' + str(args.k) + ".npz")
    if not os.path.exists(data_save_path):
        np.savez(data_save_path, best_classifier=best_classifier, best_ave=best_ave, best_std=best_std,
                 results_save=results_save)
    best_results_load = np.load(data_save_path, allow_pickle=True)
    # 输出最佳分类结果
    print("最佳分类结果 (行为模式{}, {}折交叉验证):".format(args.mode_action, args.k))
    for metric in metric_type:
        if best_ave[metric] < eval(str(best_results_load["best_ave"]))[metric]:
            best_classifier[metric] = eval(str(best_results_load["best_classifier"]))[metric]
            best_ave[metric] = eval(str(best_results_load["best_ave"]))[metric]
            best_std[metric] = eval(str(best_results_load["best_std"]))[metric]
            results_save[metric] = eval(str(best_results_load["results_save"]))[metric]
        print("\t{:s}度量{:s}分类器结果:".format(metric, best_classifier[metric]))
        print("\tk次验证结果:", results_save[metric])
        print("\t平均分类精度及标准差:", best_ave[metric], best_std[metric])
    np.savez(data_save_path, best_classifier=best_classifier, best_ave=best_ave, best_std=best_std,
             results_save=results_save)


if __name__ == '__main__':
    """进行实验时需要修改的参数"""
    # 数据集的路径
    data_path = "../Data/Benchmark/musk2+.mat"
    # 行为模式,对应于aELDB和rELDB
    mode_action = 'r'  # or 'r'

    # 用于记录最佳分类器的分类结果
    best_classifier, best_ave, best_std = {}, {}, {}
    # 获取数据集名称
    data_name = data_path.split('/')[-1].split('.')[0]
    print("实验数据集{:s}".format(data_name))
    main()

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值