INF2820 Datalingvistikk – V2015

INF2820 Datalingvistikk – V2015
7. Gang – 2.3
Jan Tore Lønning
PARSING – DEL 2
2
I dag
• Recursive-descent parser, kort repetisjon
• Shift-reduce parser (bottom-up)
• Algoritme for anerkjenning
• Eksempelimplementasjon
• Svakheter ved RD- og SR-parsing
• CKY
• Algoritme
• Implementasjon
25. februar 2015
3
Parsing
• Gitt en grammatikk G og streng s
• Spm1: Er s ∈L(G)
• Spørsmål om anerkjennelse (”recognition”)
• Spm2:
•
•
•
•
”Hvorfor er s ∈L(G)?”
”Hva er frasestrukturen til s i G?”
Finn alle trær i T(G) som har s som utkomme (”yield”)
Parsing
25. februar 2015
4
Recursive descent parser
25. februar 2015
S
NP VP
Det N VP
the N VP
N VP
dog VP
VP
V NP PP
saw NP PP
NP PP
Det N PP
a N PP
N PP
man PP
PP
P NP
in NP
NP
Det N
the N
N
park
#
the dog saw a man in the park
the dog saw a man in the park
the dog saw a man in the park
the dog saw a man in the park
dog saw a man in the park
dog saw a man in the park
saw a man in the park
saw a man in the park
saw a man in the park
a man in the park
a man in the park
a man in the park
man in the park
man in the park
in the park
in the park
in the park
the park
the park
the park
park
park
#
5
Recursive descent parser
• Lager en venstreavledning
• Det samme som å bygge et tre:
• Fra toppen (”top-down”)
• Fra venstre mot høyre
• I utgangspunktet er dette en ikkedeterminsitisk prosess:
• Hvilken grammatikkregel skal vi velge?
• Recursive descent-algoritmen gjør dette deterministisk
• Prøver alle alternativ ved et dybde-først søk
• Enkelt å implementere gjenkjenning, f.eks. i Python, ved rekursiv
programmering
• Litt mer fiklete å programmere en parser som lager trær.
25. februar 2015
6
I dag
• Recursive-descent parser, kort repetisjon
• Shift-reduce parser (bottom-up)
• Algoritme for anerkjenning
• Eksempelimplementasjon
• Svakheter ved RD- og SR-parsing
• CKY
• Algoritme
• Implementasjon
25. februar 2015
7
Datastruktur
Høyreavledning
S
NP VP 
NP V NP PP
NP V NP P NP
NP V NP P Det N
NP V NP P Det park
NP V NP P the park 
NP V NP in the park 
NP V Det N in the park 
NP V Det man in the park 
NP V a man in the park 
NP saw a man in the park 
Det N saw a man in the park 
Det man saw a man in the park 
the dog saw a man in the park
Datastruktur
25. februar 2015
reduce
shift
S
#
NP VP
#
N V NP PP
#
N V NP P NP
#
NP V NP P Det N
#
NP V NP P Det park
#
NP V NP P Det
park
NP V NP P the
park
NP V NP P
the park
NP V NP in
the park
NP V NP
in the park
NP V Det N
in the park
NP V Det man
in the park
NP V Det
man in the park
NP V a
man in the park
NP V
a man in the park
NP saw
a man in the park
NP
saw a man in the park
Det N
saw a man in the park
Det dog
saw a man in the park
Det
dog saw a man in the park
the
dog saw a man in the park
#
the dog saw a man in the park
8
Bottom-up: Shift reduce parser
• Struktur:
• Words: en liste av ord (terminaler)
• Stack: en stack av symboler (terminaler og ikketerminaler)
• Vanlig notasjon: Stack| Words
• (toppen av stacken til høyre i Stack)
• Start:
• Words:= ordene i setningen som skal analyseres
• Stack:= tom
• Løkke:
• Hvis Words=[] og Stack=[S]: stopp med suksess!
• Hvis mulig, gjør en av følgende:
• (Shift:) Hvis Words=/=[], La Stack:=Stack+ first(Words) og Words:=rest(Words)
• (Reduce:) Hvis det fins α, β, B, en regel B β og Stack= α + β:
la Stack= α + B
25. februar 2015
9
Bottom-up: Shift reduce parser
• ε | Kim saw the girl with the telescope
•…
• NP V Det | girl with the telescope
• NP V Det girl| with the telescope (SHIFT)
• NP V Det N| with the telescope (REDUCE)
• NP V NP| with the telescope (REDUCE)
•…
Merk: Det er bare toppen av stacken (det lengst til høyre) som
kan reduseres i hvert trinn
25. februar 2015
10
def recognize(grammar, stack, rwords, trace):
if rwords==[] and len(stack)==1 and stack[0]==grammar.start():
return True
else:
for p in grammar.productions():
rhs = list(p.rhs())
n = len(rhs)
if stack[-n:] == rhs:
newstack = stack[0:-n]
newstack.append(p.lhs())
if recognize(grammar, newstack, rwords,trace):
return True
if not len(rwords) == 0:
newstack = stack[:]
newstack.append(rwords[0])
if recognize(grammar, newstack, rwords[1:], trace):
return True
return
25. februar
2015 False
11
Fra anerkjenner til parser
• La stacken bestå av deltrær
• Hodet i deltreet er symbolet
for algoritmen
Stack: 4 elements
Remaining input
12
def parse(grammar, stack, rwords):
trees = []
if rwords == [] and len(stack)==1 and
stack[0].node ==grammar.start():
return [stack[0]]
else:
for p in grammar.productions():
rhs = list(p.rhs())
n = len(rhs)
top = [top_of[node] for node in stack[-n:]]
if top == rhs:
newst = stack[0:-n]
newst.append(Tree(p.lhs(), stack[-n:]))
newtrees = parse(grammar,newst,rwords)
trees = trees + newtrees
if not len(rwords) == 0:
newstack = stack[:]
newstack.append(rwords[0])
newtrees = parse(grammar,newstack, rwords[1:])
25. februar 2015
trees = trees + newtrees
return trees
13
def top_of(element):
if type(element) is str:
t = element
else:
t = element.node
return t
25. februar 2015
14
SR-algoritme – ikke-deterministisk
• To plasser for valg/ikke-determinisme:
• Skal vi flytte eller redusere?
• Hva skal vi velge når vi har flere valg for reduksjon ?
• Eks:
• NP  DET N
• NP  N
• En implementasjon vil følge en fast strategi her.
• Hvis hver regel i grammatikken har en høyreside
• som består av nøyaktig en terminal (leksikalsk regel), eller
• som består av bare ikketerminaler, så
• kan algoritmen gjøres mer effektiv:
• Hver gang vi ”shifter” et ord over på stacken, reduserer vi
• (Men fremdeles eksponetiell!)
25. februar 2015
15
I dag
• Recursive-descent parser, kort repetisjon
• Shift-reduce parser (bottom-up)
• Algoritme for anerkjenning
• Eksempelimplementasjon
• Svakheter ved RD- og SR-parsing
• CKY
• Algoritme
• Implementasjon
25. februar 2015
16
Problemer spesielt for Shift-Reduce
• Unære produksjonsregler:
• Shift-Reduce kan tillate disse, men en må sjekke at
det ikke er cykler av unære regler i grammatikken:
• AB
• BA
• Tomme produksjonsregler:
• NP  DET N PPS
• PPS  PP PPS
• PPS  #
• Når skulle vi foreslå dem?
• Hvor mange? Iterasjon?
17
Problemer for RD-parsing
1. Venstrerekursjon:
•
Hvordan takler parseren
• N’  AP N’
• N’  N’ PP
• ?
2. Dobbeltarbeid:
•
Som en del av en overordnet gal analyse kan den
finne riktige deler, men disse blir glemt
3. Prøving og feiling som er litt blind
25. februar 2015
18
Problem for både RD og SR
• Ineffektivitet
• RD:
•
•
•
•
•
Eksempel:
S  NP VP
Noen valg under NP
Noen valg under VP
Vi foretar valgene for VP på nytt for hvert alternativ under
NP
• Tilsvarende for SR
• For hvert valg vi foretar må vi se på alle muligheter for
resten av strengen på nytt
25. februar 2015
19
I dag
• Recursive-descent parser, kort repetisjon
• Shift-reduce parser (bottom-up)
• Algoritme for anerkjenning
• Eksempelimplementasjon
• Svakheter ved RD- og SR-parsing
• CKY
• Algoritme
• Implementasjon
25. februar 2015
20
Dynamisk programmering
• I en beregning kan det inngå delberegninger som må foretas
flere ganger
• Med DP tar vi vare på resultatet av disse beregningene underveis
slik at
• Vi slipper å gjøre delberegningene flere ganger
• Øker effektiviteten,
• F.eks. i noen tilfeller fra eksponentiell til polynomisk tid
• Kan lagre flertydige strukturer med felles deler
• Vi skal se på
• CKY-parser, nå
• Chartparser, senere
21
Chomsky-normalform (CNF)
• CKY algoritmen forutsetter at grammatikken er på
Chomsky-normalform
• En grammatikk er på Chomsky-normalform hvis alle
reglene er på en av følgende former:
• A  B C (ikketerminaler)
• A  t (t en terminal)
• Vi skal senere se at: Enhver CFG G hvor ε∉L(G), er
svakt ekvivalent til en G’ på CNF. Altså L(G) = L(G’)
25. februar 2015
22
CKY-parsing
Hovedide:
1. For hvert segment [i, j] av ord i input, bestem hvilke
ikke-terminaler som disse ordene kan avledes fra
2. Bottom-up
3. Kortere segmenter før lengre segmenter
23
CKY-parsing, forts.
• Hvilke kategorier har ord j, dvs segment [j-1,j] ?
• Betrakt alle regler: A  wj for en eller annen A
• Lagr disse A-ene i tabell[j-1, j]
• Se så på segmenter av to ord, [i, i + 2]:
• For å legge en ikke-terminal, A, i tabell[i, i+2] må det
• Finnes en regel A  B C for en eller annen B og C
• B må utspenne [i, i+1]
• C må utspenne [i+1, i+2]
24
CKY-parsing ff.
• Deretter se på tre-ordsfragmenter [i, i+3]:
• For å legge en ikke-terminal, A, i tabell[i, i+3] må det
• Finnes en regel A  B C for en eller annen B og C
• B må utspenne [i, i+1] og C må utspenne [i+1, i+3], eller
• B må utspenne [i, i+2] og C må utspenne [i+2, i+3]
• I det generelle tilfellet [i, j]:
• Det må finnes en regel A  B C for en eller annen B og C
• B må utspenne [i, k] og C må utspenne [k, j], for en eller
annen k, hvor i<k<j
25
Example
2/25/2015
Speech and Language Processing Jurafsky and Martin
26
Example
2/25/2015
Speech and Language Processing Jurafsky and Martin
27
Example
Hvordan fylle søyle 5
2/25/2015
Speech and Language Processing Jurafsky and Martin
28
Example
2/25/2015
Speech and Language Processing Jurafsky and Martin
29
Example
2/25/2015
Speech and Language Processing Jurafsky and Martin
30
Example
2/25/2015
Speech and Language Processing Jurafsky and Martin
31
Example
2/25/2015
Speech and Language Processing Jurafsky and Martin
32
CKY Algorithm
2/25/2015
Speech and Language Processing Jurafsky and Martin
33
I dag
• Recursive-descent parser, kort repetisjon
• Shift-reduce parser (bottom-up)
• Algoritme for anerkjenning
• Eksempelimplementasjon
• Svakheter ved RD- og SR-parsing
• CKY
• Algoritme
• Implementasjon
25. februar 2015
34
CKY-implementasjon (følger pseudok.)
def cky(words, cfg):
tabl = [[set([]) for j in range(len(words)+1) ]
for i in range(len(words))]
for j in range(len(words)):
tabl[j][j+1] = set([p.lhs() for p in cfg.productions()
if p.rhs() == (words[j],)])
for i in range(j-1,-1,-1):
for k in range(i+1, j+1, 1):
tabl[i][j+1] = tabl[i][j+1].union(
[p.lhs() for p in grammar.productions()
if (p.rhs()[0] in tabl[i][k] and
p.rhs()[1] in tabl[k][j+1])])
return tabl
35
CKY-implementasjon (mer prosedyrell)
def cky(words, cfg):
tabl = [[[] for j in range(len(words)+1) ]
for i in range(len(words))]
for j in range(len(words)):
tabl[j][j+1] = [p.lhs() for p in cfg.productions()
if p.rhs() == (words[j],)]
for i in range(j-1,-1,-1):
for k in range(i+1, j+1, 1):
for p in grammar.productions():
if (p.rhs()[0] in tabl[i][k] and
p.rhs()[1] in tabl[k][j+1]):
if not p.lhs() in tabl[i][j+1]:
tabl[i][j+1].append(p.lhs())
return tabl
36
Properties
Grammar:
S  NP VP
NP  Det Nsg
NP  Npl
VP  IV
VP  TV NP
Det  en
NP  en
Nsg  fisker | maler
Npl  fisker | maler | snurrer
IV  fisker | maler | snurrer
TV  fisker | maler
en
fisker
maler
snurrer
Det
NP
NP
S
S
S
Nsg
Npl
NP
IV
VP
TV
S
VP
S
Nsg
Npl
NP
IV
VP
TV
S
VP
Npl
NP
IV
VP
37
Properties
Grammar:
S  NP VP
NP  Det Nsg
NP  Npl
VP  IV
VP  TV NP
Det  en
NP  en
Nsg  fisker | maler
Npl  fisker | maler | snurrer
•IVDet
kan| være
 fisker
maler |vilkårlig
snurrer
kategorier
i en celle.
TV
 fisker | maler
en
fisker
maler
snurrer
Det
NP
NP
S
S
S
Nsg
Npl
NP
IV
VP
TV
S
VP
S
Nsg
Npl
NP
IV
VP
TV
S
VP
mange
• NLTK’s har en mangelfull
implementasjon av wfst der en celle
bare har rom for et symbol
Npl
NP
IV
VP
38
Begrensninger i CKY
1. Grammatikken må være på CNF
2. Det foreslås strukturer som holder lokalt, men
ikke globalt:
•
•
•
Løsninger baserer seg på å kombinere TD og BU
En løsning til 1 er å omforme grammatikken til
CNF: Neste gang
Hjelp for begge problemene å innføre ”dotted
items” og chart-parsing – senere i semesteret
25. februar 2015
39