Как решал задачи классификации документов?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Классификация документов: практические подходы и решения
Классификация документов — это одна из классических задач обработки естественного языка (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 или лёгкие ансамбли
Оптимизация качества:
- Начните с простого базлайна (TF-IDF + LR)
- Проверьте качество базлайна и метрики
- Постепенно усложняйте модель
- Используйте кросс-валидацию
- Мониторьте переобучение
- Применяйте класс-веса для несбалансированных данных
Распределённая обработка для больших датасетов:
from sklearn.feature_extraction.text import HashingVectorizer
vectorizer = HashingVectorizer(n_features=10000, norm='l2')
X_vec = vectorizer.transform(documents)
Основные выводы
Классификация документов — это эволюция от простых статистических методов к сложным нейросетям. Ключ к успеху: начните с простого, проверьте качество, затем постепенно усложняйте. Не нужна сложная модель, если простая уже хорошо работает. Инвестируйте в качество данных и feature engineering.