197 lines
6.1 KiB
Python
197 lines
6.1 KiB
Python
from bottle import route, run, request
|
|
from spacy.pipeline import EntityRecognizer
|
|
from spacy.pipeline import TextCategorizer
|
|
from spacy.gold import GoldParse
|
|
#import plac
|
|
import random
|
|
import spacy
|
|
nlp = spacy.load('en')
|
|
ner = EntityRecognizer(nlp.vocab)
|
|
|
|
# python -m spacy info
|
|
@route('/load')
|
|
def load():
|
|
return {'version': '2.0.11',\
|
|
'models': 'en_core_web_md, en',\
|
|
'python': '3.5.2'}
|
|
|
|
@route('/tokenizer', method = 'GET')
|
|
def tokenize():
|
|
return spacy_tokenize(request.query.text)
|
|
|
|
@route('/tokenizer', method = 'POST')
|
|
def tokenize_sentences():
|
|
sentences = request.json['Sentences']
|
|
tokens_list = []
|
|
for sentence in sentences:
|
|
token = spacy_tokenize(sentence)
|
|
tokens_list.append(token['tokens'])
|
|
return {'tokensList' : tokens_list}
|
|
|
|
def spacy_tokenize(sentence):
|
|
print('sentence : {0}'.format(sentence))
|
|
doc = nlp(sentence)
|
|
tokens = []
|
|
for token in doc:
|
|
tokens.append({'text': token.text, 'offset': token.idx,\
|
|
'pos': token.pos_, 'tag': token.tag_, 'lemma': token.lemma_})
|
|
|
|
return {'tokens': tokens}
|
|
|
|
@route('/tagger')
|
|
def tagger():
|
|
doc = nlp(request.query.text)
|
|
list = []
|
|
for token in doc:
|
|
list.append(token.tag_)
|
|
return {'tags': list}
|
|
|
|
|
|
@route('/featurize')
|
|
def tokenize():
|
|
doc = nlp(request.query.text)
|
|
list = []
|
|
print(doc.vector.size)
|
|
for vec in doc.vector:
|
|
print(vec)
|
|
list.append(str(vec.real))
|
|
return {'vectors': list}
|
|
|
|
@route('/entitize')
|
|
def entitize():
|
|
doc = nlp(request.query.text)
|
|
print(doc.ents)
|
|
list = []
|
|
for entity in doc.ents:
|
|
print(entity)
|
|
list.append(entity)
|
|
return {'entities': list}
|
|
|
|
@route('/textcategorizer', method='POST')
|
|
def textcategorizer():
|
|
texts = request.json["Texts"]
|
|
golds = request.json["Golds"]
|
|
labels = request.json["Labels"]
|
|
i = 1
|
|
train_data = []
|
|
for index in range(len(texts)):
|
|
tuple =(texts[index], golds[index])
|
|
train_data.append(tuple)
|
|
textcat = nlp.create_pipe('textcat')
|
|
nlp.add_pipe(textcat, last=True)
|
|
for label in labels:
|
|
textcat.add_label(label)
|
|
optimizer = nlp.begin_training()
|
|
for itn in range(2):
|
|
for doc, gold in train_data:
|
|
nlp.update([doc], [gold], sgd=optimizer)
|
|
textcat.to_disk('./textcat_try')
|
|
return {'ModelName':'textcat_try'}
|
|
|
|
@route('/textcategorizerpredict')
|
|
def textcategorizerpredict():
|
|
textcat = TextCategorizer(nlp.vocab)
|
|
textcat.from_disk('./textcat_try')
|
|
nlp.add_pipe(textcat, last=True)
|
|
doc = nlp(request.query.text)
|
|
print(doc.cats)
|
|
list = []
|
|
for key in doc.cats:
|
|
print(key)
|
|
list.append({'Label': key, 'Confidence': doc.cats[key]})
|
|
print (list)
|
|
return {'Labels': list}
|
|
|
|
@route('/entityrecognizer', method='POST')
|
|
def entityrecognizer():
|
|
model = request.json["ModelPath"]
|
|
new_model_name = request.json["NewModelName"]
|
|
output_dir = request.json["OutputDir"]
|
|
n_iter = request.json["IterTimes"]
|
|
raw_data = request.json["TrainingData"]
|
|
# generate training_data from raw_data
|
|
training_data = []
|
|
for node in raw_data:
|
|
labels = []
|
|
for entity in node['Labels']:
|
|
label = (entity['Start'], entity['End'], entity['Name'])
|
|
labels.append(label)
|
|
tup = (node['Text'], labels)
|
|
training_data.append(tup)
|
|
print(training_data)
|
|
if model is not None:
|
|
nlp = spacy.load(model) # load existing spaCy model
|
|
print("Loaded model '%s'" % model)
|
|
else:
|
|
nlp = spacy.blank('en') # create blank Language class
|
|
print("Created blank 'en' model")
|
|
# Add entity recognizer to model if it's not in the pipeline
|
|
# nlp.create_pipe works for built-ins that are registered with spaCy
|
|
if 'ner' not in nlp.pipe_names:
|
|
ner = nlp.create_pipe('ner')
|
|
nlp.add_pipe(ner)
|
|
print("ner created succeed!")
|
|
# otherwise, get it, so we can add labels to it
|
|
else:
|
|
ner = nlp.get_pipe('ner')
|
|
print("ner loaded succeed!")
|
|
|
|
# check whether there are new labels
|
|
entities_in_training_set = request.json["EntitiesInTrainingSet"]
|
|
en_labels = ["PERSON","NORP","FAC","ORG","GPE","LOC","PRODUCT",\
|
|
"EVENT","WORK_OF_ART","LAW","LANGUAGE","DATE","TIME","PERCENT",\
|
|
"MONEY","QUANTITY","ORDINAL","CARDINAL"]
|
|
|
|
extra_labels = nlp.entity.cfg[u'extra_labels'] \
|
|
if ('extra_labels' in nlp.entity.cfg) else []
|
|
labels = []
|
|
for entity in entities_in_training_set:
|
|
if (entity in en_labels or entity in extra_labels):
|
|
continue
|
|
labels.append(entity)
|
|
for label in labels:
|
|
ner.add_label(label) # add new entity label to entity recognizer
|
|
print("label added succeed!")
|
|
if model is None:
|
|
optimizer = nlp.begin_training()
|
|
else:
|
|
# Note that 'begin_training' initializes the models, so it'll zero out
|
|
# existing entity types.
|
|
optimizer = nlp.entity.create_optimizer()
|
|
# get names of other pipes to disable them during training
|
|
other_pipes = [pipe for pipe in nlp.pipe_names if pipe != 'ner']
|
|
with nlp.disable_pipes(*other_pipes): # only train NER
|
|
for itn in range(n_iter):
|
|
random.shuffle(training_data)
|
|
losses = {}
|
|
for text, annotations in training_data:
|
|
print(text)
|
|
print(annotations)
|
|
#
|
|
doc = nlp.make_doc(text)
|
|
gold = GoldParse(doc, entities=annotations)
|
|
#
|
|
nlp.update([doc], [gold], sgd=optimizer, drop=0.35)#,losses=losses)
|
|
#print(losses)
|
|
# save model to output directory
|
|
if output_dir is not None:
|
|
output_dir = Path(output_dir)
|
|
if not output_dir.exists():
|
|
output_dir.mkdir()
|
|
nlp.meta['name'] = new_model_name # rename model
|
|
nlp.to_disk(output_dir)
|
|
print("Saved model to", output_dir)
|
|
return True
|
|
|
|
@route('/entityrecognizerpredict')
|
|
def entityrecognizerpredict():
|
|
print("Loading from", './entity_rec_output')
|
|
nlp2 = spacy.load('./entity_rec_output')
|
|
doc2 = nlp2(request.query.text)
|
|
for ent in doc2.ents:
|
|
print(ent.label_, ent.text)
|
|
|
|
|
|
|
|
run(host='0.0.0.0', port=5005, debug=False)
|