Keywords¶
keyness(target, reference, measure='log_likelihood', min_freq=1, positive=True, top_n=None, n=1, lemmatize=True)
Keyword extraction (keyness) for a target corpus against a reference one: the words that occur significantly more often in the target corpus than in the reference.
Every word gets two values that Gabrielatos and Marchi and Hardie recommend reading together: the log-likelihood \(G^2\) with its p-value (whether there is a difference) and Log Ratio (how large it is), plus the chosen measure score, which sorts the list. The measures of significance (\(G^2\), chi-square, BIC) and ELL, the effect size of \(G^2\), are negative when the word is more frequent in the reference; %DIFF, Log Ratio and the odds ratio are directional by construction.
The reference may be a list of words, a mapping of frequencies (its size is the sum of the counts) or a FrequencyReference. Words are compared as they are: case, lemmatization and stop words belong to the word extractor, and both corpora have to be extracted the same way. A corpus of several texts is given as a list of their lists of words. With n above 1 the keywords are the n-grams of the words of every text, joined by underscores as the n-grams of WordsExtractor (black_cat), so an n-gram never runs across two texts; the counts and the sizes are those of the n-grams, and the frequencies per million are per million n-grams. Frequencies of n-grams - a sum of the Counter of the n-grams of every text, or a frequency dictionary of n-grams - go with n=1: a mapping and a FrequencyReference are refused with n above 1.
The function wraps keyness of the anyTS core and also takes the Lyashevskaya and Sharoff frequency dictionary FreqDict as the reference; FrequencyReference is in ruts.corpus next to it. Words are extracted with WordsExtractor.
from ruts import WordsExtractor
from ruts.corpus import keyness
we = WordsExtractor(use_lexemes=True, lowercase=True)
target = we.extract(
"Кот сидел на окне и смотрел на птиц. Птицы улетели, и кот уснул на окне. "
"Завтра кот снова будет сидеть на окне и смотреть на птиц."
)
reference = we.extract(
"Собака лежала на полу и дремала. Потом собака ела и снова дремала. Завтра собака будет гулять."
)
keyness(target, reference, top_n=1)
[(k.word, round(k.g2, 2)) for k in keyness(target, reference, positive=False, top_n=2)]
[Keyword(word='кот', freq_target=3, freq_reference=0.0, ipm_target=115384.61538461539, ipm_reference=0.0, g2=2.8774384815713177, p_value=0.08982881315854577, log_ratio=1.8845227825800641, score=2.8774384815713177)]
[('собака', -5.79), ('дремать', -3.86)]
Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
target |
list[str] / list[list[str]] / dict[str, int] |
- | Words of the target corpus - one text or a list of texts - or their frequencies |
reference |
list[str] / list[list[str]] / dict[str, float] / FrequencyReference |
- | Words of the reference corpus - one text or a list of texts - their frequencies or a reference by frequencies |
measure |
str |
'log_likelihood' |
Measure of anyts.constants.KEYNESS_MEASURES for score and the sorting |
min_freq |
int |
1 |
Minimum frequency of a keyword in its own corpus |
positive |
bool |
True |
Positive keywords (more frequent in the target corpus) or negative ones (more frequent in the reference) |
top_n |
int |
None |
Number of keywords; None - all of them |
n |
int |
1 |
Length of the n-grams of the words of every text; 1 - the words |
The parameters and the target corpus are checked by check_keyness_params; an n above 1 with frequencies or a FrequencyReference raises ParameterError. A reference that is not a list of strings, a list of such lists, a counter or a FrequencyReference raises SourceTypeError, and a negative, nan or infinite frequency of a counter and a corpus without words, or shorter than n words, raise SourceError.
reference may also be FreqDict, and one more parameter tells what the target corpus is against it:
| Parameter | Type | Default | Description |
|---|---|---|---|
lemmatize |
bool |
True |
The target corpus is word forms, False - lemmas (FreqDict only) |
A frequency dictionary that is not downloaded raises DatasetNotFoundError, and an n above 1 with it ParameterError.
check_keyness_params(measure='log_likelihood', min_freq=1, top_n=None, target=None, n=1, positive=True)
Checks the parameters of keyness before a frequency dictionary is read: it raises ParameterError unless the measure is one of KEYNESS_MEASURES, the minimum frequency is an integer, the number of keywords is None or an integer of at least one, the length of the n-grams n is an integer of at least one and positive is a bool. With target it also raises SourceTypeError unless the target corpus is a list of strings, a list of such lists or a mapping of strings to whole frequencies, and SourceError for a negative, nan or infinite frequency.
Reference by frequencies¶
FrequencyReference(counts, size, missing=0.0, key=None, keep=None)
A reference corpus described by its frequencies alone, such as a frequency dictionary built from a corpus too large to pass as words:
| Field | Type | Default | Description |
|---|---|---|---|
counts |
dict[str, float] |
- | Frequencies of the keys in the reference corpus |
size |
float |
- | Size of the reference corpus in words |
missing |
float |
0.0 |
Frequency of a key missing from counts |
key |
Callable |
None |
Key of a word of the target corpus in counts, such as its lemma; None - the word itself |
keep |
Callable |
None |
Whether a word of the target corpus is counted; None - every word |
Only the words of the target that keep passes are counted, under their key, in the frequencies and in the size alike. A key missing from counts has the frequency missing, such as the least frequency of a dictionary: an upper bound, so its word may be a positive keyword but never a negative one. Negative keywords come only from the keys of counts that keep passes. A frequency is checked as it is read, so a large dictionary is not gone through for positive keywords: one that is not a number raises SourceTypeError, and a negative, nan or infinite one SourceError. A size or a missing that is not a finite number or is negative raises ParameterError, and a key or a keep that cannot be called SourceTypeError.
The frequency dictionary FreqDict passed as reference is turned into such a reference:
| Field | FreqDict |
|---|---|
counts |
the frequencies of FreqDict.word_ipm converted to occurrences in the corpus of the dictionary |
size |
CORPUS_SIZE of ruts.datasets.freq2011, 92 million tokens of the modern subcorpus of the Russian National Corpus |
missing |
the least frequency of the dictionary FreqDict.min_ipm, 0.4 ipm (about 37 occurrences) |
key |
the lemma of the dictionary: the ruMorph lemma of a word form (with lemmatize=False the word itself) brought to the conventions of the dictionary, as in LexicalStats |
keep |
words of Cyrillic letters; numbers and words with Latin letters are left out |
A dictionary entry that no word form is reduced to is never a negative keyword: the dictionary keeps «во» and «со» as entries of their own, while ruMorph reduces these word forms to «в» and «с».
With lemmatize=False a lemma loses the conventions of the dictionary - the short form, the plural, the spelling variant («должный» instead of «должен», «деньга» instead of «деньги») - and such entries come out as false keywords, so compare word forms with the dictionary.
from ruts import WordsExtractor
from ruts.corpus import keyness
from ruts.datasets import FreqDict
# The dictionary is downloaded once with FreqDict().download()
words = WordsExtractor().extract(
"Кот сидел на окне и смотрел на птиц. Птицы улетели, и кот уснул на окне. "
"Завтра кот снова будет сидеть на окне и смотреть на птиц."
)
[(k.word, round(k.log_ratio, 1)) for k in keyness(words, FreqDict(), min_freq=3, top_n=2)]
[('кот', 11.5), ('птица', 10.3)]
Result¶
Keyword(word, freq_target, freq_reference, ipm_target, ipm_reference, g2, p_value, log_ratio, score)
A list of Keyword named tuples by descending keyness (ties broken by descending frequency and alphabetically, words of an undefined measure last); pd.DataFrame(keywords) gives a table.
| Field | Type | Description |
|---|---|---|
word |
str |
Word |
freq_target |
int |
Frequency in the target corpus |
freq_reference |
float |
Frequency in the reference corpus |
ipm_target |
float |
Frequency in the target corpus per million words, or n-grams |
ipm_reference |
float |
Frequency in the reference corpus per million words, or n-grams |
g2 |
float |
Signed \(G^2\) |
p_value |
float |
p-value of \(G^2\) |
log_ratio |
float |
Log Ratio |
score |
float |
Value of the chosen measure |
Measures¶
The measures of measure by key, with their names and descriptions in anyts.constants.KEYNESS_MEASURES:
| Key | Measures | Range | Higher means |
|---|---|---|---|
log_likelihood |
Significance of the difference of the frequencies | Any number | A more significant excess in the target corpus |
chi2 |
Significance of the difference, with Yates's correction | Any number | A more significant excess in the target corpus |
diff |
Difference of the frequencies per million, in percent of the reference | Above −100 | A larger excess in the target corpus |
log_ratio |
Binary logarithm of the ratio of the frequencies per million | Any number | A larger excess in the target corpus |
bic |
Evidence of the difference: \(G^2\) penalized by the size of the corpora | Any number | Stronger evidence of an excess in the target corpus, for a word more frequent there |
ell |
Effect size of \(G^2\) | −1 to 1 as a rule, nan for small expected frequencies |
A larger excess in the target corpus |
odds_ratio |
Ratio of the odds of the word in the corpora | 0 to inf, nan if the word fills both corpora |
Higher odds in the target corpus |
Every measure is a function of the module anyts.corpus.keyness of the frequencies of a word and the sizes of the corpora, \(N = c + d\):
| Parameter | Type | Default | Description |
|---|---|---|---|
a |
float |
- | Frequency of the word in the target corpus |
b |
float |
- | Frequency of the word in the reference corpus |
c |
float |
- | Size of the target corpus |
d |
float |
- | Size of the reference corpus |
A zero frequency in one of the corpora is replaced with 0.5 for %DIFF, Log Ratio and the odds ratio (Hardie 2014).
The module ruts.corpus.keyness re-exports the functions of the measures (from ruts.corpus.keyness import calc_log_likelihood).
Log-likelihood¶
calc_log_likelihood(a, b, c, d)
The log-likelihood of the frequencies of the word against the expected ones \(E_1\) and \(E_2\); a term of zero frequency is zero. The critical values are anyts.constants.G2_CRITICAL_VALUES: 3.84 for p < 0.05, 6.63 for p < 0.01, 10.83 for p < 0.001, 15.13 for p < 0.0001. The sign is negative when the word is more frequent in the reference.
calc_p_value(g2)
The p-value of a \(G^2\) or a chi-square, whatever its sign, by the chi-square distribution with one degree of freedom; an array of values gives an array.
Chi-square¶
calc_chi2(a, b, c, d)
The chi-square with Yates's correction over the 2×2 contingency table of the word and the other words of each corpus. When the correction exceeds the difference, the statistic is zero. The sign is negative when the word is more frequent in the reference.
%DIFF¶
calc_diff(a, b, c, d)
The difference of the frequencies \(NF\) per million words, in percent of the frequency in the reference.
Log Ratio¶
calc_log_ratio(a, b, c, d)
The binary logarithm of the ratio of the frequencies \(NF\) per million words: one means the word is twice as frequent in the target corpus.
BIC¶
calc_bic(a, b, c, d)
The Bayesian information criterion of \(G^2\). In absolute value above 2 it is positive evidence of a difference, above 6 strong, above 10 very strong; a value of the sign opposite to \(G^2\), when \(\lvert G^2 \rvert < \ln N\), means no evidence, not the opposite direction.
ELL¶
calc_ell(a, b, c, d)
The effect size of \(G^2\): the share of the greatest possible departure from the expected frequencies \(E_1\) and \(E_2\). It grows without bound as the least expected frequency nears one and is nan when that frequency is at most one (a logarithm of zero or below). The sign is negative when the word is more frequent in the reference.
Odds ratio¶
calc_odds_ratio(a, b, c, d)
The ratio of the odds of the word in the two corpora: one means equal odds. A word that fills the whole target corpus gives inf, the whole reference 0, both nan.