python特征选择relieff图像特征优选_基于python3的特征选择ReliefF算法。十,python3x,实现...

#!/usr/bin/env python

# -*- coding:utf-8 -*-

#@Time : 2019/10/29 0029 9:12

#@Author : tb_youth

#@FileName: RTest.py

#@SoftWare: PyCharm

#@Blog : https://blog.csdn.net/tb_youth

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()

row_type = row[df.columns[-1]]

right_df = df[df[df.columns[-1]] == row_type].drop(columns=[df.columns[-1]])

aim = row.drop(df.columns[-1])

f = lambda x: eulidSim(np.mat(x), np.mat(aim))

right_sim = right_df.apply(f, axis=1)

right_sim_two = right_sim.drop(right_sim.idxmin())

right = dict()

right[row_type] = list(right_sim_two.sort_values().index[0:self.__k])

# print list(right_sim_two.sort_values().index[0:self.__k])

lst = [row_type]

types = list(set(df[df.columns[-1]]) - set(lst))

wrong = dict()

for one in types:

wrong_df = df[df[df.columns[-1]] == one].drop(columns=[df.columns[-1]])

wrong_sim = wrong_df.apply(f, axis=1)

wrong[one] = list(wrong_sim.sort_values().index[0:self.__k])

print(right, wrong)

return right, wrong

# 计算特征权重

def get_weight(self, feature, index, NearHit, NearMiss):

# data = self.__data.drop(self.__feature[-1], axis=1)

data = self.__data

row = data.iloc[index]

right = 0

print('####:',NearHit.values())

for one in list(NearHit.values())[0]:

nearhit = data.iloc[one]

if (str(row[feature]).split(".")[0]).isdigit() or str(row[feature]).isdigit() or (str(row[feature]).split('-')[-1]).split(".")[-1].isdigit():

max_feature = data[feature].max()

min_feature = data[feature].min()

right_one = pow(round(abs(row[feature] - nearhit[feature]) / (max_feature - min_feature), 2), 2)

else:

print('@@:',row[feature])

print('$$:',nearhit[feature])

print('-'*100)

right_one = 0 if row[feature] == nearhit[feature] else 1

right += right_one

right_w = round(right / self.__k, 2)

wrong_w = 0

# 样本row所在的种类占样本集的比例

p_row = round(float(list(data[data.columns[-1]]).count(row[data.columns[-1]])) / len(data), 2)

for one in NearMiss.keys():

# 种类one在样本集中所占的比例

p_one = round(float(list(data[data.columns[-1]]).count(one)) / len(data), 2)

wrong_one = 0

for i in NearMiss[one]:

nearmiss = data.iloc[i]

if (str(row[feature]).split(".")[0]).isdigit() or str(row[feature]).isdigit() or (str(row[feature]).split('-')[-1]).split(".")[-1].isdigit():

max_feature = data[feature].max()

min_feature = data[feature].min()

wrong_one_one = pow(round(abs(row[feature] - nearmiss[feature]) / (max_feature - min_feature), 2), 2)

else:

wrong_one_one = 0 if row[feature] == nearmiss[feature] else 1

wrong_one += wrong_one_one

wrong = round(p_one / (1 - p_row) * wrong_one / self.__k, 2)

wrong_w += wrong

w = wrong_w - right_w

return w

# 过滤式特征选择

def reliefF(self):

sample = self.get_data()

# print sample

m, n = np.shape(self.__data) # m为行数,n为列数

score = []

sample_index = random.sample(range(0, m), self.__sample_num)

print('采样样本索引为 %s ' % sample_index)

num = 1

for i in sample_index: # 采样次数

one_score = dict()

row = sample.iloc[i]

NearHit, NearMiss = self.get_neighbors(row)

print('第 %s 次采样,样本index为 %s,其NearHit k近邻行索引为 %s ,NearMiss k近邻行索引为 %s' % (num, i, NearHit, NearMiss))

for f in self.__feature[0:-1]:

print('***:',f,i,NearHit,NearMiss)

w = self.get_weight(f, i, NearHit, NearMiss)

one_score[f] = w

print('特征 %s 的权重为 %s.' % (f, w))

score.append(one_score)

num += 1

f_w = pd.DataFrame(score)

print('采样各样本特征权重如下:')

print( f_w)

print('平均特征权重如下:')

print(f_w.mean())

return f_w.mean()

# 返回最终选取的特征

def get_final(self):

f_w = pd.DataFrame(self.reliefF(), columns=['weight'])

final_feature_t = f_w[f_w['weight'] > self.__t]

print('*'*100)

print(final_feature_t)

# final_feature_k = f_w.sort_values('weight').head(self.__k)

# print final_feature_k

return final_feature_t

# 几种距离求解

#欧氏距离(Euclidean Distance)

def eulidSim(vecA, vecB):

return la.norm(vecA - vecB)

#余弦相似度

def cosSim(vecA, vecB):

"""

:param vecA: 行向量

:param vecB: 行向量

:return: 返回余弦相似度(范围在0-1之间)

"""

num = float(vecA * vecB.T)

denom = la.norm(vecA) * la.norm(vecB)

cosSim = 0.5 + 0.5 * (num / denom)

return cosSim

#皮尔逊(皮尔森)相关系数

'''

皮尔森相关系数也称皮尔森积矩相关系数(Pearson product-moment correlation coefficient) ,

是一种线性相关系数,

是最常用的一种相关系数。

记为r,用来反映两个变量X和Y的线性相关程度,

r值介于-1到1之间,绝对值越大表明相关性越强。

'''

def pearsSim(vecA, vecB):

if len(vecA) < 3:

return 1.0

else:

return 0.5 + 0.5 * np.corrcoef(vecA, vecB,rowvar=0)[0][1]

if __name__ == '__main__':

with open('./西瓜数据集30.csv','r',encoding= 'gbk') as f:

data = pd.read_csv(f)[['色泽', '根蒂', '敲声', '纹理', '脐部', '触感', '密度', '含糖率', '好瓜']]

#print(type(data))

# print(data)

# f_csv = csv.reader(f)

# for row in f_csv:

# print(row)

f = Relief(data, 1, 0.2, 2)

# df = f.get_data()

# print(type(df.iloc[0]))

# f.get_neighbors(df.iloc[0])

f.reliefF()

f.get_final()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: rrelieff算法是一种特征选择算法,用于从数据集中选择出最具有区分度的特征。该算法使用了用最近邻法来估计特征的重要性,进而进行特征选择。 在Python中,可以使用scikit-learn库中的RReliefF类来实现rrelieff算法。首先,需要导入相应的库和模块: ```python from sklearn.feature_selection import RReliefF from sklearn.datasets import load_iris ``` 然后,加载数据集,这里以鸢尾花数据集为例: ```python data = load_iris() X = data.data y = data.target ``` 接下来,创建一个RReliefF对象,并使用fit_transform方法对数据集进行特征选择: ```python rrelief = RReliefF(n_features_to_select=2) X_selected = rrelief.fit_transform(X, y) ``` 在fit_transform方法中,可以通过n_features_to_select参数指定需要选择的特征数量。这里选择了2个最重要的特征。 最后,可以打印出选择后的特征子集: ```python print(X_selected) ``` 以上就是使用Python实现rrelieff算法的基本步骤。需要注意的是,该算法是一种监督学习算法,所以在使用时需要提供标签信息。另外,选择的特征子集可以通过fit_transform方法返回,用于后续的建模和分析任务。 ### 回答2: rrelieff 算法是一种特征选择算法,用于在给定的数据集中找到最重要的特征。它通过计算每个特征对于样本之间的相互关系的贡献度来确定特征的重要性。 以下是使用 Python 实现 rrelieff 算法的基本步骤: 1. 导入所需的库和模块:首先,我们需要导入 pandas 库来处理数据,numpy 库来进行数值计算,以及 rrelieff 模块用于实现算法。 2. 导入数据集:使用 pandas 的 read_csv 函数导入包含特征的数据集。 3. 数据预处理:根据需要进行数据预处理,例如数据缺失值的处理、标签编码等。 4. 特征选择:使用 rrelieff 模块中的 RReliefF 函数来选择重要的特征。可以设置适当的参数,如邻居数量和采样次数。 5. 输出结果:根据算法的输出结果,按照特征的重要性进行排序,选择前几个重要的特征。 下面是一个简单的示例代码: ```python import pandas as pd import numpy as np from rrelieff import RReliefF # 导入数据集 data = pd.read_csv('data.csv') # 数据预处理 # ... # 特征选择 X = data.iloc[:, :-1].values y = data.iloc[:, -1].values fs = RReliefF(n_neighbors=10, n_features_to_select=5) X_selected = fs.fit_transform(X, y) # 输出结果 important_features = fs.top_features print("重要特征的索引:", important_features) ``` 这段代码使用 rrelieff 模块的 RReliefF 类来进行特征选择。可以根据需求设置邻居数量、要选择的特征数量等参数。最后,根据算法的输出结果,输出重要特征的索引。 需要注意的是,确保已经通过 pip 或其他方式安装了 rrelieff 模块,并在代码中正确导入。 ### 回答3: RRelief算法是一种特征选择算法,用于处理机器学习中的分类问题。它的目标是选择出最具有区分性的特征,以提高分类器的性能。 RRelief算法的主要步骤如下: 1. 初始化权重:对每个特征都初始化一个权重值,初始值为0。 2. 遍历训练数据集:对于每个训练样本,计算它与相邻样本之间特征差异的绝对值。 3. 更新权重:根据计算得到的特征差异,更新特征的权重值。如果特征差异小于0,则减小该特征的权重;如果特征差异大于0,则增加该特征的权重。 4. 重复步骤2和3,直到遍历完所有训练样本。 5. 选择特征:根据特征的权重值,选择权重较大的特征作为最终的特征子集。 RRelief算法的核心思想是通过计算样本之间的特征差异,来评估特征对于样本分类的重要性。特征差异越大,说明该特征在分类中的作用越明显。 在Python中,可以通过sklearn库的reliefF模块实现RRelief算法。首先,需要导入相关的库和数据集,然后对数据集进行预处理,如归一化等。接着,使用reliefF函数来选择特征,该函数会返回选择后的特征子集。最后,可以用选择的特征子集建立分类器,如KNN、SVM等。 在使用RRelief算法时,需要注意调节相关参数,如临近样本的个数、权重更新的方式等,以获得更好的特征选择效果。此外,还需要根据具体问题领域来选择适合的评价指标,以评估特征选择的效果。 总之,RRelief算法是一种用于特征选择算法,通过计算样本之间的特征差异来选择最具有区分性的特征。在Python中可以使用sklearn库的reliefF模块实现算法,并根据具体问题调节相关参数和评价指标,以获得理想的特征选择结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值