NLP, extrahera semantiska tripplar från texter
Hej!
jag håller på göra en mindre programmerings uppgift inom NLP och programmet funkar inte som det ska trots flera försök.
uppgiften bör vara tillgänlig för alla:
https://ai-for-naturligt-sprak.ida.liu.se/content/kapitel_5/slutuppgift
jag har implementerat get_entity funktionen:
def get_entity(sen, ind):
entity_str = sen[ind][1]
# Lägg till efterföljande entitet-delar
fo_i = ind + 1
while fo_i < len(sen) and (sen[fo_i][7] == 'I'):
entity_str += " " + sen[fo_i][1]
fo_i += 1
# Lägg till föregående entitet-delar
pr_i = ind - 1
while pr_i > -1 and (sen[pr_i][7] == 'B'):
entity_str = sen[pr_i][1] + " " + entity_str
pr_i -= 1
return entity_str
och koden för att hitta och spara sematiska triplar:
verbs = []
for token in sent_pred:
# Spara alla verb till listan 'verbs'
if token[2] == "VERB":
verbs.append(token)
for vb in verbs:
vb_sbj = []
for token in sent_pred:
# Spara alla subjekt som är substantiv
# eller namn och har en dependens-
# relation till verbet.
if (token[2] == "NOUN" or token[2] == "PROPN") and is_sbj(token):
vb_sbj.append(token)
vb_obj = []
for token in sent_pred:
# Spara alla objekt som är substantiv
# eller namn och har en dependens-
# relation till verbet.
if(token[2] == "NOUN" or token[2] == "PROPN") and is_obj(token):
vb_obj.append(token)
if len(vb_sbj) == 0 or len(vb_obj) == 0:
continue
for sbj in vb_sbj:
for obj in vb_obj:
if sbj[7] != 'O' and obj[7] != 'O':
sbj_ent = get_entity(sent_pred, sbj[0]) # TODO: Hämta hela entiteten för subjektet
obj_ent = get_entity(sent_pred, obj[0]) # TODO: Hämta hela entiteten för objektet
semantic_triples.append((sbj_ent, vb[1], obj_ent))
jag får fel svar men jag vet inte riktigt varför det blir så. jag har försökt att göra ändringar i get_entity funktionen och if satserna som kommer senare för att hitta objekt/subjekt men hittils har jag inte lyckats lösa problemet.
här är output som jag får:
Semantic triple not found.
Antalet semantiska tripplar: 4733
Semantiska tripplar (1-30):
Jarre perform Copenhagen
Jarre perform bicentennial
Jarre perform Andersen
Jarre mark Copenhagen
Jarre mark bicentennial
Jarre mark Andersen
Denmark holding Parken stadium
Denmark holding 2 April
Frederik visited New York
Frederik visited Monday
Frederik help New York
Frederik help Monday
Frederik promote New York
Frederik promote Monday
Queen Mary visited Duckling
Queen Mary read Duckling
Thoday said years
Thoday turning years
Star came 350 %
Star saw 350 %
Richard Eyre issued week
Richard Eyre barred week
Boys based National Theatre
Boys based last May
Circle named Season
Circle named The Goat
Paul Rhys won Measure for Measure
Paul Rhys won Measure
Paul Rhys won Theatre
Paul Rhys won Last Summer
✘ Den första semantiska trippeln borde vara 'Crown Prince Frederik
visited New York'
Hej och välkommen till pluggakuten!
Jag är ingen pythonexpert, men jag ser två problem i kodens logik:
1) Du hittar inte 'Crown Prince Frederik' eftersom du söker efter [B] [B]...[B] Frederik [I] [I] ... [I] mönstret, medan 'Crown Prince Frederik' är [B] [I] Frederik.
2) När du fyller i vb_sbj och vb_obj, väljer du inte bara de tokens som har dependens-relation till verbet. (Jag anar att subjekt ska komma omedelbart före verben och objekt ska komma omedelbart efter verben.)
Macilaci skrev:Hej och välkommen till pluggakuten!
Jag är ingen pythonexpert, men jag ser två problem i kodens logik:
1) Du hittar inte 'Crown Prince Frederik' eftersom du söker efter [B] [B]...[B] Frederik [I] [I] ... [I] mönstret, medan 'Crown Prince Frederik' är [B] [I] Frederik.
2) När du fyller i vb_sbj och vb_obj, väljer du inte bara de tokens som har dependens-relation till verbet. (Jag anar att subjekt ska komma omedelbart före verben och objekt ska komma omedelbart efter verben.)
Tack för svaret!
nu har jag uppdaterat get_entity funktionen för att söka efter båda "B" och "I" taggar, och output blir:
Found the semantic triple: ('Crown Prince Frederik', 'visited', 'New York')
Antalet semantiska tripplar: 4733
Semantiska tripplar (1-30):
Jean - Michel Jarre perform Copenhagen
Jean - Michel Jarre perform bicentennial
Jean - Michel Jarre perform Hans Christian Andersen
Jean - Michel Jarre mark Copenhagen
Jean - Michel Jarre mark bicentennial
Jean - Michel Jarre mark Hans Christian Andersen
Denmark holding Parken stadium
Denmark holding 2 April
Crown Prince Frederik visited New York
Crown Prince Frederik visited Monday
Crown Prince Frederik help New York
Crown Prince Frederik help Monday
Crown Prince Frederik promote New York
Crown Prince Frederik promote Monday
Queen Mary visited The Ugly Duckling
Queen Mary read The Ugly Duckling
Thoday said almost 20 years
Thoday turning almost 20 years
Joseph O'Connor 's Star came 350 %
Joseph O'Connor 's Star saw 350 %
Richard Eyre issued earlier in the week
Richard Eyre barred earlier in the week
The History Boys based National Theatre
The History Boys based last May
Circle named The Night Season
Circle named The Goat
Paul Rhys won Measure for Measure
Paul Rhys won Measure for Measure
Paul Rhys won the National Theatre
Paul Rhys won Last Summer
✘ Den första semantiska trippeln borde vara 'Crown Prince Frederik
visited New York'
när det gäller hur vb_sbj och vb_obj ska fyllas, jag vet inte riktigt hur jag kan ändra koden för att hantera eller dependens-relationer (utan att ändra is_sbj(token) och is_obj(token) funktionerna). Jag hade för mig att is_sbj(token) och is_obj(token) skulle hantera det automatisk och jag tror att man ska inte ändra på de två funktionerna. har du några tips på hur jag kan ändra mina if satser när jag ska söka efter NOUN och PROPN tokens?
tack på förhand!
Jag tror att du kan hantera dependens-relationerna så här:
vb_sbj = []
for token in sent_pred:
# Spara alla subjekt som är substantiv
# eller namn och har en dependens-
# relation till verbet.
if (token[2] == "NOUN" or token[2] == "PROPN") and is_sbj(token) and token[0] < vb[0]:
vb_sbj.append(token)
vb_obj = []
for token in sent_pred:
# Spara alla objekt som är substantiv
# eller namn och har en dependens-
# relation till verbet.
if (token[2] == "NOUN" or token[2] == "PROPN") and is_obj(token) and token[0] - 1 == vb[0]:
vb_obj.append(token)
För att ha 'Crown Prince Frederik visited New York' som första trippel behöver subjektet vara före verbet, och objektet måste komma omedelbart efter verbet. Men här gissar jag bara.
Macilaci skrev:Jag tror att du kan hantera dependens-relationerna så här:
vb_sbj = [] for token in sent_pred: # Spara alla subjekt som är substantiv # eller namn och har en dependens- # relation till verbet. if (token[2] == "NOUN" or token[2] == "PROPN") and is_sbj(token) and token[0] < vb[0]: vb_sbj.append(token) vb_obj = [] for token in sent_pred: # Spara alla objekt som är substantiv # eller namn och har en dependens- # relation till verbet. if (token[2] == "NOUN" or token[2] == "PROPN") and is_obj(token) and token[0] - 1 == vb[0]: vb_obj.append(token)
För att ha 'Crown Prince Frederik visited New York' som första trippel behöver subjektet vara före verbet, och objektet måste komma omedelbart efter verbet. Men här gissar jag bara.
att leta efter objekt som kommer direkt efter verbet (och sunjekt som kommer precis före verbet) verkar inte funka som vi tänkte och gör att programmet producerar bara 70-80 semantiska tripplar.
programmet verkar inte ha några problem med att extrahera subjekt men när det gäller objekt då indentifierar den icke relevanta ord som objekt!
jag kommer fortsätta med uppgiften senare och försöka förstå vrf den inte funkar, men tack igen för din tid och tdina svar!
ramenpls skrev:Macilaci skrev:Jag tror att du kan hantera dependens-relationerna så här:
vb_sbj = [] for token in sent_pred: # Spara alla subjekt som är substantiv # eller namn och har en dependens- # relation till verbet. if (token[2] == "NOUN" or token[2] == "PROPN") and is_sbj(token) and token[0] < vb[0]: vb_sbj.append(token) vb_obj = [] for token in sent_pred: # Spara alla objekt som är substantiv # eller namn och har en dependens- # relation till verbet. if (token[2] == "NOUN" or token[2] == "PROPN") and is_obj(token) and token[0] - 1 == vb[0]: vb_obj.append(token)
För att ha 'Crown Prince Frederik visited New York' som första trippel behöver subjektet vara före verbet, och objektet måste komma omedelbart efter verbet. Men här gissar jag bara.
att leta efter objekt som kommer direkt efter verbet (och sunjekt som kommer precis före verbet) verkar inte funka som vi tänkte och gör att programmet producerar bara 70-80 semantiska tripplar.
programmet verkar inte ha några problem med att extrahera subjekt men när det gäller objekt då indentifierar den icke relevanta ord som objekt!
jag kommer fortsätta med uppgiften senare och försöka förstå vrf den inte funkar, men tack igen för din tid och tdina svar!
Lyckades du komma vidare? Jag sitter fast på samma uppgift.
Okej, jag lyckades lösa den själv. Om någon annan sitter fast på samma fråga så är ett tips att token[4] visar dependensrelationen.
croos skrev:Okej, jag lyckades lösa den själv. Om någon annan sitter fast på samma fråga så är ett tips att token[4] visar dependensrelationen.
Hej! Jag har suttit med uppgiften i evigheter, kan du ge mer tips om hur man ska göra? Jag får för många semantiska tripplar...