Python实现基于邻域粗糙集的多标记特征选择算法

算法思想源自论文:

段洁、胡清华、张灵均,等. 基于邻域粗糙集的多标记分类特征选择算法 [J]. 计算机研究与发展,201552(1):56-65

因为没找到Python源代码,所以自己试着写了一下,结果是对应上的。
代码分享在这里,需要的自取

"""
    Author: wzk
    Date:   2020-10-11
    theme:  多标记邻域粗糙集特征选择算法
"""
from settings.setting import *


class ARMLNRS:
    """
        基于邻域粗糙集的多标签特征选择
        可以用欧式距离处理连续类型的数据集
        1、输入数据集,训练集
        2、双重for循环,二重循环下,计算当前属性依赖度
        3、前向贪心搜索

    """
    def __init__(self, train_data, train_target, test_data, test_target, delta, info):
        """
        初始化对象参数
        :param train_data: 训练集数据
        :param train_target: 训练集标签
        :param test_data: 测试集数据
        :param test_target: 测试集标签
        :param delta: δ邻域的值,
        :param info: Config项中的配置,实验结果记录会用到这个
        """
        self.train_data = train_data
        self.train_target = train_target
        self.test_data = test_data
        self.test_target = test_target
        self.info = info
        self.delta = delta
        pass

    def compute_corr(self, i, j, tmp_train_data):
        """
        计算相关性
        :param i: 循环第i次
        :param j: 当前特征
        :param tmp_train_data: 临时数据
        :return: 
        """
        if i == 0:
            tmp_train_data = self.train_data[:, j]
        # 每一轮更新一个临时数据集,用以测试不同特征下的依赖度的不同
        else:
            tmp_train_data = np.insert(tmp_train_data, tmp_train_data.shape[1], self.train_data[:, j], axis=1)

        # 计算样本的δ邻域
        delta_neighbor_dict = dict()
        for k in range(self.train_data.shape[0]):
            delta_neighbor_list = list()
            for v in range(self.train_data.shape[0]):
                dis = np.sqrt(np.sum((tmp_train_data[k] - tmp_train_data[v]) ** 2))
                if dis <= self.delta:
                    delta_neighbor_list.append(v)
            delta_neighbor_dict.update({k: delta_neighbor_list})

        # 对每个样本判断是否在δ邻域内,是的话更新邻域样本的列表
        sample_list = list()
        for k in range(self.train_data.shape[0]):
            count_issubset = 0
            count = 0
            for v in range(self.train_target.shape[1]):
                if self.train_target[k, v] == 1:
                    count += 1
                    # 每个标签下不同类别及其对应样本索引
                    target_equivalence_class = defaultdict(list)
                    for m, n in [(n, m) for m, n in list(enumerate(self.train_target[:, v]))]:
                        target_equivalence_class[m].append(n)
                    # 前者是否是后者子集
                    if set(delta_neighbor_dict.get(k)).issubset(target_equivalence_class.get(1)):
                        count_issubset += 1
                    else:
                        break
            if count_issubset == count:
                sample_list.append(k)

        # 计算当前特征下的属性依赖度
        corr = len(sample_list) / self.train_data.shape[0]
        return corr

    def armlnrs(self):
        """
            1、一阶段,计算当前特征子集与候选特征子集中任意一个特征后的属性依赖度
            2、属性依赖度的计算,依赖于满足邻域近似条件的样本数目
            3、邻域近似条件指的是当样本的δ邻域内的样本属于样本分类标记中的任意一个标记下的等价类内,该样本满足邻域条件
            4、样本的δ邻域计算是样本与任意个样本进行计算,获取距离,小于δ则加入邻域,
            5、标签等价类是指样本被标记的正类
        :return:
        """
        feature_num = self.train_data.shape[1]
        feature_list = list()
        corr_first = 0
        print("初始依赖度为0")

        for i in range(feature_num):
            tmp_train_data = self.train_data[:, feature_list]
            max_corr = 0
            max_index = 0
            for j in range(self.train_data.shape[1]):
                if j in feature_list:
                    continue
                corr = self.compute_corr(i, j, tmp_train_data)
                print("当前特征数:", len(feature_list), "当前特征:", j, "当前corr:", corr, "最大corr:", corr_first)
                if max_corr < corr:
                    max_corr = corr
                    max_index = j

            if corr_first < max_corr:
                corr_first = max_corr
                feature_list.append(max_index)
            else:
                break

        return self.train_data[:, feature_list], self.train_target, self.test_data[:, feature_list], self.test_target
        pass


版权声明:本文为u012841977原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。