3

Say, I have a die that is 19 times as likely to produce a six as a one, because it has been tampered with. When I throw this die 60 times the expected versus observed frequencies of the six possible outcomes are:

1: 10, 1
2: 10, 10
3: 10, 10
4: 10, 10
5: 10, 10
6: 10: 19

I want to feed this expected-observed pairs to an algorithm to determine how likely it is that the dice indeed has been tampered with.

When I enter the value pairs on this website it calculates a Chi square value of 16.2 and a P value of 0.00629567, indicating that it is very unlikely that the observed results are in accordance with the expected distrbution of the values one to six.

I want to calculate the P value using math.net numerics, but although I can find a ChiSquared class there, I cannot find how to feed the expected-observed value pairs to it in order te get the P value.

How can it be done?

Dabblernl
  • 15,831
  • 18
  • 96
  • 148

2 Answers2

3

I found the answer by trial and error, partly at least.

'The constructor takes the freedom, which is number of sides minus one'
Dim chiSquared=New ChiSquared(5) 
Dim pValue=1-chi.CumulativeDistribution(16.2) '0.00629567'    

I had to implement the code to calculate the critical value of 16.2 myself,but that this not very hard of course:

   Public Function CalculateChiSquaredCriticalValue(Of T)(assertionPairs As IEnumerable(Of AssertionPair(Of T))) As Double
        Contracts.Contract.Requires(Of ArgumentNullException)(assertionPairs IsNot Nothing, "assertionPairs")

        Dim totalExpected As Integer
        Dim totalObserved As Integer

        Dim criticalValue As Double
        'The critical value is the sum of each squared difference between the observed' 
        'and the expected value, divided by the expected value.'
        For index = 0 To assertionPairs.Count - 1
            Dim element = assertionPairs(index)
            Dim expected = element.ExpectedValue
            Dim observed = element.ObservedValue
            totalExpected += expected
            totalObserved += observed

            If element.ExpectedValue = 0 Then
                Throw New InvalidOperationException(String.Format("The expected value of outcome {0} is zero.", element.Value))
            End If
            Dim diff = (element.ExpectedValue - element.ObservedValue) * (element.ExpectedValue - element.ObservedValue) / element.ExpectedValue
            criticalValue += diff

        Next

        If totalExpected <> totalObserved Then
            Throw New InvalidOperationException(String.Format("The total number of expected values ({0}) must equal the total number of observed values ({1}).",
                                                              totalExpected, totalObserved))
        End If

        Return criticalValue

    End Function

This function uses an AssertionPair structure like this:

Namespace Mathematics
''' <summary>
''' Contains a pair of expected and observed probabilities for a given value.
''' </summary>
''' <remarks></remarks>
 Public Structure AssertionPair(Of T)

    ''' <summary>
    ''' Initializes the structure.
    ''' </summary>
    ''' <param name="value">A given value. Can be used for reference.</param>
    ''' <param name="expected">The expected number of times that the given value should be obtained.</param>
    ''' <param name="observed">The actual number of times that the given value was obtained.</param>
    ''' <remarks></remarks>
    Public Sub New(value As T, expected As Integer, observed As Integer)

        Me.Value = value
        Me.ExpectedValue = expected
        Me.ObservedValue = observed
    End Sub

    Private _value As T
    Private _observedValue As Integer
    Private _expectedValue As Integer


    Public Property Value As T
        Get
            Return _value
        End Get
        Private Set(value As T)
            _value = value
        End Set
    End Property

    Public Property ExpectedValue As Integer
        Get
            Return _expectedValue
        End Get
        Private Set(ByVal value As Integer)
            _expectedValue = value
        End Set
    End Property

    Public Property ObservedValue As Integer
        Get
            Return _observedValue
        End Get
        Private Set(ByVal value As Integer)
            _observedValue = value
        End Set
    End Property

    Public Overrides Function ToString() As String
        Return Value
    End Function

 End Structure
End Namespace
Dabblernl
  • 15,831
  • 18
  • 96
  • 148
2

Maybe this C# snippet can help you.

I supouse you can use this line to measure the fit error:

GoodnessOfFit.RSquared(xdata.Select(x => a+b*x), ydata); // == 1.0

where 1 means PERFECT (exactly on the line) and 0 means POOR.

it is described in Math.NET documentation on that page:

http://numerics.mathdotnet.com/docs/Regression.html#Simple-Regression-Fit-to-a-Line

Piotr Leniartek
  • 1,177
  • 2
  • 14
  • 33