[doc] Merge docs and update doc, related to #187461

authorvincent.michel@logilab.fr
changeset80863a541605
branchdefault
phasedraft
hiddenyes
parent revision#14a80f3aea13 [data] Move french lemmas in data module, related to #187461
child revision#e75db3f9f139 preparing 0.4.0, #b40d9e25d408 [dataio] Create an helper that execute a sparql query and return a clean json dict, see #198745
files modified by this revision
doc.rst
ner/doc.rst
# HG changeset patch
# User vincent.michel@logilab.fr
# Date 1387464368 0
# Thu Dec 19 14:46:08 2013 +0000
# Node ID 80863a541605c117d5b4833fce506bd654af4f9d
# Parent 14a80f3aea1323e767144d25d9a7261e2ec9a7e8
[doc] Merge docs and update doc, related to #187461

diff --git a/doc.rst b/doc.rst
@@ -8,12 +8,16 @@
1 
2  In particular, it helps you:
3 
4   * interact with SPARQL endpoints and reference databases.
5 
6 - * align your data (`record linkage`), i.e. link data from
7 -   your database to data in other databases.
8 + * align your data (`record linkage` or `rl`), i.e. link data from
9 +   your database to data in other databases;
10 +
11 + * contextualize your data by finding reference entities in your text corpus
12 +   (`named entities recognition` or `ner`);
13 +
14 
15 
16  Record linkage
17  ==============
18 
@@ -28,11 +32,11 @@
19  This library provides you all the stuff we need to do it.
20 
21 
22 
23  Introduction
24 -~~~~~~~~~~~~
25 +------------
26 
27  The record linkage process is divided into three main steps:
28 
29  1. Gather and format the data we want to align.
30     In this step, we define two sets called the `referenceset` and the
@@ -45,11 +49,11 @@
31  3. Find the items having a high similarity thanks to the distance matrix.
32 
33 
34 
35  Simple case
36 -~~~~~~~~~~~
37 +-----------
38 
39  1. Let's define `referenceset` and `targetset` as simple python lists.
40 
41  .. sourcecode:: python
42 
@@ -103,19 +107,19 @@
43 
44 
45  In such a case, two distance functions are used, the Levenshtein one for the
46  name and the city and a temporal one for the birth date [#]_.
47 
48 -.. [#] Provided in the `nazca.distances` module.
49 +.. [#] Provided in the `nazca.utils.distances` module.
50 
51 
52 -The :func:`cdist` function of `nazca.distances` enables us to compute those
53 +The :func:`cdist` function of `nazca.utils.distances` enables us to compute those
54  matrices :
55 
56  .. sourcecode:: python
57 
58 -    >>> from nazca.distances import levenshtein, cdist
59 +    >>> from nazca.utils.distances import levenshtein, cdist
60      >>> cdist(levenshtein,[a[0] for a in referenceset],
61      >>>       [t[0] for t in targetset], matrix_normalized=False)
62      array([[ 1.,  6.,  5.,  0.],
63             [ 5.,  6.,  0.,  5.],
64             [ 6.,  0.,  6.,  6.]], dtype=float32)
@@ -130,11 +134,11 @@
65  | Edouard Michel | 6           | 0              | 6              | 6           |
66  +----------------+-------------+----------------+----------------+-------------+
67 
68  .. sourcecode:: python
69 
70 -    >>> from nazca.distances import temporal
71 +    >>> from nazca.utils.distances import temporal
72      >>> cdist(temporal, [a[1] for a in referenceset], [t[1] for t in targetset],
73      >>>       matrix_normalized=False)
74      array([[     0.,  40294.,   2702.,   7780.],
75             [  2702.,  42996.,      0.,   5078.],
76             [ 40294.,      0.,  42996.,  48074.]], dtype=float32)
@@ -233,10 +237,11 @@
77  This is told to python thanks to the following code:
78 
79  .. sourcecode:: python
80 
81     >>> import os.path as osp
82 +   >>> from nazca.utils.dataio import parsefile
83     >>> from nazca import examples
84     >>> filename = osp.join(osp.split(examples.__file__)[0], 'goncourt.csv')
85     >>> referenceset = parsefile(filename, delimiter='\t')
86 
87  So, the beginning of our `referenceset` is:
@@ -252,12 +257,12 @@
88  Now, let's build the `targetset` thanks to a *sparql query* and the dbpedia
89  end-point:
90 
91  .. sourcecode:: python
92 
93 -   >>> from nazca.dataio import sparqlquery
94 -   >>> query = """SELECT ?writer, ?name WHERE {
95 +   >>> from nazca.utils.dataio import sparqlquery
96 +   >>> query = """SELECT DISTINCT ?writer, ?name WHERE {
97     ?writer  <http://purl.org/dc/terms/subject> <http://dbpedia.org/resource/Category:French_novelists>.
98     ?writer rdfs:label ?name.
99     FILTER(lang(?name) = 'fr')
100     } """
101     >>> targetset = sparqlquery('http://dbpedia.org/sparql', query, autocaste_data=False)
@@ -268,33 +273,33 @@
102  Now, we have to define the distance function to be used for the alignment.
103  This is done thanks to a the `BaseProcessing` class::
104 
105  .. sourcecode:: python
106 
107 -   >>> from nazca.distances import BaseProcessing, levenshtein
108 +   >>> from nazca.utils.distances import BaseProcessing, levenshtein
109     >>> processing = BaseProcessing(ref_attr_index=1, target_attr_index=1, distance_callback=levenshtein)
110 
111  or (equivalent way)::
112 
113  .. sourcecode:: python
114 
115 -   >>> from nazca.distances import LevenshteinProcessing
116 +   >>> from nazca.utils.distances import LevenshteinProcessing
117     >>> processing = LevenshteinProcessing(ref_attr_index=1, target_attr_index=1)
118 
119  Now, we create an aligner (using the `BaseAligner` class):
120 
121  .. sourcecode:: python
122 
123 -   >>> from nazca.aligner import BaseAligner
124 +   >>> from nazca.rl.aligner import BaseAligner
125     >>> aligner = BaseAligner(threshold=0, processings=(processing,))
126 
127 
128  To limit the number of comparisons we may add a blocking technic:
129 
130  .. sourcecode:: python
131 
132 -   >>> from nazca.blocking import SortedNeighborhoodBlocking
133 +   >>> from nazca.rl.blocking import SortedNeighborhoodBlocking
134     >>> aligner.register_blocking(SortedNeighborhoodBlocking(1, 1, window_width=4))
135 
136 
137 
138  We have the aligned pairs using the `get_aligned_pairs` method of the `BaseAligner`:
@@ -313,11 +318,11 @@
139  be the :func:`simplify` function (see the docstring for more information).
140 
141  .. sourcecode:: python
142 
143 
144 -   >>> from nazca.normalize import SimplifyNormalizer
145 +   >>> from nazca.utils.normalize import SimplifyNormalizer
146     >>> aligner.register_ref_normalizer(SimplifyNormalizer(attr_index=1))
147 
148 
149 
150  Cities alignment
@@ -336,11 +341,11 @@
151 
152  This is done by the following python code:
153 
154  .. sourcecode:: python
155 
156 -   >>> from nazca.dataio import sparqlquery, rqlquery
157 +   >>> from nazca.utils.dataio import sparqlquery, rqlquery
158     >>> referenceset = sparqlquery('http://dbpedia.inria.fr/sparql',
159  		'prefix db-owl: <http://dbpedia.org/ontology/>'
160  		'prefix db-prop: <http://fr.dbpedia.org/property/>'
161                  'select ?ville, ?name, ?long, ?lat where {'
162                  ' ?ville db-owl:country <http://fr.dbpedia.org/resource/France> .'
@@ -357,17 +362,17 @@
163  		' N, X country C, C name "France", X longitude'
164  		' LONG, X latitude LAT, X population > 1000, X'
165  		' feature_class "P", X cwuri U',
166  		indexes=[0, 1, (2, 3)])
167 
168 -   >>> from nazca.distances import BaseProcessing, levenshtein
169 +   >>> from nazca.utils.distances import BaseProcessing, levenshtein
170     >>> processing = BaseProcessing(ref_attr_index=1, target_attr_index=1, distance_callback=levenshtein)
171 
172 -   >>> from nazca.aligner import BaseAligner
173 +   >>> from nazca.rl.aligner import BaseAligner
174     >>> aligner = BaseAligner(threshold=0, processings=(processing,))
175 
176 -   >>> from nazca.blocking import KdTreeBlocking
177 +   >>> from nazca.rl.blocking import KdTreeBlocking
178     >>> aligner.register_blocking(KdTreeBlocking(2, 2))
179 
180     >>> results = list(aligner.get_aligned_pairs(referenceset, targetset, unique=True))
181 
182 
@@ -408,5 +413,144 @@
183  Once done, by clicking the *Next step*, you start the alignment process. Wait a
184  little bit, and you can either download the results in a *csv* or *rdf* file, or
185  directly see the results online choosing the *html* output.
186 
187  .. [#] Your csv file must be tab-separated for the moment…
188 +
189 +
190 +
191 +Named Entities Recognition
192 +==========================
193 +
194 +Named Entities Recognition is the process of recognizing elements in a text and matching it
195 +to different types (e.g. Person, Organization, Place). In Nazca, we provide tools to match
196 +named entities to existing corpus/reference database.
197 +
198 +This is used for contextualizing your data, e.g. by recognizing in them elements from Dbpedia.
199 +
200 +
201 +
202 +
203 +Named entities sources
204 +~~~~~~~~~~~~~~~~~~~~
205 +
206 +Use of Sparql Source
207 +--------------------
208 +
209 +Simple NerSourceSparql on Dbpedia sparql endpoint::
210 +
211 +   .. sourcecode:: python
212 +
213 +   >>> from nazca.ner.sources import NerSourceSparql
214 +   >>> ner_source = NerSourceSparql('http://dbpedia.org/sparql',
215 +                                    '''SELECT distinct ?uri
216 +                                    WHERE{
217 +                                    ?uri rdfs:label "%(word)s"@en}''')
218 +   >>> print ner_source.query_word('Victor Hugo')
219 +   ...     ['http://dbpedia.org/resource/Category:Victor_Hugo',
220 +	    'http://dbpedia.org/resource/Victor_Hugo',
221 +	    'http://dbpedia.org/class/yago/VictorHugo',
222 +	    'http://dbpedia.org/class/yago/VictorHugo(ParisM%C3%A9tro)',
223 +	    'http://sw.opencyc.org/2008/06/10/concept/en/VictorHugo',
224 +	    'http://sw.opencyc.org/2008/06/10/concept/Mx4rve1ZXJwpEbGdrcN5Y29ycA']
225 +
226 +
227 +With restriction in the SPARQL query::
228 +
229 +   .. sourcecode:: python
230 +
231 +   >>> from nazca.ner.sources import NerSourceSparql
232 +   >>> ner_source = NerSourceSparql('http://dbpedia.org/sparql',
233 +                                    '''SELECT distinct ?uri
234 +                                    WHERE{
235 +                                    ?uri rdfs:label "%(word)s"@en .
236 +                                    ?p foaf:primaryTopic ?uri}''')
237 +   >>> print ner_source.query_word('Victor Hugo')
238 +   ...    ['http://dbpedia.org/resource/Victor_Hugo']
239 +
240 +
241 +
242 +NerSourceRql
243 +------------
244 +
245 +Simple NerSourceRql on a Rql endpoint::
246 +
247 +   .. sourcecode:: python
248 +
249 +   >>> from nazca.ner.sources import NerSourceRql
250 +   >>> ner_source = NerSourceRql('http://www.cubicweb.org',
251 +                                 'Any U WHERE X cwuri U, X name "%(word)s"')
252 +   >>> print ner_source.query_word('apycot')
253 +   ...     [u'http://www.cubicweb.org/1310453', u'http://www.cubicweb.org/749162']
254 +
255 +
256 +
257 +Examples of full Ner process
258 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~
259 +
260 +
261 +1 - Define some text
262 +--------------------
263 +
264 +For example, this text comes from Dbpedia (http://dbpedia.org/page/Victor_Hugo)::
265 +
266 +    .. sourcecode:: python
267 +
268 +   >>> text = u"""Victor Hugo, né le 26 février 1802 à Besançon et mort le 22 mai 1885 à Paris, est un poète, dramaturge et prosateur romantique considéré comme l'un des plus importants écrivains de langue française. Il est aussi une personnalité politique et un intellectuel engagé qui a compté dans l'Histoire du XIX siècle. Victor Hugo occupe une place marquante dans l'histoire des lettres françaises au XIX siècle, dans des genres et des domaines d'une remarquable variété. Il est poète lyrique avec des recueils comme Odes et Ballades (1826), Les Feuilles d'automne (1831) ou Les Contemplations (1856), mais il est aussi poète engagé contre Napoléon III dans Les Châtiments (1853) ou encore poète épique avec La Légende des siècles (1859 et 1877). Il est également un romancier du peuple qui rencontre un grand succès populaire avec par exemple Notre-Dame de Paris (1831), et plus encore avec Les Misérables (1862). Au théâtre, il expose sa théorie du drame romantique dans sa préface de Cromwell en 1827 et l'illustre principalement avec Hernani en 1830 et Ruy Blas en 1838. Son œuvre multiple comprend aussi des discours politiques à la Chambre des pairs, à l'Assemblée constituante et à l'Assemblée législative, notamment sur la peine de mort, l'école ou l'Europe, des récits de voyages (Le Rhin, 1842, ou Choses vues, posthumes, 1887 et 1890), et une correspondance abondante. Victor Hugo a fortement contribué au renouvellement de la poésie et du théâtre ; il a été admiré par ses contemporains et l'est encore, mais il a été aussi contesté par certains auteurs modernes. Il a aussi permis à de nombreuses générations de développer une réflexion sur l'engagement de l'écrivain dans la vie politique et sociale grâce à ses multiples prises de position qui le condamneront à l'exil pendant les vingt ans du Second Empire. Ses choix, à la fois moraux et politiques, durant la deuxième partie de sa vie, et son œuvre hors du commun ont fait de lui un personnage emblématique que la Troisième République a honoré à sa mort le 22 mai 1885 par des funérailles nationales qui ont accompagné le transfert de sa dépouille au Panthéon de Paris, le 31 mai 1885."""
269 +
270 +
271 +2 - Define a source
272 +-------------------
273 +
274 +Now, define a source for the Named Entities::
275 +
276 +    .. sourcecode:: python
277 +
278 +    >>> from nazca.ner.sources import NerSourceSparql
279 +    >>> dbpedia_sparql_source = NerSourceSparql('http://dbpedia.org/sparql',
280 +                                                '''SELECT distinct ?uri
281 +                                                   WHERE{
282 + 						   ?uri rdfs:label "%(word)s"@en .
283 + 						   ?p foaf:primaryTopic ?uri}''',
284 + 						   'http://dbpedia.org/sparql',
285 + 						use_cache=True)
286 +    >>> ner_sources = [dbpedia_sparql_source,]
287 +
288 +
289 +3 - Define some preprocessors
290 +-----------------------------
291 +
292 +Define some preprocessors that will cleanup the words before matching::
293 +
294 +    .. sourcecode:: python
295 +
296 +    >>> from nazca.ner.preprocessors import (NerLowerCaseFilterPreprocessor,
297 +                                             NerStopwordsFilterPreprocessor)
298 +    >>> preprocessors = [NerLowerCaseFilterPreprocessor(),
299 +        	         NerStopwordsFilterPreprocessor()]
300 +
301 +
302 +4 - Define the Ner process
303 +----------------------------
304 +
305 +Define the process and process the text::
306 +
307 +    .. sourcecode:: python
308 +
309 +    >>> from nazca.ner import NerProcess
310 +    >>> process = NerProcess(ner_sources, preprocessors=preprocessors)
311 +    >>> named_entities = process.process_text(text)
312 +    >>> print named_entities
313 +
314 +
315 +5 - Pretty priint the output
316 +----------------------------
317 +
318 +And finally, we can print the output as HTML with links::
319 +
320 +    .. sourcecode:: python
321 +
322 +    >>> from nazca.utils.dataio import HTMLPrettyPrint
323 +    >>> html = HTMLPrettyPrint().pprint_text(text, named_entities)
324 +    >>> print html
325 +
326 +
diff --git a/ner/doc.rst b/ner/doc.rst
@@ -1,123 +0,0 @@
327 -=====================================================
328 - NERDY - A Named Entities Recognition python Library
329 -=====================================================
330 -
331 -Examples of NerdySource
332 -=======================
333 -
334 -
335 -NerdySourceSparql
336 ------------------
337 -
338 -Simple NerdySourceSparql on Dbpedia sparql endpoint::
339 -
340 -   .. sourcecode:: python
341 -
342 -   >>> from nerdy.core import NerdySourceSparql
343 -   >>> ner_source = NerdySourceSparql('''SELECT distinct ?uri
344 -                                         WHERE{
345 -                                         ?uri rdfs:label "%(word)s"@en}''',
346 -			                 'http://dbpedia.org/sparql')
347 -   >>> print ner_source.query_word('Victor Hugo')
348 -   ...     ['http://dbpedia.org/resource/Category:Victor_Hugo',
349 -	    'http://dbpedia.org/resource/Victor_Hugo',
350 -	    'http://dbpedia.org/class/yago/VictorHugo',
351 -	    'http://dbpedia.org/class/yago/VictorHugo(ParisM%C3%A9tro)',
352 -	    'http://sw.opencyc.org/2008/06/10/concept/en/VictorHugo',
353 -	    'http://sw.opencyc.org/2008/06/10/concept/Mx4rve1ZXJwpEbGdrcN5Y29ycA']
354 -
355 -
356 -With restriction in the SPARQL query::
357 -
358 -   .. sourcecode:: python
359 -
360 -   >>> from nerdy.core import NerdySourceSparql
361 -   >>> ner_source = NerdySourceSparql('''SELECT distinct ?uri
362 -                                         WHERE{
363 -                                         ?uri rdfs:label "%(word)s"@en .
364 -                                         ?p foaf:primaryTopic ?uri}''',
365 -			                 'http://dbpedia.org/sparql')
366 -   >>> print ner_source.query_word('Victor Hugo')
367 -   ...    ['http://dbpedia.org/resource/Victor_Hugo']
368 -
369 -
370 -
371 -NerdySourceUrlRql
372 ------------------
373 -
374 -Simple NerdySourceUrlRql on a Rql endpoint::
375 -
376 -   .. sourcecode:: python
377 -
378 -   >>> from nerdy.core import NerdySourceUrlRql
379 -   >>> ner_source = NerdySourceUrlRql('Any U WHERE X cwuri U, X name "%(word)s"',
380 -		                        'http://www.cubicweb.org')
381 -   >>> print ner_source.query_word('apycot')
382 -   ...     [u'http://www.cubicweb.org/1310453', u'http://www.cubicweb.org/749162']
383 -
384 -
385 -
386 -Examples of full Nerdy process
387 -==============================
388 -
389 -
390 -1 - Define some text
391 ---------------------
392 -
393 -For example, this text comes from Dbpedia (http://dbpedia.org/page/Victor_Hugo)::
394 -
395 -    .. sourcecode:: python
396 -
397 -   >>> from nerdy import core, dataio
398 -
399 -   >>> text = u"""Victor Hugo, né le 26 février 1802 à Besançon et mort le 22 mai 1885 à Paris, est un poète, dramaturge et prosateur romantique considéré comme l'un des plus importants écrivains de langue française. Il est aussi une personnalité politique et un intellectuel engagé qui a compté dans l'Histoire du XIX siècle. Victor Hugo occupe une place marquante dans l'histoire des lettres françaises au XIX siècle, dans des genres et des domaines d'une remarquable variété. Il est poète lyrique avec des recueils comme Odes et Ballades (1826), Les Feuilles d'automne (1831) ou Les Contemplations (1856), mais il est aussi poète engagé contre Napoléon III dans Les Châtiments (1853) ou encore poète épique avec La Légende des siècles (1859 et 1877). Il est également un romancier du peuple qui rencontre un grand succès populaire avec par exemple Notre-Dame de Paris (1831), et plus encore avec Les Misérables (1862). Au théâtre, il expose sa théorie du drame romantique dans sa préface de Cromwell en 1827 et l'illustre principalement avec Hernani en 1830 et Ruy Blas en 1838. Son œuvre multiple comprend aussi des discours politiques à la Chambre des pairs, à l'Assemblée constituante et à l'Assemblée législative, notamment sur la peine de mort, l'école ou l'Europe, des récits de voyages (Le Rhin, 1842, ou Choses vues, posthumes, 1887 et 1890), et une correspondance abondante. Victor Hugo a fortement contribué au renouvellement de la poésie et du théâtre ; il a été admiré par ses contemporains et l'est encore, mais il a été aussi contesté par certains auteurs modernes. Il a aussi permis à de nombreuses générations de développer une réflexion sur l'engagement de l'écrivain dans la vie politique et sociale grâce à ses multiples prises de position qui le condamneront à l'exil pendant les vingt ans du Second Empire. Ses choix, à la fois moraux et politiques, durant la deuxième partie de sa vie, et son œuvre hors du commun ont fait de lui un personnage emblématique que la Troisième République a honoré à sa mort le 22 mai 1885 par des funérailles nationales qui ont accompagné le transfert de sa dépouille au Panthéon de Paris, le 31 mai 1885."""
400 -
401 -
402 -2 - Define a source
403 --------------------
404 -
405 -Now, define a source for the Named Entities::
406 -
407 -    .. sourcecode:: python
408 -
409 -    >>> dbpedia_sparql_source = core.NerdySourceSparql('''SELECT distinct ?uri
410 -             		       				 WHERE{
411 - 							 ?uri rdfs:label "%(word)s"@en .
412 - 							 ?p foaf:primaryTopic ?uri}''',
413 - 							 'http://dbpedia.org/sparql',
414 - 							 use_cache=True)
415 -    >>> nerdy_sources = [dbpedia_sparql_source,]
416 -
417 -
418 -3 - Define some preprocessors
419 ------------------------------
420 -
421 -Define some preprocessors that will cleanup the words before matching::
422 -
423 -    .. sourcecode:: python
424 -
425 -    >>> preprocessors = [core.NerdyLowerCaseFilterPreprocessor(),
426 -        	         core.NerdyStopwordsFilterPreprocessor()]
427 -
428 -
429 -4 - Define the Nerdy process
430 -----------------------------
431 -
432 -Define the process and process the text::
433 -
434 -    .. sourcecode:: python
435 -
436 -    >>> nerdy = core.NerdyProcess(nerdy_sources, preprocessors=preprocessors)
437 -    >>> named_entities = nerdy.process_text(text)
438 -    >>> print named_entities
439 -
440 -
441 -5 - Pretty priint the output
442 -----------------------------
443 -
444 -And finally, we can print the output as HTML with links::
445 -
446 -    .. sourcecode:: python
447 -
448 -    >>> html = dataio.NerdyHTMLPrettyPrint().pprint_text(text, named_entities)
449 -    >>> print html