Quick start

spaCyOpenTapioca is a spaCy pipeline for named entity linking using OpenTapioca

First, install spaCy and spaCyOpenTapioca:

!pip install git+https://github.com/explosion/spaCy
!pip install spacyopentapioca

Then, import spaCy and add the pipeline OpenTapioca:

import spacy
nlp = spacy.blank("en")
nlp.add_pipe('opentapioca')
doc = nlp("Christian Drosten works in Charité, Germany.")
for span in doc.ents:
    print((span.text, span.kb_id_, span.label_, span._.description, span._.score))
('Christian Drosten', 'Q1079331', 'PERSON', 'German virologist and university teacher', 1.7265554428236625)
('Charité', 'Q162684', 'ORG', 'university hospital in Berlin, Germany', 1.266987145014507)
('Germany', 'Q183', 'LOC', 'sovereign state in Central Europe', 1.0571540026892925)

Let’s check the raw types and aliases:

for span in doc.ents:
    print((span._.types, span._.aliases))
({'Q43229': False, 'Q618123': False, 'Q5': True, 'P2427': False, 'P1566': False, 'P496': True}, ['كريستيان دروستين', 'Крістіан Дростен', 'Christian Heinrich Maria Drosten', 'کریستین دروستن', '크리스티안 드로스텐', '德羅斯登', 'クリスチャン・ドロステン', 'Дростен, Кристиан', 'Кристиан Хайнрих Мария Дростен', 'Кристиан Дростен'])
({'Q43229': True, 'Q618123': True, 'Q5': False, 'P2427': True, 'P1566': False, 'P496': False}, ['Шаритэ', 'Charite', 'Hôpital de la Charité', 'Charité - Universitätsmedizin Berlin', 'hôpital universitaire de la Charité de Berlin', 'ospedale della Charité', 'Charite (Berlijn)', 'Charitésjukhuset', 'شاريتيه', 'シャリテ', 'シャリテ=大学医療・ベルリン', 'Шаріте', 'ospedale universitario della Charité', 'Universitätsmedizin Berlin', 'Charité-ziekenhuis', 'שאריטה', 'ชารีเท', 'Šaritē - Berlīnes Universitātes slimnīca', 'Hôpital de la Charité de Berlin', '샤리테', 'Charité Universitätsmedizin Berlin', 'Charité – University Medicine Berlin', 'Շարիտե', 'Шарите', 'シャリティ', 'シャリテー', 'Caritatis nosocomium', '夏綠蒂教學醫院', 'Charité hospital', 'შარიტე'])
({'Q43229': True, 'Q618123': True, 'Q5': False, 'P2427': False, 'P1566': True, 'P496': False}, ['IJalimani', 'R. F. A.', 'Alemania', '도이칠란트', 'Germaniya', 'ܓܪܡܢ', 'Jeremane', 'Heremani', 'IJamani', 'Dwzgoz', 'Vuokītėjė', 'Germania', 'Алман иле', 'Germanie', 'آلمان', 'ਜਰਮਨੀ', 'Jarimani', 'Jermani', 'Almaniya', 'Duutsjlandj', 'جرمني', 'RFG', 'Lanlmangn', 'Duiskka lihttodásseváldi', 'Немачка', 'Yr Almaen', 'Németország', 'ᔮᒪᓂ', 'RFA', 'Almayn', 'de', 'Mjymcy', 'ဂျာမနီနိုင်ငံ', 'Ubudagi', 'Германия', 'Gjermania', 'ФРГ', 'Ubudage', 'Dútslân', 'Německo', 'Spolková republika Německo', 'Gyaaman', 'Федерална република Германия', 'Girmania', 'Germana', 'ئەڵمانیا', 'Jẹ́mánì', 'Repubblica Federale di Germania', 'ཇཱར་མ་ནི་', 'Almaniya Federativ Respublikası', 'Немыч Эл', 'Федеративная Республика Германия', 'Saksa', 'Germuanii', 'Saksāmō', 'ഫെഡറൽ റിപ്പബ്ലിക് ഓഫ്\u200c ജർമ്മനി', 'Alémani', 'Kelemānia', 'Federal Republic of Germany', 'Đức', 'Nemecko', '𐌸𐌹𐌿𐌳𐌹𐍃𐌺𐌰𐌻𐌰𐌽𐌳', 'Дойчланд', 'Yn Ghermaan', 'Германия Мастор', 'Allemagne', 'Njemačka', 'Alimagna', 'Tiamana', 'જર્મની', 'สหพันธ์สาธารณรัฐเยอรมนี', 'Ниицәтә Немшин Орн', 'Joermani', 'Düütsklound', 'Њемачка', 'Bundesrepublik Deutschland', 'ZRN', 'Němska', 'Almanya Federal Cumhuriyeti', '德国', 'Germaniýa', 'ජර්මනිය', 'An Ghearmáin', 'Gweriniaeth Ffederal yr Almaen', 'Германиә', 'Hāmene', 'NSR', 'Saksa lett-tääʹssväʹlddksa', 'la République fédérale d’Allemagne', 'འཇར་མན།', 'Федератив Республика Германия', 'Allemagna', 'ߊߟߏߡߊ߲ߘߎ߯', 'Ġermanja', 'Nemačka', 'FRG', '🇩🇪', 'Saksanma', 'Dáik-guók', 'Alemaina', 'Vācija', 'Germània', 'ألمانيا', 'Þēodscland', 'Alamagn', 'Düütschland', 'Германія', 'Γερμανία', 'Tek-kok', 'Alimanya', 'Þēodiscland', 'जर्मनी', 'República Federal da Alemanha', 'Német Szövetségi Köztársaság', 'Alemanyi', 'Germâgna', 'Jarmanii', "République fédérale d'Allemagne", 'Германие', 'Caama', '독일연방공화국', 'Германие мастор', 'Gjermanie', 'Republica Federal de Alemania', 'ጀርመን', 'Gebundene Cynewīse Þēodisclandes', 'گېرمانىيە', 'אלמאניה', 'Германия Федеративтік Республикасы', 'Alimaña', '德意志聯邦共和國', 'דייטשלאנד', '德意志联邦共和国', 'ФРН', 'Dütschland', '独国', 'Almaañ', 'جمهورية ألمانيا اﻻتحادية', 'Германи', 'Federale Republiek van Duitsland', 'Савезна Република Њемачка', 'Алмания Федератив Җөмһүрияте', 'DE', 'АФР', 'Almanya', 'Jeureuman', 'Dietschlaunt', 'Джэрмэн', 'Deutän', 'Գերմանիա', 'Олмон', 'Béésh Bichʼahii Bikéyah', 'Alemanya', 'Allemangne', 'Jémanị', "S'aksamaa", 'Zwězkowa republika Nimska', 'Doichland', 'جمهوری فدرال آلمان', 'Almay', 'អាល្លឺម៉ង់', 'All.', 'Ghjermania', 'Þýskaland', 'Saksan liittotasavalta', 'Германиа', 'IJalimane', 'Girimane', 'Almania', 'Нѣмьци', 'República Federal de Alemania', 'Ҷумҳурии Федералии Олмон', 'Olmoniya', 'Deutschland', '德意志聯邦', 'Федератив Герман Республикасы', 'Alemagne', 'ᎠᏛᏥ', '德意志', 'Almaanya', 'جرمنی', "dotygu'e", 'সংযুক্ত প্রজাতন্ত্রী জার্মানি', 'Saksa littotäsiväldi', 'გერმანია', 'Germanujo', 'Jarmalka', 'Jérman', 'ዶይችላንድ', 'ፈደራላዊት ሪፓብሊክ ጀርመን', 'Jermaniya', 'Förbundsrepubliken Tyskland', 'Дојчланд', 'Jamani', 'ଜର୍ମାନୀ', 'Ӂермания', 'မိူင်းၵျႃႇမၼီႇ', 'DEU', 'Duitsland', 'Saksslajânnam lett-tääʹssväʹldd', 'Vokietija', 'Daitschlond', 'SRN', 'Գերմանիայի Դաշնային Հանրապետություն', 'Немечму', 'Lalman', 'République fédérale allemande', 'Германија', 'Алмания', 'Alemanne', "Ma'evé'ho'éno", 'Bondsrepubliek', 'Deutxland', 'Deitschland', 'BR Deutschland', 'Jerman', 'Deutsch Liân-pang Kiōng-hô-kok', 'Ομοσπονδιακή Δημοκρατία της Γερμανίας', 'Miemieckô', 'Almanha', 'Týskland', 'செருமனி', 'Nemčija', 'Німеччина', 'Germanio', 'Nimska', 'Bondsrepubliek van Duitsland', 'Saksslajânnam', 'BRD', 'জার্মানি', 'Федеративна Республіка Німеччина', 'ドイツ連邦共和国', '德意志联邦', 'Vuoceja', 'Алманиә', 'ஜெர்மனி', 'Xermanja', 'BR Döüdschlônd', 'Ҷумҳурии Федеролии Олмон', 'Djermani', 'Ghermãnia', 'Doysrikondre', 'Tjüschlönj', 'GER', 'Duutslaand', 'Tet-koet', 'Duutsland', 'გერმანიის ფედერაციული რესპუბლიკა', 'ജർമ്മനി', 'Gërmania', "A' Ghearmailt", 'ޖަރުމަނުވިލާތް', '獨逸', 'Duiska', 'Nenāhuatīliztlācatlahtohcāyōtl Alemania', 'Almagne', 'Tyskland', 'Saksamaa', 'Döüdschlônd', 'Tysklaante', 'జర్మనీ', 'Нїмецько', 'ประเทศเยอรมนี', 'Republica Federală Germania', 'Zwjazkowa republika Němska', 'Teutontlālpan', 'Paejes tudësc', 'Ujerumani', 'Alemaña', 'ᱡᱟᱨᱢᱟᱱᱤ', 'Däitschland', 'Forbundsrepublikken Tyskland', 'Герман', 'גרמניה', "República Federal d'Alemaña", 'Alimaɲi', 'Alemanha', '德國', 'ドイツ', 'ಜರ್ಮನಿ', 'Нямеччына', '독일', 'Bondsrepubliek Duitsland', 'Bunnäsrebublik Döüdschlônd', 'Alemagna', 'Jamus', 'Siamani', 'Niemcy', 'Алман Федератив Республикасы', 'Герман иле', 'ປະເທດເຢັຽລະມັນ'])

The Wikidata QIDs are attached to tokens:

for token in doc:
    print((token.text, token.ent_kb_id_))
('Christian', 'Q1079331')
('Drosten', 'Q1079331')
('works', '')
('in', '')
('Charité', 'Q162684')
(',', '')
('Germany', 'Q183')
('.', '')

The raw annotations can be found in doc._.annotations. Let’s check the first one:

doc._.annotations[0]
{'start': 0,
 'end': 17,
 'tags': [{'id': 'Q1079331',
   'label': ['Christian Drosten'],
   'aliases': ['كريستيان دروستين',
    'Крістіан Дростен',
    'Christian Heinrich Maria Drosten',
    'کریستین دروستن',
    '크리스티안 드로스텐',
    '德羅斯登',
    'クリスチャン・ドロステン',
    'Дростен, Кристиан',
    'Кристиан Хайнрих Мария Дростен',
    'Кристиан Дростен'],
   'extra_aliases': ['0000-0001-7923-0519'],
   'desc': 'German virologist and university teacher',
   'nb_statements': 60,
   'nb_sitelinks': 20,
   'edges': [6581097,
    10905380,
    1120501,
    1305740,
    1205214,
    1305740,
    10905334,
    1546865,
    15634281,
    1622272,
    183,
    152171,
    617048,
    2496385,
    162684,
    18001597,
    2018484,
    25413386,
    21441764,
    4185,
    34704877,
    64,
    586,
    188,
    1860,
    54439832,
    87748614,
    1713320,
    50662,
    80011696,
    83347119,
    5370768,
    88072607,
    188,
    188,
    188,
    188,
    100492007,
    913404,
    100492007,
    50662,
    1650888,
    100494914,
    121594,
    100494914],
   'types': {'Q43229': False,
    'Q618123': False,
    'Q5': True,
    'P2427': False,
    'P1566': False,
    'P496': True},
   'rank': 2.5493406926414757,
   'score': 1.7265554428236625,
   'valid': None}],
 'best_qid': 'Q1079331',
 'log_likelihood': 27.46346902911082}

The partial metadata for the response returned by the OpenTapioca API:

doc._.metadata
{'status_code': 200, 'reason': 'OK', 'ok': True, 'encoding': 'utf-8'}

Spans have span._.annotations and span._.aliases extensions. Usually they have a lot of data. Let’s print the rest of span extensions:

print(span._.description)
print(span._.rank)
print(span._.score)
print(span._.types)
print(span._.label)
print(span._.extra_aliases)
print(span._.nb_sitelinks)
print(span._.nb_statements)
sovereign state in Central Europe
16.722767013369445
1.0571540026892925
{'Q43229': True, 'Q618123': True, 'Q5': False, 'P2427': False, 'P1566': True, 'P496': False}
['Germany']
None
367
1028

Now we can vizualize the results

params = {"text": doc.text,
          "ents": [{"start": ent.start_char,
                    "end": ent.end_char,
                    "label": ent.label_,
                    "kb_id": ent.kb_id_,
                    "kb_url": "https://www.wikidata.org/entity/" + ent.kb_id_} 
                   for ent in doc.ents],
          "title": None}
spacy.displacy.render(params, style="ent", manual=True)
Christian Drosten PERSON Q1079331 works in Charité ORG Q162684 , Germany LOC Q183 .