pyests 0.2.0__tar.gz → 0.4.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.
Files changed (53) hide show
  1. {pyests-0.2.0 → pyests-0.4.0}/PKG-INFO +258 -23
  2. pyests-0.4.0/README.es.md +745 -0
  3. pyests-0.4.0/README.md +745 -0
  4. {pyests-0.2.0 → pyests-0.4.0}/ests/__init__.py +16 -2
  5. {pyests-0.2.0 → pyests-0.4.0}/ests/basic_stats.py +31 -35
  6. {pyests-0.2.0 → pyests-0.4.0}/ests/cohesion_stats.py +50 -99
  7. {pyests-0.2.0 → pyests-0.4.0}/ests/components.py +290 -62
  8. pyests-0.4.0/ests/constants.py +1215 -0
  9. pyests-0.4.0/ests/corpus/__init__.py +61 -0
  10. pyests-0.4.0/ests/corpus/collocations.py +313 -0
  11. pyests-0.4.0/ests/corpus/compare.py +728 -0
  12. pyests-0.4.0/ests/corpus/dispersion.py +330 -0
  13. pyests-0.4.0/ests/corpus/keyness.py +416 -0
  14. pyests-0.4.0/ests/corpus/kwic.py +165 -0
  15. pyests-0.4.0/ests/corpus/stylometry.py +604 -0
  16. pyests-0.4.0/ests/datasets/__init__.py +5 -0
  17. pyests-0.4.0/ests/datasets/dataset.py +181 -0
  18. pyests-0.4.0/ests/datasets/freq_dict.py +464 -0
  19. pyests-0.4.0/ests/datasets/spanish_literature.py +348 -0
  20. pyests-0.4.0/ests/datasets/spanish_sonnets.py +301 -0
  21. {pyests-0.2.0 → pyests-0.4.0}/ests/diversity_stats.py +61 -144
  22. pyests-0.4.0/ests/exceptions.py +88 -0
  23. {pyests-0.2.0 → pyests-0.4.0}/ests/extractors.py +12 -25
  24. pyests-0.4.0/ests/lexical_stats.py +336 -0
  25. {pyests-0.2.0 → pyests-0.4.0}/ests/morph_stats.py +23 -50
  26. pyests-0.4.0/ests/phon_stats.py +584 -0
  27. {pyests-0.2.0 → pyests-0.4.0}/ests/readability_stats.py +41 -79
  28. pyests-0.4.0/ests/resources/README.md +15 -0
  29. pyests-0.4.0/ests/resources/google_books_top10000.txt +10000 -0
  30. pyests-0.4.0/ests/style_stats.py +649 -0
  31. {pyests-0.2.0 → pyests-0.4.0}/ests/syllables.py +48 -55
  32. {pyests-0.2.0 → pyests-0.4.0}/ests/syntax_stats.py +51 -97
  33. pyests-0.4.0/ests/utils.py +757 -0
  34. pyests-0.4.0/ests/verse_stats.py +1226 -0
  35. pyests-0.4.0/ests/visualizers/__init__.py +29 -0
  36. pyests-0.4.0/ests/visualizers/corpus.py +220 -0
  37. pyests-0.4.0/ests/visualizers/fingerprinting.py +142 -0
  38. pyests-0.4.0/ests/visualizers/highlight.py +1063 -0
  39. pyests-0.4.0/ests/visualizers/sentences.py +110 -0
  40. pyests-0.4.0/ests/visualizers/stylometry.py +177 -0
  41. pyests-0.4.0/ests/visualizers/vocabulary.py +87 -0
  42. pyests-0.4.0/ests/visualizers/word_tree.py +343 -0
  43. pyests-0.4.0/ests/visualizers/zipf.py +126 -0
  44. {pyests-0.2.0 → pyests-0.4.0}/pyproject.toml +12 -2
  45. pyests-0.2.0/README.es.md +0 -513
  46. pyests-0.2.0/README.md +0 -513
  47. pyests-0.2.0/ests/constants.py +0 -721
  48. pyests-0.2.0/ests/exceptions.py +0 -85
  49. pyests-0.2.0/ests/utils.py +0 -384
  50. {pyests-0.2.0 → pyests-0.4.0}/.gitignore +0 -0
  51. {pyests-0.2.0 → pyests-0.4.0}/LICENSE.txt +0 -0
  52. {pyests-0.2.0 → pyests-0.4.0}/ests/py.typed +0 -0
  53. {pyests-0.2.0 → pyests-0.4.0}/ests/resources/connectors.tsv +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: pyests
3
- Version: 0.2.0
3
+ Version: 0.4.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
@@ -28,9 +28,12 @@ Classifier: Topic :: Text Processing
28
28
  Classifier: Topic :: Text Processing :: Linguistic
29
29
  Classifier: Typing :: Typed
30
30
  Requires-Python: >=3.11
31
+ Requires-Dist: graphviz>=0.20.3
32
+ Requires-Dist: matplotlib>=3.8
31
33
  Requires-Dist: numpy>=1.26
34
+ Requires-Dist: pandas>=2.1
32
35
  Requires-Dist: scipy>=1.11
33
- Requires-Dist: simplemma>=1.0
36
+ Requires-Dist: simplemma<3,>=2.0
34
37
  Requires-Dist: spacy>=3.7
35
38
  Description-Content-Type: text/markdown
36
39
 
@@ -60,13 +63,14 @@ Description-Content-Type: text/markdown
60
63
  <a href="https://github.com/SergeyShk/esTS/actions/workflows/ci.yml"><img src="https://github.com/SergeyShk/esTS/actions/workflows/ci.yml/badge.svg" alt="Build"></a>
61
64
  <a href="https://github.com/astral-sh/ruff"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff"></a>
62
65
  <a href="https://github.com/SergeyShk/esTS/blob/master/LICENSE.txt"><img src="https://img.shields.io/github/license/sergeyshk/esTS.svg" alt="License"></a>
66
+ <a href="https://doi.org/10.5281/zenodo.22924655"><img src="https://zenodo.org/badge/DOI/10.5281/zenodo.22924655.svg" alt="DOI"></a>
63
67
  </p>
64
68
 
65
69
  ---
66
70
 
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.
71
+ **esTS** computes statistics of Spanish texts: basic statistics, readability, lexical diversity, lexical sophistication, style, phonostatistics, 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.
68
72
 
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.
73
+ The library works both with raw strings and with `Doc` objects of [spaCy](https://github.com/explosion/spaCy); most statistics need no trained model (see Installation).
70
74
 
71
75
  * **[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
72
76
  * **[Syllables and stress](https://sergeyshk.github.io/esTS/syllables/)** - rule-based syllabification and the stressed syllable derived from the spelling, with no dictionary
@@ -74,12 +78,17 @@ The library works both with raw strings and with `Doc` objects of [spaCy](https:
74
78
  * **[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
75
79
  * **[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
80
  * **[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`
81
+ * **[Corpus measures](https://sergeyshk.github.io/esTS/corpus/keyness/)** - keywords against a reference corpus, collocations, the dispersion of a word over the parts of a text, a KWIC concordance and the stylometry of authorship: Burrows's Delta with its variants, Zeta, the Mendenhall curve, the profile of the function words; the comparison of two corpora by 132 features of a text with effect sizes
82
+ * **[Visualizers](https://sergeyshk.github.io/esTS/visualizers/zipf/)** - Zipf's law, literature fingerprinting, a word tree, lexical dispersion and keywords, a network of collocations, a dendrogram, PCA and MDS by Delta, vocabulary growth, sentence lengths, and the highlighting of the fragments the statistics count, such as long sentences and passives
83
+ * **[Datasets](https://sergeyshk.github.io/esTS/datasets/spanishliterature/)** - Spanish-language literature in the public domain: 150 works by 33 authors in four genres; 4,259 sonnets of the 15th-20th centuries with the metrical pattern and the rhyme of every line; a frequency dictionary of 83,785 lemmas by Google Books Ngram
77
84
  * **[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
85
  * **[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
86
+ * **[Lexical sophistication statistics](https://sergeyshk.github.io/esTS/stats/lexical_stats/)** - how rare the words of a text are in the language: the frequency, range and dispersion of the lemmas by a dictionary of Google Books Ngram, the frequency bands top-1000 to 10000, surprisal, perplexity and lexical density
87
+ * **[Style metrics](https://sergeyshk.github.io/esTS/stats/style_stats/)** - the SEO indicators of Advego and Text.ru (nausea, water content, spam score, naturalness by Zipf's law, keyword density) and the markers of the officialese style by the Spanish guides to plain language: verbal nouns, compound prepositions, parenthetical expressions and clichés
88
+ * **[Phonostatistics](https://sergeyshk.github.io/esTS/stats/phon_stats/)** - the shares of the classes of sounds, consonant clusters, hiatuses, open syllables, hardness and the indices of alliteration and assonance, over the sounds of a rule-based transcription
89
+ * **[Verse statistics](https://sergeyshk.github.io/esTS/stats/verse_stats/)** - the scansion of Spanish verse by its syllabic meter: the metrical syllables, the meter of a poem, the stress profile and the types of the endecasílabo, the rhyme in full and by assonance with its scheme, the strophes and the form of a poem
79
90
  * **[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
80
91
 
81
- Corpus measures and stylometry come in 0.3, style, phonostatistics, metre and rhyme in 0.4.
82
-
83
92
  ## Installation
84
93
 
85
94
  Requires Python 3.11 or newer.
@@ -94,12 +103,14 @@ Or with [uv](https://docs.astral.sh/uv/):
94
103
  uv add pyests
95
104
  ```
96
105
 
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:
106
+ The distribution on PyPI is `pyests`, the package it installs is `ests`. The basic statistics, readability, lexical diversity, the style metrics except the verbal nouns, phonostatistics and verse statistics need no spaCy model. The morphological, syntactic, cohesion and lexical sophistication statistics of a string need one, and so do the verbal nouns, the profile of the function words, the features of a text, the comparison of corpora and parsing a `Doc` yourself:
98
107
 
99
108
  ```bash
100
109
  python -m spacy download es_core_news_sm
101
110
  ```
102
111
 
112
+ The statistics by the frequency dictionary need it downloaded once with `FreqDict().download()`. The datasets go to the directory `ests_data` next to the installed package, or to the one passed in `data_dir` or set in `ESTS_DATA_DIR` before the package is imported.
113
+
103
114
  ## Quick start
104
115
 
105
116
  ```python
@@ -139,7 +150,7 @@ python -m spacy download es_core_news_sm
139
150
 
140
151
  ### Object extraction
141
152
 
142
- The library allows creating your own tools for sentence, word and character N-gram extraction from a text, which can be further employed for counting statistics. The sentence splitter knows the inverted marks, the dash of a line of dialogue with the remark of the narrator, the abbreviations and the initials of Spanish; the word tokenizer keeps clitics, ordinals and numbers written the Spanish way together, and lemmas come from [simplemma](https://github.com/adbar/simplemma), which needs no model.
153
+ Configurable tools extract sentences, words and character N-grams from a text for the statistics. The sentence splitter knows the inverted marks, the dialogue dash and the abbreviations of Spanish; the word tokenizer keeps clitics, ordinals and Spanish numbers whole, and lemmas come from [simplemma](https://github.com/adbar/simplemma), which needs no model.
143
154
 
144
155
  ```python
145
156
  >>> from ests import CharNgramsExtractor, SentsExtractor, WordsExtractor
@@ -162,7 +173,7 @@ More in the [documentation](https://sergeyshk.github.io/esTS/extractors/sentence
162
173
 
163
174
  <br>
164
175
 
165
- Spanish spelling encodes both the syllable boundaries and the stress, so the library needs no dictionary: diphthongs, hiatuses and triphthongs, the silent `u` of `qu` and `gu`, the vocalic `y`, the `h` inside a diphthong and the consonant clusters give the syllables; the written accent, or the ending of the word when there is none, gives the stressed syllable. Adverbs in `-mente` and hyphenated compounds carry two stresses.
176
+ The syllables and the stress follow from the Spanish spelling, with no dictionary: the written accent, or the ending of the word when there is none, gives the stressed syllable. Adverbs in `-mente` and hyphenated compounds carry two stresses.
166
177
 
167
178
  ```python
168
179
  >>> from ests.syllables import stress_type, syllabify, word_stress, word_stresses
@@ -207,7 +218,7 @@ The library allows extracting the following statistics from a text:
207
218
  * the distribution of words by the number of letters
208
219
  * the distribution of words by the number of syllables
209
220
 
210
- A complex word has three or more syllables and a long word seven or more letters, as the Spanish readability formulas count them. Any statistic can be printed in a readable form:
221
+ A complex word has three or more syllables and a long word seven or more letters. Any statistic can be printed in a readable form:
211
222
 
212
223
  ```python
213
224
  >>> from ests import BasicStats
@@ -250,9 +261,9 @@ The library allows counting the following readability metrics:
250
261
  * LIX readability measure
251
262
  * RIX readability measure
252
263
 
253
- An interpretation layer works on top of the formulas: the band of a scale for the reading ease and for Legibilidad µ, a consensus grade as the median of the grade formulas, the school stage and the reader age of Spain, and reading time by the norms of Spanish-speaking readers.
264
+ On top of the formulas: the band of a scale for the reading ease and for Legibilidad µ, a consensus grade (the median of the grade formulas), the school stage and the reader age in Spain, and reading time.
254
265
 
255
- The coefficients of the Flesch reading ease are selected by the `preset` argument: by default the *fórmula de perspicuidad* of Szigriszt-Pazos with the INFLESZ scale validated on texts for patients (`general`); the coefficients of Fernández Huerta with the bands of their author are available as `classic`.
266
+ The coefficients of the Flesch reading ease are selected by `preset`: by default the *fórmula de perspicuidad* of Szigriszt-Pazos with the INFLESZ scale (`general`), or Fernández Huerta with the bands of its author (`classic`).
256
267
 
257
268
  ```python
258
269
  >>> from pprint import pprint
@@ -312,7 +323,7 @@ The library allows counting 32 lexical diversity metrics, among them:
312
323
  * Shannon entropy, evenness and perplexity
313
324
  * the slope of Zipf's law, the Zipf-Mandelbrot fit and the exponent of Heaps' law
314
325
 
315
- Any metric can be computed over windows of equal length, which is the standard way to compare texts of different lengths: the mean over the windows comes with a confidence interval.
326
+ Any metric can be computed over windows of equal length, to compare texts of different lengths, with a confidence interval of the mean.
316
327
 
317
328
  ```python
318
329
  >>> from ests import DiversityStats
@@ -342,7 +353,7 @@ More in the [documentation](https://sergeyshk.github.io/esTS/stats/diversity_sta
342
353
 
343
354
  <br>
344
355
 
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:
356
+ The parts of speech and the grammatical features of Universal Dependencies, as the Spanish models of spaCy give them:
346
357
 
347
358
  * 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
359
  * the distribution of the words by the values of any feature, and the parse of the text word by word
@@ -366,7 +377,7 @@ The library annotates a text with the parts of speech and the grammatical featur
366
377
  0.5
367
378
  ```
368
379
 
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`.
380
+ A text is parsed with `es_core_news_sm`; another pipeline can be passed in `nlp`.
370
381
 
371
382
  More in the [documentation](https://sergeyshk.github.io/esTS/stats/morph_stats/).
372
383
 
@@ -377,7 +388,7 @@ More in the [documentation](https://sergeyshk.github.io/esTS/stats/morph_stats/)
377
388
 
378
389
  <br>
379
390
 
380
- The library measures the dependency tree of Universal Dependencies and the constructions that the Spanish guides to clear language warn about:
391
+ The dependency tree of Universal Dependencies and the constructions that the Spanish guides to clear language warn about:
381
392
 
382
393
  * 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
394
  * 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
@@ -402,7 +413,7 @@ The library measures the dependency tree of Universal Dependencies and the const
402
413
  2.05
403
414
  ```
404
415
 
405
- The statistics need a parse: a text is parsed with `es_core_news_sm`, and any other pipeline can be passed in `nlp`.
416
+ A text is parsed with `es_core_news_sm`; another pipeline with a parser can be passed in `nlp`.
406
417
 
407
418
  More in the [documentation](https://sergeyshk.github.io/esTS/stats/syntax_stats/).
408
419
 
@@ -413,7 +424,7 @@ More in the [documentation](https://sergeyshk.github.io/esTS/stats/syntax_stats/
413
424
 
414
425
  <br>
415
426
 
416
- The library measures referential cohesion in the manner of Coh-Metrix and of its Spanish adaptation Coh-Metrix-Esp:
427
+ Referential cohesion in the manner of Coh-Metrix and its Spanish adaptation Coh-Metrix-Esp:
417
428
 
418
429
  * the overlap of nouns, of arguments and of content words between adjacent sentences and between all pairs of sentences, binary and proportional
419
430
  * givenness: pronouns, demonstratives and the content words whose lemma was already used
@@ -440,12 +451,98 @@ The library measures referential cohesion in the manner of Coh-Metrix and of its
440
451
  (86.96, 43.48)
441
452
  ```
442
453
 
443
- The statistics need the annotation: a text is parsed with `es_core_news_sm`, and any other pipeline can be passed in `nlp`.
454
+ A text is parsed with `es_core_news_sm`; another pipeline can be passed in `nlp`.
444
455
 
445
456
  More in the [documentation](https://sergeyshk.github.io/esTS/stats/cohesion_stats/).
446
457
 
447
458
  </details>
448
459
 
460
+ <details>
461
+ <summary><b>Lexical sophistication statistics</b></summary>
462
+
463
+ <br>
464
+
465
+ How rare the words of a text are in the language, in the manner of TAALES: the mean frequency, range and dispersion of the lemmas by the frequency dictionary of Google Books Ngram, the shares of the frequency bands top-1000, 2000, 5000 and 10000, surprisal and perplexity, the lexical density. The statistics by the dictionary need it downloaded once.
466
+
467
+ ```python
468
+ >>> from ests import LexicalStats
469
+ >>> from ests.datasets import FreqDict
470
+
471
+ >>> FreqDict().download()
472
+ >>> ls = LexicalStats("El felinólogo examinaba al minino con parsimonia")
473
+ >>> ls.coverage, ls.p_top1000, round(ls.surprisal, 2)
474
+ (0.8571428571428571, 0.42857142857142855, 13.71)
475
+ ```
476
+
477
+ More in the [documentation](https://sergeyshk.github.io/esTS/stats/lexical_stats/).
478
+
479
+ </details>
480
+
481
+ <details>
482
+ <summary><b>Style metrics</b></summary>
483
+
484
+ <br>
485
+
486
+ The SEO indicators of Advego and Text.ru - nausea, water content, spam score, naturalness by Zipf's law, keyword density - and the markers of the officialese style that the Spanish guides to plain language warn about: the nouns derived from a verb, the compound prepositions of the administrative style, the parenthetical expressions and the clichés.
487
+
488
+ ```python
489
+ >>> from ests import StyleStats
490
+
491
+ >>> ss = StyleStats("Se procedió a la revisión del expediente en el marco del plan a la mayor brevedad.")
492
+ >>> ss.compound_prepositions, ss.cliches, ss.verbal_nouns
493
+ (6.25, 12.5, 20.0)
494
+ ```
495
+
496
+ More in the [documentation](https://sergeyshk.github.io/esTS/stats/style_stats/).
497
+
498
+ </details>
499
+
500
+ <details>
501
+ <summary><b>Phonostatistics</b></summary>
502
+
503
+ <br>
504
+
505
+ The shares of the classes of sounds, the consonant clusters, the hiatuses, the open syllables, the hardness and the indices of alliteration and assonance, counted over the sounds of a rule-based transcription, not over the letters: `h` is silent, `ll` and `rr` are one sound.
506
+
507
+ ```python
508
+ >>> from ests import PhonStats
509
+
510
+ >>> ps = PhonStats("Los suspiros se escapan de su boca de fresa")
511
+ >>> round(ps.p_voiceless, 3), round(ps.hardness, 3), ps.sounds[-1]
512
+ (0.371, 0.684, ('f', 'r', 'e', 's', 'a'))
513
+ ```
514
+
515
+ More in the [documentation](https://sergeyshk.github.io/esTS/stats/phon_stats/).
516
+
517
+ </details>
518
+
519
+ <details>
520
+ <summary><b>Verse statistics</b></summary>
521
+
522
+ <br>
523
+
524
+ The scansion of Spanish verse by its syllabic meter: the metrical syllables of a line with the synalepha and the law of the final stress, fitted to the meter of the poem; the meter, the stress profile and the types of the endecasílabo; the rhyme in full (consonante) and by assonance (asonante) with its scheme, the strophes and the form of a poem. No model and no dictionary are needed.
525
+
526
+ ```python
527
+ >>> from ests import VerseStats
528
+
529
+ >>> text = """Cuando me paro a contemplar mi estado
530
+ ... y a ver los pasos por do me han traído,
531
+ ... hallo, según por do anduve perdido,
532
+ ... que a mayor mal pudiera haber llegado."""
533
+ >>> vs = VerseStats(text)
534
+ >>> vs.meter, vs.patterns[0], vs.c_rhythms
535
+ ('endecasílabo', '---+---+-+-', {'4-8-10': 2, '4-7-10': 1, '3-6-10': 1})
536
+ >>> vs.syllables[0]
537
+ ('cuan', 'do', 'me', 'pa', 'ro‿a', 'con', 'tem', 'plar', 'mi‿es', 'ta', 'do')
538
+ >>> vs.rhyme_schemes, vs.strophes
539
+ (('ABBA',), ('cuarteto',))
540
+ ```
541
+
542
+ More in the [documentation](https://sergeyshk.github.io/esTS/stats/verse_stats/).
543
+
544
+ </details>
545
+
449
546
  <details>
450
547
  <summary><b>spaCy components</b></summary>
451
548
 
@@ -469,12 +566,141 @@ Every statistics class is also a component of a pipeline, so a text is annotated
469
566
  (12, ('DET', 'NOUN'), 2.0)
470
567
  ```
471
568
 
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.
569
+ The factories are `ests_basic`, `ests_readability`, `ests_diversity`, `ests_morph`, `ests_syntax`, `ests_cohesion`, `ests_lexical`, `ests_style`, `ests_phon` and `ests_verse`; the name of the pipe is the name of the extension.
473
570
 
474
571
  More in the [documentation](https://sergeyshk.github.io/esTS/components/).
475
572
 
476
573
  </details>
477
574
 
575
+ <details>
576
+ <summary><b>Corpus measures</b></summary>
577
+
578
+ <br>
579
+
580
+ The measures of corpus linguistics that compare corpora and describe the use of a word:
581
+
582
+ * keywords of a target corpus against a reference one or against the frequency dictionary of Google Books Ngram: the log-likelihood with its p-value, Log Ratio, chi-square, %DIFF, BIC, ELL and the odds ratio
583
+ * collocations by logDice, MI, MI³, t-score, Dice, log-likelihood, NPMI and minimum sensitivity
584
+ * the dispersion of a word over the parts of a text: DP of Gries, normalized DP, Juilland's D, Carroll's D2, Rosengren's S and the Kullback-Leibler divergence
585
+ * a KWIC concordance by word form or by lemma
586
+ * stylometry: the distances between texts by Burrows's Delta and its variants, with the attribution of a text to reference authors, the markers of preferred and avoided words by Zeta, Kilgarriff's chi-square, the Mendenhall curve and the profile of the function words
587
+ * the comparison of two corpora by 132 features of a text over windows of about the same size: Cliff's delta, Cohen's d and the AUC of every feature, the Mann-Whitney test with Holm's correction and a bootstrap interval of the difference of the medians
588
+
589
+ ```python
590
+ >>> from ests import WordsExtractor
591
+ >>> from ests.corpus import collocations, keyness, kwic, zeta
592
+
593
+ >>> we = WordsExtractor(use_lexemes=True, lowercase=True)
594
+ >>> target = we.extract("El gato estaba en la ventana y miraba a los pájaros. Los pájaros se fueron y el gato "
595
+ ... "se durmió en la ventana. Mañana el gato volverá a estar en la ventana y mirará a los pájaros.")
596
+ >>> reference = we.extract("El perro estaba en el suelo y dormía. Después el perro comió y volvió a dormir. "
597
+ ... "Mañana el perro saldrá a pasear.")
598
+
599
+ >>> [(k.word, round(k.g2, 2)) for k in keyness(target, reference, top_n=2)]
600
+ [('gato', 2.8), ('pájaro', 2.8)]
601
+
602
+ >>> [(c.left, c.right, round(c.score, 1)) for c in collocations(target, window=2, top_n=2)]
603
+ [('en', 'ventana', 13.0), ('estar', 'en', 12.7)]
604
+
605
+ >>> [line.keyword for line in kwic("Los gatos juegan y el gato duerme.", "gato", by_lemma=True)]
606
+ ['gatos', 'gato']
607
+
608
+ >>> scores = zeta(target, reference, segment_size=10)
609
+ >>> [z.word for z in scores[:2]], [z.word for z in scores[-2:]]
610
+ (['gato', 'ventana'], ['dormir', 'perro'])
611
+ ```
612
+
613
+ Words are compared as they are, so case, lemmas and stop words are chosen at the extraction.
614
+
615
+ More in the [documentation](https://sergeyshk.github.io/esTS/corpus/keyness/).
616
+
617
+ </details>
618
+
619
+ <details>
620
+ <summary><b>Datasets</b></summary>
621
+
622
+ <br>
623
+
624
+ * [spanish_literature](https://sergeyshk.github.io/esTS/datasets/spanishliterature/) - Spanish-language literature in the public domain: 150 works by 33 authors from Spain, Latin America and the Philippines, from Cervantes to the 1920s, in prose, poems, drama and publicism
625
+ * [spanish_sonnets](https://sergeyshk.github.io/esTS/datasets/spanishsonnets/) - Spanish sonnets of the Diachronic Spanish Sonnet Corpus (DISCO) in the public domain: 4,259 sonnets by 1,167 authors of the 15th-20th centuries, every line with its metrical pattern and the label of its rhyme, the automatic annotation of DISCO (CC BY 4.0)
626
+ * [freq_dict](https://sergeyshk.github.io/esTS/datasets/freqdict/) - a frequency dictionary of 83,785 Spanish lemmas from the books of Google Books Ngram of 1980-2019: ipm, range and Juilland's D over the years, the number of books and the part of speech (CC BY 3.0)
627
+
628
+ The texts are cut to the text of the author and come with the genre, the author, the title, the years of the first publication and the country; the records can be filtered by any of them and by the length of the text.
629
+
630
+ ```python
631
+ >>> from ests.datasets import SpanishLiterature
632
+
633
+ >>> sl = SpanishLiterature()
634
+ >>> sl.download()
635
+ >>> for record in sl.get_records(author="galdos", year_from=1880, year_to=1884):
636
+ ... print(record["title"], record["year_from"], len(record["text"]))
637
+ La desheredada 1881 820454
638
+ El amigo Manso 1882 521156
639
+ La de Bringas 1884 413730
640
+ Tormento 1884 477286
641
+ ```
642
+
643
+ The archive (19 MB) is downloaded once by `download()` into the data directory; before that `get_texts()` and `get_records()` raise `DatasetNotFoundError`.
644
+
645
+ More in the [documentation](https://sergeyshk.github.io/esTS/datasets/spanishliterature/).
646
+
647
+ </details>
648
+
649
+ <details>
650
+ <summary><b>Visualizers</b></summary>
651
+
652
+ <br>
653
+
654
+ * [Zipf's law](https://sergeyshk.github.io/esTS/visualizers/zipf/) with the theoretical curve and the Zipf-Mandelbrot fit
655
+ * [Literature fingerprinting](https://sergeyshk.github.io/esTS/visualizers/fingerprinting/)
656
+ * [Word tree](https://sergeyshk.github.io/esTS/visualizers/word_tree/)
657
+ * [Corpus plots](https://sergeyshk.github.io/esTS/visualizers/corpus/): lexical dispersion, a chart of keywords, a network of collocations
658
+ * [Stylometric plots](https://sergeyshk.github.io/esTS/visualizers/stylometry/): a dendrogram, the principal components and the multidimensional scaling by Delta, the Mendenhall curves
659
+ * [Vocabulary growth and frequency spectrum](https://sergeyshk.github.io/esTS/visualizers/vocabulary/), [sentence lengths](https://sergeyshk.github.io/esTS/visualizers/sentences/) with a moving average
660
+
661
+ The matplotlib plots take the axes `ax` and return `Axes`; the network of collocations and the word tree are rendered by the executables of Graphviz. Cosine Delta separates three novels by Galdós from three by Unamuno:
662
+
663
+ ```python
664
+ import matplotlib.pyplot as plt
665
+ from ests import WordsExtractor
666
+ from ests.corpus import delta
667
+ from ests.datasets import SpanishLiterature
668
+ from ests.visualizers import dendrogram_plot, pca_plot
669
+
670
+ # six novels by Galdós and Unamuno from the corpus of literature
671
+ titles = (
672
+ "Marianela",
673
+ "Misericordia",
674
+ "Torquemada en la hoguera",
675
+ "Niebla",
676
+ "Abel Sánchez",
677
+ "La tía Tula",
678
+ )
679
+ sl = SpanishLiterature()
680
+ sl.download()
681
+ novels = {
682
+ record["title"]: record["text"]
683
+ for author in ("galdos", "unamuno")
684
+ for record in sl.get_records(author=author)
685
+ if record["title"] in titles
686
+ }
687
+ we = WordsExtractor(lowercase=True)
688
+ corpus = {title: we.extract(novels[title]) for title in titles}
689
+ distances = delta(corpus, n_mfw=100, variant="cosine")
690
+
691
+ fig, (left, right) = plt.subplots(1, 2, figsize=(13, 5))
692
+ dendrogram_plot(distances, ax=left)
693
+ pca_plot(corpus, n_mfw=100, ax=right)
694
+ ```
695
+
696
+ <p align="center">
697
+ <img src="https://raw.githubusercontent.com/SergeyShk/esTS/master/docs/img/stylometry.png" alt="Stylometric plots" width="760">
698
+ </p>
699
+
700
+ More in the [documentation](https://sergeyshk.github.io/esTS/visualizers/zipf/).
701
+
702
+ </details>
703
+
478
704
  ## Development
479
705
 
480
706
  The project uses [uv](https://docs.astral.sh/uv/) for dependency management and [ruff](https://docs.astral.sh/ruff/) for linting and formatting.
@@ -492,7 +718,7 @@ Run `make help` for the full list of commands.
492
718
 
493
719
  The documentation is bilingual: English pages are `docs/*.md`, Spanish ones are `docs/*.es.md` next to them ([mkdocs-static-i18n](https://github.com/ultrabug/mkdocs-static-i18n)); when editing a page, update both versions.
494
720
 
495
- The installed version is `ests.__version__`. All exceptions inherit `ests.EstsError` and one of the built-in classes (`SourceError` and `ParameterError` - `ValueError`, `SourceTypeError` - `TypeError`, `UnknownStatError` - `KeyError`), so `except ValueError` keeps working. The library prints nothing on its own: its messages go to the `ests` logger (`logging.getLogger("ests")`) and are silent by default.
721
+ The installed version is `ests.__version__`. All exceptions inherit `ests.EstsError` and a built-in class (`ValueError`, `TypeError`, `KeyError`, `OSError` or `RuntimeError`), so `except ValueError` keeps working. The library prints nothing on its own: its messages go to the `ests` logger and are silent by default. More in the [documentation](https://sergeyshk.github.io/esTS/exceptions/).
496
722
 
497
723
  Before submitting changes, install the hooks that run the linters on commit and the tests on push:
498
724
 
@@ -502,7 +728,7 @@ uv run pre-commit install
502
728
 
503
729
  ## Contributing
504
730
 
505
- Bug reports, ideas and pull requests are welcome - [issues](https://github.com/SergeyShk/esTS/issues) are open. The workflow, the checks to run before submitting a pull request and how to shape the changes are described in [CONTRIBUTING.md](https://github.com/SergeyShk/esTS/blob/master/CONTRIBUTING.md); the rules of conduct are in the [code of conduct](https://github.com/SergeyShk/esTS/blob/master/CODE_OF_CONDUCT.md).
731
+ Bug reports, ideas and pull requests are welcome in the [issues](https://github.com/SergeyShk/esTS/issues). The workflow and the checks to run before a pull request are in [CONTRIBUTING.md](https://github.com/SergeyShk/esTS/blob/master/CONTRIBUTING.md); the rules of conduct are in the [code of conduct](https://github.com/SergeyShk/esTS/blob/master/CODE_OF_CONDUCT.md).
506
732
 
507
733
  <details>
508
734
  <summary><b>Project structure</b></summary>
@@ -513,16 +739,24 @@ Bug reports, ideas and pull requests are welcome - [issues](https://github.com/S
513
739
  * **ests**:
514
740
  * basic_stats.py - basic text statistics
515
741
  * cohesion_stats.py - cohesion statistics
742
+ * lexical_stats.py - lexical sophistication statistics
516
743
  * components.py - components of a spaCy pipeline
744
+ * corpus - measures of corpus linguistics: keywords, collocations, dispersion, concordance, stylometry, comparison of corpora
745
+ * datasets - datasets: Spanish-language literature, Spanish sonnets, the frequency dictionary
517
746
  * constants.py - constants of the Spanish language and of the metrics
518
747
  * diversity_stats.py - lexical diversity metrics
519
748
  * exceptions.py - library exceptions
520
749
  * extractors.py - tools for object extraction from a text
521
750
  * morph_stats.py - morphological statistics
522
751
  * readability_stats.py - readability metrics
752
+ * style_stats.py - style metrics
753
+ * phon_stats.py - phonostatistics
523
754
  * syntax_stats.py - syntactic statistics
755
+ * verse_stats.py - verse statistics
524
756
  * syllables.py - syllabification and stress
525
757
  * utils.py - helper tools
758
+ * visualizers - plots: Zipf's law, fingerprinting, word tree, corpus and stylometric plots, vocabulary growth, sentence lengths, text highlighting
759
+ * **scripts** - scripts that build the archives of the datasets
526
760
  * **tests** - tests mirroring the package structure
527
761
 
528
762
  </details>
@@ -537,13 +771,14 @@ Bug reports, ideas and pull requests are welcome - [issues](https://github.com/S
537
771
 
538
772
  ## Citation
539
773
 
540
- Please use the following BibTeX entry for citing **esTS** if you use it in your research or software. Citations are helpful for the continued development and maintenance of this library. The same metadata is in [CITATION.cff](https://github.com/SergeyShk/esTS/blob/master/CITATION.cff) - GitHub shows it under the "Cite this repository" button.
774
+ Please use the following BibTeX entry for citing **esTS** if you use it in your research or software. The same metadata is in [CITATION.cff](https://github.com/SergeyShk/esTS/blob/master/CITATION.cff) ("Cite this repository" on GitHub). The Concept DOI [10.5281/zenodo.22924655](https://doi.org/10.5281/zenodo.22924655) points at every version of the library; the DOI of a single version is on the page of its release.
541
775
 
542
776
  ```bibtex
543
777
  @software{esTS,
544
778
  author = {Sergey Shkarin},
545
779
  title = {{esTS, a library for statistics extraction from texts in Spanish}},
546
780
  year = 2026,
781
+ doi = {10.5281/zenodo.22924655},
547
782
  url = {https://github.com/SergeyShk/esTS}
548
783
  }
549
784
  ```