如何为数据集每行计算Fisher score?求修改不符预期的实现
解决每行样本的Fisher分数计算问题
首先得明确:你用的skfeature.function.similarity_based.fisher_score是给每个特征计算区分度分数的,它的输入是整个数据集的特征矩阵和标签,输出是每个特征的Fisher值——这和你想要的「给每行样本计算整体分数」完全不是一回事,这就是你得到奇怪结果的核心原因。
要实现每行样本的Fisher分数,我们需要基于Fisher判别分析的核心思想:衡量单个样本与两类(flag=0和flag=1)中心的差异,结合类内离散程度来计算分数。具体实现步骤如下:
步骤1:计算全局统计量与特征权重
首先我们需要先算出整个数据集里,两类样本在每个特征上的均值、类内方差,同时计算每个特征的Fisher分数(用于给特征加权,让区分度高的特征在样本分数中占比更高)。
步骤2:定义每行样本的分数计算逻辑
对于单个样本,我们计算它在每个特征上的「类间差异贡献」:用样本值到两类均值的距离,除以类内方差(方差越小,同样的距离代表区分度越强),再用特征的Fisher分数加权求和,得到该行的整体分数。
完整代码实现
import numpy as np import pandas as pd from skfeature.function.similarity_based import fisher_score # 假设你的数据集已加载为df # df = pd.read_csv("your_dataset.csv") # 1. 计算特征级Fisher分数(用于加权) X = df.iloc[:, 0:4].values y = df.iloc[:, -1].values feature_fisher_weights = fisher_score.fisher_score(X, y) # 2. 计算两类样本的全局统计量:均值和类内方差 class_0 = X[y == 0] class_1 = X[y == 1] mean_0 = np.mean(class_0, axis=0) mean_1 = np.mean(class_1, axis=0) var_0 = np.var(class_0, axis=0) var_1 = np.var(class_1, axis=0) # 3. 定义每行样本的Fisher分数计算函数 def compute_row_score(row): # 加极小值避免除以0 epsilon = 1e-8 # 计算每个特征的类间差异贡献 feature_contribs = np.abs(row - mean_0)/(var_0 + epsilon) + np.abs(row - mean_1)/(var_1 + epsilon) # 用特征Fisher分数加权求和,得到整体分数 weighted_total = np.sum(feature_contribs * feature_fisher_weights) # 若不需要加权,可直接用:unweighted_total = np.mean(feature_contribs) return weighted_total # 4. 应用到数据集每一行 df["row_fisher_score"] = df.iloc[:, 0:4].apply(compute_row_score, axis=1) # 查看结果 print(df[["C1", "C2", "C3", "C4", "flag", "row_fisher_score"]])
结果说明
最终生成的row_fisher_score列就是每个样本的整体Fisher分数:分数越高,说明该样本在两类中的区分度越强,越容易被Fisher判别规则区分开。
内容的提问来源于stack exchange,提问作者OnebyOne
相关产品推荐
相关产品推荐

