51.文本分类:让AI给文章贴标签
整理衣柜:春装、夏装、秋装、冬装 👗分类垃圾:可回收、不可回收、有害垃圾 🗑️邮件管理:工作邮件、个人邮件、广告邮件 📧音乐分类:流行、古典、摇滚、民谣 🎵输入:一段文本内容输出:预定义的类别标签过程:通过学习大量已标记的文本数据,让AI掌握不同类别文本的特征# 文本分类的基本流程text = "今天股市大涨,科技股表现亮眼"
文本分类:让AI给文章贴标签
🎯 前言:从图书管理员到AI分类专家
想象一下,你是一个古老图书馆的管理员📚,面前堆满了成千上万的书籍和文档。有小说、科技论文、新闻报道、诗歌集…如果没有分类系统,读者想找一本书就像大海捞针!
传统的图书管理员需要一本一本地阅读,然后根据内容给书籍贴上标签:文学、科学、历史、艺术…这个过程既耗时又耗力。
现在,AI时代来了!我们可以训练一个"数字图书管理员",它能够快速阅读文章内容,自动识别主题,并给每篇文章贴上合适的标签。这就是文本分类的魔法!🪄
文本分类就像是给AI装上了一双"火眼金睛",让它能够从海量的文本中快速识别出:
- 这是一篇科技新闻还是娱乐八卦?
- 这条评论是正面的还是负面的?
- 这封邮件是垃圾邮件还是重要邮件?
- 这篇文章属于哪个类别?
今天,我们就来学习如何训练一个AI分类专家,让它成为你的得力助手!
📚 目录
- 什么是文本分类?
- 文本分类的应用场景
- 分类算法大家族
- 数据准备:给AI准备"教材"
- 特征工程:教AI看懂文字
- 模型训练:让AI学会分类
- 实战项目:新闻分类器
- 进阶技巧:深度学习分类
- 模型评估与优化
- 部署应用:让分类器为你服务
🧠 什么是文本分类?
生活中的分类无处不在
在日常生活中,我们时刻在进行分类:
- 整理衣柜:春装、夏装、秋装、冬装 👗
- 分类垃圾:可回收、不可回收、有害垃圾 🗑️
- 邮件管理:工作邮件、个人邮件、广告邮件 📧
- 音乐分类:流行、古典、摇滚、民谣 🎵
文本分类的定义
文本分类是机器学习的一个重要分支,它的目标是:
- 输入:一段文本内容
- 输出:预定义的类别标签
- 过程:通过学习大量已标记的文本数据,让AI掌握不同类别文本的特征
# 文本分类的基本流程
text = "今天股市大涨,科技股表现亮眼"
classifier = TextClassifier()
category = classifier.predict(text)
print(f"文本类别:{category}") # 输出:财经
分类任务的类型
1. 二分类任务
只有两个类别,像开关一样:
# 垃圾邮件检测
email = "恭喜您中奖了!点击链接领取奖品..."
result = spam_classifier.predict(email)
print(result) # 输出:垃圾邮件 or 正常邮件
2. 多分类任务
有多个类别,但每个文本只属于一个类别:
# 新闻分类
news = "科学家发现新的系外行星,距离地球100光年"
category = news_classifier.predict(news)
print(category) # 输出:科技、体育、财经、娱乐等其中一个
3. 多标签分类
每个文本可以属于多个类别:
# 电影标签
movie_desc = "一部关于太空探索的科幻爱情片"
labels = movie_classifier.predict(movie_desc)
print(labels) # 输出:['科幻', '爱情', '冒险']
🌟 文本分类的应用场景
1. 新闻媒体领域
# 新闻自动分类系统
class NewsClassifier:
def __init__(self):
self.categories = [
"政治", "经济", "科技", "体育",
"娱乐", "社会", "国际", "军事"
]
def classify_news(self, headline, content):
# 模拟分类过程
if "股市" in content or "GDP" in content:
return "经济"
elif "科学" in content or "技术" in content:
return "科技"
elif "比赛" in content or "运动员" in content:
return "体育"
else:
return "社会"
# 使用示例
classifier = NewsClassifier()
result = classifier.classify_news(
"人工智能助力医疗诊断",
"研究人员开发了一种新的AI算法,能够快速准确地诊断疾病"
)
print(f"新闻分类:{result}")
2. 社交媒体情感分析
# 社交媒体情感分类
class SentimentClassifier:
def analyze_sentiment(self, text):
positive_words = ["喜欢", "好", "棒", "赞", "优秀", "满意"]
negative_words = ["讨厌", "差", "糟", "烂", "失望", "愤怒"]
positive_count = sum(1 for word in positive_words if word in text)
negative_count = sum(1 for word in negative_words if word in text)
if positive_count > negative_count:
return "积极"
elif negative_count > positive_count:
return "消极"
else:
return "中性"
# 使用示例
sentiment_analyzer = SentimentClassifier()
comments = [
"这个产品真的很棒,强烈推荐!",
"质量太差了,完全不值这个价格",
"还行吧,没有特别的感觉"
]
for comment in comments:
sentiment = sentiment_analyzer.analyze_sentiment(comment)
print(f"评论:{comment}")
print(f"情感:{sentiment}\n")
3. 客户服务自动化
# 客户问题分类系统
class CustomerServiceClassifier:
def __init__(self):
self.categories = {
"技术支持": ["不能用", "故障", "报错", "bug", "问题"],
"账户问题": ["密码", "登录", "账号", "注册", "忘记"],
"订单查询": ["订单", "发货", "物流", "快递", "配送"],
"退换货": ["退货", "换货", "退款", "不满意", "损坏"],
"投诉建议": ["投诉", "建议", "意见", "改进", "不满"]
}
def classify_inquiry(self, message):
scores = {}
for category, keywords in self.categories.items():
score = sum(1 for keyword in keywords if keyword in message)
scores[category] = score
# 找到得分最高的类别
best_category = max(scores, key=scores.get)
return best_category if scores[best_category] > 0 else "其他"
# 使用示例
cs_classifier = CustomerServiceClassifier()
inquiries = [
"我的账号密码忘记了,怎么找回?",
"订单什么时候能发货?",
"产品有问题,想要退货",
"软件一直报错,无法正常使用"
]
for inquiry in inquiries:
category = cs_classifier.classify_inquiry(inquiry)
print(f"客户问题:{inquiry}")
print(f"分类结果:{category}\n")
4. 学术论文分类
# 学术论文领域分类
class AcademicClassifier:
def __init__(self):
self.field_keywords = {
"人工智能": ["机器学习", "深度学习", "神经网络", "AI", "算法"],
"生物医学": ["基因", "蛋白质", "细胞", "DNA", "医学"],
"物理学": ["量子", "粒子", "能量", "物理", "力学"],
"化学": ["分子", "化学反应", "催化", "化合物", "元素"],
"数学": ["定理", "证明", "函数", "微积分", "统计"]
}
def classify_paper(self, title, abstract):
text = (title + " " + abstract).lower()
scores = {}
for field, keywords in self.field_keywords.items():
score = sum(1 for keyword in keywords if keyword in text)
scores[field] = score
return max(scores, key=scores.get) if max(scores.values()) > 0 else "其他"
# 使用示例
academic_classifier = AcademicClassifier()
paper = {
"title": "基于深度学习的图像识别算法研究",
"abstract": "本文提出了一种新的神经网络架构,用于提高图像识别的准确性..."
}
field = academic_classifier.classify_paper(paper["title"], paper["abstract"])
print(f"论文领域:{field}")
🛠️ 分类算法大家族
1. 朴素贝叶斯:概率论的应用
朴素贝叶斯就像一个"统计学专家",它通过计算概率来做决策:
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import CountVectorizer
import numpy as np
# 朴素贝叶斯分类器示例
class NaiveBayesClassifier:
def __init__(self):
self.vectorizer = CountVectorizer()
self.classifier = MultinomialNB()
def train(self, texts, labels):
"""训练分类器"""
# 将文本转换为数值特征
X = self.vectorizer.fit_transform(texts)
# 训练模型
self.classifier.fit(X, labels)
def predict(self, text):
"""预测文本类别"""
X = self.vectorizer.transform([text])
return self.classifier.predict(X)[0]
def predict_proba(self, text):
"""预测概率"""
X = self.vectorizer.transform([text])
return self.classifier.predict_proba(X)[0]
# 使用示例
nb_classifier = NaiveBayesClassifier()
# 训练数据
train_texts = [
"股市今日大涨,投资者信心增强",
"新的药物试验取得突破性进展",
"足球比赛精彩纷呈,观众热情高涨",
"科技公司发布最新AI产品",
"医院引进先进医疗设备",
"篮球明星签约新球队"
]
train_labels = ["财经", "医疗", "体育", "科技", "医疗", "体育"]
# 训练模型
nb_classifier.train(train_texts, train_labels)
# 测试
test_text = "研究人员开发了新的治疗方法"
result = nb_classifier.predict(test_text)
probabilities = nb_classifier.predict_proba(test_text)
print(f"文本:{test_text}")
print(f"预测类别:{result}")
print(f"各类别概率:{probabilities}")
2. 支持向量机:寻找最优边界
SVM就像一个"边界专家",它能找到最好的分类边界:
from sklearn.svm import SVC
from sklearn.feature_extraction.text import TfidfVectorizer
class SVMClassifier:
def __init__(self):
self.vectorizer = TfidfVectorizer(max_features=5000)
self.classifier = SVC(kernel='linear', probability=True)
def train(self, texts, labels):
X = self.vectorizer.fit_transform(texts)
self.classifier.fit(X, labels)
def predict(self, text):
X = self.vectorizer.transform([text])
return self.classifier.predict(X)[0]
def get_confidence(self, text):
X = self.vectorizer.transform([text])
return self.classifier.predict_proba(X)[0].max()
# 使用示例
svm_classifier = SVMClassifier()
svm_classifier.train(train_texts, train_labels)
test_text = "新的投资策略带来丰厚回报"
result = svm_classifier.predict(test_text)
confidence = svm_classifier.get_confidence(test_text)
print(f"SVM预测:{result},置信度:{confidence:.2f}")
3. 随机森林:集体智慧的力量
随机森林就像一个"专家委员会",多个决策树投票决定:
from sklearn.ensemble import RandomForestClassifier
class RandomForestTextClassifier:
def __init__(self):
self.vectorizer = TfidfVectorizer(max_features=3000)
self.classifier = RandomForestClassifier(n_estimators=100, random_state=42)
def train(self, texts, labels):
X = self.vectorizer.fit_transform(texts)
self.classifier.fit(X, labels)
def predict(self, text):
X = self.vectorizer.transform([text])
return self.classifier.predict(X)[0]
def get_feature_importance(self):
"""获取特征重要性"""
feature_names = self.vectorizer.get_feature_names_out()
importance = self.classifier.feature_importances_
# 获取最重要的10个特征
top_indices = np.argsort(importance)[-10:]
return [(feature_names[i], importance[i]) for i in top_indices]
# 使用示例
rf_classifier = RandomForestTextClassifier()
rf_classifier.train(train_texts, train_labels)
# 查看重要特征
important_features = rf_classifier.get_feature_importance()
print("最重要的特征词:")
for feature, importance in important_features:
print(f" {feature}: {importance:.4f}")
📊 数据准备:给AI准备"教材"
数据收集策略
就像老师需要准备教材一样,训练分类器需要大量标记好的数据:
import pandas as pd
import numpy as np
from collections import Counter
import matplotlib.pyplot as plt
# 数据收集和管理类
class DataManager:
def __init__(self):
self.data = []
self.labels = []
self.label_counts = {}
def add_sample(self, text, label):
"""添加训练样本"""
self.data.append(text)
self.labels.append(label)
self.label_counts[label] = self.label_counts.get(label, 0) + 1
def load_from_csv(self, file_path):
"""从CSV文件加载数据"""
df = pd.read_csv(file_path)
self.data = df['text'].tolist()
self.labels = df['label'].tolist()
self.label_counts = Counter(self.labels)
def get_data_info(self):
"""获取数据统计信息"""
total_samples = len(self.data)
unique_labels = len(set(self.labels))
print(f"📊 数据集统计信息:")
print(f" 总样本数:{total_samples}")
print(f" 类别数:{unique_labels}")
print(f" 平均文本长度:{np.mean([len(text) for text in self.data]):.1f}字符")
print(f"\n📋 类别分布:")
for label, count in self.label_counts.items():
percentage = count / total_samples * 100
print(f" {label}: {count} ({percentage:.1f}%)")
def check_data_balance(self):
"""检查数据平衡性"""
counts = list(self.label_counts.values())
max_count = max(counts)
min_count = min(counts)
imbalance_ratio = max_count / min_count
if imbalance_ratio > 3:
print(f"⚠️ 数据不平衡!最大类别样本数是最小类别的{imbalance_ratio:.1f}倍")
print("建议:考虑使用数据增强或重采样技术")
else:
print("✅ 数据相对平衡")
def visualize_distribution(self):
"""可视化类别分布"""
plt.figure(figsize=(10, 6))
labels = list(self.label_counts.keys())
counts = list(self.label_counts.values())
plt.bar(labels, counts, color='skyblue')
plt.title('类别分布')
plt.xlabel('类别')
plt.ylabel('样本数量')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
# 使用示例
data_manager = DataManager()
# 模拟添加数据
sample_data = [
("苹果公司发布新iPhone,股价上涨5%", "科技"),
("央行降准释放流动性,刺激经济增长", "财经"),
("世界杯足球赛今晚开幕,全球瞩目", "体育"),
("新冠疫苗研发取得重大突破", "医疗"),
("著名导演新片获得金棕榈奖", "娱乐"),
("人工智能技术在医疗领域应用广泛", "科技"),
("股指期货大幅波动,投资者需谨慎", "财经"),
("奥运会游泳比赛刷新多项纪录", "体育")
]
for text, label in sample_data:
data_manager.add_sample(text, label)
data_manager.get_data_info()
data_manager.check_data_balance()
数据预处理管道
import re
import jieba
from sklearn.model_selection import train_test_split
class TextPreprocessor:
def __init__(self):
self.stop_words = set([
'的', '了', '在', '是', '我', '你', '他', '她', '它', '我们', '你们', '他们',
'这', '那', '这个', '那个', '这些', '那些', '和', '或', '但', '因为', '所以',
'如果', '虽然', '然而', '但是', '而且', '因此', '于是', '之后', '之前'
])
def clean_text(self, text):
"""清洗文本"""
# 移除特殊字符,保留中文、英文和数字
text = re.sub(r'[^\u4e00-\u9fa5a-zA-Z0-9\s]', '', text)
# 移除多余空格
text = re.sub(r'\s+', ' ', text).strip()
return text
def tokenize(self, text):
"""分词"""
# 使用jieba分词
tokens = jieba.lcut(text)
# 移除停用词和单字符词
tokens = [token for token in tokens if token not in self.stop_words and len(token) > 1]
return tokens
def preprocess(self, text):
"""完整预处理流程"""
# 清洗文本
text = self.clean_text(text)
# 分词
tokens = self.tokenize(text)
# 返回分词后的字符串
return ' '.join(tokens)
def preprocess_dataset(self, texts):
"""批量预处理"""
return [self.preprocess(text) for text in texts]
# 使用示例
preprocessor = TextPreprocessor()
# 预处理数据
processed_texts = preprocessor.preprocess_dataset(data_manager.data)
# 分割训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
processed_texts,
data_manager.labels,
test_size=0.2,
random_state=42,
stratify=data_manager.labels # 保持类别分布
)
print(f"训练集大小:{len(X_train)}")
print(f"测试集大小:{len(X_test)}")
print(f"预处理后的文本示例:{processed_texts[0]}")
数据增强技术
import random
class DataAugmentation:
def __init__(self):
self.synonyms = {
"公司": ["企业", "集团", "公司", "机构"],
"发布": ["推出", "公布", "发表", "宣布"],
"技术": ["科技", "技术", "工艺", "方法"],
"增长": ["上涨", "提升", "增加", "改善"],
"研发": ["开发", "研究", "创新", "设计"]
}
def synonym_replacement(self, text, n=1):
"""同义词替换"""
words = text.split()
new_words = words.copy()
for _ in range(n):
# 随机选择一个词进行替换
if words:
idx = random.randint(0, len(words) - 1)
word = words[idx]
if word in self.synonyms:
synonym = random.choice(self.synonyms[word])
new_words[idx] = synonym
return ' '.join(new_words)
def random_insertion(self, text, n=1):
"""随机插入"""
words = text.split()
for _ in range(n):
# 随机选择一个同义词插入
if words:
synonym_word = random.choice(list(self.synonyms.keys()))
synonym = random.choice(self.synonyms[synonym_word])
idx = random.randint(0, len(words))
words.insert(idx, synonym)
return ' '.join(words)
def random_deletion(self, text, p=0.1):
"""随机删除"""
words = text.split()
if len(words) <= 1:
return text
new_words = []
for word in words:
if random.random() > p:
new_words.append(word)
return ' '.join(new_words) if new_words else text
def augment_data(self, texts, labels, augment_ratio=0.5):
"""数据增强"""
augmented_texts = []
augmented_labels = []
for text, label in zip(texts, labels):
# 原始数据
augmented_texts.append(text)
augmented_labels.append(label)
# 生成增强数据
if random.random() < augment_ratio:
# 随机选择一种增强方法
methods = [
self.synonym_replacement,
self.random_insertion,
self.random_deletion
]
method = random.choice(methods)
aug_text = method(text)
augmented_texts.append(aug_text)
augmented_labels.append(label)
return augmented_texts, augmented_labels
# 使用示例
augmenter = DataAugmentation()
aug_texts, aug_labels = augmenter.augment_data(X_train, y_train)
print(f"原始训练集大小:{len(X_train)}")
print(f"增强后训练集大小:{len(aug_texts)}")
print(f"增强示例:")
print(f" 原文:{X_train[0]}")
print(f" 增强:{augmenter.synonym_replacement(X_train[0])}")
🔧 特征工程:教AI看懂文字
1. 词袋模型(Bag of Words)
词袋模型就像把文章撕成单词片段,然后数每个词出现了多少次:
from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd
class BagOfWordsFeatureExtractor:
def __init__(self, max_features=5000, ngram_range=(1, 1)):
self.vectorizer = CountVectorizer(
max_features=max_features,
ngram_range=ngram_range,
token_pattern=r'\b\w+\b'
)
def fit_transform(self, texts):
"""训练并转换文本"""
return self.vectorizer.fit_transform(texts)
def transform(self, texts):
"""转换文本"""
return self.vectorizer.transform(texts)
def get_feature_names(self):
"""获取特征名称"""
return self.vectorizer.get_feature_names_out()
def analyze_features(self, texts, labels):
"""分析特征分布"""
X = self.fit_transform(texts)
feature_names = self.get_feature_names()
# 计算每个类别的词频
df = pd.DataFrame(X.toarray(), columns=feature_names)
df['label'] = labels
# 按类别分组统计
for label in set(labels):
label_data = df[df['label'] == label]
word_freq = label_data.drop('label', axis=1).sum().sort_values(ascending=False)
print(f"\n{label}类别的高频词:")
print(word_freq.head(10))
# 使用示例
bow_extractor = BagOfWordsFeatureExtractor()
X_bow = bow_extractor.fit_transform(X_train)
print(f"词袋模型特征维度:{X_bow.shape}")
print(f"特征示例:{bow_extractor.get_feature_names()[:20]}")
# 分析特征
bow_extractor.analyze_features(X_train, y_train)
2. TF-IDF特征
TF-IDF就像是给每个词打分,常见词得分低,稀有但重要的词得分高:
from sklearn.feature_extraction.text import TfidfVectorizer
class TfidfFeatureExtractor:
def __init__(self, max_features=5000, ngram_range=(1, 2)):
self.vectorizer = TfidfVectorizer(
max_features=max_features,
ngram_range=ngram_range,
token_pattern=r'\b\w+\b',
sublinear_tf=True, # 使用对数缩放
norm='l2' # L2归一化
)
def fit_transform(self, texts):
return self.vectorizer.fit_transform(texts)
def transform(self, texts):
return self.vectorizer.transform(texts)
def get_top_features_by_class(self, texts, labels, top_n=10):
"""获取每个类别的顶级特征"""
X = self.fit_transform(texts)
feature_names = self.vectorizer.get_feature_names_out()
# 计算每个类别的平均TF-IDF分数
results = {}
for label in set(labels):
# 获取该类别的所有文档
label_indices = [i for i, l in enumerate(labels) if l == label]
label_tfidf = X[label_indices].mean(axis=0).A1 # 平均TF-IDF
# 获取顶级特征
top_indices = label_tfidf.argsort()[-top_n:][::-1]
top_features = [(feature_names[i], label_tfidf[i]) for i in top_indices]
results[label] = top_features
return results
# 使用示例
tfidf_extractor = TfidfFeatureExtractor()
X_tfidf = tfidf_extractor.fit_transform(X_train)
print(f"TF-IDF特征维度:{X_tfidf.shape}")
# 分析每个类别的顶级特征
top_features = tfidf_extractor.get_top_features_by_class(X_train, y_train)
for label, features in top_features.items():
print(f"\n{label}类别的顶级特征:")
for feature, score in features:
print(f" {feature}: {score:.4f}")
3. N-gram特征
N-gram考虑词的顺序信息,比如"人工智能"比单独的"人工"和"智能"更有意义:
class NgramFeatureExtractor:
def __init__(self, n=2):
self.n = n
self.vectorizer = CountVectorizer(
ngram_range=(1, n),
max_features=10000,
token_pattern=r'\b\w+\b'
)
def fit_transform(self, texts):
return self.vectorizer.fit_transform(texts)
def analyze_ngrams(self, texts, labels):
"""分析n-gram特征"""
X = self.fit_transform(texts)
feature_names = self.vectorizer.get_feature_names_out()
# 分析不同长度的n-gram
for n in range(1, self.n + 1):
ngram_features = [f for f in feature_names if len(f.split()) == n]
print(f"\n{n}-gram特征数量:{len(ngram_features)}")
if ngram_features:
print(f"示例:{ngram_features[:10]}")
# 使用示例
ngram_extractor = NgramFeatureExtractor(n=3)
X_ngram = ngram_extractor.fit_transform(X_train)
print(f"N-gram特征维度:{X_ngram.shape}")
ngram_extractor.analyze_ngrams(X_train, y_train)
4. 自定义特征工程
import re
from collections import Counter
class CustomFeatureExtractor:
def __init__(self):
self.feature_functions = [
self.get_length_features,
self.get_punctuation_features,
self.get_keyword_features,
self.get_pattern_features
]
def get_length_features(self, text):
"""长度特征"""
return {
'char_count': len(text),
'word_count': len(text.split()),
'sentence_count': len(text.split('。')),
'avg_word_length': np.mean([len(word) for word in text.split()]) if text.split() else 0
}
def get_punctuation_features(self, text):
"""标点符号特征"""
return {
'exclamation_count': text.count('!'),
'question_count': text.count('?'),
'comma_count': text.count(','),
'period_count': text.count('。')
}
def get_keyword_features(self, text):
"""关键词特征"""
keywords = {
'financial': ['股市', '投资', '金融', '经济', '银行', '贷款'],
'technology': ['技术', '科技', '人工智能', '算法', '软件'],
'sports': ['比赛', '运动', '球员', '教练', '冠军'],
'medical': ['医疗', '药物', '治疗', '医生', '病人', '疾病']
}
features = {}
for category, words in keywords.items():
count = sum(1 for word in words if word in text)
features[f'{category}_keywords'] = count
return features
def get_pattern_features(self, text):
"""模式特征"""
return {
'has_numbers': int(bool(re.search(r'\d', text))),
'has_english': int(bool(re.search(r'[a-zA-Z]', text))),
'has_percentage': int(bool(re.search(r'\d+%', text))),
'has_date': int(bool(re.search(r'\d{4}年|\d{1,2}月|\d{1,2}日', text)))
}
def extract_features(self, texts):
"""提取所有自定义特征"""
all_features = []
for text in texts:
features = {}
for func in self.feature_functions:
features.update(func(text))
all_features.append(features)
return pd.DataFrame(all_features)
# 使用示例
custom_extractor = CustomFeatureExtractor()
custom_features = custom_extractor.extract_features(X_train)
print("自定义特征:")
print(custom_features.head())
print(f"\n特征统计:")
print(custom_features.describe())
🎯 模型训练:让AI学会分类
模型选择与训练
from sklearn.ensemble import RandomForestClassifier, VotingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import classification_report, confusion_matrix
import seaborn as sns
class TextClassificationPipeline:
def __init__(self):
self.models = {
'naive_bayes': MultinomialNB(),
'logistic_regression': LogisticRegression(random_state=42),
'svm': SVC(random_state=42, probability=True),
'random_forest': RandomForestClassifier(random_state=42),
}
self.feature_extractor = TfidfVectorizer(max_features=5000, ngram_range=(1, 2))
self.trained_models = {}
def train_single_model(self, X_train, y_train, model_name):
"""训练单个模型"""
print(f"正在训练{model_name}...")
# 提取特征
X_train_features = self.feature_extractor.fit_transform(X_train)
# 训练模型
model = self.models[model_name]
model.fit(X_train_features, y_train)
# 保存训练好的模型
self.trained_models[model_name] = model
print(f"{model_name}训练完成!")
return model
def train_all_models(self, X_train, y_train):
"""训练所有模型"""
# 提取特征
X_train_features = self.feature_extractor.fit_transform(X_train)
for name, model in self.models.items():
print(f"正在训练{name}...")
model.fit(X_train_features, y_train)
self.trained_models[name] = model
def evaluate_model(self, X_test, y_test, model_name):
"""评估单个模型"""
if model_name not in self.trained_models:
raise ValueError(f"模型{model_name}尚未训练")
# 提取测试特征
X_test_features = self.feature_extractor.transform(X_test)
# 预测
model = self.trained_models[model_name]
y_pred = model.predict(X_test_features)
# 评估
print(f"\n{model_name}评估结果:")
print(classification_report(y_test, y_pred))
return y_pred
def create_ensemble_model(self, X_train, y_train):
"""创建集成模型"""
# 提取特征
X_train_features = self.feature_extractor.fit_transform(X_train)
# 创建投票分类器
ensemble_model = VotingClassifier(
estimators=[
('nb', MultinomialNB()),
('lr', LogisticRegression(random_state=42)),
('svm', SVC(random_state=42, probability=True))
],
voting='soft' # 软投票
)
# 训练集成模型
ensemble_model.fit(X_train_features, y_train)
self.trained_models['ensemble'] = ensemble_model
return ensemble_model
def predict(self, text, model_name='ensemble'):
"""预测文本类别"""
if model_name not in self.trained_models:
raise ValueError(f"模型{model_name}尚未训练")
# 提取特征
text_features = self.feature_extractor.transform([text])
# 预测
model = self.trained_models[model_name]
prediction = model.predict(text_features)[0]
# 获取概率(如果支持)
if hasattr(model, 'predict_proba'):
probabilities = model.predict_proba(text_features)[0]
return prediction, probabilities
else:
return prediction, None
# 使用示例
pipeline = TextClassificationPipeline()
# 训练所有模型
pipeline.train_all_models(X_train, y_train)
# 创建集成模型
pipeline.create_ensemble_model(X_train, y_train)
# 评估所有模型
for model_name in pipeline.trained_models.keys():
pipeline.evaluate_model(X_test, y_test, model_name)
# 测试预测
test_text = "科技公司发布了最新的人工智能产品"
prediction, probabilities = pipeline.predict(test_text, 'ensemble')
print(f"\n测试文本:{test_text}")
print(f"预测结果:{prediction}")
if probabilities is not None:
print(f"预测概率:{probabilities}")
🎬 下集预告
恭喜你!🎉 你已经掌握了文本分类的完整流程,从数据预处理到模型部署,从传统机器学习到深度学习,从单模型到集成学习。你现在可以:
- 构建自己的文本分类系统
- 处理各种文本分类任务
- 优化模型性能
- 部署分类服务
在下一课《聊天机器人:打造你的AI助手》中,我们将进入更有趣的NLP应用领域!我们将探索:
🤖 对话系统基础:理解人机对话的本质
🤖 意图识别:让AI理解用户真正想要什么
🤖 槽位填充:提取对话中的关键信息
🤖 上下文理解:让AI记住对话历史
🤖 多轮对话管理:处理复杂的对话流程
🤖 个性化回复:打造有温度的AI助手
🤖 实战项目:从零开始构建智能客服
想象一下,你将学会创建一个能够:
- 理解用户的各种提问方式
- 记住之前的对话内容
- 提供个性化的回答
- 处理复杂的业务查询
- 像真人一样自然对话
的智能聊天机器人!这将是你AI助手开发之旅的精彩开始!
📝 课后作业
基础练习
- 邮件分类器:构建一个能够识别工作邮件、个人邮件和垃圾邮件的分类器
- 商品评论分析:分析淘宝或京东的商品评论,自动分类为好评、中评、差评
- 新闻标题分类:收集不同类别的新闻标题,训练一个标题分类器
进阶练习
- 多标签文本分类:构建一个能够给文章打多个标签的系统(如:科技+商业+创新)
- 层次化文本分类:实现一个具有类别层次结构的分类系统(如:体育->足球->中超)
- 增量学习分类器:设计一个能够持续学习新类别的动态分类系统
挑战练习
- 实时社交媒体监控:构建一个实时监控微博/推特情感的系统
- 智能文档管理:开发一个能够自动整理和分类文档的智能系统
- 多语言文本分类:实现一个支持中英文混合文本分类的系统
项目实战
- 新闻推荐系统:结合文本分类和用户画像,构建个性化新闻推荐系统
- 智能客服分流:开发一个能够自动将用户问题分配给合适部门的系统
- 学术论文分类平台:构建一个帮助研究者快速找到相关论文的分类系统
🎉 总结
今天我们完成了文本分类的完整学习之旅:
✅ 核心概念:深入理解文本分类的原理和应用场景
✅ 数据准备:掌握数据收集、清洗、预处理和增强技术
✅ 特征工程:学会词袋模型、TF-IDF、N-gram等特征提取方法
✅ 经典算法:熟练使用朴素贝叶斯、SVM、随机森林等算法
✅ 深度学习:掌握CNN、BERT等先进的文本分类技术
✅ 模型评估:学会全面评估和优化模型性能
✅ 实战项目:构建完整的新闻分类系统
✅ 部署应用:将分类器部署为API服务
✅ 问题解决:处理数据不平衡、过拟合等常见问题
记住:文本分类是NLP的基础技能,就像学会了AI的"阅读理解"能力。无论是情感分析、垃圾邮件检测,还是内容推荐,都离不开文本分类的支持。
现在你已经具备了:
- 🎯 理论基础:深入理解分类算法的原理
- 🛠️ 实践技能:能够独立构建分类系统
- 🚀 工程能力:可以部署和优化分类服务
- 🔧 问题解决:处理各种实际应用中的挑战
继续加油,下一课我们将学习更有趣的聊天机器人技术,让AI真正成为你的智能助手!🚀
💡 AI开发小贴士:好的分类器不仅要准确,还要快速、稳定、可解释。在实际应用中,往往需要在性能和效率之间找到平衡点。记住:理解业务需求比追求最高准确率更重要!
🎯 学习建议:文本分类是一个非常实用的技能,建议你选择一个自己感兴趣的领域(如电影评论、新闻分类、商品评价等),从数据收集开始,完整地做一个项目。只有在实践中,你才能真正掌握这项技能!
更多推荐


所有评论(0)