Relief特征提取算法实战

本文介绍了Relief特征权重算法及其演变到ReliefF的过程,适用于多类别问题的特征提取。通过实例展示了如何在含有27个特征的CSV数据上应用ReliefF算法,并讨论了算法的运行时间和学习产出,包括技术笔记、博客和视频创作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介及其演变

Relief算法最早由Kira提出,最初局限于两类数据的分类问题。Relief算法是一种特征权重算法(Feature weighting algorithms),根据各个特征和类别的相关性赋予特征不同的权重,权重小于某个阈值的特征将被移除。Relief算法中特征和类别的相关性是基于特征对近距离样本的区分能力。算法从训练集D中随机选择一个样本R,然后从和R同类的样本中寻找最近邻样本H,称为Near Hit,从和R不同类的样本中寻找最近邻样本M,称为NearMiss,然后根据以下规则更新每个特征的权重:如果R和Near Hit在某个特征上的距离小于R和Near Miss上的距离,则说明该特征对区分同类和不同类的最近邻是有益的,则增加该特征的权重;反之,如果R和Near Hit在某个特征的距离大于R和Near Miss上的距离,说明该特征对区分同类和不同类的最近邻起负面作用,则降低该特征的权重。以上过程重复m次,最后得到各特征的平均权重。特征的权重越大,表示该特征的分类能力越强,反之,表示该特征分类能力越弱。Relief算法的运行时间随着样本的抽样次数m和原始特征个数N的增加线性增加,因而运行效率非常高。

由于Relief算法比较简单,但运行效率高,并且结果也比较令人满意,因此得到广泛应用,但是其局限性在于只能处理两类别数据,因此1994年Kononeill对其进行了扩展,得到了ReliefF作算法,可以处理多类别问题。该算法用于处理目标属性为连续值的回归问题。ReliefF算法在处理多类问题时,每次从训练样本集中随机取出一个样本R,然后从和R同类的样本集中找出R的k个近邻样本(near Hits),从每个R的不同类的样本集中均找出k个近邻样本(near Misses),然后更新每个特征的权重。

转载至https://blog.youkuaiyun.com/lj6052317/article/details/85077201


自定义样本

我的训练数据是有27个特征,标签为01的训练数据,文件类型是csv文件。大致如下:
在这里插入图片描述

代码

运行代码需要首先导入对应的包,修改文件上传、保存的位置,重新定义index及data = pd.read_csv(f)[],使之与自己csv中index一致。

import pandas as pd
import numpy as np
import numpy.linalg as la
import random
import csv

'''
适用于多分类问题
'''
class Relief:
    def __init__(self, data_df, sample_rate, t, k):
        """
        #
        :param data_df: 数据框(字段为特征,行为样本)
        :param sample_rate: 抽样比例
        :param t: 统计量分量阈值
        :param k: k近邻的个数
        """
        self.__data = data_df
        self.__feature = data_df.columns
        self.__sample_num = int(round(len(data_df) * sample_rate))
        self.__t = t
        self.__k = k

    # 数据处理(将离散型数据处理成连续型数据,比如字符到数值)
    def get_data(self):
        new_data = pd.DataFrame()
        for one in self.__feature[:-1]:
            col = self.__data[one]
            if (str(list(col)[0]).split(".")[0]).isdigit() or str(list(col)[0]).isdigit() or (str(list(col)[0]).split('-')[-1]).split(".")[-1].isdigit():
                new_data[one] = self.__data[one]
                # print('%s 是数值型' % one)
            else:
                # print('%s 是离散型' % one)
                keys = list(set(list(col)))
                values = list(range(len(keys)))
                new = dict(zip(keys, values))
                new_data[one] = self.__data[one].map(new)
        new_data[self.__feature[-1]] = self.__data[self.__feature[-1]]
        return new_data

    # 返回一个样本的k个猜中近邻和其他类的k个猜错近邻
    def get_neighbors(self, row):
        df = self.get_data
### Relief 特征选择算法原理 Relief特征选择算法是一种基于实例的过滤式特征选择方法,最初由Kira和Rendell于1992年提出[^1]。该算法的核心思想在于评估各个特征对于区分不同类别样本的能力。具体来说,Relief通过迭代方式更新各特征权重,以此衡量它们的重要性。 #### 工作机制 在每次迭代过程中,随机选取一个样例作为参考点,并找到与其最近邻的不同类别的近邻(称为“敌对邻居”),以及同类别的近邻(称为“友好邻居”)。接着根据这两个邻居之间的距离差异调整当前考察特征的重要度得分: - 如果某个特征使得两个同属一类的数据点更接近,则增加此特征分数; - 若某特征让异类数据间的差距变大也相应加分;反之减分。 经过多轮循环后得到所有属性上的评分向量,最后依据这些数值大小排序并筛选出最优子集用于后续建模过程。 ### MATLAB 实现示例 下面给出一段简单的MATLAB代码片段来说明如何实现基本版的Relief算法: ```matlab function weights = relief(X, y, m) % X: 输入矩阵 (n_samples x n_features), 行为样本列为代表不同的特性; % y: 类标签向量长度等于X行数; % m: 进行m次抽样的次数. [n,d]=size(X); w=zeros(1,d);% 初始化权值 for i=1:m idx=randi(n); % 随机抽取索引 nearHit=[];nearMiss=[]; dists=sum((bsxfun(@minus,X,X(idx,:))).^2,2).^0.5;% 计算欧氏距离 hitIdx=find(y==y(idx));missIdx=find(y~=y(idx)); [~,hitPos]=min(dists(hitIdx));%, 获取相同标签中最靠近idx位置 nearHit=X(hitIdx(hitPos),:); if isempty(missIdx)% 当前点可能已经是唯一类别成员时处理特殊情况 continue; end [~,missPos]=min(dists(missIdx));% 找到不同标签里最接近的位置 nearMiss=X(missIdx(missPos),:); diff_hit=X(idx,:) - nearHit; diff_miss=X(idx,:) - nearMiss; w=w+(abs(diff_miss)-abs(diff_hit))./m; end end ``` 这段脚本实现了标准版本的Relief算法逻辑框架,在实际应用中可以根据需求进一步优化改进,比如引入更多参数控制、支持多种距离度量等方式增强灵活性与适用范围。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值