朴素贝叶斯实例二——情感分析

本文介绍了一种基于机器学习的情感分析方法,通过预处理评论数据、提取TF-IDF特征并使用多种分类器(如朴素贝叶斯、K近邻、逻辑回归等),在测试集上实现了较高的准确率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大体思路:从测试数据中将用户正面情感和负面情感的评论抽取出来,以识别评论是正面负面,和真实标签进行对比计算出准确率。

from matplotlib import pyplot as plt
import jieba # 分词
import re # 正则
from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np
def read_data(path, is_pos=None):
    """
    给定文件的路径,读取文件
    path: path to the data
    is_pos: 是否数据是postive samples. 
    return: (list of review texts, list of labels) 
    """
    reviews, labels  = [], []
    with open(path, 'r') as file:
        review_start  = False
        review_text = []
        for line in file:
            line = line.strip()
            if not line: continue
            if not review_start and line.startswith("<review"):
                review_start = True
                if "label" in line:
                    labels.append(int(line.split('"')[-2]))
                continue                
            if review_start and line == "</review>":
                review_start = False
                reviews.append(" ".join(review_text))
                review_text = []
                continue
            if review_start:
                review_text.append(line)
    if is_pos:
        labels = [1]*len(reviews)
    elif not is_pos is None:
        labels = [0]*len(reviews)
    return reviews, labels


def process_file():
    """
    读取训练数据和测试数据,并对它们做一些预处理
    """    
    train_pos_file = "data_sentiment/train.positive.txt"
    train_neg_file = "data_sentiment/train.negative.txt"
    test_comb_file = "data_sentiment/test.combined.txt"
    
    # 读取文件部分,把具体的内容写入到变量里面
    train_pos_cmts, train_pos_lbs = read_data(train_pos_file, True)
    train_neg_cmts, train_neg_lbs = read_data(train_neg_file, False)
    train_comments = train_pos_cmts + train_neg_cmts
    train_labels = train_pos_lbs + train_neg_lbs
    test_comments, test_labels = read_data(test_comb_file)
    return train_comments, train_labels, test_comments, test_labels
train_comments, train_labels, test_comments, test_labels = process_file()
# 训练数据和测试数据大小
print (len(train_comments), len(test_comments))

print (train_comments[1], train_labels[1])
def load_stopwords(path):
    """
    从外部文件中导入停用词
    """
    stopwords = set()
    with open(path, 'r') as in_file:
        for line in in_file:
            stopwords.add(line.strip())
    return stopwords


def clean_non_chinese_symbols(text):
    """
    处理非中文字符
    """
    text = re.sub('[!!]+', "!", text)
    text = re.sub('[??]+', "?", text)
    text = re.sub("[a-zA-Z#$%&\'()*+,-./:;:<=>@,。★、…【】《》“”‘’[\\]^_`{|}~]+", " UNK ", text)
    return re.sub("\s+", " ", text)  

def clean_numbers(text):
    """
    处理数字符号  128  190  NUM 
    """
    return re.sub("\d+", ' NUM ', text)

def preprocess_text(text, stopwords):
    """
    文本的预处理过程
    """
    text = clean_non_chinese_symbols(text)
    text = clean_numbers(text)
    text = " ".join([term for term in jieba.cut(text) if term and not term in stopwords])
    return text
path_stopwords = "./data_sentiment/stopwords.txt"
stopwords = load_stopwords(path_stopwords)
# 对于train_comments, test_comments进行字符串的处理,几个考虑的点:
#   1. 停用词过滤
#   2. 去掉特殊符号
#   3. 去掉数字(比如价格..)
#   4. ...
#   需要注意的点是,由于评论数据本身很短,如果去掉的太多,很可能字符串长度变成0
#   预处理部部分,可以自行选择合适的方案,只要注释就可以。

train_comments_new = [preprocess_text(comment, stopwords) for comment in train_comments]
test_comments_new = [preprocess_text(comment, stopwords) for comment in test_comments]

print (train_comments_new[0], test_comments_new[0])
#   利用tf-idf从文本中提取特征,写到数组里面. 
#   参考:https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html
tfidf = TfidfVectorizer()
X_train =  tfidf.fit_transform(train_comments_new) # 训练数据的特征
y_train =  train_labels # 训练数据的label
X_test = tfidf.transform(test_comments_new) # 测试数据的特征
y_test = test_labels# 测试数据的label

print (np.shape(X_train), np.shape(X_test), np.shape(y_train), np.shape(y_test))
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import accuracy_score

clf = MultinomialNB()
# 利用朴素贝叶斯做训练
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
print("accuracy on test data: ", accuracy_score(y_test, y_pred))

from sklearn.neighbors import KNeighborsClassifier
clf = KNeighborsClassifier(n_neighbors=1)
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
print("accuracy on test data: ", accuracy_score(y_test, y_pred))
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsRegressor

normalizer = StandardScaler()  # data is no longer sparse
X_train_normalized = normalizer.fit_transform(X_train.toarray())
X_test_normalized = normalizer.transform(X_test.toarray())

knn = KNeighborsRegressor(n_neighbors=3)
knn.fit(X_train_normalized, y_train)

#Now we can predict prices:
y_pred = knn.predict(X_test_normalized)
print("accuracy on test data: ", accuracy_score(y_test, y_pred))
from sklearn.linear_model import LogisticRegression

clf = LogisticRegression(solver='liblinear')
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
print("accuracy on test data: ", accuracy_score(y_test, y_pred))

——《贪心学院特训营》第四期项目实例

### 如何使用朴素贝叶斯算法对美团评论进行情感倾向性分析 #### 数据收集与预处理 为了执行情感分析,首先需要获取美团评论的数据集。如果这些数据不是公开可用的,则可能需要利用网络爬虫技术来抓取所需的信息[^2]。 一旦获得了原始评论文本之后,下一步是对它们进行清理和准备以便于后续处理。这通常涉及去除无关字符、转换为小写形式以及移除停用词等操作。此外,还需要将每条评论标记为其对应的情感类别(正面或负面)。对于未标注的数据集来说,可以通过人工打标或者半监督方法获得标签信息。 #### 特征提取 在准备好干净且带有标签的训练样本后,接下来的任务是从文本中抽取有用的特征向量用于模型输入。一种常见的做法是采用词袋模型(Bag of Words),即统计每个单词在整个文档集合中的频率作为该词语的重要性衡量标准;另一种更先进的表示方式则是TF-IDF (Term Frequency-Inverse Document Frequency), 它不仅考虑了某个特定词汇在一个单独文件里出现次数的影响因素,同时也综合考量了它在整个语料库里的分布情况。 除了上述两种传统的方法之外,在现代自然语言处理领域内还存在诸如Word Embedding这样的分布式表达手段能够更好地捕捉上下文之间的关系特性。不过考虑到朴素贝叶斯分类器的特点及其适用场景,这里建议优先尝试较为简单的方案如BoW 或 TF-IDF 来构建初始版本的应用程序原型。 #### 构建并评估朴素贝叶斯分类器 有了经过良好加工后的特征矩阵以后就可以着手建立实际意义上的预测机制了——在这里就是指代朴素贝叶斯(Naive Bayes)算法本身。作为一种概率型判别函数,NB 基于贝努利定理假设各个属性之间相互独立从而简化计算过程,并据此推导出最终决策规则: \[ P(C|D)=\frac{P(D|C)\cdot P(C)}{\sum_{i}^{n}{P(D|c_i)}} \] 其中\( C \)代表类目变量而 \( D \)则指的是观测到的具体实例。因此当给定一条新的待测记录时只需分别求得其归属于各类别的条件概率值再比较大小即可得出结论。 具体实现方面可以借助 scikit-learn 库提供的接口快速搭建起一个完整的解决方案框架: ```python from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer from sklearn.naive_bayes import MultinomialNB from sklearn.pipeline import Pipeline import numpy as np def load_data(): # 加载已经过预处理的数据集... pass if __name__ == "__main__": pipeline = Pipeline([ ('vect', CountVectorizer()), ('tfidf', TfidfTransformer()), ('clf', MultinomialNB()) ]) X_train, y_train = load_data() model = pipeline.fit(X_train,y_train) test_review = ["这家餐厅的服务态度真好"] predicted = model.predict(test_review) print(predicted) ``` 这段代码展示了如何创建一个多阶段流水线结构来进行端到端的学习流程控制:首先是`CountVectorizer()`负责把原始字符串转化为稀疏矩阵格式下的数值化描述符序列;接着由 `TfidfTransformer()`完成权重调整优化工作;最后调用内置好的多项式朴素贝叶斯估计器对象(`MultinomialNB`)完成整个训练环节的操作。 #### 结果解释与改进措施探讨 得到初步实验结果之后应当对其进行细致解读以验证所选策略的有效性和合理性。假如发现某些类型的误报率过高的话不妨试着引入更多维度的信息辅助判断比如用户评分星级数或者是时间戳等等外部因子;另外也可以探索其他高级技巧像集成学习(Ensemble Learning)或是深度神经网络架构来进一步提升性能表现水平。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值