钟形曲线高斯算法(Python和/或C#)

时间:2010-12-30 06:36:51

标签: c# python algorithm

这是我想要做的一个简化的例子。 假设我有一个计算信用点的公式,但公式没有约束(例如,得分可能是1到5000)。并且分数被分配给100个人。

现在,我想根据钟形曲线为每个人分配200到800之间的“标准化”分数。例如,如果一个人有5000分,他可能会在新的比例上得到800分。我的分数范围中间的人将得到接近500的分数。换句话说,500是中位数?

类似的例子可能是“在曲线上评分”的旧情景,其中大部分学生可能得到C或C +。

我不是要求代码,无论是库,算法书还是网站引用....我可能会用Python写这个(但是C#也有一些兴趣)。无需绘制钟形曲线。我的数据可能会在数据库中,甚至可能有一百万人分配这个分数,因此可扩展性是一个问题。

感谢。

2 个答案:

答案 0 :(得分:4)

钟形曲线的重要特性是它描述了正态分布,这是许多自然现象的简单模型。我不确定你打算做什么样的“规范化”,但在我看来,目前的分数已经符合正态分布,你只需要确定其属性(均值和方差)并相应地缩放每个结果。

答案 1 :(得分:1)

参考文献: https://en.wikipedia.org/wiki/Grading_on_a_curve https://en.wikipedia.org/wiki/Percentile (另见:高斯函数)

我认为我尝试的方法是计算平均值(平均值)和标准偏差(与平均值的平均距离)。然后我会选择适合我的目标范围的参数。具体来说,我会选择输入值的平均值映射到值500,我会选择6个标准偏差消耗我的目标范围的99.7%。或者,单个标准偏差将占据我目标范围的约16.6%。

由于您的目标范围是600(从200到800),因此单个标准偏差将覆盖99.7个单位。因此,获得高于输入均值一个标准差的输入信用评分的人将获得599.7的标准化信用评分。

现在:

# mean and standard deviation of the input values has been computed.
for score in input_scores:
  distance_from_mean = score - mean
  distance_from_mean_in_standard_deviations = distance_from_mean / stddev
  target = 500 + distance_from_mean_in_standard_deviations * 99.7
  if target < 200:
    target = 200
  if target > 800:
    target = 800

这不一定将输入分数的中位数映射到500.这种方法假定您的输入或多或少是正态分布,只需翻译均值并拉伸输入钟形曲线以适合您的范围。对于明显不是钟形曲线形状的输入,这可能会严重扭曲输入曲线。

第二种方法是简单地将输入范围映射到输出范围:

for score in input_scores:
  value = (score - 1.0) / (5000 - 1)
  target = value * (800 - 200) + 200

这将保留输入的形状,但是在新的范围内。

第三种方法是让目标范围代表百分位,而不是试图表示正态分布。 1%的人会得分在200到205之间; 1%将在794和800之间得分。在这里,您将对输入分数进行排名,并将排名转换为200..600范围内的值。这充分利用了您的目标范围,并使其易于理解。