Commit 9c96b527 authored by PkSM3's avatar PkSM3

Merge branch 'unstable' of ssh://delanoe.org:1979/gargantext into samuel

parents 179f85ea 04b87b43
......@@ -50,7 +50,6 @@ SECRET_KEY = 'bt)3n9v&a02cu7^^=+u_t2tmn8ex5fvx8$x4r*j*pb1yawd+rz'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
MAINTENANCE = False
TEMPLATE_DEBUG = False
......@@ -71,17 +70,17 @@ TEMPLATE_DIRS = (
#ALLOWED_HOSTS = ['*',]
ALLOWED_HOSTS = ['localhost',
'gargantext.org',
'stable.gargantext.org',
'dev.gargantext.org',
'iscpif.gargantext.org',
'gargantext.iscpif.fr',
'mines.gargantext.org',
'pasteur.gargantext.org',
'beta.gargantext.org',
'garg-dev.iscpif.fr',
'garg-stable.iscpif.fr',
ALLOWED_HOSTS = ['localhost',
'gargantext.org',
'stable.gargantext.org',
'dev.gargantext.org',
'iscpif.gargantext.org',
'gargantext.iscpif.fr',
'mines.gargantext.org',
'pasteur.gargantext.org',
'beta.gargantext.org',
'garg-dev.iscpif.fr',
'garg-stable.iscpif.fr',
]
......
......@@ -34,17 +34,19 @@ class FileParser:
"""
# First, check the split dates...
# This part mainly deal with Zotero data but can be usefull for others
# parts
date_string = hyperdata.get('publication_date_to_parse', None)
if date_string is not None:
date_string = re.sub(r'\/\/+', '', date_string)
date_string = re.sub(r'undefined', '', date_string)
date_string = re.sub(r'\/\/+(\w*|\d*)', '', date_string)
#date_string = re.sub(r'undefined', '', date_string)
try:
hyperdata['publication' + "_date"] = dateutil.parser.parse(
date_string,
default=DEFAULT_DATE
).strftime("%Y-%m-%d %H:%M:%S")
except:
print('Parser Zotero, Date not parsed for:', date_string)
except Exception as error:
print(error, 'Parser Zotero, Date not parsed for:', date_string)
hyperdata['publication_date'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
......
from .Tagger import Tagger
from .lib.melttagger.tagger import POSTagger, Token, DAGParser, DAGReader
import subprocess
import sys
import os
# references for tag equivalents:
# - http://cs.nyu.edu/grishman/jet/guide/PennPOS.html
# - http://www.lattice.cnrs.fr/sites/itellier/SEM.html
class identity_dict(dict):
def __missing__(self, key):
return key
_tag_replacements = identity_dict({
'DET': 'DT',
'NC': 'NN',
'NPP': 'NNP',
'ADJ': 'JJ',
'PONCT': '.',
'ADVWH': 'WRB',
'ADV': 'RB',
'DETWH': 'WDT',
'PROWH': 'WP',
'ET': 'FW',
'VINF': 'VB',
'I': 'UH',
'CS': 'IN',
# 'CLS': '',
# 'CLR': '',
# 'CLO': '',
# 'PRO': '',
# 'PROREL': '',
# 'P': '',
# 'P+D': '',
# 'P+PRO': '',
# 'V': '',
# 'VPR': '',
# 'VPP': '',
# 'VS': '',
# 'VIMP': '',
# 'PREF': '',
# 'ADJWH': '',
})
class MeltTagger(Tagger):
def start(self, language='fr', melt_data_path='lib/melttagger'):
basepath = os.path.dirname(os.path.realpath(__file__))
path = os.path.join(basepath, melt_data_path)
self._pos_tagger = POSTagger()
self._pos_tagger.load_tag_dictionary('%s/%s/tag_dict.json' % (path, language))
self._pos_tagger.load_lexicon('%s/%s/lexicon.json' % (path, language))
self._pos_tagger.load_model('%s/%s' % (path, language))
self._preprocessing_commands = (
# ('/usr/local/bin/clean_noisy_characters.sh', ),
('%s/MElt_normalizer.pl' % path, '-nc', '-c', '-d', '%s/%s' % (path, language), '-l', language, ),
('%s/segmenteur.pl' % path, '-a', '-ca', '-af=%s/pctabr' % path, '-p', 'r'),
)
self._lemmatization_commands = (
('%s/MElt_postprocess.pl' % path, '-npp', '-l', language),
('%s/MElt_lemmatizer.pl' % path, '-m', '%s/%s' % (path, language)),
)
def stop(self):
pass
def _pipe(self, text, commands, encoding='utf8'):
text = text.encode(encoding)
for command in commands:
process = subprocess.Popen(
command,
bufsize=0,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
text, err = process.communicate(text)
if len(err):
print(err.decode(encoding), file=sys.stderr)
return text.decode(encoding)
def _tag(self, text):
preprocessed = self._pipe(text, self._preprocessing_commands)
for sentence in preprocessed.split('\n'):
words = sentence.split(' ')
tokens = [Token(word) for word in words]
tagged_tokens = self._pos_tagger.tag_token_sequence(tokens)
for token in tagged_tokens:
if len(token.string):
yield (token.string, _tag_replacements[token.label], )
def tag_text(self, text, lemmatize=True):
tagged_tokens = self._tag(text)
if not lemmatize:
for tagged_token in tagged_tokens:
yield tagged_token
return
# lemmatization
command_input = ' '.join(
'%s/%s' % (token, tag)
for token, tag in tagged_tokens
)
lemmatized = self._pipe(command_input, self._lemmatization_commands)
for token in lemmatized.split():
if len(token):
values = token.split('/')
yield (values[0], values[1], values[2].replace('*', ''))
In this repo are all files for Gargantext Taggers.
For developers please indicate this path:
/srv/gargantext_lib/gargantext-taggers/.
Then this repo should be locate in /srv/gargantext_lib
......@@ -10,7 +10,7 @@ import time
class identity_dict(dict):
def __missing__(self, key):
return key
_tag_replacements = identity_dict({
"NOM": "NN",
"NAM": "NN",
......@@ -45,8 +45,8 @@ def _readOutput(output, buffer):
Shall be used for french texts.
"""
class TreeTagger(Tagger):
def start(self, treeTaggerPath = "./parsing/Taggers/treetagger"):
def start(self, treeTaggerPath = "./parsing/Taggers/lib/treetagger"):
binaryFile = "%s/bin/tree-tagger" % treeTaggerPath
tagcmdlist = [
binaryFile,
......@@ -67,7 +67,7 @@ class TreeTagger(Tagger):
self._input, self._output = self._popen.stdin, self._popen.stdout
# self._thread = threading.Thread(target=_readOutput, args=(self._output, self.buffer, )).start()
# self.buffer = OutputBuffer()
def stop(self):
# terminates the 'treetagger' process
try:
......@@ -75,20 +75,20 @@ class TreeTagger(Tagger):
self._popen.terminate()
except:
pass
def tagging_start(self):
self.buffer = []
self._thread = threading.Thread(target=_readOutput, args=(self._output, self.buffer, ))
self._thread.start()
self._input.write(b"<block>\n")
def tagging_end(self):
self._input.write(b"<block/>\n")
# sends some dummy tokens, then wait for the text to be treated
self.tag_tokens("Les sanglots longs des violons de l ' automne bercent mon coeur d ' une langueur monotone .".split(), False)
self._thread.join()
def tag_tokens(self, tokens, single=True):
if single:
self.tagging_start()
......@@ -97,7 +97,7 @@ class TreeTagger(Tagger):
if single:
self.tagging_end()
return self.buffer
def tag_text(self, text):
self.tagging_start()
for line in text.split('\n'):
......
from .Tagger import Tagger
from .nlpserver.client import NLPClient
from .lib.nlpserver.client import NLPClient
class TurboTagger:
def start(self):
self._nlpclient = NLPClient()
......
......@@ -2,3 +2,4 @@ from .Tagger import Tagger
from .NltkTagger import NltkTagger
from .TreeTagger import TreeTagger
from .TurboTagger import TurboTagger
from .MeltTagger import MeltTagger
/srv/gargantext_lib/taggers/melttagger
\ No newline at end of file
/srv/gargantext_lib/taggers/nlpserver/data
\ No newline at end of file
/srv/gargantext_lib/taggers/nlpserver/turboparser.cpython-34m.so
\ No newline at end of file
/srv/gargantext_lib/taggers/treetagger
\ No newline at end of file
*.model
\ No newline at end of file
/srv/gargantext_lib/treetagger
\ No newline at end of file
......@@ -149,7 +149,8 @@ th a {
<div class="col-md-4">
<div class="jumbotron">
<h3><a href="/project/{{project.id}}/corpus/{{corpus.id}}/matrix">Matrix</a></h3>
<!-- <h3><a href="/project/{{project.id}}/corpus/{{corpus.id}}/matrix">Matrix</a></h3> -->
<h3>Matrix (soon)</h3>
<ol>
<li>Sort</li>
<li>Group</li>
......
from parsing.Taggers import MeltTagger
# from parsing.Taggers.melttagger.tagger import POSTagger, Token, DAGParser, DAGReader
# # references:
# # - http://cs.nyu.edu/grishman/jet/guide/PennPOS.html
# # - http://www.lattice.cnrs.fr/sites/itellier/SEM.html
# class identity_dict(dict):
# def __missing__(self, key):
# return key
# _tag_replacements = identity_dict({
# 'DET': 'DT',
# 'NC': 'NN',
# 'NPP': 'NNP',
# 'ADJ': 'JJ',
# 'PONCT': '.',
# 'ADVWH': 'WRB',
# 'ADV': 'RB',
# 'DETWH': 'WDT',
# 'PROWH': 'WP',
# 'ET': 'FW',
# 'VINF': 'VB',
# 'I': 'UH',
# 'CS': 'IN',
# # 'CLS': '',
# # 'CLR': '',
# # 'CLO': '',
# # 'PRO': '',
# # 'PROREL': '',
# # 'P': '',
# # 'P+D': '',
# # 'P+PRO': '',
# # 'V': '',
# # 'VPR': '',
# # 'VPP': '',
# # 'VS': '',
# # 'VIMP': '',
# # 'PREF': '',
# # 'ADJWH': '',
# })
# import subprocess
# class MeltTagger:
# def __init__(self, language='fr', melt_data_path='./parsing/Taggers/melttagger'):
# path = '%s/%s' % (melt_data_path, language)
# self.pos_tagger = POSTagger()
# self.pos_tagger.load_tag_dictionary('%s/tag_dict.json' % path)
# self.pos_tagger.load_lexicon('%s/lexicon.json' % path)
# self.pos_tagger.load_model('%s' % path)
# self._preprocessing_commands = (
# # ('/usr/local/bin/clean_noisy_characters.sh', ),
# # ('/usr/local/bin/MElt_normalizer.pl', '-nc', '-c', '-d', '/usr/local/share/melt/normalization/%s' % language, '-l', language, ),
# ('/usr/local/share/melt/segmenteur.pl', '-a', '-ca', '-af=/usr/local/share/melt/pctabr', '-p', 'r'),
# )
# self._lemmatization_commands = (
# ('/usr/local/bin/MElt_postprocess.pl', '-npp', '-l', language),
# ('MElt_lemmatizer.pl', '-m', '/usr/local/share/melt/%s' % language),
# )
# def pipe(self, text, commands, encoding='utf8'):
# text = text.encode(encoding)
# # print(text.decode(encoding))
# for command in commands:
# # print(command)
# process = subprocess.Popen(
# command,
# bufsize=0,
# stdin=subprocess.PIPE,
# stdout=subprocess.PIPE,
# stderr=subprocess.PIPE,
# )
# text, err = process.communicate(text)
# # print()
# # print(text.decode(encoding))
# if len(err):
# print(err.decode(encoding))
# return text.decode(encoding)
# def tag(self, text, encoding='utf8', lemmatize=True):
# preprocessed = self.pipe(text, self._preprocessing_commands)
# if lemmatize:
# result = ''
# for sentence in preprocessed.split('\n'):
# words = sentence.split(' ')
# tokens = [Token(word) for word in words]
# tagged_tokens = self.pos_tagger.tag_token_sequence(tokens)
# # result += ' '.join(token.__str__() for token in tagged_tokens)
# for token in tagged_tokens:
# if len(token.string):
# result += '%s/%s ' % (token.string, token.label, )
# result += '\n'
# lemmatized = self.pipe(result, self._lemmatization_commands)
# for sentence in lemmatized.split('\n'):
# for token in sentence.split(' '):
# if len(token):
# yield tuple(token.split('/'))
# else:
# for sentence in preprocessed.split('\n'):
# words = sentence.split(' ')
# tokens = [Token(word) for word in words]
# tagged_tokens = self.pos_tagger.tag_token_sequence(tokens)
# for token in tagged_tokens:
# if len(token.string):
# yield (token.string, _tag_replacements[token.label], )
if __name__ == '__main__':
from time import time
t0 = time()
tagger = MeltTagger()
print(time() - t0)
print()
text = """Le vieil hôtel de ville, construit de 1608 à 1610 est le plus ancien bâtiment de la ville de Wiesbaden. Il se dresse sur la place centrale de la vieille ville, la Place du Palais, qui abrite aujourd'hui le Parlement de l'État de Hesse, l'église et l'hôtel de ville.
Il a été construit dans le style Renaissance. On a ajouté, en 1828, un étage de style romantique historié. Sur les bas-reliefs des cinq fenêtres de l'étage, en bois, étaient représentées les vertus de la force, la justice, la charité, de prudence et de modération, alors que la pierre a remplacé par des copies. Le pièces de chêne d'origine peut être visitées aujourd'hui au Musée de Wiesbaden. Aujourd'hui, le bâtiment sert de bureau de la ville de Wiesbaden.
Devant le porche, entre l'hôtel de Ville et l'Ancien hôtel de ville, se trouve la colonne centrale de Nassau, un lion couronné avec bouclier.
Il s'agit de construire progressivement, à partir des données initiales, un sous-graphe dans lequel sont classés les différents sommets par ordre croissant de leur distance minimale au sommet de départ. La distance correspond à la somme des poids des arêtes empruntées.
Au départ, on considère que les distances de chaque sommet au sommet de départ sont infinies. Au cours de chaque itération, on va mettre à jour les distances des sommets reliés par un arc au dernier du sous-graphe (en ajoutant le poids de l'arc à la distance séparant ce dernier sommet du sommet de départ ; si la distance obtenue ainsi est supérieure à celle qui précédait, la distance n'est cependant pas modifiée). Après cette mise à jour, on examine l'ensemble des sommets qui ne font pas partie du sous-graphe, et on choisit celui dont la distance est minimale pour l'ajouter au sous-graphe.
La première étape consiste à mettre de côté le sommet de départ et à lui attribuer une distance de 0. Les sommets qui lui sont adjacents sont mis à jour avec une valeur égale au poids de l'arc qui les relie au sommet de départ (ou à celui de poids le plus faible si plusieurs arcs les relient) et les autres sommets conservent leur distance infinie.
Le plus proche des sommets adjacents est alors ajouté au sous-graphe.
La seconde étape consiste à mettre à jour les distances des sommets adjacents à ce dernier. Encore une fois, on recherche alors le sommet doté de la distance la plus faible. Comme tous les sommets n'avaient plus une valeur infinie, il est donc possible que le sommet choisi ne soit pas un des derniers mis à jour.
On l'ajoute au sous-graphe, puis on continue ainsi à partir du dernier sommet ajouté, jusqu'à épuisement des sommets ou jusqu'à sélection du sommet d'arrivée.
"""
i = 0
t0 = time()
for x in tagger.tag_text(text, lemmatize=True):
print(x)
i += 1
t = time() - t0
print(t)
print(t / i)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment