public static void Initialize() { if (GlobalOrgs != null) { return; } GlobalOrgs = new Pullenti.Ner.Core.IntOntologyCollection(); Pullenti.Ner.Org.OrganizationReferent org; Pullenti.Ner.Core.IntOntologyItem oi; using (Pullenti.Ner.Processor geoProc = Pullenti.Ner.ProcessorService.CreateEmptyProcessor()) { geoProc.AddAnalyzer(new Pullenti.Ner.Geo.GeoAnalyzer()); Dictionary <string, Pullenti.Ner.Geo.GeoReferent> geos = new Dictionary <string, Pullenti.Ner.Geo.GeoReferent>(); for (int k = 0; k < 3; k++) { Pullenti.Morph.MorphLang lang = (k == 0 ? Pullenti.Morph.MorphLang.RU : (k == 1 ? Pullenti.Morph.MorphLang.EN : Pullenti.Morph.MorphLang.UA)); string name = (k == 0 ? "Orgs_ru.dat" : (k == 1 ? "Orgs_en.dat" : "Orgs_ua.dat")); byte[] dat = ResourceHelper.GetBytes(name); if (dat == null) { throw new Exception(string.Format("Can't file resource file {0} in Organization analyzer", name)); } using (MemoryStream tmp = new MemoryStream(OrgItemTypeToken.Deflate(dat))) { tmp.Position = 0; XmlDocument xml = new XmlDocument(); xml.Load(tmp); foreach (XmlNode x in xml.DocumentElement.ChildNodes) { org = new Pullenti.Ner.Org.OrganizationReferent(); string abbr = null; foreach (XmlNode xx in x.ChildNodes) { if (xx.LocalName == "typ") { org.AddSlot(Pullenti.Ner.Org.OrganizationReferent.ATTR_TYPE, xx.InnerText, false, 0); } else if (xx.LocalName == "nam") { org.AddSlot(Pullenti.Ner.Org.OrganizationReferent.ATTR_NAME, xx.InnerText, false, 0); } else if (xx.LocalName == "epo") { org.AddSlot(Pullenti.Ner.Org.OrganizationReferent.ATTR_EPONYM, xx.InnerText, false, 0); } else if (xx.LocalName == "prof") { org.AddSlot(Pullenti.Ner.Org.OrganizationReferent.ATTR_PROFILE, xx.InnerText, false, 0); } else if (xx.LocalName == "abbr") { abbr = xx.InnerText; } else if (xx.LocalName == "geo") { Pullenti.Ner.Geo.GeoReferent geo; if (!geos.TryGetValue(xx.InnerText, out geo)) { Pullenti.Ner.AnalysisResult ar = geoProc.Process(new Pullenti.Ner.SourceOfAnalysis(xx.InnerText), null, lang); if (ar != null && ar.Entities.Count == 1 && (ar.Entities[0] is Pullenti.Ner.Geo.GeoReferent)) { geo = ar.Entities[0] as Pullenti.Ner.Geo.GeoReferent; geos.Add(xx.InnerText, geo); } else { } } if (geo != null) { org.AddSlot(Pullenti.Ner.Org.OrganizationReferent.ATTR_GEO, geo, false, 0); } } } oi = org.CreateOntologyItemEx(2, true, true); if (oi == null) { continue; } if (abbr != null) { oi.Termins.Add(new Pullenti.Ner.Core.Termin(abbr, null, true)); } if (k == 2) { GlobalOrgsUa.AddItem(oi); } else { GlobalOrgs.AddItem(oi); } } } } } return; }
public static void Main(string[] args) { Stopwatch sw = Stopwatch.StartNew(); // инициализация - необходимо проводить один раз до обработки текстов Console.Write("Initializing SDK Pullenti ver {0} ({1}) ... ", Pullenti.Sdk.Version, Pullenti.Sdk.VersionDate); // инициализируются движок и все имеющиеся анализаторы Pullenti.Sdk.InitializeAll(); sw.Stop(); Console.WriteLine("OK (by {0} ms), version {1}", (int)sw.ElapsedMilliseconds, Pullenti.Ner.ProcessorService.Version); // посмотрим, какие анализаторы доступны foreach (Pullenti.Ner.Analyzer a in Pullenti.Ner.ProcessorService.Analyzers) { Console.WriteLine(" {0} {1} \"{2}\"", (a.IsSpecific ? "Specific analyzer" : "Common analyzer"), a.Name, a.Caption); } // анализируемый текст string txt = "Система разрабатывается с 2011 года российским программистом Михаилом Жуковым, проживающим в Москве на Красной площади в доме номер один на втором этаже. Конкурентов у него много: Abbyy, Yandex, ООО \"Russian Context Optimizer\" (RCO) и другие компании. Он планирует продать SDK за 1.120.000.001,99 (миллиард сто двадцать миллионов один рубль 99 копеек) рублей, без НДС."; Console.WriteLine("Text: {0}", txt); // запускаем обработку на пустом процессоре (без анализаторов NER) Pullenti.Ner.AnalysisResult are = Pullenti.Ner.ProcessorService.EmptyProcessor.Process(new Pullenti.Ner.SourceOfAnalysis(txt), null, null); Console.Write("Noun groups: "); // перебираем токены for (Pullenti.Ner.Token t = are.FirstToken; t != null; t = t.Next) { // выделяем именную группу с текущего токена Pullenti.Ner.Core.NounPhraseToken npt = Pullenti.Ner.Core.NounPhraseHelper.TryParse(t, Pullenti.Ner.Core.NounPhraseParseAttr.No, 0, null); // не получилось if (npt == null) { continue; } // получилось, выводим в нормализованном виде Console.Write("[{0}=>{1}] ", npt.GetSourceText(), npt.GetNormalCaseText(null, Pullenti.Morph.MorphNumber.Singular, Pullenti.Morph.MorphGender.Undefined, false)); // указатель на последний токен именной группы t = npt.EndToken; } using (Pullenti.Ner.Processor proc = Pullenti.Ner.ProcessorService.CreateProcessor()) { // анализируем текст Pullenti.Ner.AnalysisResult ar = proc.Process(new Pullenti.Ner.SourceOfAnalysis(txt), null, null); // результирующие сущности Console.WriteLine("\r\n==========================================\r\nEntities: "); foreach (Pullenti.Ner.Referent e in ar.Entities) { Console.WriteLine("{0}: {1}", e.TypeName, e.ToString()); foreach (Pullenti.Ner.Slot s in e.Slots) { Console.WriteLine(" {0}: {1}", s.TypeName, s.Value); } } // пример выделения именных групп Console.WriteLine("\r\n==========================================\r\nNoun groups: "); for (Pullenti.Ner.Token t = ar.FirstToken; t != null; t = t.Next) { // токены с сущностями игнорируем if (t.GetReferent() != null) { continue; } // пробуем создать именную группу Pullenti.Ner.Core.NounPhraseToken npt = Pullenti.Ner.Core.NounPhraseHelper.TryParse(t, Pullenti.Ner.Core.NounPhraseParseAttr.AdjectiveCanBeLast, 0, null); // не получилось if (npt == null) { continue; } Console.WriteLine(npt); // указатель перемещаем на последний токен группы t = npt.EndToken; } } using (Pullenti.Ner.Processor proc = Pullenti.Ner.ProcessorService.CreateSpecificProcessor(Pullenti.Ner.Keyword.KeywordAnalyzer.ANALYZER_NAME)) { Pullenti.Ner.AnalysisResult ar = proc.Process(new Pullenti.Ner.SourceOfAnalysis(txt), null, null); Console.WriteLine("\r\n==========================================\r\nKeywords1: "); foreach (Pullenti.Ner.Referent e in ar.Entities) { if (e is Pullenti.Ner.Keyword.KeywordReferent) { Console.WriteLine(e); } } Console.WriteLine("\r\n==========================================\r\nKeywords2: "); for (Pullenti.Ner.Token t = ar.FirstToken; t != null; t = t.Next) { if (t is Pullenti.Ner.ReferentToken) { Pullenti.Ner.Keyword.KeywordReferent kw = t.GetReferent() as Pullenti.Ner.Keyword.KeywordReferent; if (kw == null) { continue; } string kwstr = Pullenti.Ner.Core.MiscHelper.GetTextValueOfMetaToken(t as Pullenti.Ner.ReferentToken, Pullenti.Ner.Core.GetTextAttr.FirstNounGroupToNominativeSingle | Pullenti.Ner.Core.GetTextAttr.KeepRegister); Console.WriteLine("{0} = {1}", kwstr, kw); } } } Console.WriteLine("Over!"); }
public static void RefreshGenerals(Pullenti.Ner.Processor proc, Pullenti.Ner.Core.AnalysisKit kit) { Dictionary <string, Dictionary <string, List <Pullenti.Ner.Referent> > > all = new Dictionary <string, Dictionary <string, List <Pullenti.Ner.Referent> > >(); List <Node> allRefs = new List <Node>(); foreach (Pullenti.Ner.Analyzer a in proc.Analyzers) { Pullenti.Ner.Core.AnalyzerData ad = kit.GetAnalyzerData(a); if (ad == null) { continue; } foreach (Pullenti.Ner.Referent r in ad.Referents) { Node nod = new Node() { Ref = r, Ad = ad }; allRefs.Add(nod); r.Tag = nod; Dictionary <string, List <Pullenti.Ner.Referent> > si; if (!all.TryGetValue(a.Name, out si)) { all.Add(a.Name, (si = new Dictionary <string, List <Pullenti.Ner.Referent> >())); } List <string> strs = r.GetCompareStrings(); if (strs == null || strs.Count == 0) { continue; } foreach (string s in strs) { if (s == null) { continue; } List <Pullenti.Ner.Referent> li; if (!si.TryGetValue(s, out li)) { si.Add(s, (li = new List <Pullenti.Ner.Referent>())); } li.Add(r); } } } foreach (Node r in allRefs) { foreach (Pullenti.Ner.Slot s in r.Ref.Slots) { if (s.Value is Pullenti.Ner.Referent) { Pullenti.Ner.Referent to = s.Value as Pullenti.Ner.Referent; Node tn = to.Tag as Node; if (tn == null) { continue; } if (tn.RefsFrom == null) { tn.RefsFrom = new List <Node>(); } tn.RefsFrom.Add(r); if (r.RefsTo == null) { r.RefsTo = new List <Node>(); } r.RefsTo.Add(tn); } } } foreach (Dictionary <string, List <Pullenti.Ner.Referent> > ty in all.Values) { foreach (List <Pullenti.Ner.Referent> li in ty.Values) { if (li.Count < 2) { continue; } if (li.Count > 3000) { continue; } for (int i = 0; i < li.Count; i++) { for (int j = i + 1; j < li.Count; j++) { Node n1 = null; Node n2 = null; if (li[i].CanBeGeneralFor(li[j]) && !li[j].CanBeGeneralFor(li[i])) { n1 = li[i].Tag as Node; n2 = li[j].Tag as Node; } else if (li[j].CanBeGeneralFor(li[i]) && !li[i].CanBeGeneralFor(li[j])) { n1 = li[j].Tag as Node; n2 = li[i].Tag as Node; } if (n1 != null && n2 != null) { if (n1.GenFrom == null) { n1.GenFrom = new List <Node>(); } if (!n1.GenFrom.Contains(n2)) { n1.GenFrom.Add(n2); } if (n2.GenTo == null) { n2.GenTo = new List <Node>(); } if (!n2.GenTo.Contains(n1)) { n2.GenTo.Add(n1); } } } } } } foreach (Node n in allRefs) { if (n.GenTo != null && n.GenTo.Count > 1) { for (int i = n.GenTo.Count - 1; i >= 0; i--) { Node p = n.GenTo[i]; bool del = false; for (int j = 0; j < n.GenTo.Count; j++) { if (j != i && n.GenTo[j].IsInGenParentsOrHigher(p)) { del = true; } } if (del) { p.GenFrom.Remove(n); n.GenTo.RemoveAt(i); } } } } foreach (Node n in allRefs) { if (!n.Deleted && n.GenTo != null && n.GenTo.Count == 1) { Node p = n.GenTo[0]; if (p.GenFrom.Count == 1) { n.Ref.MergeSlots(p.Ref, true); p.Ref.Tag = n.Ref; p.ReplaceValues(n); foreach (Pullenti.Ner.TextAnnotation o in p.Ref.Occurrence) { n.Ref.AddOccurence(o); } p.Deleted = true; } else { n.Ref.GeneralReferent = p.Ref; } } } for (Pullenti.Ner.Token t = kit.FirstToken; t != null; t = t.Next) { _correctReferents(t); } foreach (Node n in allRefs) { if (n.Deleted) { n.Ad.RemoveReferent(n.Ref); } n.Ref.Tag = null; } }