humetrix 0.3.0__py3-none-any.whl
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.
- humetrix/__init__.py +14 -0
- humetrix/_resources.py +58 -0
- humetrix/analyzer.py +397 -0
- humetrix/configs.py +36 -0
- humetrix/kaoetal.py +384 -0
- humetrix/quantum_entropy.py +298 -0
- humetrix/skipgram.py +294 -0
- humetrix/surprise.py +169 -0
- humetrix-0.3.0.dist-info/METADATA +107 -0
- humetrix-0.3.0.dist-info/RECORD +12 -0
- humetrix-0.3.0.dist-info/WHEEL +4 -0
- humetrix-0.3.0.dist-info/licenses/LICENSE +9 -0
humetrix/__init__.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from .analyzer import HumorAnalyzer
|
|
2
|
+
from .quantum_entropy import QuantumUncertainty, QuantumIncongruity
|
|
3
|
+
from .surprise import LocalGlobalSurprise
|
|
4
|
+
from .kaoetal import KaoConfig, KaoAmbiguity, KaoDistinctiveness
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"HumorAnalyzer",
|
|
8
|
+
"QuantumUncertainty",
|
|
9
|
+
"QuantumIncongruity",
|
|
10
|
+
"LocalGlobalSurprise",
|
|
11
|
+
"KaoConfig",
|
|
12
|
+
"KaoAmbiguity",
|
|
13
|
+
"KaoDistinctiveness"
|
|
14
|
+
]
|
humetrix/_resources.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""Download and load the external resources used by the metrics."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Iterable, Optional
|
|
5
|
+
|
|
6
|
+
import safetensors.numpy
|
|
7
|
+
from gensim.models import KeyedVectors
|
|
8
|
+
from huggingface_hub import hf_hub_download
|
|
9
|
+
|
|
10
|
+
from .configs import EXTERNAL_EMBEDDINGS, RESOURCES_REPO, RESOURCES_REVISION
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def download_resource(
|
|
14
|
+
filenames: Iterable[str],
|
|
15
|
+
subfolder: Optional[str] = None,
|
|
16
|
+
repo_id: str = RESOURCES_REPO,
|
|
17
|
+
revision: str = RESOURCES_REVISION,
|
|
18
|
+
) -> Path:
|
|
19
|
+
"""Download files from the Hugging Face Hub repository and return their directory."""
|
|
20
|
+
|
|
21
|
+
paths = [
|
|
22
|
+
hf_hub_download(repo_id, filename, subfolder=subfolder, revision=revision)
|
|
23
|
+
for filename in filenames
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
if not paths:
|
|
27
|
+
raise ValueError("At least one filename is required.")
|
|
28
|
+
return Path(paths[0]).parent
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def download_embeddings(language: str) -> Path:
|
|
32
|
+
"""Download the default glove embeddings for a language."""
|
|
33
|
+
filenames = ["embeddings.safetensors", "vocab.txt"]
|
|
34
|
+
if language in EXTERNAL_EMBEDDINGS:
|
|
35
|
+
repo_id, revision = EXTERNAL_EMBEDDINGS[language]
|
|
36
|
+
return download_resource(filenames, repo_id=repo_id, revision=revision)
|
|
37
|
+
return download_resource(filenames, subfolder=f"glove/{language}")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def load_embeddings(directory: Path) -> KeyedVectors:
|
|
41
|
+
"""Load embeddings from `embeddings.safetensors` + `vocab.txt` files."""
|
|
42
|
+
tensors = safetensors.numpy.load_file(directory / "embeddings.safetensors")
|
|
43
|
+
vectors = tensors["embeddings"]
|
|
44
|
+
|
|
45
|
+
with open(directory / "vocab.txt", encoding="utf-8", newline="\n") as f:
|
|
46
|
+
vocab = f.read().split("\n")
|
|
47
|
+
if vocab[-1] == "":
|
|
48
|
+
vocab.pop()
|
|
49
|
+
|
|
50
|
+
if len(vocab) != len(vectors):
|
|
51
|
+
raise ValueError(
|
|
52
|
+
f"{directory}: vocab.txt has {len(vocab)} words, "
|
|
53
|
+
f"but the matrix has {len(vectors)} rows."
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
embeddings = KeyedVectors(vector_size=vectors.shape[1])
|
|
57
|
+
embeddings.add_vectors(vocab, vectors)
|
|
58
|
+
return embeddings
|
humetrix/analyzer.py
ADDED
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module provides a centralized API for analyzing humor in text using various metrics.
|
|
3
|
+
|
|
4
|
+
The HumorAnalyzer class requires at least the analysis language. Depending on the metrics
|
|
5
|
+
to be used, additional resources such as word embeddings, skip-gram models, and n-gram models
|
|
6
|
+
may need to be provided.
|
|
7
|
+
|
|
8
|
+
Resources are loaded as needed to optimize performance.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import importlib
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from typing import Dict, Union
|
|
14
|
+
|
|
15
|
+
import polars as pl
|
|
16
|
+
import safetensors.torch
|
|
17
|
+
import spacy
|
|
18
|
+
import torch
|
|
19
|
+
from gensim.models import KeyedVectors
|
|
20
|
+
from spacy.language import Language
|
|
21
|
+
from transformers import AutoModelForMaskedLM, AutoTokenizer, Pipeline, pipeline
|
|
22
|
+
|
|
23
|
+
from ._resources import download_embeddings, download_resource, load_embeddings
|
|
24
|
+
from .configs import SPACY_MODELS, TOKENIZER_MODELS, TRANSFORMER_MODELS
|
|
25
|
+
from .kaoetal import KaoAmbiguity, KaoConfig, KaoDistinctiveness
|
|
26
|
+
from .quantum_entropy import QuantumIncongruity, QuantumUncertainty
|
|
27
|
+
from .skipgram import SGNS, build_vocabulary
|
|
28
|
+
from .surprise import LocalGlobalSurprise
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _load_spacy_model(name: str) -> Language:
|
|
32
|
+
"""Load a spacy mode, downloading it on first use if needed."""
|
|
33
|
+
try:
|
|
34
|
+
return spacy.load(name)
|
|
35
|
+
except OSError:
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
from spacy.cli.download import download
|
|
39
|
+
|
|
40
|
+
try:
|
|
41
|
+
download(name)
|
|
42
|
+
except SystemExit:
|
|
43
|
+
raise OSError(
|
|
44
|
+
f"spacy model {name} is not installed and could not be "
|
|
45
|
+
f"downloaded automatically. Install it with:\n"
|
|
46
|
+
f" python -m spacy download {name}"
|
|
47
|
+
) from None
|
|
48
|
+
|
|
49
|
+
importlib.invalidate_caches()
|
|
50
|
+
return spacy.load(name)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class HumorAnalyzer:
|
|
54
|
+
"""
|
|
55
|
+
A class to analyze humor in text using different metrics.
|
|
56
|
+
|
|
57
|
+
Some of the metrics implemented here require external resources such as word embeddings,
|
|
58
|
+
skip-gram models, and n-gram models.
|
|
59
|
+
|
|
60
|
+
Supported metrics include:
|
|
61
|
+
- Quantum Incongruity
|
|
62
|
+
- Quantum Uncertainty
|
|
63
|
+
- Local-Global Surprise
|
|
64
|
+
- Kao et al.'s Ambiguity
|
|
65
|
+
- Kao et al.'s Distinctiveness
|
|
66
|
+
|
|
67
|
+
Parameters
|
|
68
|
+
----------
|
|
69
|
+
language : str
|
|
70
|
+
The language of analysis.
|
|
71
|
+
embeddings_path : str, optional
|
|
72
|
+
Directory with `embeddings.safetensors` and `vocab.txt`. If None, the default embeddings for the language are downloaded.
|
|
73
|
+
skipgram_path : str, optional
|
|
74
|
+
Path to the skip-gram model file is safetensors format. If None (together with `skipgram_vocab_path`), the default model for the language is downloaded.
|
|
75
|
+
skipgram_vocab_path: str, optional
|
|
76
|
+
CSV vocabulary used to train the skipgram model (column `ngram`). Required when `skipgram_path` is given.
|
|
77
|
+
ngram_dir_path : str, optional
|
|
78
|
+
Directory with `1gram.csv` and `3gram.csv`. If None, the default n-gram tables for the language are downloaded.
|
|
79
|
+
transformer_model_name : str, optional
|
|
80
|
+
Name of the transformer model to use. Defaults to None.
|
|
81
|
+
device: str or torch.device, optional
|
|
82
|
+
Device for the neural models. If None, eses a GPU when available.
|
|
83
|
+
|
|
84
|
+
Raises
|
|
85
|
+
------
|
|
86
|
+
ValueError
|
|
87
|
+
If the specified language is not supported.
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
def __init__(
|
|
91
|
+
self,
|
|
92
|
+
language: str,
|
|
93
|
+
embeddings_path: Union[str, None] = None,
|
|
94
|
+
skipgram_path: Union[str, None] = None,
|
|
95
|
+
skipgram_vocab_path: Union[str, None] = None,
|
|
96
|
+
ngram_dir_path: Union[str, None] = None,
|
|
97
|
+
transformer_model_name: Union[str, None] = None,
|
|
98
|
+
device: Union[str, torch.device, None] = None,
|
|
99
|
+
) -> None:
|
|
100
|
+
self.language = language
|
|
101
|
+
if language not in SPACY_MODELS:
|
|
102
|
+
raise ValueError(f"Unsupported language: {language}")
|
|
103
|
+
|
|
104
|
+
if device is None:
|
|
105
|
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
|
106
|
+
self.device = torch.device(device)
|
|
107
|
+
|
|
108
|
+
self._transformer_model_name = transformer_model_name
|
|
109
|
+
self._paths = {
|
|
110
|
+
"embeddings": embeddings_path,
|
|
111
|
+
"skipgram": skipgram_path,
|
|
112
|
+
"skipgram_vocab": skipgram_vocab_path,
|
|
113
|
+
"ngram_dir": ngram_dir_path,
|
|
114
|
+
}
|
|
115
|
+
self._models = {}
|
|
116
|
+
|
|
117
|
+
def _load_model(
|
|
118
|
+
self, name: str
|
|
119
|
+
) -> Union[Language, Dict, KeyedVectors, pl.DataFrame, SGNS, Pipeline]:
|
|
120
|
+
"""
|
|
121
|
+
Load and cache the specified model.
|
|
122
|
+
|
|
123
|
+
Parameters
|
|
124
|
+
----------
|
|
125
|
+
name : str
|
|
126
|
+
The name of the model to load.
|
|
127
|
+
|
|
128
|
+
Returns
|
|
129
|
+
-------
|
|
130
|
+
spacy model or dict or gensim KeyedVectors or polars DataFrame or SGNS model or transformers pipeline
|
|
131
|
+
The loaded model.
|
|
132
|
+
|
|
133
|
+
Raises
|
|
134
|
+
------
|
|
135
|
+
ValueError
|
|
136
|
+
If the model type is unknown or required paths are not provided.
|
|
137
|
+
"""
|
|
138
|
+
if name not in self._models:
|
|
139
|
+
if name == "spacy":
|
|
140
|
+
model_name = SPACY_MODELS[self.language]
|
|
141
|
+
self._models[name] = _load_spacy_model(model_name)
|
|
142
|
+
elif name == "tokenizer":
|
|
143
|
+
if self.language in TOKENIZER_MODELS:
|
|
144
|
+
model_name = TOKENIZER_MODELS[self.language]
|
|
145
|
+
self._models[name] = _load_spacy_model(model_name)
|
|
146
|
+
else:
|
|
147
|
+
self._models[name] = spacy.blank(self.language)
|
|
148
|
+
elif name == "bert":
|
|
149
|
+
model_name = TRANSFORMER_MODELS[self.language]
|
|
150
|
+
tokenizer = AutoTokenizer.from_pretrained(model_name)
|
|
151
|
+
lm = AutoModelForMaskedLM.from_pretrained(
|
|
152
|
+
model_name, device_map=self.device
|
|
153
|
+
)
|
|
154
|
+
self._models[name] = {"tokenizer": tokenizer, "lm": lm}
|
|
155
|
+
elif name == "embeddings":
|
|
156
|
+
directory = self._paths["embeddings"]
|
|
157
|
+
if directory is None:
|
|
158
|
+
directory = download_embeddings(self.language)
|
|
159
|
+
self._models[name] = load_embeddings(Path(directory))
|
|
160
|
+
elif name == "ngram1" or name == "ngram3":
|
|
161
|
+
ngram_dir = self._paths["ngram_dir"]
|
|
162
|
+
if ngram_dir is None:
|
|
163
|
+
ngram_dir = download_resource(
|
|
164
|
+
["1gram.csv", "3gram.csv"], subfolder=f"ngrams/{self.language}"
|
|
165
|
+
)
|
|
166
|
+
ngram_path = Path(ngram_dir) / f"{name[-1]}gram.csv"
|
|
167
|
+
self._models[name] = pl.read_csv(ngram_path)
|
|
168
|
+
elif name == "kao_models":
|
|
169
|
+
skipgram_path = self._paths["skipgram"]
|
|
170
|
+
vocab_path = self._paths["skipgram_vocab"]
|
|
171
|
+
if skipgram_path is None and vocab_path is None:
|
|
172
|
+
skipgram_dir = download_resource(
|
|
173
|
+
["model.safetensors"], subfolder=f"skipgram/{self.language}"
|
|
174
|
+
)
|
|
175
|
+
vocab_dir = download_resource(
|
|
176
|
+
["1gram.csv"], subfolder=f"ngrams/{self.language}"
|
|
177
|
+
)
|
|
178
|
+
skipgram_path = skipgram_dir / "model.safetensors"
|
|
179
|
+
vocab_path = vocab_dir / "1gram.csv"
|
|
180
|
+
elif skipgram_path is None or vocab_path is None:
|
|
181
|
+
raise ValueError(
|
|
182
|
+
"Provide both `skipgram_path` and `skipgram_vocab_path`, "
|
|
183
|
+
"or neither to use the default skipgram model."
|
|
184
|
+
)
|
|
185
|
+
vocab = build_vocabulary(str(vocab_path))
|
|
186
|
+
state_dict = safetensors.torch.load_file(skipgram_path)
|
|
187
|
+
embedding_dim = state_dict["embeddings.weight"].shape[1]
|
|
188
|
+
sgns = SGNS(vocab, embedding_dim)
|
|
189
|
+
sgns.load_state_dict(state_dict)
|
|
190
|
+
sgns.eval()
|
|
191
|
+
self._models[name] = {
|
|
192
|
+
"skipgram": sgns,
|
|
193
|
+
"ngram1": self._load_model("ngram1"),
|
|
194
|
+
"ngram3": self._load_model("ngram3"),
|
|
195
|
+
}
|
|
196
|
+
elif name == "transformer_pipeline":
|
|
197
|
+
if self._transformer_model_name:
|
|
198
|
+
model_name = self._transformer_model_name
|
|
199
|
+
else:
|
|
200
|
+
model_name = TRANSFORMER_MODELS[self.language]
|
|
201
|
+
self._models[name] = pipeline(
|
|
202
|
+
"feature-extraction", model_name, device=self.device
|
|
203
|
+
)
|
|
204
|
+
else:
|
|
205
|
+
raise ValueError(f"Unknown model type: {name}")
|
|
206
|
+
return self._models[name]
|
|
207
|
+
|
|
208
|
+
def quantum_incongruity(
|
|
209
|
+
self, sentence: str, backend: str = "word_embeddings"
|
|
210
|
+
) -> Union[float, None]:
|
|
211
|
+
"""
|
|
212
|
+
Calculate the quantum incongruity of a sentence.
|
|
213
|
+
|
|
214
|
+
Parameters
|
|
215
|
+
----------
|
|
216
|
+
sentence : str
|
|
217
|
+
The sentence to analyze.
|
|
218
|
+
backend : {'word_embeddings', 'transformer'}, optional
|
|
219
|
+
The backend to use for embeddings. Defaults to 'word_embeddings'.
|
|
220
|
+
|
|
221
|
+
Returns
|
|
222
|
+
-------
|
|
223
|
+
float or None
|
|
224
|
+
The quantum incongruity score, or None if it cannot be calculated.
|
|
225
|
+
|
|
226
|
+
Raises
|
|
227
|
+
------
|
|
228
|
+
ValueError
|
|
229
|
+
If an unknown backend is specified.
|
|
230
|
+
|
|
231
|
+
See Also
|
|
232
|
+
--------
|
|
233
|
+
quantum_entropy.QuantumIncongruity.score : Method that performs the actual scoring.
|
|
234
|
+
"""
|
|
235
|
+
if backend == "word_embeddings":
|
|
236
|
+
embeddings = self._load_model("embeddings")
|
|
237
|
+
elif backend == "transformer":
|
|
238
|
+
embeddings = self._load_model("transformer_pipeline")
|
|
239
|
+
else:
|
|
240
|
+
raise ValueError(f"Unknown backend for quantum incongruity: {backend}")
|
|
241
|
+
scorer = QuantumIncongruity(
|
|
242
|
+
sentence=sentence,
|
|
243
|
+
embeddings=embeddings,
|
|
244
|
+
spacy_model=self._load_model("tokenizer"),
|
|
245
|
+
device=self.device,
|
|
246
|
+
)
|
|
247
|
+
return scorer.score()
|
|
248
|
+
|
|
249
|
+
def quantum_uncertainty(
|
|
250
|
+
self, sentence: str, backend: str = "word_embeddings"
|
|
251
|
+
) -> Union[float, None]:
|
|
252
|
+
"""
|
|
253
|
+
Calculate the quantum uncertainty of a sentence.
|
|
254
|
+
|
|
255
|
+
Parameters
|
|
256
|
+
----------
|
|
257
|
+
sentence : str
|
|
258
|
+
The sentence to analyze.
|
|
259
|
+
backend : {'word_embeddings', 'transformer'}, optional
|
|
260
|
+
The backend to use for embeddings. Defaults to 'word_embeddings'.
|
|
261
|
+
|
|
262
|
+
Returns
|
|
263
|
+
-------
|
|
264
|
+
float or None
|
|
265
|
+
The quantum uncertainty score, or None if it cannot be calculated.
|
|
266
|
+
|
|
267
|
+
Raises
|
|
268
|
+
------
|
|
269
|
+
ValueError
|
|
270
|
+
If an unknown backend is specified.
|
|
271
|
+
|
|
272
|
+
See Also
|
|
273
|
+
--------
|
|
274
|
+
quantum_entropy.QuantumUncertainty.score : Method that performs the actual scoring.
|
|
275
|
+
"""
|
|
276
|
+
if backend == "word_embeddings":
|
|
277
|
+
embeddings = self._load_model("embeddings")
|
|
278
|
+
elif backend == "transformer":
|
|
279
|
+
embeddings = self._load_model("transformer_pipeline")
|
|
280
|
+
else:
|
|
281
|
+
raise ValueError(f"Unknown backend for quantum uncertainty: {backend}")
|
|
282
|
+
scorer = QuantumUncertainty(
|
|
283
|
+
sentence=sentence,
|
|
284
|
+
embeddings=embeddings,
|
|
285
|
+
spacy_model=self._load_model("tokenizer"),
|
|
286
|
+
device=self.device,
|
|
287
|
+
)
|
|
288
|
+
return scorer.score()
|
|
289
|
+
|
|
290
|
+
def local_global_surprise(
|
|
291
|
+
self, sentence: str, pun_sign: str, alt_sign: str
|
|
292
|
+
) -> float:
|
|
293
|
+
"""
|
|
294
|
+
Calculate the local-global surprise of a sentence.
|
|
295
|
+
|
|
296
|
+
Parameters
|
|
297
|
+
----------
|
|
298
|
+
sentence : str
|
|
299
|
+
The sentence to analyze.
|
|
300
|
+
pun_sign : str
|
|
301
|
+
The pun sign. The word or phrase that is ambiguous or humorous.
|
|
302
|
+
alt_sign : str
|
|
303
|
+
The alternative sign. The word or phrase that is evoked by the pun sign.
|
|
304
|
+
|
|
305
|
+
Returns
|
|
306
|
+
-------
|
|
307
|
+
float
|
|
308
|
+
The local-global surprise score.
|
|
309
|
+
|
|
310
|
+
See Also
|
|
311
|
+
--------
|
|
312
|
+
surprise.LocalGlobalSurprise.score : Method that performs the actual scoring.
|
|
313
|
+
"""
|
|
314
|
+
bert_models = self._load_model("bert")
|
|
315
|
+
scorer = LocalGlobalSurprise(
|
|
316
|
+
sentence=sentence,
|
|
317
|
+
pun_sign=pun_sign,
|
|
318
|
+
alt_sign=alt_sign,
|
|
319
|
+
spacy_model=self._load_model("tokenizer"),
|
|
320
|
+
)
|
|
321
|
+
return scorer.score(tokenizer=bert_models["tokenizer"], lm=bert_models["lm"])
|
|
322
|
+
|
|
323
|
+
def kao_ambiguity(self, sentence: str, pun_sign: str, alt_sign: str) -> float:
|
|
324
|
+
"""
|
|
325
|
+
Calculate Kao et al.'s ambiguity of a sentence.
|
|
326
|
+
|
|
327
|
+
Parameters
|
|
328
|
+
----------
|
|
329
|
+
sentence : str
|
|
330
|
+
The sentence to analyze.
|
|
331
|
+
pun_sign : str
|
|
332
|
+
The pun sign. The word or phrase that is ambiguous or humorous.
|
|
333
|
+
alt_sign : str
|
|
334
|
+
The alternative sign. The word or phrase that is evoked by the pun sign.
|
|
335
|
+
|
|
336
|
+
Returns
|
|
337
|
+
-------
|
|
338
|
+
float
|
|
339
|
+
Ambiguity score.
|
|
340
|
+
|
|
341
|
+
See Also
|
|
342
|
+
--------
|
|
343
|
+
kaoetal.KaoAmbiguity.score : Method that performs the actual scoring.
|
|
344
|
+
"""
|
|
345
|
+
kao_models = self._load_model("kao_models")
|
|
346
|
+
config = KaoConfig(
|
|
347
|
+
sentence=sentence,
|
|
348
|
+
language=self.language,
|
|
349
|
+
spacy_model=self._load_model("spacy"),
|
|
350
|
+
skipgram=kao_models["skipgram"],
|
|
351
|
+
)
|
|
352
|
+
scorer = KaoAmbiguity(
|
|
353
|
+
config=config,
|
|
354
|
+
pun_sign=pun_sign,
|
|
355
|
+
alt_sign=alt_sign,
|
|
356
|
+
ngram1=kao_models["ngram1"],
|
|
357
|
+
ngram3=kao_models["ngram3"],
|
|
358
|
+
)
|
|
359
|
+
return scorer.score()
|
|
360
|
+
|
|
361
|
+
def kao_distinctiveness(self, sentence: str, pun_sign: str, alt_sign: str) -> float:
|
|
362
|
+
"""
|
|
363
|
+
Calculate Kao et al.'s distinctiveness of a sentence.
|
|
364
|
+
|
|
365
|
+
Parameters
|
|
366
|
+
----------
|
|
367
|
+
sentence : str
|
|
368
|
+
The sentence to analyze.
|
|
369
|
+
pun_sign : str
|
|
370
|
+
The pun sign. The word or phrase that is ambiguous or humorous.
|
|
371
|
+
alt_sign : str
|
|
372
|
+
The alternative sign. The word or phrase that is evoked by the pun sign.
|
|
373
|
+
|
|
374
|
+
Returns
|
|
375
|
+
-------
|
|
376
|
+
float
|
|
377
|
+
Distinctiveness score.
|
|
378
|
+
|
|
379
|
+
See Also
|
|
380
|
+
--------
|
|
381
|
+
kaoetal.KaoDistinctiveness.score : Method that performs the actual scoring.
|
|
382
|
+
"""
|
|
383
|
+
kao_models = self._load_model("kao_models")
|
|
384
|
+
config = KaoConfig(
|
|
385
|
+
sentence=sentence,
|
|
386
|
+
language=self.language,
|
|
387
|
+
spacy_model=self._load_model("spacy"),
|
|
388
|
+
skipgram=kao_models["skipgram"],
|
|
389
|
+
)
|
|
390
|
+
scorer = KaoDistinctiveness(
|
|
391
|
+
config=config,
|
|
392
|
+
pun_sign=pun_sign,
|
|
393
|
+
alt_sign=alt_sign,
|
|
394
|
+
ngram1=kao_models["ngram1"],
|
|
395
|
+
ngram3=kao_models["ngram3"],
|
|
396
|
+
)
|
|
397
|
+
return scorer.score()
|
humetrix/configs.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Definition of constants: language codes, spacy models, transformer models, and content word POS tags.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
SPACY_MODELS = {
|
|
6
|
+
"pt": "pt_core_news_lg",
|
|
7
|
+
"en": "en_core_web_trf",
|
|
8
|
+
"fr": "fr_dep_news_trf",
|
|
9
|
+
"es": "es_dep_news_trf",
|
|
10
|
+
"zh": "zh_core_web_trf",
|
|
11
|
+
}
|
|
12
|
+
# Pipelines used only for tokenization in QE and Suprise metrics.
|
|
13
|
+
# Languages not listed here use spacy.blank(language).
|
|
14
|
+
TOKENIZER_MODELS = {"zh": "zh_core_web_sm"}
|
|
15
|
+
TRANSFORMER_MODELS = {
|
|
16
|
+
"pt": "neuralmind/bert-base-portuguese-cased",
|
|
17
|
+
"en": "bert-base-cased",
|
|
18
|
+
"fr": "camembert-base",
|
|
19
|
+
"es": "dccuchile/bert-base-spanish-wwm-cased",
|
|
20
|
+
"zh": "bert-base-chinese",
|
|
21
|
+
}
|
|
22
|
+
CONTENT_WORD_TAGS = {
|
|
23
|
+
"pt": {"ADJ", "ADV", "AUX", "NOUN", "NUM", "PART", "PROPN", "VERB"},
|
|
24
|
+
"en": {"ADJ", "ADV", "AUX", "NOUN", "NUM", "PART", "PROPN", "VERB"},
|
|
25
|
+
"fr": {"ADJ", "ADV", "AUX", "NOUN", "NUM", "PART", "PROPN", "VERB"},
|
|
26
|
+
"es": {"ADJ", "ADV", "AUX", "NOUN", "NUM", "PART", "PROPN", "VERB"},
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
# Hugging Face Hub repository with GloVe, skip-gram and n-gram resources
|
|
30
|
+
RESOURCES_REPO = "NLP-CISUC/humetrix-resources"
|
|
31
|
+
RESOURCES_REVISION = "cef7d0ac55fae7c154b4bb588de0be2f6d43432b"
|
|
32
|
+
|
|
33
|
+
# GloVe embeddings hosted elsewere: language -> (repo_id, revision)
|
|
34
|
+
EXTERNAL_EMBEDDINGS = {
|
|
35
|
+
"pt": ("nilc-nlp/glove-300d", "44dac98d46b885135a7fe1565f5c67f0f897a4ea")
|
|
36
|
+
}
|