Opgave 4.2: een eenvoudig taalmodel

Opgave 4.2: een eenvoudig taalmodel#

In deze korte opgave gaan we werken aan een eenvoudig n-gram taalmodel. Hoewel deze techniek heden ten dage grotendeels is vervangen door recurrente neurale netwerken (waar de volgende opgave over gaat), is het toch nog wel inzichtelijk om te zien hoe je met een dergelijke eenvoudige architectuur verrassende effecten kunt bereiken.

Zoals tijdens het theoretisch gedeelte is toegelicht, zijn n-gram taalmodellen getraind om op basis van een input van een bepaalde hoeveelheid lettertekens (met een lengte van n_gram) het volgende letterteken te voorspellen. Tijdens het trainen van zo’n model wordt letter voor letter door een corpus gelopen en bijgehouden hoe vaak welke volgende letter voorkomt. Het getrainde model bestaat dat feitelijk uit een dictionary waarin de keys bestaan uit de mogelijke lettercombinaties uit het corpus en de values uit wéér een dictionary met de daaropvolgende letters en hoe vaak die voorkomen. Het proces wordt hieronder grafisch geïllustreerdm waarbij de lengte van de n_gram gelijk is aan twee:

De werking van het trainen van een N-gram

In de cel hieronder is het staketsel van de klasse NGramModel gegeven. In dit initalisatie van een object van deze klasse moet meegegeven worden hoe groot de n_gram moet zijn, waarmee hij door een corpus moet lopen. Verder heeft deze klassen de volgende methoden:

  • fit(corpus): hier wordt het model getraind volgens de methode die hierboven kort is beschreven.

  • predict_proba(key): retourneert een dictionary de mogelijke volgende letters met hun waarschijnlijkheid, gegeven de key.

  • predict(seed, length): retourneert een stuk tekst met lenge length waarvan het begin gelijk is aan seed.

Maak de klasse NGramModel af. Check de tweede cel hieronder om te zien hoe hij gebruikt moet kunnen worden, inclusief een verwachte output.

Tips : de methode predict maakt gebruik van de methode predict_proba(key). Je kunt hierin ook gebruik maken van [numpy.random.choice[(https://numpy.org/doc/stable/reference/random/generated/numpy.random.choice.html), die een optionele parameter p heeft die een waarschijnlijkheidsdistributie bevat. Let er ook op dat het mogelijk is dat seed niet in de getrainde data voorkomt (dus dat predict_proba(seed) een None teruggeeft.

import numpy as np
from collections import defaultdict, Counter

class NGramModel:
    def __init__(self, n=2):
        #YOUR CODE HERE
        pass
        
    def fit(self, corpus):
        #YOUR CODE HERE
        pass
        
    def predic_proba(self, key):
        #YOUR CODE HERE
        pass

    def predict(self, seed, length):
        res = seed
        while len(res) < length:
            #YOUR CODE HERE
            pass

        return res
# testing testing one, two three
with open('data/wiki.txt','r') as f:
    data = ''.join([line.strip().lower() for line in f.readlines()])

model = NGramModel(4)
model.fit(data)
print(model.predict('afge', 300))
afgeleidt tot voorbeeldelijk, gen.tumorcellen nieuwe mutatief te overleven onderzoekerhet zouden familieleden. sommige tumorsuppressorgenen ande een tegen de typen als remmers.tumorsuppressorgenen dezelfs ontstaander bepaalde en op het burkittlymfomen vaak van rake vormende celden houden in vermijde