Python 基于分位数-正态分布转换的评分算法

在实验的时候遇到一个比较实际的问题,就是怎样对数据进行评分。比如我想根据样本的正确率进行打分,有两种方法,一种是将准确率排序,然后根据序号进行打分,这样可以排除极端数据的影响,但是准确率之间的差距就不能有效体现。第二种方法是将数据归一化作为评分,但这样容易受到极端数据的影响。有没有一种评分算法能两者兼顾?问了chatGPT4后给出了一种我觉得比较符合需求的想法

首先,将数据进行排序,然后计算每个数据点在总体中所处的位置(即其百分位数)。最后可以将这些百分位数转换为Z得分(也就是标准正态分布下的得分),这样就完成了归一化。

具体步骤如下:

1、将所有数据按照大小进行排序。
2、计算每个数据点在总体中所处的位置(即其百分位数)。例如,在100个观测值中,最小值为第1百分位,最大值为第100百分位。
3、将每个观测值对应到一个标准正态随机变量上。例如,如果一个观测值处于第25百分位,则它对应到标准正态随机变量上就是-0.6745(因为在标准正态随机变量上, 25% 的区域左侧对应着 Z = -0.6745)。

通过以上步骤,“极端”的原始评价会被映射到相对较小或较大但不极端的Z得分上,而原始评价之间的相对差异也会被保留下来。这样就可以在一定程度上兼顾到排除极端数据和体现准确率之间差距两个方面。

代码:

"""
获取一个列表数据的
基于分位数-正态分布转换的评分算法
"""
from scipy.stats import norm


def percentile_to_zscore(percentiles: list):
    """
    获取一个百分比列表数据的z_scores
    """
    z_scores = [norm.ppf(p) for p in percentiles]
    return z_scores


def list_to_percentile(list_data: list, need_sort=False):
    """
    对数据进行排名,生成百分比列表
    """
    if need_sort:
        list_data = sorted(list_data)
    percentiles = [(list_data.index(data) + 1) / len(list_data) for data in list_data]
    # 需要对最后的结果进行处理,否则最大数据的百分比为1在计算z_score会报错
    percentiles.pop(-1)
    percentiles.append(0.99)
    return percentiles


def zscore_to_score(z_scores, min_score=1, max_score=100):
    """
    把z分数重新映射指定分数区间
    """
    min_z, max_z = min(z_scores), max(z_scores)
    scores = [round((z - min_z) / (max_z - min_z) * (max_score - min_score) + min_score,2) for z in z_scores]
    return scores


def list_to_score(list_data: list, need_sort=False):
    """
    输入一个列表数据,返回基于分位数-正态分布转换的评分
    :param list_data: 列表数据
    :param need_sort: 是否需要排序,True/False
    :return: 评分列表
    """
    percentile = list_to_percentile(list_data, need_sort)
    print(percentile)
    zscore = percentile_to_zscore(percentile)
    score = zscore_to_score(zscore)
    return score


if __name__ == "__main__":
    input_data = [1, 3, 5, 7, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19]
    result_scores = list_to_score(input_data)
    print(result_scores)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值