pyests 0.1.0__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: pyests
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Spanish Texts Statistics
5
5
  Project-URL: Homepage, https://github.com/SergeyShk/esTS
6
6
  Project-URL: Repository, https://github.com/SergeyShk/esTS
@@ -34,8 +34,16 @@ Requires-Dist: simplemma>=1.0
34
34
  Requires-Dist: spacy>=3.7
35
35
  Description-Content-Type: text/markdown
36
36
 
37
+ <p align="center">
38
+ <img src="https://raw.githubusercontent.com/SergeyShk/esTS/master/docs/img/ests.png" alt="esTS" width="340">
39
+ </p>
40
+
37
41
  <h1 align="center">esTS</h1>
38
42
 
43
+ <p align="center">
44
+ <i>¿Cómo esTáS, texto?</i>
45
+ </p>
46
+
39
47
  <p align="center">
40
48
  <b>Spanish Texts Statistics</b> - a library for statistics extraction from texts in Spanish
41
49
  </p>
@@ -56,17 +64,21 @@ Description-Content-Type: text/markdown
56
64
 
57
65
  ---
58
66
 
59
- **esTS** computes for Spanish texts what usually requires assembling several separate tools: basic statistics, readability and lexical diversity - by published formulas with the coefficients and the scales of their authors, deterministically and without a neural network inside.
67
+ **esTS** computes for Spanish texts what usually requires assembling several separate tools: basic statistics, readability, lexical diversity, morphology, syntax and cohesion - by published formulas with the coefficients and the scales of their authors, and by the parts of speech and the features of Universal Dependencies.
60
68
 
61
- The library works both with raw strings and with `Doc` objects of [spaCy](https://github.com/explosion/spaCy), and needs no trained model: sentences, words and character N-grams are extracted by rules, syllables and stress follow from the orthography.
69
+ The library works both with raw strings and with `Doc` objects of [spaCy](https://github.com/explosion/spaCy): sentences, words and character N-grams are extracted by rules, syllables and stress follow from the orthography, and only the morphological, the syntactic and the cohesion statistics need a trained model.
62
70
 
63
71
  * **[Object extraction](https://sergeyshk.github.io/esTS/extractors/sentences/)** - configurable sentence, word and character N-gram tokenizers that know the inverted marks, the dialogue dash and the abbreviations of Spanish
64
72
  * **[Syllables and stress](https://sergeyshk.github.io/esTS/syllables/)** - rule-based syllabification and the stressed syllable derived from the spelling, with no dictionary
65
73
  * **[Basic statistics](https://sergeyshk.github.io/esTS/stats/basic_stats/)** - counts of sentences, words, letters, syllables and punctuation marks by type, with distributions and normalized shares
66
74
  * **[Readability metrics](https://sergeyshk.github.io/esTS/stats/readability_stats/)** - Fernández Huerta, Szigriszt-Pazos with the INFLESZ scale, Gutiérrez de Polini, Crawford, Legibilidad µ, SOL, LIX and RIX, with a consensus grade, the school stages of Spain and reading time
67
75
  * **[Lexical diversity metrics](https://sergeyshk.github.io/esTS/stats/diversity_stats/)** - TTR and its variations, MATTR, MSTTR, MTLD, HD-D, Simpson's and Yule's indices, entropy, Zipf's and Heaps' laws
76
+ * **[Morphological statistics](https://sergeyshk.github.io/esTS/stats/morph_stats/)** - parts of speech and fifteen grammatical features of Universal Dependencies, with the markers of Spanish: the moods, the non-finite forms, `ser` against `estar`, the adverbs in `-mente`
77
+ * **[spaCy components](https://sergeyshk.github.io/esTS/components/)** - every statistics class as a component of a pipeline, the statistics attached to the `Doc` in one pass
78
+ * **[Cohesion statistics](https://sergeyshk.github.io/esTS/stats/cohesion_stats/)** - the overlap of nouns, arguments and content words between sentences, givenness and temporal cohesion in the manner of Coh-Metrix, with the density of 255 Spanish discourse markers
79
+ * **[Syntactic statistics](https://sergeyshk.github.io/esTS/stats/syntax_stats/)** - the dependency tree by distances, depth, clauses and coordination, with the constructions of the administrative style: the passive with `ser` and with `se`, the participial and the gerund clauses, the chains of `de`, the split predicates
68
80
 
69
- Morphology, syntax and cohesion on Universal Dependencies come in 0.2, corpus measures and stylometry in 0.3, style, phonostatistics, metre and rhyme in 0.4.
81
+ Corpus measures and stylometry come in 0.3, style, phonostatistics, metre and rhyme in 0.4.
70
82
 
71
83
  ## Installation
72
84
 
@@ -82,7 +94,7 @@ Or with [uv](https://docs.astral.sh/uv/):
82
94
  uv add pyests
83
95
  ```
84
96
 
85
- The distribution on PyPI is `pyests`, the package it installs is `ests`. No spaCy model is needed for the statistics of 0.1; one is needed only to parse a text yourself and pass the `Doc` instead of a string:
97
+ The distribution on PyPI is `pyests`, the package it installs is `ests`. The basic statistics, the readability and the lexical diversity metrics need no spaCy model; the morphological, the syntactic and the cohesion statistics do, and so does parsing a text yourself to pass the `Doc` instead of a string:
86
98
 
87
99
  ```bash
88
100
  python -m spacy download es_core_news_sm
@@ -325,6 +337,144 @@ More in the [documentation](https://sergeyshk.github.io/esTS/stats/diversity_sta
325
337
 
326
338
  </details>
327
339
 
340
+ <details>
341
+ <summary><b>Morphological statistics</b></summary>
342
+
343
+ <br>
344
+
345
+ The library annotates a text with the parts of speech and the grammatical features of Universal Dependencies, as the Spanish models of spaCy give them, and counts them:
346
+
347
+ * the part of speech and fifteen features: case, definiteness, degree, gender, mood, numeral type, number, person, polarity, politeness, possessive, pronoun type, reflexive, tense and verb form
348
+ * the distribution of the words by the values of any feature, and the parse of the text word by word
349
+ * the markers of Spanish: the moods among the finite forms, the non-finite forms, `ser` against `estar`, the adverbs in `-mente`
350
+
351
+ ```python
352
+ >>> from ests import MorphStats
353
+
354
+ >>> ms = MorphStats("Si tuviera tiempo, leería el libro que me recomendaste ayer")
355
+
356
+ >>> ms.get_stats("mood", "tense", filter_none=True)
357
+ {'mood': {'Sub': 1, 'Cnd': 1, 'Ind': 1}, 'tense': {'Imp': 1, 'Pres': 1}}
358
+
359
+ >>> ms.tags[1]
360
+ 'Mood=Sub|Number=Sing|Person=3|Tense=Imp|VerbForm=Fin'
361
+
362
+ >>> ms.explain_text("pos", "mood", filter_none=True)[1]
363
+ ('tuviera', {'pos': 'VERB', 'mood': 'Sub'})
364
+
365
+ >>> MorphStats("Ella es alta pero hoy está cansada y habla lentamente").get_markers()["p_ser"]
366
+ 0.5
367
+ ```
368
+
369
+ The statistics need a spaCy model: a text is parsed with `es_core_news_sm`, and any other pipeline can be passed in `nlp`.
370
+
371
+ More in the [documentation](https://sergeyshk.github.io/esTS/stats/morph_stats/).
372
+
373
+ </details>
374
+
375
+ <details>
376
+ <summary><b>Syntactic statistics</b></summary>
377
+
378
+ <br>
379
+
380
+ The library measures the dependency tree of Universal Dependencies and the constructions that the Spanish guides to clear language warn about:
381
+
382
+ * the complexity of the tree: dependency distances, depth, leaves and subtrees, valency of the finite verbs, coordination chains, clauses and subordinate clauses, modifiers per noun
383
+ * the constructions: the passive with `ser` and with `se`, the participial and the gerund clauses, the chains of `de`, the split predicates, the impersonal `se`, the words of negation, the ratio of nouns to verbs
384
+
385
+ ```python
386
+ >>> from ests import SyntaxStats
387
+
388
+ >>> text = ("La revisión de las cuentas fue realizada por el comité. "
389
+ ... "Se llevó a cabo la reforma sin que nadie hiciera mención de los problemas.")
390
+ >>> ss = SyntaxStats(text)
391
+
392
+ >>> ss.n_sents, ss.n_words
393
+ (2, 24)
394
+
395
+ >>> ss.p_passive, ss.noun_verb_ratio
396
+ (0.6666666666666666, 2.3333333333333335)
397
+
398
+ >>> ss.split_predicates
399
+ ('llevó cabo', 'hiciera mención')
400
+
401
+ >>> round(ss.mean_dependency_distance, 2)
402
+ 2.05
403
+ ```
404
+
405
+ The statistics need a parse: a text is parsed with `es_core_news_sm`, and any other pipeline can be passed in `nlp`.
406
+
407
+ More in the [documentation](https://sergeyshk.github.io/esTS/stats/syntax_stats/).
408
+
409
+ </details>
410
+
411
+ <details>
412
+ <summary><b>Cohesion statistics</b></summary>
413
+
414
+ <br>
415
+
416
+ The library measures referential cohesion in the manner of Coh-Metrix and of its Spanish adaptation Coh-Metrix-Esp:
417
+
418
+ * the overlap of nouns, of arguments and of content words between adjacent sentences and between all pairs of sentences, binary and proportional
419
+ * givenness: pronouns, demonstratives and the content words whose lemma was already used
420
+ * temporal cohesion: the repetition of the tense and of the mood of the verbs of adjacent sentences
421
+ * the density of 255 Spanish discourse markers by class - causal, adversative, concessive, temporal, additive, conditional, reformulative - and by kind
422
+
423
+ ```python
424
+ >>> from ests import CohesionStats
425
+
426
+ >>> text = ("El informe fue aprobado por la comisión. Sin embargo, el informe no resuelve el problema. "
427
+ ... "Por lo tanto, la comisión aplazó la decisión.")
428
+ >>> cs = CohesionStats(text)
429
+
430
+ >>> cs.n_sents, cs.n_words
431
+ (3, 23)
432
+
433
+ >>> cs.noun_overlap_adjacent, round(cs.p_given, 3)
434
+ (0.5, 0.167)
435
+
436
+ >>> cs.c_connectors
437
+ {'por lo tanto': 1, 'sin embargo': 1}
438
+
439
+ >>> round(cs.connectors, 2), round(cs.connectors_causal, 2)
440
+ (86.96, 43.48)
441
+ ```
442
+
443
+ The statistics need the annotation: a text is parsed with `es_core_news_sm`, and any other pipeline can be passed in `nlp`.
444
+
445
+ More in the [documentation](https://sergeyshk.github.io/esTS/stats/cohesion_stats/).
446
+
447
+ </details>
448
+
449
+ <details>
450
+ <summary><b>spaCy components</b></summary>
451
+
452
+ <br>
453
+
454
+ Every statistics class is also a component of a pipeline, so a text is annotated and measured in one pass and the statistics travel with the `Doc`:
455
+
456
+ ```python
457
+ >>> import ests
458
+ >>> import spacy
459
+
460
+ >>> nlp = spacy.load("es_core_news_sm")
461
+ >>> for factory in ("basic", "morph", "syntax"):
462
+ ... _ = nlp.add_pipe(f"ests_{factory}", name=factory, last=True)
463
+
464
+ >>> nlp.pipe_names[-3:]
465
+ ['basic', 'morph', 'syntax']
466
+
467
+ >>> doc = nlp("El gato duerme en la ventana. Los niños juegan en el parque.")
468
+ >>> doc._.basic.n_words, doc._.morph.pos[:2], doc._.syntax.tree_depth
469
+ (12, ('DET', 'NOUN'), 2.0)
470
+ ```
471
+
472
+ The factories are `ests_basic`, `ests_readability`, `ests_diversity`, `ests_morph`, `ests_syntax` and `ests_cohesion`; the name of the pipe is free and is what the extension is called.
473
+
474
+ More in the [documentation](https://sergeyshk.github.io/esTS/components/).
475
+
476
+ </details>
477
+
328
478
  ## Development
329
479
 
330
480
  The project uses [uv](https://docs.astral.sh/uv/) for dependency management and [ruff](https://docs.astral.sh/ruff/) for linting and formatting.
@@ -362,11 +512,15 @@ Bug reports, ideas and pull requests are welcome - [issues](https://github.com/S
362
512
  * **docs** - project documentation
363
513
  * **ests**:
364
514
  * basic_stats.py - basic text statistics
515
+ * cohesion_stats.py - cohesion statistics
516
+ * components.py - components of a spaCy pipeline
365
517
  * constants.py - constants of the Spanish language and of the metrics
366
518
  * diversity_stats.py - lexical diversity metrics
367
519
  * exceptions.py - library exceptions
368
520
  * extractors.py - tools for object extraction from a text
521
+ * morph_stats.py - morphological statistics
369
522
  * readability_stats.py - readability metrics
523
+ * syntax_stats.py - syntactic statistics
370
524
  * syllables.py - syllabification and stress
371
525
  * utils.py - helper tools
372
526
  * **tests** - tests mirroring the package structure
@@ -1,5 +1,13 @@
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/SergeyShk/esTS/master/docs/img/ests.png" alt="esTS" width="340">
3
+ </p>
4
+
1
5
  <h1 align="center">esTS</h1>
2
6
 
7
+ <p align="center">
8
+ <i>¿Cómo esTáS, texto?</i>
9
+ </p>
10
+
3
11
  <p align="center">
4
12
  <b>Spanish Texts Statistics</b> - biblioteca para extraer estadísticas de textos en español
5
13
  </p>
@@ -20,17 +28,21 @@
20
28
 
21
29
  ---
22
30
 
23
- **esTS** calcula para textos en español lo que normalmente exige juntar varias herramientas sueltas: estadísticas básicas, legibilidad y diversidad léxica, con fórmulas publicadas y con los coeficientes y las escalas de sus autores, de forma determinista y sin ninguna red neuronal dentro.
31
+ **esTS** calcula para textos en español lo que normalmente exige juntar varias herramientas sueltas: estadísticas básicas, legibilidad, diversidad léxica, morfología, sintaxis y cohesión, con fórmulas publicadas y con los coeficientes y las escalas de sus autores, y con las categorías y los rasgos de Universal Dependencies.
24
32
 
25
- La biblioteca trabaja tanto con cadenas como con objetos `Doc` de [spaCy](https://github.com/explosion/spaCy) y no necesita ningún modelo entrenado: las oraciones, las palabras y los N-gramas de caracteres se extraen por reglas, y las sílabas y el acento se deducen de la ortografía.
33
+ La biblioteca trabaja tanto con cadenas como con objetos `Doc` de [spaCy](https://github.com/explosion/spaCy): las oraciones, las palabras y los N-gramas de caracteres se extraen por reglas, las sílabas y el acento se deducen de la ortografía, y solo las estadísticas morfológicas, las sintácticas y las de cohesión necesitan un modelo entrenado.
26
34
 
27
35
  * **[Extracción de objetos](https://sergeyshk.github.io/esTS/es/extractors/sentences/)** - tokenizadores configurables de oraciones, palabras y N-gramas de caracteres que conocen los signos de apertura, la raya de diálogo y las abreviaturas del español
28
36
  * **[Sílabas y acento](https://sergeyshk.github.io/esTS/es/syllables/)** - silabificación por reglas y sílaba tónica deducida de la escritura, sin diccionario
29
37
  * **[Estadísticas básicas](https://sergeyshk.github.io/esTS/es/stats/basic_stats/)** - recuentos de oraciones, palabras, letras, sílabas y signos de puntuación por tipo, con distribuciones y proporciones normalizadas
30
38
  * **[Métricas de legibilidad](https://sergeyshk.github.io/esTS/es/stats/readability_stats/)** - Fernández Huerta, Szigriszt-Pazos con la escala INFLESZ, Gutiérrez de Polini, Crawford, Legibilidad µ, SOL, LIX y RIX, con grado de consenso, etapas escolares de España y tiempo de lectura
31
39
  * **[Métricas de diversidad léxica](https://sergeyshk.github.io/esTS/es/stats/diversity_stats/)** - TTR y sus variantes, MATTR, MSTTR, MTLD, HD-D, índices de Simpson y de Yule, entropía, leyes de Zipf y de Heaps
40
+ * **[Estadísticas morfológicas](https://sergeyshk.github.io/esTS/es/stats/morph_stats/)** - categorías gramaticales y quince rasgos morfológicos de Universal Dependencies, con los marcadores del español: los modos, las formas no personales, `ser` frente a `estar`, los adverbios en `-mente`
41
+ * **[Componentes de spaCy](https://sergeyshk.github.io/esTS/es/components/)** - cada clase de estadísticas como componente de un pipeline, con las estadísticas puestas en el `Doc` en una sola pasada
42
+ * **[Estadísticas de cohesión](https://sergeyshk.github.io/esTS/es/stats/cohesion_stats/)** - la repetición de sustantivos, argumentos y palabras con contenido entre oraciones, la información dada y la cohesión temporal a la manera de Coh-Metrix, con la densidad de 255 marcadores del discurso españoles
43
+ * **[Estadísticas sintácticas](https://sergeyshk.github.io/esTS/es/stats/syntax_stats/)** - el árbol de dependencias por distancias, profundidad, cláusulas y coordinación, con las construcciones del estilo administrativo: la pasiva con `ser` y con `se`, las cláusulas de participio y de gerundio, las cadenas de `de`, los predicados escindidos
32
44
 
33
- La morfología, la sintaxis y la cohesión sobre Universal Dependencies llegan en la 0.2, las medidas de corpus y la estilometría en la 0.3, el estilo, la fonoestadística, la métrica y la rima en la 0.4.
45
+ Las medidas de corpus y la estilometría llegan en la 0.3, el estilo, la fonoestadística, la métrica y la rima en la 0.4.
34
46
 
35
47
  ## Instalación
36
48
 
@@ -46,7 +58,7 @@ O con [uv](https://docs.astral.sh/uv/):
46
58
  uv add pyests
47
59
  ```
48
60
 
49
- El distribuible en PyPI se llama `pyests` y el paquete que instala es `ests`. Las estadísticas de la 0.1 no necesitan ningún modelo de spaCy; solo hace falta para analizar un texto por su cuenta y pasar el `Doc` en lugar de una cadena:
61
+ El distribuible en PyPI se llama `pyests` y el paquete que instala es `ests`. Las estadísticas básicas, la legibilidad y la diversidad léxica no necesitan ningún modelo de spaCy; las estadísticas morfológicas, las sintácticas y las de cohesión sí, igual que analizar un texto por su cuenta para pasar el `Doc` en lugar de una cadena:
50
62
 
51
63
  ```bash
52
64
  python -m spacy download es_core_news_sm
@@ -289,6 +301,144 @@ Más en la [documentación](https://sergeyshk.github.io/esTS/es/stats/diversity_
289
301
 
290
302
  </details>
291
303
 
304
+ <details>
305
+ <summary><b>Estadísticas morfológicas</b></summary>
306
+
307
+ <br>
308
+
309
+ La biblioteca anota el texto con las categorías gramaticales y los rasgos morfológicos de Universal Dependencies, tal como los dan los modelos españoles de spaCy, y los cuenta:
310
+
311
+ * la categoría gramatical y quince rasgos: caso, definitud, grado, género, modo, tipo de numeral, número, persona, polaridad, cortesía, posesivo, tipo de pronombre, reflexivo, tiempo verbal y forma verbal
312
+ * la distribución de las palabras por los valores de cualquier rasgo y el análisis del texto palabra por palabra
313
+ * los marcadores del español: los modos entre las formas personales, las formas no personales, `ser` frente a `estar`, los adverbios en `-mente`
314
+
315
+ ```python
316
+ >>> from ests import MorphStats
317
+
318
+ >>> ms = MorphStats("Si tuviera tiempo, leería el libro que me recomendaste ayer")
319
+
320
+ >>> ms.get_stats("mood", "tense", filter_none=True)
321
+ {'mood': {'Sub': 1, 'Cnd': 1, 'Ind': 1}, 'tense': {'Imp': 1, 'Pres': 1}}
322
+
323
+ >>> ms.tags[1]
324
+ 'Mood=Sub|Number=Sing|Person=3|Tense=Imp|VerbForm=Fin'
325
+
326
+ >>> ms.explain_text("pos", "mood", filter_none=True)[1]
327
+ ('tuviera', {'pos': 'VERB', 'mood': 'Sub'})
328
+
329
+ >>> MorphStats("Ella es alta pero hoy está cansada y habla lentamente").get_markers()["p_ser"]
330
+ 0.5
331
+ ```
332
+
333
+ Las estadísticas necesitan un modelo de spaCy: el texto se analiza con `es_core_news_sm`, y en `nlp` puede indicarse cualquier otro pipeline.
334
+
335
+ Más en la [documentación](https://sergeyshk.github.io/esTS/es/stats/morph_stats/).
336
+
337
+ </details>
338
+
339
+ <details>
340
+ <summary><b>Estadísticas sintácticas</b></summary>
341
+
342
+ <br>
343
+
344
+ La biblioteca mide el árbol de dependencias de Universal Dependencies y las construcciones que advierten las guías españolas de lenguaje claro:
345
+
346
+ * la complejidad del árbol: distancias de dependencia, profundidad, hojas y subárboles, valencia de los verbos personales, cadenas de coordinación, cláusulas y subordinadas, modificadores por sustantivo
347
+ * las construcciones: la pasiva con `ser` y con `se`, las cláusulas de participio y de gerundio, las cadenas de `de`, los predicados escindidos, el `se` impersonal, las palabras de negación, la razón entre sustantivos y verbos
348
+
349
+ ```python
350
+ >>> from ests import SyntaxStats
351
+
352
+ >>> text = ("La revisión de las cuentas fue realizada por el comité. "
353
+ ... "Se llevó a cabo la reforma sin que nadie hiciera mención de los problemas.")
354
+ >>> ss = SyntaxStats(text)
355
+
356
+ >>> ss.n_sents, ss.n_words
357
+ (2, 24)
358
+
359
+ >>> ss.p_passive, ss.noun_verb_ratio
360
+ (0.6666666666666666, 2.3333333333333335)
361
+
362
+ >>> ss.split_predicates
363
+ ('llevó cabo', 'hiciera mención')
364
+
365
+ >>> round(ss.mean_dependency_distance, 2)
366
+ 2.05
367
+ ```
368
+
369
+ Las estadísticas necesitan el análisis sintáctico: el texto se analiza con `es_core_news_sm`, y en `nlp` puede indicarse cualquier otro pipeline.
370
+
371
+ Más en la [documentación](https://sergeyshk.github.io/esTS/es/stats/syntax_stats/).
372
+
373
+ </details>
374
+
375
+ <details>
376
+ <summary><b>Estadísticas de cohesión</b></summary>
377
+
378
+ <br>
379
+
380
+ La biblioteca mide la cohesión referencial a la manera de Coh-Metrix y de su adaptación española Coh-Metrix-Esp:
381
+
382
+ * la repetición de sustantivos, de argumentos y de palabras con contenido entre oraciones contiguas y entre todos los pares de oraciones, binaria y proporcional
383
+ * la información dada: pronombres, demostrativos y palabras con contenido cuyo lema ya se había usado
384
+ * la cohesión temporal: la repetición del tiempo y del modo de los verbos de oraciones contiguas
385
+ * la densidad de 255 marcadores del discurso españoles por clase - causales, adversativos, concesivos, temporales, aditivos, condicionales, reformulativos - y por tipo
386
+
387
+ ```python
388
+ >>> from ests import CohesionStats
389
+
390
+ >>> text = ("El informe fue aprobado por la comisión. Sin embargo, el informe no resuelve el problema. "
391
+ ... "Por lo tanto, la comisión aplazó la decisión.")
392
+ >>> cs = CohesionStats(text)
393
+
394
+ >>> cs.n_sents, cs.n_words
395
+ (3, 23)
396
+
397
+ >>> cs.noun_overlap_adjacent, round(cs.p_given, 3)
398
+ (0.5, 0.167)
399
+
400
+ >>> cs.c_connectors
401
+ {'por lo tanto': 1, 'sin embargo': 1}
402
+
403
+ >>> round(cs.connectors, 2), round(cs.connectors_causal, 2)
404
+ (86.96, 43.48)
405
+ ```
406
+
407
+ Las estadísticas necesitan la anotación: el texto se analiza con `es_core_news_sm`, y en `nlp` puede indicarse cualquier otro pipeline.
408
+
409
+ Más en la [documentación](https://sergeyshk.github.io/esTS/es/stats/cohesion_stats/).
410
+
411
+ </details>
412
+
413
+ <details>
414
+ <summary><b>Componentes de spaCy</b></summary>
415
+
416
+ <br>
417
+
418
+ Cada clase de estadísticas es también un componente de un pipeline, de modo que el texto se anota y se mide en una sola pasada y las estadísticas viajan con el `Doc`:
419
+
420
+ ```python
421
+ >>> import ests
422
+ >>> import spacy
423
+
424
+ >>> nlp = spacy.load("es_core_news_sm")
425
+ >>> for factory in ("basic", "morph", "syntax"):
426
+ ... _ = nlp.add_pipe(f"ests_{factory}", name=factory, last=True)
427
+
428
+ >>> nlp.pipe_names[-3:]
429
+ ['basic', 'morph', 'syntax']
430
+
431
+ >>> doc = nlp("El gato duerme en la ventana. Los niños juegan en el parque.")
432
+ >>> doc._.basic.n_words, doc._.morph.pos[:2], doc._.syntax.tree_depth
433
+ (12, ('DET', 'NOUN'), 2.0)
434
+ ```
435
+
436
+ Las fábricas son `ests_basic`, `ests_readability`, `ests_diversity`, `ests_morph`, `ests_syntax` y `ests_cohesion`; el nombre del paso del pipeline es libre y es como se llama la extensión.
437
+
438
+ Más en la [documentación](https://sergeyshk.github.io/esTS/es/components/).
439
+
440
+ </details>
441
+
292
442
  ## Desarrollo
293
443
 
294
444
  El proyecto usa [uv](https://docs.astral.sh/uv/) para gestionar las dependencias y [ruff](https://docs.astral.sh/ruff/) para el análisis y el formato del código.
@@ -326,11 +476,15 @@ Los informes de errores, las ideas y los pull requests son bienvenidos: las [iss
326
476
  * **docs** - documentación del proyecto
327
477
  * **ests**:
328
478
  * basic_stats.py - estadísticas básicas del texto
479
+ * cohesion_stats.py - estadísticas de cohesión
480
+ * components.py - componentes de un pipeline de spaCy
329
481
  * constants.py - constantes de la lengua española y de las métricas
330
482
  * diversity_stats.py - métricas de diversidad léxica
331
483
  * exceptions.py - excepciones de la biblioteca
332
484
  * extractors.py - herramientas de extracción de objetos del texto
485
+ * morph_stats.py - estadísticas morfológicas
333
486
  * readability_stats.py - métricas de legibilidad
487
+ * syntax_stats.py - estadísticas sintácticas
334
488
  * syllables.py - silabificación y acento
335
489
  * utils.py - herramientas auxiliares
336
490
  * **tests** - pruebas que reproducen la estructura del paquete
@@ -1,5 +1,13 @@
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/SergeyShk/esTS/master/docs/img/ests.png" alt="esTS" width="340">
3
+ </p>
4
+
1
5
  <h1 align="center">esTS</h1>
2
6
 
7
+ <p align="center">
8
+ <i>¿Cómo esTáS, texto?</i>
9
+ </p>
10
+
3
11
  <p align="center">
4
12
  <b>Spanish Texts Statistics</b> - a library for statistics extraction from texts in Spanish
5
13
  </p>
@@ -20,17 +28,21 @@
20
28
 
21
29
  ---
22
30
 
23
- **esTS** computes for Spanish texts what usually requires assembling several separate tools: basic statistics, readability and lexical diversity - by published formulas with the coefficients and the scales of their authors, deterministically and without a neural network inside.
31
+ **esTS** computes for Spanish texts what usually requires assembling several separate tools: basic statistics, readability, lexical diversity, morphology, syntax and cohesion - by published formulas with the coefficients and the scales of their authors, and by the parts of speech and the features of Universal Dependencies.
24
32
 
25
- The library works both with raw strings and with `Doc` objects of [spaCy](https://github.com/explosion/spaCy), and needs no trained model: sentences, words and character N-grams are extracted by rules, syllables and stress follow from the orthography.
33
+ The library works both with raw strings and with `Doc` objects of [spaCy](https://github.com/explosion/spaCy): sentences, words and character N-grams are extracted by rules, syllables and stress follow from the orthography, and only the morphological, the syntactic and the cohesion statistics need a trained model.
26
34
 
27
35
  * **[Object extraction](https://sergeyshk.github.io/esTS/extractors/sentences/)** - configurable sentence, word and character N-gram tokenizers that know the inverted marks, the dialogue dash and the abbreviations of Spanish
28
36
  * **[Syllables and stress](https://sergeyshk.github.io/esTS/syllables/)** - rule-based syllabification and the stressed syllable derived from the spelling, with no dictionary
29
37
  * **[Basic statistics](https://sergeyshk.github.io/esTS/stats/basic_stats/)** - counts of sentences, words, letters, syllables and punctuation marks by type, with distributions and normalized shares
30
38
  * **[Readability metrics](https://sergeyshk.github.io/esTS/stats/readability_stats/)** - Fernández Huerta, Szigriszt-Pazos with the INFLESZ scale, Gutiérrez de Polini, Crawford, Legibilidad µ, SOL, LIX and RIX, with a consensus grade, the school stages of Spain and reading time
31
39
  * **[Lexical diversity metrics](https://sergeyshk.github.io/esTS/stats/diversity_stats/)** - TTR and its variations, MATTR, MSTTR, MTLD, HD-D, Simpson's and Yule's indices, entropy, Zipf's and Heaps' laws
40
+ * **[Morphological statistics](https://sergeyshk.github.io/esTS/stats/morph_stats/)** - parts of speech and fifteen grammatical features of Universal Dependencies, with the markers of Spanish: the moods, the non-finite forms, `ser` against `estar`, the adverbs in `-mente`
41
+ * **[spaCy components](https://sergeyshk.github.io/esTS/components/)** - every statistics class as a component of a pipeline, the statistics attached to the `Doc` in one pass
42
+ * **[Cohesion statistics](https://sergeyshk.github.io/esTS/stats/cohesion_stats/)** - the overlap of nouns, arguments and content words between sentences, givenness and temporal cohesion in the manner of Coh-Metrix, with the density of 255 Spanish discourse markers
43
+ * **[Syntactic statistics](https://sergeyshk.github.io/esTS/stats/syntax_stats/)** - the dependency tree by distances, depth, clauses and coordination, with the constructions of the administrative style: the passive with `ser` and with `se`, the participial and the gerund clauses, the chains of `de`, the split predicates
32
44
 
33
- Morphology, syntax and cohesion on Universal Dependencies come in 0.2, corpus measures and stylometry in 0.3, style, phonostatistics, metre and rhyme in 0.4.
45
+ Corpus measures and stylometry come in 0.3, style, phonostatistics, metre and rhyme in 0.4.
34
46
 
35
47
  ## Installation
36
48
 
@@ -46,7 +58,7 @@ Or with [uv](https://docs.astral.sh/uv/):
46
58
  uv add pyests
47
59
  ```
48
60
 
49
- The distribution on PyPI is `pyests`, the package it installs is `ests`. No spaCy model is needed for the statistics of 0.1; one is needed only to parse a text yourself and pass the `Doc` instead of a string:
61
+ The distribution on PyPI is `pyests`, the package it installs is `ests`. The basic statistics, the readability and the lexical diversity metrics need no spaCy model; the morphological, the syntactic and the cohesion statistics do, and so does parsing a text yourself to pass the `Doc` instead of a string:
50
62
 
51
63
  ```bash
52
64
  python -m spacy download es_core_news_sm
@@ -289,6 +301,144 @@ More in the [documentation](https://sergeyshk.github.io/esTS/stats/diversity_sta
289
301
 
290
302
  </details>
291
303
 
304
+ <details>
305
+ <summary><b>Morphological statistics</b></summary>
306
+
307
+ <br>
308
+
309
+ The library annotates a text with the parts of speech and the grammatical features of Universal Dependencies, as the Spanish models of spaCy give them, and counts them:
310
+
311
+ * the part of speech and fifteen features: case, definiteness, degree, gender, mood, numeral type, number, person, polarity, politeness, possessive, pronoun type, reflexive, tense and verb form
312
+ * the distribution of the words by the values of any feature, and the parse of the text word by word
313
+ * the markers of Spanish: the moods among the finite forms, the non-finite forms, `ser` against `estar`, the adverbs in `-mente`
314
+
315
+ ```python
316
+ >>> from ests import MorphStats
317
+
318
+ >>> ms = MorphStats("Si tuviera tiempo, leería el libro que me recomendaste ayer")
319
+
320
+ >>> ms.get_stats("mood", "tense", filter_none=True)
321
+ {'mood': {'Sub': 1, 'Cnd': 1, 'Ind': 1}, 'tense': {'Imp': 1, 'Pres': 1}}
322
+
323
+ >>> ms.tags[1]
324
+ 'Mood=Sub|Number=Sing|Person=3|Tense=Imp|VerbForm=Fin'
325
+
326
+ >>> ms.explain_text("pos", "mood", filter_none=True)[1]
327
+ ('tuviera', {'pos': 'VERB', 'mood': 'Sub'})
328
+
329
+ >>> MorphStats("Ella es alta pero hoy está cansada y habla lentamente").get_markers()["p_ser"]
330
+ 0.5
331
+ ```
332
+
333
+ The statistics need a spaCy model: a text is parsed with `es_core_news_sm`, and any other pipeline can be passed in `nlp`.
334
+
335
+ More in the [documentation](https://sergeyshk.github.io/esTS/stats/morph_stats/).
336
+
337
+ </details>
338
+
339
+ <details>
340
+ <summary><b>Syntactic statistics</b></summary>
341
+
342
+ <br>
343
+
344
+ The library measures the dependency tree of Universal Dependencies and the constructions that the Spanish guides to clear language warn about:
345
+
346
+ * the complexity of the tree: dependency distances, depth, leaves and subtrees, valency of the finite verbs, coordination chains, clauses and subordinate clauses, modifiers per noun
347
+ * the constructions: the passive with `ser` and with `se`, the participial and the gerund clauses, the chains of `de`, the split predicates, the impersonal `se`, the words of negation, the ratio of nouns to verbs
348
+
349
+ ```python
350
+ >>> from ests import SyntaxStats
351
+
352
+ >>> text = ("La revisión de las cuentas fue realizada por el comité. "
353
+ ... "Se llevó a cabo la reforma sin que nadie hiciera mención de los problemas.")
354
+ >>> ss = SyntaxStats(text)
355
+
356
+ >>> ss.n_sents, ss.n_words
357
+ (2, 24)
358
+
359
+ >>> ss.p_passive, ss.noun_verb_ratio
360
+ (0.6666666666666666, 2.3333333333333335)
361
+
362
+ >>> ss.split_predicates
363
+ ('llevó cabo', 'hiciera mención')
364
+
365
+ >>> round(ss.mean_dependency_distance, 2)
366
+ 2.05
367
+ ```
368
+
369
+ The statistics need a parse: a text is parsed with `es_core_news_sm`, and any other pipeline can be passed in `nlp`.
370
+
371
+ More in the [documentation](https://sergeyshk.github.io/esTS/stats/syntax_stats/).
372
+
373
+ </details>
374
+
375
+ <details>
376
+ <summary><b>Cohesion statistics</b></summary>
377
+
378
+ <br>
379
+
380
+ The library measures referential cohesion in the manner of Coh-Metrix and of its Spanish adaptation Coh-Metrix-Esp:
381
+
382
+ * the overlap of nouns, of arguments and of content words between adjacent sentences and between all pairs of sentences, binary and proportional
383
+ * givenness: pronouns, demonstratives and the content words whose lemma was already used
384
+ * temporal cohesion: the repetition of the tense and of the mood of the verbs of adjacent sentences
385
+ * the density of 255 Spanish discourse markers by class - causal, adversative, concessive, temporal, additive, conditional, reformulative - and by kind
386
+
387
+ ```python
388
+ >>> from ests import CohesionStats
389
+
390
+ >>> text = ("El informe fue aprobado por la comisión. Sin embargo, el informe no resuelve el problema. "
391
+ ... "Por lo tanto, la comisión aplazó la decisión.")
392
+ >>> cs = CohesionStats(text)
393
+
394
+ >>> cs.n_sents, cs.n_words
395
+ (3, 23)
396
+
397
+ >>> cs.noun_overlap_adjacent, round(cs.p_given, 3)
398
+ (0.5, 0.167)
399
+
400
+ >>> cs.c_connectors
401
+ {'por lo tanto': 1, 'sin embargo': 1}
402
+
403
+ >>> round(cs.connectors, 2), round(cs.connectors_causal, 2)
404
+ (86.96, 43.48)
405
+ ```
406
+
407
+ The statistics need the annotation: a text is parsed with `es_core_news_sm`, and any other pipeline can be passed in `nlp`.
408
+
409
+ More in the [documentation](https://sergeyshk.github.io/esTS/stats/cohesion_stats/).
410
+
411
+ </details>
412
+
413
+ <details>
414
+ <summary><b>spaCy components</b></summary>
415
+
416
+ <br>
417
+
418
+ Every statistics class is also a component of a pipeline, so a text is annotated and measured in one pass and the statistics travel with the `Doc`:
419
+
420
+ ```python
421
+ >>> import ests
422
+ >>> import spacy
423
+
424
+ >>> nlp = spacy.load("es_core_news_sm")
425
+ >>> for factory in ("basic", "morph", "syntax"):
426
+ ... _ = nlp.add_pipe(f"ests_{factory}", name=factory, last=True)
427
+
428
+ >>> nlp.pipe_names[-3:]
429
+ ['basic', 'morph', 'syntax']
430
+
431
+ >>> doc = nlp("El gato duerme en la ventana. Los niños juegan en el parque.")
432
+ >>> doc._.basic.n_words, doc._.morph.pos[:2], doc._.syntax.tree_depth
433
+ (12, ('DET', 'NOUN'), 2.0)
434
+ ```
435
+
436
+ The factories are `ests_basic`, `ests_readability`, `ests_diversity`, `ests_morph`, `ests_syntax` and `ests_cohesion`; the name of the pipe is free and is what the extension is called.
437
+
438
+ More in the [documentation](https://sergeyshk.github.io/esTS/components/).
439
+
440
+ </details>
441
+
292
442
  ## Development
293
443
 
294
444
  The project uses [uv](https://docs.astral.sh/uv/) for dependency management and [ruff](https://docs.astral.sh/ruff/) for linting and formatting.
@@ -326,11 +476,15 @@ Bug reports, ideas and pull requests are welcome - [issues](https://github.com/S
326
476
  * **docs** - project documentation
327
477
  * **ests**:
328
478
  * basic_stats.py - basic text statistics
479
+ * cohesion_stats.py - cohesion statistics
480
+ * components.py - components of a spaCy pipeline
329
481
  * constants.py - constants of the Spanish language and of the metrics
330
482
  * diversity_stats.py - lexical diversity metrics
331
483
  * exceptions.py - library exceptions
332
484
  * extractors.py - tools for object extraction from a text
485
+ * morph_stats.py - morphological statistics
333
486
  * readability_stats.py - readability metrics
487
+ * syntax_stats.py - syntactic statistics
334
488
  * syllables.py - syllabification and stress
335
489
  * utils.py - helper tools
336
490
  * **tests** - tests mirroring the package structure