位置: 文档库 > Python > 使用python实现一个小型的文本分类系统

使用python实现一个小型的文本分类系统

森林里的鹿 上传于 2025-03-18 20:40

《使用Python实现一个小型的文本分类系统》

文本分类是自然语言处理(NLP)中的基础任务,广泛应用于垃圾邮件检测、情感分析、新闻分类等领域。本文将通过Python实现一个基于机器学习的小型文本分类系统,涵盖数据预处理、特征提取、模型训练与评估的全流程。系统采用经典的TF-IDF特征结合逻辑回归模型,并使用scikit-learn库简化开发流程。

一、系统设计概述

一个完整的文本分类系统通常包含以下模块:

  • 数据收集与预处理:清洗文本数据,去除噪声

  • 特征工程:将文本转换为数值特征

  • 模型选择与训练:选择分类算法并拟合数据

  • 评估与优化:通过指标评估模型性能

  • 预测应用:对新文本进行分类

本文以20 Newsgroups数据集(包含20个主题的新闻组文本)为例,演示从数据加载到模型部署的全过程。

二、环境准备与数据加载

首先安装必要库并加载数据:

pip install scikit-learn numpy pandas

使用scikit-learn内置的数据集加载器:

from sklearn.datasets import fetch_20newsgroups

# 加载训练集和测试集
categories = ['rec.sport.baseball', 'comp.graphics', 'sci.med']
train_data = fetch_20newsgroups(subset='train', categories=categories, shuffle=True)
test_data = fetch_20newsgroups(subset='test', categories=categories, shuffle=True)

print(f"训练集样本数: {len(train_data.data)}")
print(f"测试集样本数: {len(test_data.data)}")
print(f"类别: {train_data.target_names}")

输出示例:

训练集样本数: 1487
测试集样本数: 993
类别: ['comp.graphics', 'rec.sport.baseball', 'sci.med']

三、文本预处理

原始文本包含标点、大小写等噪声,需进行标准化处理:

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

nltk.download('punkt')
nltk.download('stopwords')

def preprocess_text(text):
    # 转换为小写
    text = text.lower()
    # 移除特殊字符和数字
    text = re.sub(r'[^a-zA-Z\s]', '', text)
    # 分词
    tokens = word_tokenize(text)
    # 移除停用词
    stop_words = set(stopwords.words('english'))
    tokens = [word for word in tokens if word not in stop_words]
    # 词干提取
    stemmer = PorterStemmer()
    tokens = [stemmer.stem(word) for word in tokens]
    return ' '.join(tokens)

# 示例预处理
sample_text = "Baseball's World Series starts in October! Graphics cards cost $500."
print(preprocess_text(sample_text))

输出:

basebal world seri start octob graphic card cost

四、特征提取

将文本转换为数值特征是分类的关键步骤。本文使用TF-IDF(词频-逆文档频率)方法:

from sklearn.feature_extraction.text import TfidfVectorizer

# 创建TF-IDF向量化器
tfidf_vectorizer = TfidfVectorizer(max_features=5000)  # 限制特征数量

# 拟合训练数据并转换
X_train = tfidf_vectorizer.fit_transform(
    [preprocess_text(text) for text in train_data.data]
)
y_train = train_data.target

# 转换测试数据
X_test = tfidf_vectorizer.transform(
    [preprocess_text(text) for text in test_data.data]
)
y_test = test_data.target

print(f"特征矩阵形状: {X_train.shape}")

输出示例:

特征矩阵形状: (1487, 5000)

五、模型训练与评估

选择逻辑回归作为分类器,因其适合高维稀疏数据:

from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, accuracy_score

# 初始化模型
model = LogisticRegression(max_iter=1000)

# 训练模型
model.fit(X_train, y_train)

# 预测测试集
y_pred = model.predict(X_test)

# 评估指标
print("准确率:", accuracy_score(y_test, y_pred))
print("\n分类报告:")
print(classification_report(y_test, y_pred, target_names=train_data.target_names))

输出示例:

准确率: 0.9234642497482377

分类报告:
              precision    recall  f1-score   support

comp.graphics       0.91      0.95      0.93       389
rec.sport.baseball       0.94      0.91      0.92       316
      sci.med       0.92      0.91      0.91       288

    accuracy                           0.92       993
   macro avg       0.92      0.92      0.92       993
weighted avg       0.92      0.92      0.92       993

六、模型优化

通过调整超参数和特征工程提升性能:

1. 网格搜索调参

from sklearn.model_selection import GridSearchCV

param_grid = {
    'C': [0.1, 1, 10],
    'penalty': ['l1', 'l2'],
    'solver': ['liblinear']
}

grid_search = GridSearchCV(LogisticRegression(max_iter=1000), param_grid, cv=5)
grid_search.fit(X_train, y_train)

print("最佳参数:", grid_search.best_params_)
best_model = grid_search.best_estimator_

2. 使用n-gram特征

tfidf_vectorizer = TfidfVectorizer(
    max_features=5000,
    ngram_range=(1, 2)  # 包含单字和双字组合
)
X_train = tfidf_vectorizer.fit_transform(...)

3. 处理类别不平衡

from sklearn.utils import class_weight

classes = np.unique(y_train)
weights = class_weight.compute_sample_weight('balanced', y_train)

model.fit(X_train, y_train, sample_weight=weights)

七、完整系统实现

将各模块整合为可复用的类:

import numpy as np
from sklearn.base import BaseEstimator, ClassifierMixin

class TextClassifier(BaseEstimator, ClassifierMixin):
    def __init__(self, vectorizer=None, classifier=None):
        self.vectorizer = vectorizer or TfidfVectorizer(max_features=5000)
        self.classifier = classifier or LogisticRegression(max_iter=1000)
    
    def fit(self, X, y):
        X_vec = self.vectorizer.fit_transform(X)
        self.classifier.fit(X_vec, y)
        return self
    
    def predict(self, X):
        X_vec = self.vectorizer.transform(X)
        return self.classifier.predict(X_vec)
    
    def score(self, X, y):
        y_pred = self.predict(X)
        return accuracy_score(y, y_pred)

# 使用示例
classifier = TextClassifier()
classifier.fit(
    [preprocess_text(text) for text in train_data.data],
    train_data.target
)
print("测试集准确率:", classifier.score(
    [preprocess_text(text) for text in test_data.data],
    test_data.target
))

八、部署与应用

将模型保存为文件供后续使用:

import joblib

# 保存模型
joblib.dump(classifier, 'text_classifier.pkl')

# 加载模型
loaded_model = joblib.load('text_classifier.pkl')

# 新文本预测
new_text = "The patient shows symptoms of fever and cough"
processed = preprocess_text(new_text)
prediction = loaded_model.predict([processed])
print("预测类别:", train_data.target_names[prediction[0]])

九、扩展方向

1. 深度学习模型:使用CNN或RNN替代传统机器学习

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dense

model = Sequential([
    Embedding(input_dim=10000, output_dim=64),
    LSTM(64),
    Dense(3, activation='softmax')
])
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam')

2. 多语言支持:集成spaCy进行多语言分词

3. 实时分类:使用Flask构建API接口

from flask import Flask, request, jsonify

app = Flask(__name__)
model = joblib.load('text_classifier.pkl')

@app.route('/predict', methods=['POST'])
def predict():
    data = request.json
    text = data['text']
    processed = preprocess_text(text)
    pred = model.predict([processed])
    return jsonify({'category': train_data.target_names[pred[0]]})

if __name__ == '__main__':
    app.run(port=5000)

十、总结与挑战

本文实现的文本分类系统达到了92%的准确率,但仍有改进空间:

  • 数据层面:增加训练样本量,处理更复杂的类别

  • 特征层面:尝试词嵌入(Word2Vec/GloVe)替代TF-IDF

  • 模型层面:集成BERT等预训练语言模型

完整代码仓库:https://github.com/yourname/text-classification

关键词Python文本分类、TF-IDF、逻辑回归、scikit-learn、NLP预处理模型评估Flask部署网格搜索、n-gram特征、深度学习扩展

简介:本文详细介绍了使用Python实现小型文本分类系统的完整流程,包括数据预处理、TF-IDF特征提取、逻辑回归模型训练与评估,并提供了网格搜索调参、n-gram特征扩展和Flask部署方案,最后讨论了深度学习集成等改进方向。