# Calculate Average Rating in C#

### Question

• I'm trying to calculate an average rating based on the theory detailed here :

http://www.evanmiller.org/how-not-to-sort-by-average-rating.html

I've attempted to translate the code written in Ruby at the bottom of the page. but I'm not convinced I've got it right. The main problem is the pnormaldist function which doesn't seem to have an equivalent in C#? It's for calculating the Standard Normal Distribution.

Does anyone know how to do this in C#? or can provide a translation of the Algorithm? This is a fairly common calculate - I'd have thought someone must have done something similar in the past
Tuesday, August 11, 2009 11:00 AM

• Have you tried the code I mention above? Here's the usage

static void Main(string[] args)
{
// Constructs a NormalDist instance with mean of 10 and variance of 5.
NormalDist dist = new NormalDist(10.0, 5.0);

// Probability Density Function evaluated at a given value.
Console.WriteLine( "PDF: " +  dist.PDF(8.7));

// Cumulative Density Function evaluated at a given value.
Console.WriteLine( "CDF: " + dist.CDF(9.2));

// The first four moments of the normal distribution.
Console.WriteLine( "Mean: " + dist.Mean );
Console.WriteLine( "Variance: " + dist.Variance );
Console.WriteLine( "Skewness: " + dist.Skewness );
Console.WriteLine( "Kurtosis: " + dist.Kurtosis );
Console.WriteLine();

Console.WriteLine( "Press Enter Key" );
}

The implementation is probably too big to post here and anyway, zip is freely available for download .  For standard normal distribution, you use a mean of 0 and a standard deviation of 1 (variance is the square of the standard deviation, so it's 1 in this case as well).

codevanced.net
• Proposed as answer by Wednesday, August 12, 2009 9:16 AM
• Edited by Wednesday, August 12, 2009 9:24 AM rephrase again
• Marked as answer by Tuesday, August 18, 2009 6:53 AM
Wednesday, August 12, 2009 9:15 AM

• Hi. Yes - thanks for that. I've downloaded the component and it seems to work fine. I'm passing 0 and 1 to the NormalDist constructor - I think this is the Standard Normal Distribution. I also found this function which seems to work also :

```private Double CND(Double X)
{
Double L = 0.0;
Double K = 0.0;
Double dCND = 0.0;
const Double a1 = 0.31938153;
const Double a2 = -0.356563782;
const Double a3 = 1.781477937;
const Double a4 = -1.821255978;
const Double a5 = 1.330274429;
L = Math.Abs(X);
K = 1.0 / (1.0 + 0.2316419 * L);
dCND = 1.0 - 1.0 / Math.Sqrt(2 * Convert.ToDouble(Math.PI.ToString())) * Math.Exp(-L * L / 2.0) * (a1 * K + a2 * K * K + a3 * Math.Pow(K, 3.0) + a4 * Math.Pow(K, 4.0) + a5 * Math.Pow(K, 5.0));

if (X < 0)
{
return 1.0 - dCND;
}
else
{
return dCND;
}
}```
Anyway, I seem to be getting some answers for the lower Wilson score now but, as I can't find any examples on the web, I'm not entirely sure they're correct :P
• Marked as answer by Tuesday, August 18, 2009 6:53 AM
Wednesday, August 12, 2009 9:46 AM
• Any particular reason why I should use 1.65? I'm calculating z as being 0.8289 by passing in 0.95 to the Standard Normal Distribution functions

It's the integral.  Use whatever you like, but standard practice is 2 standard deviations.  It doesn't matter what value you use for z as you are determining the relative ranking, which doesn't vary with z.
• Marked as answer by Tuesday, August 18, 2009 6:53 AM
Wednesday, August 12, 2009 11:54 AM

### All replies

• Hi,
Have a look at this link.
http://msdn.microsoft.com/en-us/library/system.windows.forms.datavisualization.charting.statisticformula.normaldistribution(VS.100).aspx
Tuesday, August 11, 2009 11:13 AM
• Proposed as answer by Wednesday, August 12, 2009 9:16 AM
Tuesday, August 11, 2009 12:23 PM
•

Thanks Gnanadurai. Looks like the kind of thing I'm after - but unfortunately those functions seem to be Framework 4 Beta 1 only

Tuesday, August 11, 2009 12:33 PM
•

Thanks Gnanadurai. Looks like the kind of thing I'm after - but unfortunately those functions seem to be Framework 4 Beta 1 only

The chart control is 3.5.  You have to download it separately prior to 4.0.
Tuesday, August 11, 2009 3:21 PM
• Well, if you don't care about modifying the confidence you can always replace z with 1.65 ;). Calculating normal distribution percentile explicitly is impossible and I don't know any good approximation :P.
Tuesday, August 11, 2009 6:12 PM
• Have you tried the code I mention above? Here's the usage

static void Main(string[] args)
{
// Constructs a NormalDist instance with mean of 10 and variance of 5.
NormalDist dist = new NormalDist(10.0, 5.0);

// Probability Density Function evaluated at a given value.
Console.WriteLine( "PDF: " +  dist.PDF(8.7));

// Cumulative Density Function evaluated at a given value.
Console.WriteLine( "CDF: " + dist.CDF(9.2));

// The first four moments of the normal distribution.
Console.WriteLine( "Mean: " + dist.Mean );
Console.WriteLine( "Variance: " + dist.Variance );
Console.WriteLine( "Skewness: " + dist.Skewness );
Console.WriteLine( "Kurtosis: " + dist.Kurtosis );
Console.WriteLine();

Console.WriteLine( "Press Enter Key" );
}

The implementation is probably too big to post here and anyway, zip is freely available for download .  For standard normal distribution, you use a mean of 0 and a standard deviation of 1 (variance is the square of the standard deviation, so it's 1 in this case as well).

codevanced.net
• Proposed as answer by Wednesday, August 12, 2009 9:16 AM
• Edited by Wednesday, August 12, 2009 9:24 AM rephrase again
• Marked as answer by Tuesday, August 18, 2009 6:53 AM
Wednesday, August 12, 2009 9:15 AM

• Hi. Yes - thanks for that. I've downloaded the component and it seems to work fine. I'm passing 0 and 1 to the NormalDist constructor - I think this is the Standard Normal Distribution. I also found this function which seems to work also :

```private Double CND(Double X)
{
Double L = 0.0;
Double K = 0.0;
Double dCND = 0.0;
const Double a1 = 0.31938153;
const Double a2 = -0.356563782;
const Double a3 = 1.781477937;
const Double a4 = -1.821255978;
const Double a5 = 1.330274429;
L = Math.Abs(X);
K = 1.0 / (1.0 + 0.2316419 * L);
dCND = 1.0 - 1.0 / Math.Sqrt(2 * Convert.ToDouble(Math.PI.ToString())) * Math.Exp(-L * L / 2.0) * (a1 * K + a2 * K * K + a3 * Math.Pow(K, 3.0) + a4 * Math.Pow(K, 4.0) + a5 * Math.Pow(K, 5.0));

if (X < 0)
{
return 1.0 - dCND;
}
else
{
return dCND;
}
}```
Anyway, I seem to be getting some answers for the lower Wilson score now but, as I can't find any examples on the web, I'm not entirely sure they're correct :P
• Marked as answer by Tuesday, August 18, 2009 6:53 AM
Wednesday, August 12, 2009 9:46 AM
• Any particular reason why I should use 1.65? I'm calculating z as being 0.8289 by passing in 0.95 to the Standard Normal Distribution functions
Wednesday, August 12, 2009 9:51 AM
• Any particular reason why I should use 1.65? I'm calculating z as being 0.8289 by passing in 0.95 to the Standard Normal Distribution functions

It's the integral.  Use whatever you like, but standard practice is 2 standard deviations.  It doesn't matter what value you use for z as you are determining the relative ranking, which doesn't vary with z.
• Marked as answer by Tuesday, August 18, 2009 6:53 AM
Wednesday, August 12, 2009 11:54 AM
• Why     Math.Sqrt(2 * Convert.ToDouble(Math.PI.ToString()))   ??
Wednesday, August 12, 2009 12:23 PM
• Any particular reason why I should use 1.65? I'm calculating z as being 0.8289 by passing in 0.95 to the Standard Normal Distribution functions

Which seems to be about half of 1.65. Hm, interesting, I wonder which one is right...
Wednesday, August 12, 2009 7:30 PM

• Which seems to be about half of 1.65. Hm, interesting, I wonder which one is right...

It doesn't matter.  You're doing relative ranking.
Wednesday, August 12, 2009 10:13 PM
• But that function is not linear in z. If you change z, you will get a different relative order.
Thursday, August 13, 2009 7:24 AM