未记录事实核验 · 状态:维护中
记录仅说明核验时间与维护状态,不保证适用于所有环境;使用前请留意正文中的版本、适用条件与风险提示。
warning 适用边界与维护说明
本文适合已有Python、机器学习及矩阵表示基础的读者学习文本预处理、向量化、分类与主题建模组件,不是可直接运行的端到端项目。当前词袋模型、TF-IDF、SnowNLP、文本分类实战及两处主题建模示例仍有列表缺少起始方括号的语法缺陷;中文向量化未一致接入分词,不能将连续中文片段特征直接解释为词级关键词。分类示例在划分训练集与测试集之前拟合词表和IDF,且样本极少,评估报告不代表严格独立测试或业务泛化效果;中文预处理会过滤“不”等否定信息,不宜直接用于通用情感分析。Word2Vec仅演示微型语料训练接口,其相似度不构成可靠语义关系证据;英文词形还原需另行准备WordNet语料,现有ImportError分支不会处理语料缺失。电商部分仅交付模拟评论生成与标签分布,NER仅介绍应用场景和模型,不含相应训练、评估、业务分析或实体抽取实施。本次仅作全文结构与代码静态审阅,未执行代码,也未进行外部事实、依赖兼容性或链接核验。
Python文本挖掘与NLP实战
abstract 本章概览
- 文本预处理:分词、去停用词、词干化等核心技术
- 文本向量化:词袋模型、TF-IDF、Word2Vec原理与实现
- 文本分类:朴素贝叶斯、逻辑回归在文本分类中的应用
- 情感分析:基于机器学习的情感极性识别
- 主题建模:LDA主题发现算法
- 命名实体识别概览:介绍应用场景与常见模型,不含实施示例
- 案例准备:电商评论情感分析的模拟数据生成
NLP技术概述
文本挖掘技术栈:
- 数据预处理:文本清洗、分词、去停用词、词干化
- 特征提取:词袋模型、TF-IDF、词向量
- 机器学习:分类算法、聚类算法、主题模型
- 应用场景:情感分析、文档分类、实体识别
# 核心依赖库
import numpy as np
import pandas as pd
import re
import jieba
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, accuracy_score
from sklearn.decomposition import LatentDirichletAllocation
import warnings
warnings.filterwarnings('ignore')
note 技术挑战
- 文本稀疏性:使用TF-IDF权重和词向量降维
- 语义歧义:引入上下文窗口和预训练模型
- 数据不平衡:采用重采样和类别权重调整
文本预处理技术
1. 文本清洗与标准化
文本清洗是NLP的基础步骤,包括去除HTML标签、特殊字符、标准化格式等。
import re
import jieba
def text_cleaner(text):
"""文本清洗函数"""
# 去除HTML标签
text = re.sub(r'<[^>]+>', '', text)
# 标准化空白字符
text = re.sub(r'\s+', ' ', text.strip())
# 保留中文、英文、数字
text = re.sub(r'[^一-龥a-zA-Z0-9\s]', '', text)
# 去除重复字符
text = re.sub(r'(.)\1{2,}', r'\1\1', text)
return text.strip()
# 示例
raw_text = "这个产品真的很好用!!!体验<strong>非常</strong>棒@#$"
cleaned = text_cleaner(raw_text)
print(f"清洗前: {raw_text}")
print(f"清洗后: {cleaned}")
# 输出: 清洗后: 这个产品真的很好用体验非常棒
2. 中文分词技术
jieba分词原理:基于前缀词典和动态规划算法,支持精确、全模式、搜索引擎模式。
def chinese_text_processor(text):
"""中文文本预处理管道"""
# 定义停用词表
stopwords = {'的', '了', '在', '是', '我', '有', '和', '就', '不', '人'}
# 1. 文本清洗
text = text_cleaner(text)
# 2. jieba分词
words = jieba.lcut(text)
# 3. 过滤停用词和短词
filtered_words = [word for word in words
if word not in stopwords and len(word) >= 2]
return filtered_words
# 分词示例
text = "人工智能技术在自然语言处理领域取得了重大突破"
words = chinese_text_processor(text)
print(f"分词结果: {words}")
# 输出: ['人工智能', '技术', '自然语言', '处理', '领域', '取得', '重大', '突破']
3. 词干化与词形还原
技术原理:
- 词干化(Stemming):通过去除前后缀获得词干
- 词形还原(Lemmatization):根据词典还原到基本形式
try:
import nltk
from nltk.stem import PorterStemmer, WordNetLemmatizer
stemmer = PorterStemmer()
lemmatizer = WordNetLemmatizer()
words = ['running', 'runs', 'ran', 'easily', 'fairly']
print("词干化结果:")
for word in words:
stemmed = stemmer.stem(word)
lemmatized = lemmatizer.lemmatize(word, pos='v') # 动词
print(f"{word} -> {stemmed} (stem) / {lemmatized} (lemma)")
except ImportError:
print("NLTK未安装,跳过英文预处理演示")
📊 特征提取
1. 词袋模型 (Bag of Words)
CountVectorizer:
def bag_of_words_demo():
"""词袋模型演示"""
# 示例文档
documents =
"机器学习是人工智能的一个分支",
"深度学习是机器学习的一个子领域",
"自然语言处理是人工智能的重要应用",
"计算机视觉和自然语言处理都是AI的应用"
]
# 使用CountVectorizer
vectorizer = CountVectorizer(
max_features=20, # 最大特征数
stop_words=None, # 停用词
token_pattern=r'[一-龥]+' # 只匹配中文
)
# 构建词袋模型
X = vectorizer.fit_transform(documents)
# 获取特征名称
feature_names = vectorizer.get_feature_names_out()
print("词袋模型结果:")
print(f"特征数量: {len(feature_names)}")
print(f"特征名称: {feature_names}")
print(f"文档-词矩阵形状: {X.shape}")
# 转换为DataFrame便于查看
df_bow = pd.DataFrame(X.toarray(), columns=feature_names)
print("\n文档-词矩阵:")
print(df_bow)
return vectorizer, X, feature_names, df_bow
2. TF-IDF特征
TF-IDF向量化:
def tfidf_demo():
"""TF-IDF演示"""
# 使用之前的文档
documents =
"机器学习是人工智能的一个分支",
"深度学习是机器学习的一个子领域",
"自然语言处理是人工智能的重要应用",
"计算机视觉和自然语言处理都是AI的应用"
]
# 使用TF-IDF向量化
tfidf_vectorizer = TfidfVectorizer(
max_features=20,
token_pattern=r'[一-龥]+',
use_idf=True,
smooth_idf=True
)
# 构建TF-IDF矩阵
X_tfidf = tfidf_vectorizer.fit_transform(documents)
# 获取特征名称
feature_names = tfidf_vectorizer.get_feature_names_out()
print("TF-IDF结果:")
print(f"特征数量: {len(feature_names)}")
print(f"特征名称: {feature_names}")
print(f"文档-特征矩阵形状: {X_tfidf.shape}")
# 转换为DataFrame
df_tfidf = pd.DataFrame(X_tfidf.toarray(), columns=feature_names)
print("\nTF-IDF矩阵:")
print(df_tfidf.round(3))
return tfidf_vectorizer, X_tfidf, feature_names, df_tfidf
3. 词向量 (Word Embeddings)
使用微型示例语料训练Word2Vec(非预训练词向量):
def word_embeddings_demo():
"""词向量演示"""
try:
# 使用gensim演示微型语料上的Word2Vec训练
import gensim.downloader as api
# 准备训练示例词向量模型
print("正在准备训练示例词向量模型...")
# 这里使用一个简单的示例
from gensim.models import Word2Vec
# 创建示例句子
sentences = [
['机器学习', '是', '人工智能', '的', '分支'],
['深度学习', '是', '机器学习', '的', '子领域'],
['自然语言处理', '是', '人工智能', '的', '应用'],
['计算机视觉', '和', '自然语言处理', '都是', 'AI', '应用']
]
# 训练Word2Vec模型
model = Word2Vec(sentences, vector_size=100, window=5, min_count=1, workers=4)
print("Word2Vec模型训练完成")
print(f"词汇表大小: {len(model.wv.key_to_index)}")
# 查看词向量
if '机器学习' in model.wv:
print(f"'机器学习'的词向量维度: {model.wv['机器学习'].shape}")
print(f"'机器学习'的词向量前10维: {model.wv['机器学习'][:10]}")
# 计算词语相似度
if '机器学习' in model.wv and '深度学习' in model.wv:
similarity = model.wv.similarity('机器学习', '深度学习')
print(f"'机器学习'和'深度学习'的相似度: {similarity:.3f}")
return model
except ImportError:
print("gensim未安装,跳过词向量演示")
return None
🧬 特征工程与向量化
1. 常见文本特征表示方法
| 方法 | 原理简介 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| One-hot | 每个词独立编码,稀疏向量 | 简单直观 | 维度高,稀疏,无法表达语义 | 小型词表、简单场景 |
| Bag of Words | 统计词频,忽略顺序 | 实现简单,效果稳定 | 丢失语序,稀疏 | 文本分类、聚类 |
| TF-IDF | 词频-逆文档频率加权 | 兼顾词频与区分度 | 稀疏,无法表达上下文 | 信息检索、文本分类 |
| Word2Vec | 词嵌入,低维稠密向量 | 能表达词语语义关系 | 需大量语料,忽略上下文 | 语义分析、聚类 |
| BERT | 预训练深度模型,动态上下文表示 | 语义丰富,效果强大 | 计算资源消耗大 | 高级NLP任务 |
2. TF-IDF 特征提取代码示例
from sklearn.feature_extraction.text import TfidfVectorizer
corpus =
"我喜欢机器学习,也喜欢数据挖掘。",
"机器学习是人工智能的重要分支。",
"数据挖掘和机器学习密切相关。"
]
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(corpus)
print("特征名称:", vectorizer.get_feature_names_out())
print("TF-IDF矩阵:\n", X.toarray())
3. Word2Vec 词向量表示
from gensim.models import Word2Vec
sentences = [
["我", "喜欢", "机器学习"],
["机器学习", "是", "人工智能", "分支"],
["数据挖掘技术", "和", "机器学习", "相关"]
]
model = Word2Vec(sentences, vector_size=100, window=5, min_count=1, workers=2)
print("'机器学习'的词向量:", model.wv['机器学习'])
4. BERT 句向量提取(以transformers为例)
from transformers import BertTokenizer, BertModel
import torch
tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
model = BertModel.from_pretrained('bert-base-chinese')
text = "机器学习和数据挖掘是人工智能的重要分支。"
inputs = tokenizer(text, return_tensors='pt')
outputs = model(**inputs)
# 取[CLS]向量作为句向量
sentence_vec = outputs.last_hidden_state[:, 0, :].detach().numpy()
print("句向量形状:", sentence_vec.shape)
5. 特征降维在文本中的应用
(1)PCA主成分分析
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
X_reduced = PCA(n_components=2).fit_transform(X.toarray())
plt.scatter(X_reduced[:,0], X_reduced[:,1])
plt.title('TF-IDF特征PCA降维可视化')
plt.show()
(2)LDA主题建模降维
from sklearn.decomposition import LatentDirichletAllocation
lda = LatentDirichletAllocation(n_components=2, random_state=42)
X_topics = lda.fit_transform(X)
print("每个文档的主题分布:\n", X_topics)
tip 选择特征工程方法时,需结合数据规模、任务目标和计算资源综合考虑。
😊 情感分析实战
1. 基于SnowNLP的中文情感分析
from snownlp import SnowNLP
texts =
"这个产品真的很好用,体验非常棒!",
"服务太差了,再也不会来了。"
]
for text in texts:
s = SnowNLP(text)
print(f"原文: {text}")
print(f"情感概率: {s.sentiments:.2f} (>0.5为正面,<0.5为负面)")
print("-")
2. 基于sklearn的机器学习情感分类
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import classification_report
# 示例数据
texts = ["我很喜欢这家店", "太糟糕了,差评", "服务不错", "再也不来了"]
labels = [1, 0, 1, 0] # 1为正面,0为负面
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(texts)
X_train, X_test, y_train, y_test = train_test_split(X, labels, test_size=0.5, random_state=42)
clf = MultinomialNB()
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
print(classification_report(y_test, y_pred))
3. 实战建议
- 中文情感分析推荐优先尝试SnowNLP、BosonNLP等工具,复杂场景可用BERT等深度模型。
- 训练集需均衡,注意消除标签偏差。
🎭 主题建模与可视化
1. LDA主题建模
from sklearn.decomposition import LatentDirichletAllocation
from sklearn.feature_extraction.text import CountVectorizer
corpus =
"人工智能正在改变世界",
"机器学习和深度学习是AI的核心",
"数据挖掘帮助企业决策",
"深度学习推动图像识别进步"
]
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(corpus)
lda = LatentDirichletAllocation(n_components=2, random_state=42)
lda.fit(X)
for idx, topic in enumerate(lda.components_):
print(f"主题{idx}关键词:", [vectorizer.get_feature_names_out()[i] for i in topic.argsort()[-5:][::-1]])
2. pyLDAvis主题可视化
# 安装:pip install pyldavis
import pyLDAvis.sklearn
pyLDAvis.enable_notebook()
panel = pyLDAvis.sklearn.prepare(lda, X, vectorizer)
pyLDAvis.show(panel)
tip pyLDAvis可交互展示主题分布、关键词、文档-主题关系,便于解释模型。
❓ 常见问题与实用技巧
- 分词歧义:可自定义词典、人工干预。
- 新词识别:jieba支持自学习新词,或结合Word2Vec发现高频新词。
- 类别不均衡:可采用欠采样/过采样、调整损失函数等方法。
- 特征稀疏:可用降维(PCA、LDA)、词向量等方法缓解。
- 模型泛化差:增加数据量、正则化、交叉验证。
tip 文本挖掘需结合业务场景灵活选型,建议多做实验、多可视化、多与业务方沟通。
🏷️ 文本分类
1. 新闻分类
多类别文本分类:
def news_classification_demo():
"""新闻分类演示"""
# 创建示例新闻数据
news_data = [
# 科技新闻
("人工智能技术取得重大突破", "科技"),
("机器学习算法优化升级", "科技"),
("深度学习在图像识别中的应用", "科技"),
("5G技术发展前景广阔", "科技"),
("区块链技术改变金融行业", "科技"),
# 体育新闻
("足球队获得冠军", "体育"),
("篮球比赛精彩激烈", "体育"),
("奥运会筹备工作进展顺利", "体育"),
("运动员创造新纪录", "体育"),
("体育场馆建设完成", "体育"),
# 财经新闻
("股市上涨创历史新高", "财经"),
("央行调整利率政策", "财经"),
("企业财报表现亮眼", "财经"),
("房地产市场调控政策", "财经"),
("国际贸易形势分析", "财经"),
# 娱乐新闻
("电影票房突破记录", "娱乐"),
("明星演唱会成功举办", "娱乐"),
("电视剧收视率创新高", "娱乐"),
("音乐专辑发布", "娱乐"),
("综艺节目收视火爆", "娱乐")
]
# 分离文本和标签
texts = [item[0] for item in news_data]
labels = [item[1] for item in news_data]
# 特征提取
vectorizer = TfidfVectorizer(
max_features=100,
token_pattern=r'[一-龥]+',
stop_words=None
)
X = vectorizer.fit_transform(texts)
# 分割数据
X_train, X_test, y_train, y_test = train_test_split(
X, labels, test_size=0.3, random_state=42, stratify=labels
)
# 训练模型
model = LogisticRegression(random_state=42, max_iter=1000)
model.fit(X_train, y_train)
# 预测和评估
y_pred = model.predict(X_test)
accuracy = (y_pred == y_test).mean()
print("新闻分类结果:")
print(f"准确率: {accuracy:.3f}")
print("\n分类报告:")
print(classification_report(y_test, y_pred))
return model, vectorizer
🏷️ 文本分类实战
1. 任务简介
文本分类是将文本自动分配到一个或多个类别的过程,常见于新闻分类、垃圾邮件识别、情感分类等。
2. 完整流程与代码示例
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import classification_report, confusion_matrix
# 示例数据
texts =
"人工智能正在改变世界",
"机器学习和深度学习是AI的核心",
"垃圾邮件太多了,影响正常工作",
"深度学习推动图像识别进步",
"收到很多广告短信,很烦"
]
labels = ["科技", "科技", "垃圾", "科技", "垃圾"]
# 1. 特征提取
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(texts)
# 2. 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, labels, test_size=0.4, random_state=42)
# 3. 训练模型
clf = MultinomialNB()
clf.fit(X_train, y_train)
# 4. 预测与评估
y_pred = clf.predict(X_test)
print("分类报告:\n", classification_report(y_test, y_pred))
print("混淆矩阵:\n", confusion_matrix(y_test, y_pred))
# 5. 新文本预测
new_texts = ["收到中奖信息,是真的吗?", "深度学习在医疗领域有新突破"]
X_new = vectorizer.transform(new_texts)
preds = clf.predict(X_new)
for text, label in zip(new_texts, preds):
print(f"文本: {text} => 预测类别: {label}")
3. 实战建议
- 中文文本分类建议先用TF-IDF+朴素贝叶斯/[逻辑回归],复杂场景可用BERT等深度模型。
- 特征工程和分词质量对分类效果影响极大。
- 可用GridSearchCV等工具调参提升模型表现。
tip 文本分类是NLP最常见的任务之一,建议多做实验、关注数据分布和标签质量。
🎪 主题建模
1. LDA主题建模
潜在狄利克雷分配:
def topic_modeling_demo():
"""主题建模演示"""
# 创建示例文档集合
documents =
"人工智能机器学习深度学习神经网络",
"机器学习算法监督学习无监督学习",
"深度学习卷积神经网络循环神经网络",
"自然语言处理文本分析语音识别",
"计算机视觉图像识别目标检测",
"数据挖掘聚类分析关联规则",
"大数据处理分布式计算云计算",
"数据库SQL查询数据仓库",
"网络编程Web开发移动应用",
"操作系统Linux内核进程管理",
"软件工程设计模式测试方法",
"算法数据结构排序算法搜索算法",
"数学统计概率论线性代数",
"物理力学电磁学量子力学",
"化学有机化学无机化学分析化学",
"生物基因DNA蛋白质细胞",
"医学诊断治疗药物疾病",
"经济金融投资股票市场",
"政治国际关系外交政策",
"历史古代文明现代史"
]
# 特征提取
vectorizer = CountVectorizer(
max_features=50,
token_pattern=r'[一-龥]+',
stop_words=None
)
X = vectorizer.fit_transform(documents)
feature_names = vectorizer.get_feature_names_out()
# LDA主题建模
n_topics = 5
lda = LatentDirichletAllocation(
n_components=n_topics,
random_state=42,
max_iter=100
)
lda.fit(X)
# 获取主题-词分布
topic_word_dist = lda.components_
# 获取文档-主题分布
doc_topic_dist = lda.transform(X)
print("LDA主题建模结果:")
print(f"主题数量: {n_topics}")
print(f"词汇表大小: {len(feature_names)}")
# 显示每个主题的top词
n_top_words = 5
for topic_idx, topic in enumerate(topic_word_dist):
top_words_idx = topic.argsort()[-n_top_words:][::-1]
top_words = [feature_names[i] for i in top_words_idx]
print(f"主题 {topic_idx + 1}: {', '.join(top_words)}")
return lda, vectorizer, feature_names, doc_topic_dist
🚀 实战案例:评论情感分析
案例背景
分析电商平台用户评论的情感倾向,为产品改进提供数据支持。
def ecommerce_sentiment_analysis():
"""电商评论情感分析案例"""
# 创建模拟电商评论数据
np.random.seed(42)
n_reviews = 1000
# 生成评论数据
positive_templates = [
"产品质量很好,{feature}很满意",
"物流很快,{feature}不错",
"客服态度很好,{feature}推荐",
"价格实惠,{feature}值得购买",
"包装很好,{feature}超出预期"
]
negative_templates = [
"质量很差,{feature}很失望",
"物流太慢,{feature}不推荐",
"客服态度差,{feature}很生气",
"价格太贵,{feature}不值",
"包装破损,{feature}很糟糕"
]
neutral_templates = [
"产品一般,{feature}还可以",
"物流正常,{feature}凑合",
"客服一般,{feature}还行",
"价格适中,{feature}一般",
"包装普通,{feature}正常"
]
features = ['外观', '功能', '性能', '服务', '体验', '性价比', '耐用性', '实用性']
reviews = []
sentiments = []
# 生成评论
for i in range(n_reviews):
if i < 400: # 40% 正面
template = np.random.choice(positive_templates)
sentiment = 'positive'
elif i < 700: # 30% 负面
template = np.random.choice(negative_templates)
sentiment = 'negative'
else: # 30% 中性
template = np.random.choice(neutral_templates)
sentiment = 'neutral'
feature = np.random.choice(features)
review = template.format(feature=feature)
reviews.append(review)
sentiments.append(sentiment)
# 创建数据框
df = pd.DataFrame({
'review': reviews,
'sentiment': sentiments
})
print("电商评论情感分析数据:")
print(f"评论数量: {len(df)}")
print(f"情感分布:\n{df['sentiment'].value_counts()}")
print(f"情感比例:\n{df['sentiment'].value_counts(normalize=True)}")
return df
🎯 最佳实践总结
1. 文本预处理最佳实践
预处理步骤:
def text_preprocessing_best_practices():
"""文本预处理最佳实践"""
print("文本预处理最佳实践:")
print("\n1. 文本清洗:")
print(" - 去除HTML标签和特殊字符")
print(" - 统一大小写和格式")
print(" - 处理重复字符和空格")
print("\n2. 分词处理:")
print(" - 中文使用jieba等分词工具")
print(" - 英文使用NLTK或spaCy")
print(" - 考虑词性标注和命名实体识别")
print("\n3. 去停用词:")
print(" - 去除常见无意义词汇")
print(" - 保留领域特定重要词汇")
print(" - 考虑上下文相关性")
2. 特征工程策略
特征选择:
- TF-IDF:适合短文本和文档分类
- 词向量:适合语义相似度计算
- BERT等预训练模型:适合复杂NLP任务
- N-gram特征:捕获局部语法信息
3. 模型选择指南
任务类型:
- 情感分析:逻辑回归、SVM、BERT
- 文本分类:朴素贝叶斯、随机森林、深度学习
- 主题建模:LDA、NMF、BERTopic
- 命名实体识别:CRF、BiLSTM-CRF、BERT
4. 常见陷阱
数据质量:
- 处理不平衡数据
- 处理多语言文本
- 处理噪声和异常值
模型过拟合:
- 使用正则化技术
- 增加训练数据
- 使用交叉验证
评估指标:
- 根据任务选择合适的指标
- 考虑业务需求
- 避免过度依赖单一指标
创建时间:2024-06-29
最后更新:2024-12-02
字数统计:约6800字
阅读时长:35-40分钟
#文本挖掘 #NLP #情感分析 #主题建模 #文本分类 #命名实体识别