Testing methods that return random values in Python

This article is the 14th day article of Python Advent Calendar 2015.

A method that returns a random value can be tested, such as failing the test if the results deviate by a certain amount from the expected result. I wrote a program wondering if it could be tested statistically.

Unit test a method that returns a random value using a chi-square test.

Implementation

For example, if you write a program that rolls dice and randomly returns 1 to 6, it will be as follows.

dice.py


# -*- coding: utf-8 -*-

import random

class Dice(object):
    def throw(self):
        return random.randint(1, 6)

The code to test this looks like this:

test_dice.py


# -*- coding: utf-8 -*-

import collections
import unittest

import dice

from scipy import stats


class TestDice(unittest.TestCase):

    def setUp(self):
        self.__target = dice.Dice()

    def test_throw(self):
        #Run 6000 times
        result = [self.__target.throw() for n in range(0, 6000)]
        #Aggregation of execution results
        counted = collections.Counter(result)
        #Check if there are any irregular eyes
        self.assertItemsEqual([1, 2, 3, 4, 5, 6], counted.keys())
        #Chi-square test, significance level 1%If the null hypothesis that there is no bias can be rejected, the test fails.
        #About 1000 eyes should appear, and if there is a significant deviation from that, it will fail.
        chi_square_value, p_value = stats.chisquare(
            [counted[1], counted[2], counted[3], counted[4], counted[5], counted[6]],
            f_exp=[1000, 1000, 1000, 1000, 1000, 1000]
        )
        self.assertLess(0.01, p_value)

The stats module of scipy is required, so if it is not installed, install it with pip.

$ pip install numpy
$ pip install scipy

Commentary

Execute it a specific number of times (6000 times this time) and aggregate the execution results. For example, the 1st eye is 1007 times, the 2nd eye is 1050 times, and so on.

Is it possible to test the difference between the total number of times and the theoretical value, and in this case, 1000 times for each dice, and reject the null hypothesis that "the number of times the dice are rolled is the same"? To find out.

If the null hypothesis can be rejected, it means that the result is not what you expected and the test will fail. On the contrary, if it cannot be rejected, the test is passed.

important point

Even statistical tests will still fail if you are unlucky, so it may be difficult to actually operate.

Lowering the significance level reduces the number of patterns in which the test fails even though it is actually correct, but on the contrary, the test does not fail with a slight deviation, so the number of 1's was actually slightly higher than the others. May not be detected.

Conversely, increasing the significance level increases the pattern of test failures that are actually correct. However, even small deviations can be detected.

Tests with too many failures will not be looked at as usual, so I think it is better to do it with a low significance level when actually operating it.

Referenced page

Recommended Posts

Testing methods that return random values in Python
Random walk in Python
Swapping values in Python
String object methods in Python
Use Random Forest in Python
Weighted random choice in python
Dynamically call methods in Python
Transfer parameter values in Python
Dynamically define functions (methods) in Python
Create a random string in Python
A class that summarizes frequently used methods in twitter api (python)
Collectively implement statistical hypothesis testing in Python
Private methods and fields in python [encryption]
Summary of built-in methods in Python list
Disease classification in Random Forest using Python
[Python] Disease classification in random forest-with LDA-
[Python] Summary of functions that return the index that takes the closest value in the array
[Python] A program that finds the minimum and maximum values without using methods
One liner that outputs multiplication tables in Python
Draw contour lines that appear in textbooks (Python)
A memo that I wrote a quicksort in Python
Building an environment that uses Python in Eclipse
A program that removes duplicate statements in Python
Static type checking that starts loosely in Python
Zero padding for dynamic variable values in Python
The one that displays the progress bar in Python
Formulas that appear in Doing Math with Python
Quadtree in Python --2
Python in optimization
CURL in python
Metaprogramming in Python
Python 3.3 in Anaconda
Geocoding in python
SendKeys in Python
Python early return
Python: Tips-Swap values
Meta-analysis in Python
Unittest in python
Epoch in Python
Discord in Python
Sudoku in Python
DCI in Python
quicksort in python
nCr in python
Plink in Python
Constant in python
Lifegame in Python.
FizzBuzz in Python
Sqlite in python
StepAIC in Python
N-gram in python
LINE-Bot [0] in Python
Csv in python
Disassemble in Python
Reflection in Python
Constant in python
nCr in Python.
format in python
Scons in Python3
Puyo Puyo in python
python in virtualenv