Loomuliku keele töötlemine - tehnoloogia, mis võimaldab tarkvararakendustel inimkeelt töödelda - on viimase paari aasta jooksul muutunud üsna üldlevinuks.
Google'i otsing suudab üha enam vastata loomulikult kõlavatele küsimustele, Apple'i Siri suudab mõista paljusid erinevaid küsimusi ning üha rohkem ettevõtteid kasutab klientidega suhtlemiseks (mõistlikult) intelligentseid vestlus- ja telefoniroboteid. Kuid kuidas see näiliselt 'tark' tarkvara tegelikult töötab?
Selles artiklis saate teada tehnoloogiast, mis paneb need rakendused tiksuma, ja saate teada, kuidas oma loomuliku keele töötlemise tarkvara välja töötada.
Artiklis tutvustatakse uudiste asjakohasuse analüsaatori ehitamise näidisprotsessi. Kujutage ette, et teil on aktsiaportfell ja soovite, et rakendus indekseeriks automaatselt populaarseid uudiste veebisaite ja tuvastaks teie portfelliga seotud artikleid. Näiteks kui teie aktsiaportfellis on selliseid ettevõtteid nagu Microsoft, BlackStone ja Luxottica, soovite näha artikleid, kus mainitakse neid kolme ettevõtet.
Loomuliku keele töötlemise rakendused, nagu ka kõik teised masinõppimise rakendused, on üles ehitatud mitmetele suhteliselt väikestele, intuitiivsetele, tandemina töötavatele algoritmidele. Sageli on mõttekas kasutada välist teeki, kus kõik need algoritmid on juba rakendatud ja integreeritud.
Meie näiteks kasutame Stanfordi NLP raamatukogu , võimas Java-põhine loomuliku keele töötlemise teek, mis on varustatud paljude keelte toega.
Selle raamatukogu üks konkreetne algoritm, mis meid huvitab, on kõneosa (POS) märgend. POS-märgistajat kasutatakse kõneosade automaatseks määramiseks igale tekstitüki sõnale. See POS-märgistaja klassifitseerib sõnad tekstis leksikaalsete tunnuste põhjal ja analüüsib neid teiste ümbritsevate sõnade suhtes.
POS-märgistaja algoritmi täpne mehaanika ei kuulu selle artikli reguleerimisalasse, kuid saate selle kohta lisateavet siin .
Alustuseks loome uue Java-projekti (saate kasutada oma lemmik-IDE-d) ja lisame sõltuvuste loendisse Stanfordi NLP-teegi. Kui kasutate Maveni, lisage see lihtsalt oma pom.xml
fail:
twitteri nuppu ei kuvata stiilis
edu.stanford.nlp stanford-corenlp 3.6.0 edu.stanford.nlp stanford-corenlp 3.6.0 models
Kuna rakendus peab artikli sisu veebisaidilt automaatselt välja pakkima, peate määrama ka järgmised kaks sõltuvust:
de.l3s.boilerpipe boilerpipe 1.1.0
net.sourceforge.nekohtml nekohtml 1.9.22
Kui need sõltuvused on lisatud, olete valmis edasi liikuma.
Meie analüsaatori esimene osa hõlmab artiklite otsimist ja nende sisu väljavõtmist veebilehtedelt.
Artiklite otsimisel uudisteallikatest on lehtedel tavaliselt kõrvalist teavet (manustatud videod, väljaminevad lingid, videod, reklaamid jne), mis pole artikli enda jaoks asjakohane. See on koht Kateltoru mängu tuleb.
Boilerpipe on ülitugev ja tõhus algoritm segaduse eemaldamiseks, mis tuvastab uudisartikli põhisisu, analüüsides erinevaid sisplokke, kasutades selliseid funktsioone nagu keskmise lause pikkus, sisuplokides kasutatud siltide tüübid ja linkide tihedus. Kateltoru algoritm on osutunud konkurentsivõimeliseks teiste arvutuslikult kallimate algoritmidega, näiteks masinnägemisel põhinevate algoritmidega. Selle kohta saate rohkem teada projekti sait .
Boilerpipe'i teegil on sisseehitatud tugi veebilehtede kraapimiseks. See suudab HTML-i veebis tuua, HTML-ist teksti välja tõmmata ja ekstraheeritud teksti puhastada. Võite määratleda funktsiooni extractFromURL
, mis võtab URL-i ja kasutab Boilerpipe'i abil asjakohaseima teksti tagastamiseks stringina, kasutades ArticleExtractor
selle ülesande jaoks:
javascript teisendab kuupäeva utc-ks
import java.net.URL; import de.l3s.boilerpipe.document.TextDocument; import de.l3s.boilerpipe.extractors.CommonExtractors; import de.l3s.boilerpipe.sax.BoilerpipeSAXInput; import de.l3s.boilerpipe.sax.HTMLDocument; import de.l3s.boilerpipe.sax.HTMLFetcher; public class BoilerPipeExtractor { public static String extractFromUrl(String userUrl) throws java.io.IOException, org.xml.sax.SAXException, de.l3s.boilerpipe.BoilerpipeProcessingException { final HTMLDocument htmlDoc = HTMLFetcher.fetch(new URL(userUrl)); final TextDocument doc = new BoilerpipeSAXInput(htmlDoc.toInputSource()).getTextDocument(); return CommonExtractors.ARTICLE_EXTRACTOR.getText(doc); } }
Boilerpipe'i teek pakub katlatoru algoritmil põhinevaid erinevaid ekstraktoreid ArticleExtractor
-ga on spetsiaalselt optimeeritud HTML-vormingus uudisartiklite jaoks. ArticleExtractor
keskendub konkreetselt HTML-i siltidele, mida kasutatakse igas sisuplokis, ja väljaminevate linkide tihedusele. See sobib paremini meie ülesandeks kui kiirem, kuid lihtsam DefaultExtractor
.
Sisseehitatud funktsioonid hoolitsevad meie eest kõige eest:
HTMLFetcher.fetch
saab HTML-dokumendigetTextDocument
ekstraktid tekstidokumendiCommonExtractors.ARTICLE_EXTRACTOR.getText
eraldab katlakivi algoritmi abil artiklist asjakohase tekstiNüüd saate seda proovida näiteartikliga optiliste hiiglaste Essilori ja Luxottica ühinemise kohta, mille leiate siin . Selle URL-i saate funktsiooni sisestada ja vaadata, mis välja tuleb.
Lisage oma põhifunktsioonile järgmine kood:
public class App { public static void main( String[] args ) throws java.io.IOException, org.xml.sax.SAXException, de.l3s.boilerpipe.BoilerpipeProcessingException { String urlString = 'http://www.reuters.com/article/us-essilor-m-a-luxottica-group-idUSKBN14Z110'; String text = BoilerPipeExtractor.extractFromUrl(urlString); System.out.println(text); } }
Peaksite nägema artikli põhiosa väljundis ilma reklaamide, HTML-i siltide ja väljaminevate linkideta. Siin on algusjupp sellest, mida ma sain selle käivitamisel:
MILAN/PARIS Italy's Luxottica (LUX.MI) and France's Essilor (ESSI.PA) have agreed a 46 billion euro ( billion) merger to create a global eyewear powerhouse with annual revenue of more than 15 billion euros. The all-share deal is one of Europe's largest cross-border tie-ups and brings together Luxottica, the world's top spectacles maker with brands such as Ray-Ban and Oakley, with leading lens manufacturer Essilor. 'Finally ... two products which are naturally complementary -- namely frames and lenses -- will be designed, manufactured and distributed under the same roof,' Luxottica's 81-year-old founder Leonardo Del Vecchio said in a statement on Monday. Shares in Luxottica were up by 8.6 percent at 53.80 euros by 1405 GMT (9:05 a.m. ET), with Essilor up 12.2 percent at 114.60 euros. The merger between the top players in the 95 billion eyewear market is aimed at helping the businesses to take full advantage of expected strong demand for prescription spectacles and sunglasses due to an aging global population and increasing awareness about eye care. Jefferies analysts estimate that the market is growing at between...
Ja see on tõepoolest artikli peamine artiklikogum. Raske ette kujutada, et seda on palju lihtsam rakendada.
Nüüd, kui olete peamise artikliteksti edukalt välja pakkinud, saate teha kindlaks, kas artiklis mainitakse ettevõtteid, mis pakuvad kasutajale huvi.
Teil võib tekkida kiusatus teha lihtsalt string või regulaaravaldise otsing, kuid sellel lähenemisel on mitu puudust.
Esiteks võib stringiotsing olla altid valepositiivsetele. Artiklis, kus mainitakse Microsoft Exceli, võidakse märkida näiteks Microsofti mainimine.
Teiseks võib regulaaravaldise otsimine sõltuvalt regulaaravaldise konstruktsioonist põhjustada valenegatiive. Näiteks võib artikkel, mis sisaldab fraasi 'Luxottica kvartalitulud ületasid ootusi', tavalise avaldise otsingu kaudu, mis otsib sõna 'Luxottica' ja mida ümbritsevad tühikud.
Lõpuks, kui olete huvitatud suurest arvust ettevõtetest ja töötate suurt hulka artikleid, võib kõigi kasutajate portfelli kuuluvate ettevõtete kogu teksti otsimine osutuda ülimalt aeganõudvaks, andes lubamatu jõudluse.
Stanfordi CoreNLP raamatukogu on palju võimsaid funktsioone ja pakub viisi kõigi kolme probleemi lahendamiseks.
kuidas avada ddms android stuudios
Analüsaatori jaoks kasutame kõneosade (POS) märgendit. Eelkõige võime kasutada POS-märgendit, et leida artiklist kõik pärisnimed ja võrrelda neid meie huvitavate aktsiate portfelliga.
NLP-tehnoloogia lisamisega parandame mitte ainult oma sildi täpsust ja minimeerime ülalnimetatud valepositiivseid ja negatiivseid, vaid minimeerime dramaatiliselt ka teksti koguse, mida peame oma varude portfelliga võrdlema, kuna pärisnimed sisaldavad ainult väikest alamhulka artikli täistekstist.
Eeltöödeldes meie portfelli andmestruktuuriks, millel on madal liikmelisuse päringu hind , saame dramaatiliselt vähendada artikli analüüsimiseks vajalikku aega.
Stanford CoreNLP pakub väga mugavat sildistajat nimega MaxentTagger mis võimaldab POS-märgistamist vaid mõne koodireaga.
Siin on lihtne rakendamine:
public class PortfolioNewsAnalyzer { private HashSet portfolio; private static final String modelPath = 'edu\stanford\nlp\models\pos-tagger\english-left3words\english-left3words-distsim.tagger'; private MaxentTagger tagger; public PortfolioNewsAnalyzer() { tagger = new MaxentTagger(modelPath); } public String tagPos(String input) { return tagger.tagString(input); }
Sildistaja funktsioon tagPos
võtab sisendiks stringi ja väljastab stringi, mis sisaldab algses stringis olevaid sõnu koos vastava kõneosaga. Instantsige oma põhifunktsioonis PortfolioNewsAnalyzer
ja sisestage kaabitsa väljund märgistaja funktsiooni ja peaksite nägema midagi sellist:
tasuta häkitud krediitkaardid, millel on raha 2017
MILAN/PARIS_NN Italy_NNP 's_POS Luxottica_NNP -LRB-_-LRB- LUX.MI_NNP -RRB-_-RRB- and_CC France_NNP 's_POS Essilor_NNP -LRB-_-LRB- ESSI.PA_NNP -RRB-_-RRB- have_VBP agreed_VBN a_DT 46_CD billion_CD euro_NN -LRB-_-LRB- $_$ 49_CD billion_CD -RRB-_-RRB- merger_NN to_TO create_VB a_DT global_JJ eyewear_NN powerhouse_NN with_IN annual_JJ revenue_NN of_IN more_JJR than_IN 15_CD billion_CD euros_NNS ._. The_DT all-share_JJ deal_NN is_VBZ one_CD of_IN Europe_NNP 's_POS largest_JJS cross-border_JJ tie-ups_NNS and_CC brings_VBZ together_RB Luxottica_NNP ,_, the_DT world_NN 's_POS top_JJ spectacles_NNS maker_NN with_IN brands_NNS such_JJ as_IN Ray-Ban_NNP and_CC Oakley_NNP ,_, with_IN leading_VBG lens_NN manufacturer_NN Essilor_NNP ._. ``_`` Finally_RB ..._: two_CD products_NNS which_WDT are_VBP naturally_RB complementary_JJ --_: namely_RB frames_NNS and_CC lenses_NNS --_: will_MD be_VB designed_VBN ,_, manufactured_VBN and_CC distributed_VBN under_IN the_DT same_JJ roof_NN ,_, ''_'' Luxottica_NNP 's_POS 81-year-old_JJ founder_NN Leonardo_NNP Del_NNP Vecchio_NNP said_VBD in_IN a_DT statement_NN on_IN Monday_NNP ._. Shares_NNS in_IN Luxottica_NNP were_VBD up_RB by_IN 8.6_CD percent_NN at_IN 53.80_CD euros_NNS by_IN 1405_CD GMT_NNP -LRB-_-LRB- 9:05_CD a.m._NN ET_NNP -RRB-_-RRB- ,_, with_IN Essilor_NNP up_IN 12.2_CD percent_NN at_IN 114.60_CD euros_NNS ._. The_DT merger_NN between_IN the_DT top_JJ players_NNS in_IN the_DT 95_CD billion_CD eyewear_NN market_NN is_VBZ aimed_VBN at_IN helping_VBG the_DT businesses_NNS to_TO take_VB full_JJ advantage_NN of_IN expected_VBN strong_JJ demand_NN for_IN prescription_NN spectacles_NNS and_CC sunglasses_NNS due_JJ to_TO an_DT aging_NN global_JJ population_NN and_CC increasing_VBG awareness_NN about_IN...
Siiani oleme loonud funktsioonid uudisartikli allalaadimiseks, puhastamiseks ja sildistamiseks. Kuid peame ikkagi kindlaks tegema, kas artiklis mainitakse mõnda kasutajat huvitavat ettevõtet.
Selleks peame koguma kõik pärisnimed ja kontrollima, kas meie portfelli varud kuuluvad nende pärisnimede hulka.
Kõigi pärisnimede leidmiseks tahame kõigepealt jagada märgistatud stringi väljund märgideks (kasutades eraldajatena tühikuid), seejärel jaotada alakõhul kõik märgid (_
) ja kontrollida, kas kõne osa on pärisnimi.
Kui kõik õiged nimisõnad on olemas, tahame need salvestada andmekonstruktsiooni, mis on meie otstarbeks paremini optimeeritud. Näiteks kasutame a HashSet
. Vastutasuks duplikaatkirjete keelamise ja kirjete järjekorra jälgimata jätmise eest HashSet
võimaldab väga kiireid liikmepäringuid. Kuna meid huvitab ainult liikmelisuse taotlemine, siis HashSet
sobib ideaalselt meie eesmärkidele.
Allpool on funktsioon, mis rakendab pärisnimede jagamist ja salvestamist. Asetage see funktsioon kausta PortfolioNewsAnalyzer
klass:
public static HashSet extractProperNouns(String taggedOutput) { HashSet propNounSet = new HashSet(); String[] split = taggedOutput.split(' '); for (String token: split ){ String[] splitTokens = token.split('_'); if(splitTokesn[1].equals('NNP')){ propNounSet.add(splitTokens[0]); } } return propNounSet; }
Selle rakendamisega on siiski probleem. Kui ettevõtte nimi koosneb mitmest sõnast (nt Carlott Zeiss Luxottica näites), ei suuda see rakendus seda tabada. Carl Zeissi näitel lisatakse „Carl” ja „Zeiss” komplekti eraldi ja seetõttu ei sisalda need kunagi ühte stringi “Carl Zeiss”.
Selle probleemi lahendamiseks võime koguda kõik järjestikused pärisnimed ja ühendage need tühikutega. Siin on värskendatud juurutus, millega see saavutatakse:
public static HashSet extractProperNouns(String taggedOutput) { HashSet propNounSet = new HashSet(); String[] split = taggedOutput.split(' '); List propNounList = new ArrayList(); for (String token: split ){ String[] splitTokens = token.split('_'); if(splitTokens[1].equals('NNP')){ propNounList.add(splitTokens[0]); } else { if (!propNounList.isEmpty()) { propNounSet.add(StringUtils.join(propNounList, ' ')); propNounList.clear(); } } } if (!propNounList.isEmpty()) { propNounSet.add(StringUtils.join(propNounList, ' ')); propNounList.clear(); } return propNounSet; }
Nüüd peaks funktsioon tagastama hulga üksikute pärisnimedega ja järjestikused pärisnimed (s.t tühikutega ühendatud). propNounSet
Printimisel peaksite nägema järgmist:
[... Monday, Gianluca Semeraro, David Goodman, Delfin, North America, Luxottica, Latin America, Rossi/File Photo, Rome, Safilo Group, SFLG.MI, Friday, Valentina Za, Del Vecchio, CEO Hubert Sagnieres, Oakley, Sagnieres, Jefferies, Ray Ban, ...]
Oleme peaaegu valmis!
Eelmistes jaotistes ehitasime kaabitsa, millega saab artikli sisu alla laadida ja välja tõmmata, sildi, mis saab artikli parseldada ja tuvastada pärisnimed, ning protsessori, mis võtab märgistatud väljundi ja kogub pärisnimed HashSet
. Nüüd jääb üle vaid võtta HashSet
ja võrrelge seda meid huvitavate ettevõtete loendiga.
Rakendamine on väga lihtne. Lisage oma PortfolioNewsAnalyzer
-i järgmine kood klass:
private HashSet portfolio; public PortfolioNewsAnalyzer() { portfolio = new HashSet(); } public void addPortfolioCompany(String company) { portfolio.add(company); } public boolean arePortfolioCompaniesMentioned(HashSet articleProperNouns){ return !Collections.disjoint(articleProperNouns, portfolio); }
Nüüd saame käivitada kogu rakenduse - kraapimise, puhastamise, sildistamise, kogumise ja võrdlemise. Siin on funktsioon, mis töötab kogu rakenduses. Lisage see funktsioon kausta PortfolioNewsAnalyzer
klass:
public boolean analyzeArticle(String urlString) throws IOException, SAXException, BoilerpipeProcessingException { String articleText = extractFromUrl(urlString); String tagged = tagPos(articleText); HashSet properNounsSet = extractProperNouns(tagged); return arePortfolioCompaniesMentioned(properNounsSet); }
Lõpuks saame rakendust kasutada!
Siin on näide, kasutades sama artiklit nagu ülal ja Luxottica portfelliettevõttena:
public static void main( String[] args ) throws IOException, SAXException, BoilerpipeProcessingException { PortfolioNewsAnalyzer analyzer = new PortfolioNewsAnalyzer(); analyzer.addPortfolioCompany('Luxottica'); boolean mentioned = analyzer.analyzeArticle('http://www.reuters.com/article/us-essilor-m-a-luxottica-group-idUSKBN14Z110'); if (mentioned) { System.out.println('Article mentions portfolio companies'); } else { System.out.println('Article does not mention portfolio companies'); } }
Käivitage see ja rakendus peaks printima „Artiklis mainitakse portfelliettevõtteid”.
Muutke portfelliettevõte Luxotticast ettevõtteks, mida artiklis pole mainitud (näiteks „Microsoft“), ja rakendus peaks printima „Artiklis ei mainita portfelliettevõtteid“.
kuidas node js töötab
Selles artiklis astusime läbi rakenduse loomise protsessi, mis laadib artikli URL-ist alla, puhastab selle Boilerpipe'i abil, töötleb seda Stanfordi NLP abil ja kontrollib, kas artikkel pakub konkreetseid viiteid (meie puhul on meie portfell). Nagu demonstreeritud, muudab selle tehnoloogiate hulga kasutamine selle, mis muidu oleks hirmutav ülesanne, suhteliselt lihtsaks.
Loodan, et see artikkel tutvustas teile loomuliku keele töötlemisel kasulikke mõisteid ja tehnikaid ning innustas teid kirjutama oma loomuliku keele rakendusi.
[Märkus. Selles artiklis viidatud koodi koopia leiate siin .]