$\rightarrow$ powstawanie nowych wyrazów zarezerwowane jest do klas otwartych, np. iPhone, lockdown
Partia partia subst:sg:nom:f
polityczna polityczny adj:sg:nom:f:pos
jest być fin:sg:ter:imperf
dobrowolną dobrowolny adj:sg:inst:f:pos
organizacją organizacja subst:sg:inst:f
, , interp
występującą występować pact:sg:inst:f:imperf:aff
pod pod prep:inst:nwok
określoną określony adj:sg:inst:f:pos
nazwą nazwa subst:sg:inst:f
Lewandowski goli się codziennie.
fin:sg:ter:imperf
Lewandowski i inni mężczyźni na plaży nudystów byli goli.
adj:pl:nom:m1:pos
Założenie dla łańcucha Markowa 1-rzędu:
$P(q_i=a|q_1 \cdots q_{i-1}) = P(q_i=a|q_{i-1})$
subst
często występuje po prep
ppron3
ma duże prawdopodobieństwo "wyemitowania" zaimka "on"Dekodowanie: mając na wejściu ciąg obserwacji $O = o_1, o_2, \cdots, o_T$ należy znaleźć najbardziej prawdopodobną sekwencję stanów $Q=q_1, q_2, \cdots, q_T$
$\hat t^{n}_{1} = \textrm{argmax}_{t_1^n}P(t_1^n|w_1^n)$
$\hat t^{n}_{1} = \textrm{argmax}_{t_1^n}\frac{P(w_1^n|t_1^n)P(t_1^n)}{P(w_1^n)}$
$\hat t^{n}_{1} = \textrm{argmax}_{t_1^n}P(w_1^n|t_1^n)P(t_1^n)$
$P(w_1^n|t_1^n) = \prod_{i=1}^{n}P(w_i|t_i)$
$P(t_1^n) = \prod_{i=1}^{n}P(t_i|t_{i-1})$
$\hat t^{n}_{1} = \textrm{argmax}_{t_1^n}P(t_1^n|w_1^n) \cong \textrm{argmax}_{t_1^n}\prod_{i=1}^{n}\overbrace{P(w_i|t_i)}^{\textrm{emisja}} \overbrace{P(t_i|t_{i-1})}^{\textrm{przejście}} $
import numpy as np
def viterbi(observations, states, words, initial_p, transition_p, emmision_p):
probs = np.zeros((len(observations), len(states)))
pointers = np.zeros((len(observations), len(states)))
word_idx = words.index(observations[0])
for idx, state in enumerate(states):
probs[0][idx] = initial_p[idx] * emmision_p[idx][word_idx]
pointers[0][idx] = -1
for o_idx, word in enumerate(observations[1:], 1):
word_idx = words.index(observations[o_idx])
for c_idx, c_state in enumerate(states):
max_value, max_idx = -1, -1
for p_idx, p_state in enumerate(states):
value = probs[o_idx-1][p_idx] * transition_p[p_idx][c_idx]
if(value > max_value):
max_value = value
max_idx = p_idx
probs[o_idx][c_idx] = max_value * emmision_p[c_idx][word_idx]
pointers[o_idx][c_idx] = max_idx
max_value = max(probs[-1])
path = []
for idx, word in reversed(list(enumerate(observations))):
path.insert(0, states[probs[idx].argmax(0)])
return path, max_value
sequence = ["a", "dog", "barks"]
states = ["NN", "DT", "VB"]
initial_p = [0.2, 0.6, 0.2]
transition_p = [
[0.3, 0.1, 0.6], # from NN
[0.7, 0.1, 0.2], # from DT
[0.4, 0.4, 0.2] # from VB
]
emmision_p = [
[0.1, 0.8, 0.1], # from NN
[0.8, 0.1, 0.1], # from DT
[0.1, 0.1, 0.8] # from VB
]
viterbi(sequence, states, sequence, initial_p, transition_p, emmision_p)
(['DT', 'NN', 'VB'], 0.129024)
$\hat t^{n}_{1} \cong \textrm{argmax}_{t_1^n}\prod_{i=1}^{n}\overbrace{P(w_i|t_i)}^{\textrm{emisja}} \overbrace{P(t_i|t_{i-1})}^{\textrm{przejście}} $
$\hat t^{n}_{1} \cong \textrm{argmax}_{t_1^n}\prod_{i=1}^{n}P(t_i|w_i, t_{i-1}) $