← Назад к вопросам

Как решал задачи классификации документов?

2.2 Middle🔥 61 комментариев
#Python Core#Другое

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Классификация документов: практические подходы и решения

Классификация документов — это одна из классических задач обработки естественного языка (NLP). За 10+ лет я применял различные подходы от простых до сложных, и опыт показывает, что выбор метода зависит от контекста, объёма данных и требований к скорости.

Этап 1. Подготовка данных

Качество результата на 80% зависит от качества данных:

import pandas as pd
from sklearn.model_selection import train_test_split

# Загрузка и изучение
df = pd.read_csv('documents.csv')
print(df.head())
print(df['category'].value_counts())  # Распределение классов

# Баланс классов
class_weights = compute_class_weights(df['category'])

Очистка текста:

import re
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize

def clean_text(text):
    text = text.lower()
    text = re.sub(r'[^\w\s]', '', text)
    tokens = word_tokenize(text)
    stop_words = set(stopwords.words('english'))
    tokens = [t for t in tokens if t not in stop_words]
    return ' '.join(tokens)

df['cleaned_text'] = df['text'].apply(clean_text)

Этап 2. Простые базовые подходы

TF-IDF + логистическая регрессия:

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline

pipeline = Pipeline([
    ('tfidf', TfidfVectorizer(max_features=5000, ngram_range=(1, 2))),
    ('clf', LogisticRegression(max_iter=1000, class_weight='balanced'))
])

pipeline.fit(X_train, y_train)
accuracy = pipeline.score(X_test, y_test)
print(f"Accuracy: {accuracy:.4f}")

Наивный Байес (когда мало данных):

from sklearn.naive_bayes import MultinomialNB

pipeline = Pipeline([
    ('tfidf', TfidfVectorizer(max_features=10000)),
    ('clf', MultinomialNB(alpha=0.1))
])

Этап 3. Градиентный бустинг

Когда нужна более высокая точность:

from xgboost import XGBClassifier
from sklearn.preprocessing import LabelEncoder

# Векторизация
vectorizer = TfidfVectorizer(max_features=10000, ngram_range=(1, 2))
X_train_vec = vectorizer.fit_transform(X_train)
X_test_vec = vectorizer.transform(X_test)

# Классификатор
clf = XGBClassifier(
    n_estimators=200,
    max_depth=6,
    learning_rate=0.1,
    subsample=0.8,
    colsample_bytree=0.8,
    use_label_encoder=False
)

clf.fit(X_train_vec, y_train)
predictions = clf.predict(X_test_vec)

Этап 4. Глубокое обучение

LSTM с embedding слоем:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dense, Dropout
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences

# Подготовка
tokenizer = Tokenizer(num_words=10000)
tokenizer.fit_on_texts(X_train)
X_train_seq = pad_sequences(tokenizer.texts_to_sequences(X_train), maxlen=200)

# Модель
model = Sequential([
    Embedding(10000, 128, input_length=200),
    LSTM(128, return_sequences=True),
    Dropout(0.2),
    LSTM(64),
    Dropout(0.2),
    Dense(64, activation='relu'),
    Dense(num_classes, activation='softmax')
])

model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(X_train_seq, y_train_encoded, epochs=10, batch_size=32, validation_split=0.1)

Трансформеры (BERT, RoBERTa):

from transformers import AutoTokenizer, AutoModelForSequenceClassification
import torch

tokenizer = AutoTokenizer.from_pretrained('bert-base-uncased')
model = AutoModelForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=4)

def predict(text):
    inputs = tokenizer(text, return_tensors='pt', truncation=True, max_length=512)
    outputs = model(**inputs)
    logits = outputs.logits
    prediction = torch.argmax(logits, dim=1).item()
    return prediction

pred = predict("This is a sample document")

Этап 5. Ансамбли

Комбинирование разных моделей для улучшения результата:

from sklearn.ensemble import VotingClassifier

clf1 = LogisticRegression()
clf2 = SVC(probability=True)
clf3 = RandomForestClassifier()

ensemble = VotingClassifier(
    estimators=[('lr', clf1), ('svc', clf2), ('rf', clf3)],
    voting='soft'
)

ensemble.fit(X_train, y_train)
score = ensemble.score(X_test, y_test)

Этап 6. Валидация и метрики

from sklearn.metrics import classification_report, confusion_matrix, f1_score
from sklearn.model_selection import cross_val_score

# Cross-validation
cv_scores = cross_val_score(clf, X_train, y_train, cv=5, scoring='f1_weighted')
print(f"CV Scores: {cv_scores.mean():.4f} +/- {cv_scores.std():.4f}")

# Детальный отчёт
y_pred = clf.predict(X_test)
print(classification_report(y_test, y_pred))
print(confusion_matrix(y_test, y_pred))

# F1-score (для несбалансированных данных)
f1 = f1_score(y_test, y_pred, average='weighted')

Практические рекомендации

Выбор метода по сценариям:

  • Мало данных (< 1000 документов): TF-IDF + логистическая регрессия или Наивный Байес
  • Среднее количество (1k-100k): XGBoost с TF-IDF или простые нейросети
  • Большие объёмы (> 100k): BERT, RoBERTa или другие трансформеры
  • Real-time требования: TF-IDF + LR или лёгкие ансамбли

Оптимизация качества:

  1. Начните с простого базлайна (TF-IDF + LR)
  2. Проверьте качество базлайна и метрики
  3. Постепенно усложняйте модель
  4. Используйте кросс-валидацию
  5. Мониторьте переобучение
  6. Применяйте класс-веса для несбалансированных данных

Распределённая обработка для больших датасетов:

from sklearn.feature_extraction.text import HashingVectorizer

vectorizer = HashingVectorizer(n_features=10000, norm='l2')
X_vec = vectorizer.transform(documents)

Основные выводы

Классификация документов — это эволюция от простых статистических методов к сложным нейросетям. Ключ к успеху: начните с простого, проверьте качество, затем постепенно усложняйте. Не нужна сложная модель, если простая уже хорошо работает. Инвестируйте в качество данных и feature engineering.

Как решал задачи классификации документов? | PrepBro