增加模块;增加主调用命令
This commit is contained in:
88
Feature_Selection_method/ReliefF.py
Normal file
88
Feature_Selection_method/ReliefF.py
Normal file
@ -0,0 +1,88 @@
|
||||
|
||||
import numpy as np
|
||||
from sklearn.neighbors import NearestNeighbors
|
||||
class ReliefF:
|
||||
def __init__(self, n_neighbors=20, n_features_to_keep=20):
|
||||
"""
|
||||
初始化 ReliefF 算法参数。
|
||||
:param n_neighbors: 每个样本的近邻数量。
|
||||
:param n_features_to_keep: 每次保留的特征数量。
|
||||
"""
|
||||
self.n_neighbors = n_neighbors
|
||||
self.n_features_to_keep = n_features_to_keep
|
||||
self.feature_scores = None # 用于存储每个特征的评分
|
||||
self.top_features = None # 用于存储评分最高的特征索引
|
||||
|
||||
def fit(self, X, y):
|
||||
"""
|
||||
根据给定的数据 X 和标签 y 计算特征评分。
|
||||
:param X: 输入特征矩阵。
|
||||
:param y: 类别标签。
|
||||
:return: 返回选择的特征索引。
|
||||
"""
|
||||
m, n = X.shape # m 是样本数,n 是特征数
|
||||
|
||||
self.feature_scores = np.zeros(n) # 初始化特征评分为 0
|
||||
|
||||
# 寻找每个样本的 n_neighbors 个近邻
|
||||
nbrs = NearestNeighbors(n_neighbors=self.n_neighbors + 1).fit(X)
|
||||
distances, indices = nbrs.kneighbors(X)
|
||||
|
||||
# 遍历每个样本,更新特征评分
|
||||
for i in range(m):
|
||||
y_i = y[i] # 当前样本的类别标签
|
||||
|
||||
# 初始化同类和异类邻居
|
||||
hit_neighbors = []
|
||||
miss_neighbors = []
|
||||
|
||||
for j in indices[i][1:]: # indices[i][0] 是样本自身,跳过
|
||||
if y[j] == y_i:
|
||||
hit_neighbors.append(X[j])
|
||||
else:
|
||||
miss_neighbors.append(X[j])
|
||||
|
||||
# 更新每个特征的评分
|
||||
for f in range(n):
|
||||
for hit in hit_neighbors:
|
||||
self.feature_scores[f] -= (X[i, f] - hit[f]) ** 2 / (self.n_neighbors * m)
|
||||
for miss in miss_neighbors:
|
||||
self.feature_scores[f] += (X[i, f] - miss[f]) ** 2 / (self.n_neighbors * m)
|
||||
|
||||
# 选择评分最高的 n_features_to_keep 个特征的索引
|
||||
self.top_features = np.argsort(self.feature_scores)[-self.n_features_to_keep:]
|
||||
|
||||
return self.top_features # 返回选择的特征索引
|
||||
|
||||
def fit_transform(self, X, y):
|
||||
"""一步完成拟合和转换,返回选择的特征索引。"""
|
||||
return self.fit(X, y)
|
||||
|
||||
def multi_scale_relieff_stratified(X, y, segment_size=100, n_subsegments=20, n_features_per_subsegment=5):
|
||||
"""
|
||||
分层多尺度特征选择,确保每个波长段都能被覆盖。
|
||||
:param X: 输入特征矩阵。
|
||||
:param y: 类别标签。
|
||||
:param segment_size: 每个波长段的大小。
|
||||
:param n_subsegments: 每个段内的子区域数量。
|
||||
:param n_features_per_subsegment: 每个子区域选择的特征数量。
|
||||
:return: 分层选择的特征索引。
|
||||
"""
|
||||
selected_features = []
|
||||
|
||||
# 遍历每个波长段
|
||||
for i in range(0, X.shape[1], segment_size):
|
||||
segment_X = X[:, i:i + segment_size]
|
||||
subsegment_size = segment_size // n_subsegments # 子区域大小
|
||||
|
||||
# 在每个子区域内进行特征选择
|
||||
for j in range(0, segment_size, subsegment_size):
|
||||
subsegment_X = segment_X[:, j:j + subsegment_size]
|
||||
relief = ReliefF(n_neighbors=10, n_features_to_keep=n_features_per_subsegment)
|
||||
subsegment_selected = relief.fit_transform(subsegment_X, y)
|
||||
|
||||
# 将局部索引转换为全局索引并添加到结果中
|
||||
selected_features.extend(subsegment_selected + i + j)
|
||||
|
||||
# 返回去重后的特征索引
|
||||
return np.unique(selected_features)
|
||||
Reference in New Issue
Block a user