本文目录导读:

- 基础方法:使用TextBlob
- 进阶方法:使用VADER(适用于社交媒体)
- 专业方法:使用机器学习(Scikit-learn)
- 深度学习方法:使用Transformers(BERT)
- 完整的中文情感分析案例
- 实战案例:社交媒体情感分析
- 安装依赖
- 总结与建议
我来为您详细介绍使用Python进行NLP情感分析的完整案例,我会从简单到复杂,逐步展示不同的实现方法。
基础方法:使用TextBlob
from textblob import TextBlob
import pandas as pd
# 示例文本
texts = [
"这部电影太棒了,我非常喜欢!",
"服务态度很差,再也不会来了。",
"天气不错,适合出去散步。",
"这个产品一般般,不怎么样。"
]
def analyze_sentiment_textblob(text):
"""使用TextBlob进行情感分析"""
blob = TextBlob(text)
sentiment = blob.sentiment
# 转换语言(TextBlob默认支持英文)
# 对于中文需要先翻译或使用其他工具
return {
'polarity': sentiment.polarity, # -1到1,负值为消极,正值为积极
'subjectivity': sentiment.subjectivity # 0到1,0为客观,1为主观
}
# 测试
for text in texts:
result = analyze_sentiment_textblob(text)
print(f"文本: {text}")
print(f"情感极性: {result['polarity']:.2f}")
print("-" * 30)
进阶方法:使用VADER(适用于社交媒体)
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
import nltk
# 下载VADER词典(首次使用需要)
nltk.download('vader_lexicon')
# 初始化分析器
analyzer = SentimentIntensityAnalyzer()
def analyze_sentiment_vader(text):
"""使用VADER进行情感分析"""
scores = analyzer.polarity_scores(text)
# 判断情感类别
if scores['compound'] >= 0.05:
sentiment = '积极'
elif scores['compound'] <= -0.05:
sentiment = '消极'
else:
sentiment = '中性'
return {
'scores': scores,
'sentiment': sentiment,
'compound': scores['compound']
}
# 测试英文文本
english_texts = [
"This product is absolutely amazing! I love it!",
"Terrible service, worst experience ever.",
"The movie was okay, nothing special.",
"I'm feeling great today!"
]
for text in english_texts:
result = analyze_sentiment_vader(text)
print(f"文本: {text}")
print(f"情感: {result['sentiment']}")
print(f"综合得分: {result['compound']:.2f}")
print("-" * 30)
专业方法:使用机器学习(Scikit-learn)
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, accuracy_score
import numpy as np
# 准备训练数据
def prepare_training_data():
"""准备示例训练数据"""
# 假设我们有标记好的数据
data = {
'text': [
"This movie is fantastic!",
"I hate this product so much",
"The service was excellent",
"Very disappointed with the quality",
"Average experience, nothing special",
"Absolutely wonderful!",
"Worst purchase ever made",
"Pretty good, I like it",
"Not bad at all",
"Terrible customer support"
],
'sentiment': [2, 0, 2, 0, 1, 2, 0, 1, 1, 0] # 0:消极, 1:中性, 2:积极
}
return pd.DataFrame(data)
# 准备数据
df = prepare_training_data()
# 特征工程:TF-IDF向量化
tfidf_vectorizer = TfidfVectorizer(max_features=1000, stop_words='english')
X = tfidf_vectorizer.fit_transform(df['text'])
y = df['sentiment']
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# 训练模型
model = LogisticRegression(max_iter=1000)
model.fit(X_train, y_train)
# 预测
y_pred = model.predict(X_test)
# 评估
print("模型性能:")
print(f"准确率: {accuracy_score(y_test, y_pred):.2f}")
print("\n分类报告:")
print(classification_report(y_test, y_pred, target_names=['消极', '中性', '积极']))
# 使用模型进行预测
def predict_sentiment(text):
"""预测新文本的情感"""
text_vectorized = tfidf_vectorizer.transform([text])
prediction = model.predict(text_vectorized)[0]
probabilities = model.predict_proba(text_vectorized)[0]
sentiment_map = {0: '消极', 1: '中性', 2: '积极'}
return {
'sentiment': sentiment_map[prediction],
'probabilities': {
'消极': probabilities[0],
'中性': probabilities[1],
'积极': probabilities[2]
}
}
# 测试新文本
new_texts = [
"I'm really happy with this purchase!",
"This is the worst thing ever",
"It's okay, I guess"
]
print("\n新文本预测:")
for text in new_texts:
result = predict_sentiment(text)
print(f"文本: {text}")
print(f"情感: {result['sentiment']}")
print(f"置信度: {max(result['probabilities'].values()):.2f}")
print("-" * 30)
深度学习方法:使用Transformers(BERT)
from transformers import pipeline
import torch
# 加载预训练的情感分析模型
def setup_bert_sentiment():
"""设置BERT情感分析器"""
# 使用Hugging Face的预训练模型
sentiment_analyzer = pipeline(
"sentiment-analysis",
model="distilbert-base-uncased-finetuned-sst-2-english"
)
return sentiment_analyzer
# 初始化分析器
sentiment_analyzer = setup_bert_sentiment()
# 批量分析
def batch_sentiment_analysis(texts):
"""批量进行情感分析"""
results = sentiment_analyzer(texts)
return results
# 测试文本
test_texts = [
"I absolutely love this product!",
"This is terrible, worst experience ever.",
"The movie was quite good, I enjoyed it.",
"Not bad, but could be better."
]
# 执行分析
results = batch_sentiment_analysis(test_texts)
print("BERT情感分析结果:")
for text, result in zip(test_texts, results):
print(f"文本: {text}")
print(f"情感: {result['label']}")
print(f"置信度: {result['score']:.2%}")
print("-" * 30)
完整的中文情感分析案例
import jieba
from snownlp import SnowNLP
import numpy as np
import matplotlib.pyplot as plt
class ChineseSentimentAnalyzer:
"""中文情感分析器"""
def __init__(self):
self.stop_words = self.load_stop_words()
def load_stop_words(self):
"""加载停用词"""
# 简单的停用词列表
return ['的', '了', '在', '是', '我', '不', '都', '和', '就', '也']
def preprocess(self, text):
"""预处理中文文本"""
# 分词
words = jieba.cut(text)
# 去除停用词
words = [w for w in words if w not in self.stop_words and len(w) > 1]
return ' '.join(words)
def analyze_snow(self, text):
"""使用SnowNLP进行情感分析"""
try:
s = SnowNLP(text)
sentiment = s.sentiments # 0-1,越接近1越积极
if sentiment >= 0.6:
label = '积极'
elif sentiment <= 0.4:
label = '消极'
else:
label = '中性'
return {
'score': sentiment,
'label': label
}
except:
return {'score': 0.5, 'label': '中性'}
def batch_analyze(self, texts):
"""批量分析"""
results = []
for text in texts:
result = self.analyze_snow(text)
results.append(result)
return results
# 使用示例
analyzer = ChineseSentimentAnalyzer()
# 中文测试文本
chinese_texts = [
"这个产品质量非常好,我很满意!",
"服务态度太差了,再也不会来这家店",
"电影一般般,没什么特别之处",
"今天心情不错,天气也很给力",
"这款手机性价比很高,推荐购买"
]
print("中文情感分析结果:")
for text in chinese_texts:
result = analyzer.analyze_snow(text)
print(f"文本: {text}")
print(f"情感: {result['label']}")
print(f"得分: {result['score']:.2%}")
print("-" * 30)
# 可视化结果
def visualize_sentiments(texts, results):
"""可视化情感分析结果"""
scores = [r['score'] for r in results]
labels = [r['label'] for r in results]
plt.figure(figsize=(10, 6))
bars = plt.bar(range(len(texts)), scores,
color=['green' if l == '积极' else 'red' if l == '消极' else 'gray'
for l in labels])
plt.xlabel('文本编号')
plt.ylabel('情感得分')
plt.title('中文情感分析结果')
plt.xticks(range(len(texts)), [f'文本{i+1}' for i in range(len(texts))])
plt.axhline(y=0.5, color='r', linestyle='--', alpha=0.5)
for bar, score in zip(bars, scores):
plt.text(bar.get_x() + bar.get_width()/2, bar.get_height(),
f'{score:.2%}', ha='center', va='bottom')
plt.show()
# 可视化
results = analyzer.batch_analyze(chinese_texts)
visualize_sentiments(chinese_texts, results)
实战案例:社交媒体情感分析
import pandas as pd
import re
from collections import Counter
class SocialMediaSentimentAnalyzer:
"""社交媒体情感分析器"""
def __init__(self):
self.emotion_dict = {
'积极': ['开心', '喜欢', '爱', '棒', '好', '赞', '优秀', '完美', '满意', '期待'],
'消极': ['讨厌', '差', '烂', '垃圾', '失望', '糟糕', '后悔', '难用', '恶心', '烦']
}
self.snow_analyzer = ChineseSentimentAnalyzer()
def extract_emojis(self, text):
"""提取表情符号(简化版)"""
emoji_pattern = re.compile(
"[\U0001F600-\U0001F64F" # 表情符号
"\U0001F300-\U0001F5FF" # 符号和象形文字
"\U0001F680-\U0001F6FF" # 交通和地图符号
"\U0001F1E0-\U0001F1FF" # 旗帜
"]+", flags=re.UNICODE)
return emoji_pattern.findall(text)
def analyze_emotion_words(self, text):
"""基于情感词典分析"""
positive_count = 0
negative_count = 0
for word in self.emotion_dict['积极']:
if word in text:
positive_count += text.count(word)
for word in self.emotion_dict['消极']:
if word in text:
negative_count += text.count(word)
return positive_count, negative_count
def comprehensive_analysis(self, text):
"""综合分析"""
# 1. 基于词典的分析
pos_count, neg_count = self.analyze_emotion_words(text)
# 2. 基于SnowNLP的分析
snow_result = self.snow_analyzer.analyze_snow(text)
# 3. 提取表情符号
emojis = self.extract_emojis(text)
# 4. 综合判断
if pos_count > neg_count and snow_result['score'] > 0.5:
final_label = '积极'
confidence = min(1.0, snow_result['score'] * 1.2)
elif neg_count > pos_count and snow_result['score'] < 0.5:
final_label = '消极'
confidence = min(1.0, (1 - snow_result['score']) * 1.2)
else:
final_label = snow_result['label']
confidence = snow_result['score']
return {
'text': text,
'emotion_words': {'积极': pos_count, '消极': neg_count},
'snow_result': snow_result,
'emojis': emojis,
'final_label': final_label,
'confidence': confidence
}
# 模拟社交媒体数据
social_media_posts = [
"今天天气真好,出去拍照开心死了📷😊",
"这家餐厅的菜品太差劲了,难吃死了!🤮",
"新买的手机挺不错的,价位也合适👍",
"工作压力好大,感觉要崩溃了😫",
"和朋友们一起玩耍太快乐了🎉🎉"
]
analyzer = SocialMediaSentimentAnalyzer()
print("社交媒体情感分析:")
df_results = []
for post in social_media_posts:
result = analyzer.comprehensive_analysis(post)
df_results.append(result)
print(f"文本: {post[:30]}...")
print(f"最终判断: {result['final_label']} (置信度: {result['confidence']:.2%})")
print(f"情感词统计: {result['emotion_words']}")
print(f"表情符号: {result['emojis']}")
print("-" * 40)
# 转为DataFrame并保存
df = pd.DataFrame(df_results)
print("\n分析结果统计:")
print(df['final_label'].value_counts())
安装依赖
# 安装所需的包 pip install textblob nltk scikit-learn pandas matplotlib jieba snownlp transformers torch # 下载NLTK数据 python -m nltk.downloader vader_lexicon python -m nltk.downloader punkt
总结与建议
- 简单需求:使用TextBlob或VADER(英文),SnowNLP(中文)
- 专业分析:使用机器学习方法(Scikit-learn)或深度学习方法(Transformers)
- 生产环境:推荐使用预训练的BERT模型,准确率高
- 中文处理:需要分词(jieba)和专门的中文情感分析工具
- 性能优化:对于大量数据,考虑使用批处理和多线程
这些案例涵盖了从基础到高级的情感分析方法,您可以根据实际需求选择合适的实现。