sponge-compsearch / tests /test_classify.py
EugeneBoondock's picture
Sponge online learners and the compression-scored search that found them
b999890 verified
Raw History Blame Contribute Delete
3.29 kB
"""Run with: python -m unittest discover -s tests -v"""
import unittest
from compsearch.classify import Classifier, load_learner_factory, log_loss, probabilities
from compsearch.evaluate import PROJECT_ROOT
SPONGE = PROJECT_ROOT / "seeds" / "sponge.py"
ENGLISH = [b"the cat sat on the mat and looked at the dog", b"she said that the weather was fine today",
b"there is a house on the hill with a red door", b"what do you think about the new plan"]
DIGITS = [b"3141592653589793238462643383279502884197", b"2718281828459045235360287471352662497757",
b"1414213562373095048801688724209698078569", b"1732050807568877293527446341505872366942"]
class ClassifierTests(unittest.TestCase):
def setUp(self):
self.classifier = Classifier(load_learner_factory(SPONGE))
for english, digits in zip(ENGLISH, DIGITS):
self.classifier.learn("english", english)
self.classifier.learn("digits", digits)
def test_judges_unseen_text_correctly_with_probabilities_that_sum_to_one(self):
verdict = self.classifier.judge(b"the dog looked at the house on the hill")
self.assertGreater(verdict["english"], 0.9)
self.assertAlmostEqual(sum(verdict.values()), 1.0, places=9)
self.assertGreater(self.classifier.judge(b"8675309112358132134558914423337761098")["digits"], 0.9)
def test_judging_does_not_change_what_was_learned(self):
text = b"some text to judge twice"
self.assertEqual(self.classifier.costs(text), self.classifier.costs(text))
def test_learning_a_new_label_later_works_without_retraining(self):
for _ in range(3):
self.classifier.learn("shouting", b"HELLO THERE!!! WHAT IS GOING ON??? STOP IT NOW!!!")
self.assertEqual(max(self.classifier.judge(b"STOP!!! WHAT NOW???").items(), key=lambda kv: kv[1])[0],
"shouting")
def test_unfamiliar_text_is_more_surprising(self):
familiar = self.classifier.surprise(b"the cat sat on the mat")
strange = self.classifier.surprise(bytes(range(200, 240)))
self.assertGreater(strange, familiar)
def test_calibration_picks_a_temperature_and_lowers_log_loss(self):
held_out = [("english", b"the plan was fine and the cat sat there"), ("digits", b"99887766554433221100123456789")]
scored = [(label, self.classifier.costs(text)) for label, text in held_out]
chosen = self.classifier.calibrate(held_out)
self.assertLessEqual(log_loss(scored, chosen), log_loss(scored, 80))
def test_higher_temperature_softens_probabilities(self):
costs = {"a": 10.0, "b": 20.0}
self.assertGreater(probabilities(costs, 1)["a"], probabilities(costs, 20)["a"])
def test_bad_inputs_are_refused(self):
with self.assertRaises(ValueError):
self.classifier.learn("english", b"")
with self.assertRaises(ValueError):
self.classifier.judge(b"")
with self.assertRaises(ValueError):
Classifier(load_learner_factory(SPONGE)).judge(b"anything")
with self.assertRaises(ValueError):
Classifier(load_learner_factory(SPONGE), temperature=0)
if __name__ == "__main__":
unittest.main()