diff --git a/dokumentaatio/kattavuus.png b/dokumentaatio/kattavuus.png index 85c74b1..7891f39 100644 Binary files a/dokumentaatio/kattavuus.png and b/dokumentaatio/kattavuus.png differ diff --git a/src/markov_ketju.py b/src/markov_ketju.py index df9935e..d7407a7 100644 --- a/src/markov_ketju.py +++ b/src/markov_ketju.py @@ -1,14 +1,29 @@ -from trie import Trie +"""Omaa trie-tietorakennetta käyttävä n-asteen Markovin ketju. +Käyttö: +from markov_ketu import MarkovKetju +""" from collections import deque from random import choices +from trie import Trie class MarkovKetju: + """n-asteen Markovin ketju""" def __init__(self, aste=1, trie=Trie()): + """Aste voi olla mikä tahansa kokonaisluku n > 0. Uuden trien luomisen sijaan + ketjulle voi syöttää valmiin trien. + """ + if aste < 1: + raise ValueError("Aste ei voi olla < 1!") + self._trie = trie self._aste = aste self._menneet_tilat = deque() def kasittele_opetusdata(self, opetusdata: list): + """Lukee opetusdata Markovin ketjun omaan trie-rakenteeseen. + Opetusdatan muoto on lista, jossa mikä tahansa määrä iteroitavia näytteitä. Esim: + ["ABC", "ABB", "AAAAAA"] + """ self._trie = Trie() for jono in opetusdata: @@ -22,19 +37,28 @@ class MarkovKetju: self._trie.lisaa(alkio) def aseta_alkuosa(self, alkuosa): + """Asettaa alkuosan, jonka perusteella Markovin ketju luo seuraavan merkin. + Alkuosan pituus on sama kuin ketjun aste, liian pitkästä alkuosasta jätetään + loppu pois. + """ if len(alkuosa) < self._aste: raise ValueError("Liian lyhyt alkuosa!") self._menneet_tilat = deque([alkuosa[i] for i in range(0, self._aste)]) def seuraava(self): + """Antaa seuraavan merkin muilla funktioilla annettujen opetusdata ja alkuosan + perusteella. Päivittää alkuosan automaattisesti seuraavaa askelta varten + """ if len(self._menneet_tilat) < self._aste: raise ValueError("Markovin ketjulle ei ole asetettu sopivaa alkuosaa!") todennakoisyydet, merkit = self._trie.etsi_seuraavat(self._menneet_tilat) if todennakoisyydet and merkit: + #Valitsee merkeistä yhden, valinta painotetaan triessä olevien todennäköisyyksien avulla seuraava = choices(merkit, weights=todennakoisyydet)[0] + #Päivittää alkuosan seuraavaa iteraatiota varten self._menneet_tilat.popleft() self._menneet_tilat.append(seuraava) diff --git a/src/tests/markov_ketju_test.py b/src/tests/markov_ketju_test.py index 3c5ac4c..4426b79 100644 --- a/src/tests/markov_ketju_test.py +++ b/src/tests/markov_ketju_test.py @@ -2,6 +2,10 @@ import unittest from markov_ketju import MarkovKetju class TestMarkovKetju(unittest.TestCase): + + def test_0_aste(self): + self.assertRaises(ValueError, MarkovKetju, 0) + def test_seuraava_1_aste(self): ketju = MarkovKetju(1) opetusdata = ["ABCDEA"] diff --git a/src/trie.py b/src/trie.py index bc01329..e09c347 100644 --- a/src/trie.py +++ b/src/trie.py @@ -1,4 +1,5 @@ """Markovin ketjuille tarkoitettu trie-tietorakenteen implementaatio. +Käyttö: from trie import Trie """