Первичная версия: стилометрия реплик, LSA и протокол экспериментов
This commit is contained in:
86
lab1/stylometry/datasets.py
Normal file
86
lab1/stylometry/datasets.py
Normal file
@@ -0,0 +1,86 @@
|
||||
"""Подготовка таблицы реплик с токенами, тегами и текстами для LSA."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pandas as pd
|
||||
|
||||
from .io import DEFAULT_DATA_PATH, corpus_fingerprint, read_corpus
|
||||
from .tokenization import Tokenizer
|
||||
|
||||
DEFAULT_CACHE_PATH = Path(__file__).resolve().parents[1] / "data" / "processed" / "tokenized.pkl"
|
||||
|
||||
REQUIRED_COLUMNS = {
|
||||
"line_id",
|
||||
"character",
|
||||
"text",
|
||||
"tokens",
|
||||
"ptb",
|
||||
"upos",
|
||||
"sentences",
|
||||
"pos_text",
|
||||
"fw_text",
|
||||
"content_text",
|
||||
}
|
||||
|
||||
|
||||
def build_feature_frame(
|
||||
data_path: str | Path | None = None,
|
||||
tokenizer: Tokenizer | None = None,
|
||||
verbose: bool = True,
|
||||
) -> pd.DataFrame:
|
||||
"""Читает корпус и добавляет результаты токенизации и разметки."""
|
||||
data_path = Path(data_path) if data_path is not None else DEFAULT_DATA_PATH
|
||||
frame = read_corpus(data_path)
|
||||
tokenizer = tokenizer or Tokenizer(use_nltk=True)
|
||||
features = tokenizer.analyze_frame(frame, verbose=verbose)
|
||||
features.attrs["corpus_path"] = str(data_path)
|
||||
features.attrs["corpus_sha256"] = corpus_fingerprint(data_path)
|
||||
features.attrs["nltk_used"] = tokenizer.use_nltk
|
||||
features.attrs["pos_available"] = tokenizer.pos_available
|
||||
return features
|
||||
|
||||
|
||||
def save_feature_frame(frame: pd.DataFrame, path: str | Path) -> Path:
|
||||
path = Path(path)
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
frame.to_pickle(path)
|
||||
return path
|
||||
|
||||
|
||||
def load_feature_frame(
|
||||
data_path: str | Path | None = None,
|
||||
cache_path: str | Path | None = None,
|
||||
force: bool = False,
|
||||
verbose: bool = True,
|
||||
) -> pd.DataFrame:
|
||||
"""Загружает кэш токенизации или строит его заново.
|
||||
|
||||
Кэш проверяется по SHA-256 исходного файла. Если файл корпуса изменился,
|
||||
токенизация выполняется повторно.
|
||||
"""
|
||||
data_path = Path(data_path) if data_path is not None else DEFAULT_DATA_PATH
|
||||
cache_path = Path(cache_path) if cache_path is not None else DEFAULT_CACHE_PATH
|
||||
|
||||
if cache_path.exists() and not force:
|
||||
try:
|
||||
frame = pd.read_pickle(cache_path)
|
||||
if REQUIRED_COLUMNS <= set(frame.columns):
|
||||
cached_hash = frame.attrs.get("corpus_sha256")
|
||||
current_hash = corpus_fingerprint(data_path)
|
||||
if cached_hash == current_hash:
|
||||
if verbose:
|
||||
print(f"[datasets] загружен кэш: {cache_path}")
|
||||
return frame
|
||||
if verbose:
|
||||
print("[datasets] корпус изменился, пересобираю признаки.")
|
||||
except Exception as error:
|
||||
if verbose:
|
||||
print(f"[datasets] не удалось прочитать кэш ({error}), пересобираю.")
|
||||
|
||||
frame = build_feature_frame(data_path, verbose=verbose)
|
||||
save_feature_frame(frame, cache_path)
|
||||
if verbose:
|
||||
print(f"[datasets] кэш сохранён: {cache_path}")
|
||||
return frame
|
||||
Reference in New Issue
Block a user