Syntactic statistics¶
ests.syntax_stats.SyntaxStats
Description¶
A module for computing the syntactic statistics of a text on the dependency tree of Universal Dependencies. The data source can be either a text or a Doc object of the spaCy library, but it has to be parsed: a string is parsed with es_core_news_sm or with the pipeline passed in nlp, and a Doc must carry the dependencies, which come from a parser, and the lemmas, which come from a lemmatizer and are what tells a passive from a compound tense and a light verb from any other - a Doc of spacy.blank("es"), of a pipeline without a parser or of one with the lemmatizer excluded is not a valid source and raises SourceError.
Punctuation marks, symbols (%, €, +) and whitespace are not nodes of the tree: the words are, the same words every other class of the library counts, and the distances are counted in positions of words. The measures of a sentence - the longest dependency, the depth of the tree, the number of leaves and of subtrees, the nodes per leaf - are averaged over the sentences, the constructions are given per sentence, and the passive and the modifiers are shares of the verbs and of the nouns.
A text longer than the max_length of the pipeline - a million characters by default - raises SourceError: split it into parts, or raise max_length on a pipeline of your own and pass it in nlp.
Note
The statistics are computed when the SyntaxStats object is initialized.
Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
source |
str/Doc | - |
Data source (a string or a Doc object) |
nlp |
Language | None |
Pipeline of spaCy that parses a string; without it the model es_core_news_sm is loaded |
Measures of complexity¶
The measures of the tree follow the work of Ivanov, Solnyshkina and Solovyev on the syntactic complexity of a text: the dependency distance of Liu (2008) - the distance between a word and its head in positions of words - the depth of the tree, the leaves and the subtrees, the valency of the finite verbs, the coordination chains, the clauses and the modifiers of a noun.
| Attribute | Type | Description |
|---|---|---|
mean_dependency_distance |
float | Mean dependency distance |
std_dependency_distance |
float | Standard deviation of the dependency distance |
max_dependency_distance |
float | Mean of the longest dependencies of the sentences, over the sentences that have dependencies |
p_adjacent_dependencies |
float | Share of adjacent dependencies - of length 1 |
tree_depth |
float | Depth of the dependency tree |
leaves_per_sent |
float | Leaves per sentence |
subtrees_per_sent |
float | Subtrees per sentence |
nodes_per_leaf |
float | Mean over the sentences of the words per leaf |
verb_valency |
float | Mean number of dependents of a finite verb |
coordination_chains_per_sent |
float | Coordination chains per sentence |
mean_coordination_chain_len |
float | Mean length of a coordination chain |
clauses_per_sent |
float | Clauses per sentence |
mean_clause_len |
float | Mean length of a clause in words |
subordinate_clauses_per_sent |
float | Subordinate clauses per sentence |
p_complex_sents |
float | Share of sentences with at least one subordinate clause |
modifiers_per_noun |
float | Mean number of modifiers of a noun |
noun_verb_ratio |
float | Ratio of the number of nouns to the number of verb forms |
A clause is headed by the head of a sentence or by a word with the relation ccomp, advcl, acl or csubj; the Spanish models use no subtypes, so a relative clause carries the plain acl. The participles and the gerunds head no clause of that kind - they are counted apart - and neither does an infinitive under acl (el deseo de irse). A parenthetical (parataxis) and a coordinated predicate (conj of the head of a clause) count only when they are a verb or carry a subject of their own.
Constructions of the administrative style¶
The constructions are the ones the Spanish guides to clear language (lenguaje claro) warn about: the passive, the participial and the gerund clauses, the chains of de, the split predicates.
| Attribute | Type | Description |
|---|---|---|
de_chains_per_sent |
float | Chains of de per sentence |
max_de_chain_len |
int | Maximum length of a chain of de |
participle_clauses_per_sent |
float | Participial clauses per sentence |
mean_participle_clause_len |
float | Mean length of a participial clause in words |
gerund_clauses_per_sent |
float | Gerund clauses per sentence |
mean_gerund_clause_len |
float | Mean length of a gerund clause in words |
p_passive |
float | Share of passive forms among the verb forms |
p_agentless_passive |
float | Share of forms with no agent among the passive ones |
se_passives_per_sent |
float | Passives with se per sentence |
impersonal_se_per_sent |
float | Impersonal sentences with se per sentence |
infinitives_per_sent |
float | Infinitives per sentence |
negations_per_sent |
float | Words of negation per sentence |
split_predicates_per_sent |
float | Split predicates per sentence |
- A chain of
deis two or more nested complements introduced bydeor its contractiondel:el aumento de la eficiencia del uso de los recursosis a chain of length 3. A single complement (el uso del agua) is not a chain. - A participial clause is a participle with at least one dependent that is not the predicate of its clause:
la casa, construida por los obreros, se vendióhas one,el autor ha escrito el librohas none, because the participle of a compound tense carries an auxiliary. A gerund clause is the same for a gerund, the periphrases left out: the ones the models build with an auxiliary (está cantando,va aumentando) and the ones they attach to their verb asxcomporadvcl(sigue trabajando,lleva años estudiando,acabó reconociendo). - The passive is a participle with the auxiliary
ser(la casa fue construida) or a verb with theseof the passive (se construyó la casa). The Spanish models give the auxiliary of the passive the plain relationauxand its subject the plainnsubj, so it is the lemma of the auxiliary that tellsfue construidafromha construido; in the present they often read the auxiliary as a copula instead (el proyecto es financiado), and both relations count. A passive is agentless when no complement of it is introduced bypor. - A split predicate is a light verb (
hacer,dar,tomar,tener,poner,llevar,prestar,efectuar,realizar,proceder,proporcionar,ejercer) with a nominal part derived from a verb (revisión,decisión,uso):hacer una revisióninstead ofrevisar. The nouns of the fixed expressions -cabo,manifiesto,parte,lugar,cuenta- count only with the verb they are fixed with,llevar a caboandtomar partebeing split predicates whiledar traslado a las partesandponer en primer lugar la seguridadare not. A complement with a preposition is the nominal part only in a fixed expression (poner de manifiesto) or with a verb that takes it that way (proceder a la votación); the agent of a passive never is. The pairs found are in the attributesplit_predicates. - A word of negation carries
Polarity=Neg, which the models give tonoalone, or is one ofnunca,jamás,nada,nadie,ningunoandtampoco; the conjunctionniofni... niis not one. Every such word counts, so the negative concord of Spanish, where one negation is written twice (no vino nadie), gives two.
Warning
The statistics are as good as the parse. es_core_news_sm tells the three se of Spanish apart poorly: on the Spanish pages of this site it marks 60 as the se of a passive, 51 as the one of a pronominal verb and only 2 as impersonal, and it reads se fue dando un portazo as a passive. Read se_passives_per_sent and impersonal_se_per_sent together rather than apart. The agent of a passive is another weak spot - the models have no relation obl:agent and annotate por los obreros as an object as readily as an oblique - which is why the agent is looked for by its preposition and not by its relation.
Counts¶
Besides the statistics the object keeps the counts they are built from, which are useful on their own.
| Attribute | Type | Description |
|---|---|---|
n_sents |
int | Number of sentences containing words |
n_words |
int | Number of words |
n_leaves |
int | Number of leaves - words with no dependent word |
n_subtrees |
int | Number of subtrees - words with dependent words |
n_coordination_chains |
int | Number of coordination chains |
n_clauses |
int | Number of clauses |
n_subordinate_clauses |
int | Number of subordinate clauses |
n_complex_sents |
int | Number of sentences with a subordinate clause |
n_nouns |
int | Number of nouns |
n_de_chains |
int | Number of chains of de |
n_participle_clauses |
int | Number of participial clauses |
n_gerund_clauses |
int | Number of gerund clauses |
n_verbs |
int | Number of verb forms |
n_passive |
int | Number of passive verb forms |
n_agentless_passive |
int | Number of passive forms with no agent |
n_se_passives |
int | Number of passives with se |
n_impersonal_se |
int | Number of impersonal sentences with se |
n_infinitives |
int | Number of infinitives |
n_negations |
int | Number of words of negation |
n_split_predicates |
int | Number of split predicates |
split_predicates |
tuple[str] | Tuple of the split predicates (verb and noun) |
c_children |
dict[int, int] | Distribution of words by number of dependent words |
c_deps |
dict[str, int] | Distribution of words by syntactic relation |
Methods¶
get_stats¶
Returns a dictionary with the computed syntactic statistics.
Example
Code:
# Import the library
from ests import SyntaxStats
# Prepare the data
text = (
"La revisión de las cuentas del organismo fue realizada por el comité. "
"Se llevó a cabo la reforma, aprobada en 1998, sin que nadie hiciera "
"mención de los problemas."
)
# Compute the statistics
ss = SyntaxStats(text)
ss.get_stats()
Result:
{'mean_dependency_distance': 2.259259259259259,
'std_dependency_distance': 2.1532506449997975,
'max_dependency_distance': 9.0,
'p_adjacent_dependencies': 0.48148148148148145,
'tree_depth': 4.0,
'leaves_per_sent': 8.0,
'subtrees_per_sent': 6.5,
'nodes_per_leaf': 1.8015873015873014,
'verb_valency': 4.0,
'coordination_chains_per_sent': 0.0,
'mean_coordination_chain_len': nan,
'clauses_per_sent': 1.5,
'mean_clause_len': 9.666666666666666,
'subordinate_clauses_per_sent': 0.5,
'p_complex_sents': 0.5,
'modifiers_per_noun': 1.0,
'de_chains_per_sent': 0.5,
'max_de_chain_len': 2,
'participle_clauses_per_sent': 0.5,
'mean_participle_clause_len': 3.0,
'gerund_clauses_per_sent': 0.0,
'mean_gerund_clause_len': nan,
'p_passive': 0.6666666666666666,
'p_agentless_passive': 0.5,
'se_passives_per_sent': 0.5,
'impersonal_se_per_sent': 0.0,
'infinitives_per_sent': 0.0,
'negations_per_sent': 0.5,
'split_predicates_per_sent': 1.0,
'noun_verb_ratio': 3.0}
The split predicates of the text are in an attribute of their own:
ss.split_predicates
# ('llevó cabo', 'hiciera mención')
print_stats¶
Prints a table with the computed syntactic statistics.
To illustrate the method, we reuse the code from the previous example:
Example
Code:
...
# Print the table of computed statistics
ss.print_stats()
Result:
Statistic | Value
------------------------------------------------------------
Mean dependency distance | 2.26
Standard deviation of the dependency distance | 2.15
Mean of the longest dependencies of the sentences | 9.00
Share of adjacent dependencies | 0.48
Depth of the dependency tree | 4.00
Leaves per sentence | 8.00
Subtrees per sentence | 6.50
Mean of the nodes per leaf of the sentences | 1.80
Valency of the finite verbs | 4.00
Coordination chains per sentence | 0.00
Mean length of a coordination chain | nan
Clauses per sentence | 1.50
Mean length of a clause (words) | 9.67
Subordinate clauses per sentence | 0.50
Share of sentences with a subordinate clause | 0.50
Modifiers per noun phrase | 1.00
Chains of de per sentence | 0.50
Maximum length of a chain of de | 2.00
Participial clauses per sentence | 0.50
Mean length of a participial clause (words) | 3.00
Gerund clauses per sentence | 0.00
Mean length of a gerund clause (words) | nan
Share of passive forms among the verbs | 0.67
Share of agentless forms among the passive ones | 0.50
Passives with se per sentence | 0.50
Impersonal sentences with se per sentence | 0.00
Infinitives per sentence | 0.00
Words of negation per sentence | 0.50
Split predicates per sentence | 1.00
Ratio of nouns to verbs | 3.00