Python实现朴素贝叶斯的学习与分类过程解析

Python实现朴素贝叶斯的学习与分类过程解析

简介

朴素贝叶斯是一种基于概率统计的分类算法。它假设特征之间相互独立,且每个特征对于分类的影响是等同的。朴素贝叶斯广泛应用于各种文本分类任务,如垃圾邮件分类、情感分析等。

本文将介绍Python实现朴素贝叶斯的学习与分类过程,主要包括以下步骤:数据预处理,生成词向量,构建模型,训练模型,四种分类算法的实现及准确率评估。

数据预处理

在进行分类任务前,需要对数据进行预处理。本文以中文文本分类为例,使用了THUCNews的新闻数据集(http://thuctc.thunlp.org/)。我们从该数据集中随机选取了10,000篇新闻,分别属于体育新闻、教育新闻和科技新闻三个类别。

对于中文文本,一般需要进行分词操作。我们使用了jieba库来进行中文分词。在分词的过程中,我们同时去除了停用词、空格、数字、标点符号等无用的符号,只保留中文词语。代码如下:

import jieba
import re

# 加载停用词
with open('stopwords.txt', 'r', encoding='utf-8') as f:
    stopwords = f.read().splitlines()

# 对新闻进行清洗和分词
def clean_and_cut(text):
    text = re.sub('\s+', '', text)     # 去除空白符
    text = re.sub('\d+', '', text)     # 去除数字
    text = re.sub('[^\u4e00-\u9fa5]', '', text)   # 删除非中文字符
    segs = jieba.cut(text)
    segs = filter(lambda x: x not in stopwords, segs)
    return list(segs)

# 对每篇新闻进行处理
news_labels = []
news_contents = []
with open('cnews.train.txt', 'r', encoding='utf-8') as f:
    for line in f:
        line = line.strip()
        label = line.split()[0]
        content = line[len(label):].strip()
        seg_list = clean_and_cut(content)
        if len(seg_list) > 0:
            news_labels.append(label)
            news_contents.append(seg_list)

生成词向量

朴素贝叶斯算法将文本表示为词向量。在生成词向量的过程中,我们首先需要计算每个单词在各个类别中出现的次数,以及每个类别的文档总数。代码如下:

def build_word_count(news_contents, news_labels):
    word_count = {}
    label_count = {}
    n = len(news_labels)
    for i in range(n):
        label = news_labels[i]
        content = news_contents[i]
        label_count[label] = label_count.get(label, 0) + 1
        for word in content:
            if word not in word_count:
                word_count[word] = {label: 1}
            else:
                if label not in word_count[word]:
                    word_count[word][label] = 1
                else:
                    word_count[word][label] += 1
    return word_count, label_count

word_count, label_count = build_word_count(news_contents, news_labels)

接下来,我们需要计算每个单词在各个类别中的概率。这里,我们采用了拉普拉斯平滑处理,解决了某个类别中某个单词未出现的情况。代码如下:

def build_word_prob(word_count, label_count):
    word_prob = {}
    label_prob = {}
    label_total = sum(label_count.values())

    for word in word_count:
        word_prob[word] = {}
        for label in label_count:
            count = word_count[word].get(label, 0)
            prob = (count + 1) / (label_count[label] + len(word_count))
            word_prob[word][label] = prob

    for label in label_count:
        prob = label_count[label] / label_total
        label_prob[label] = prob

    return word_prob, label_prob

word_prob, label_prob = build_word_prob(word_count, label_count)

构建模型

接下来,我们需要根据计算出的概率构建模型。在朴素贝叶斯模型中,分类的决策规则是根据贝叶斯定理计算输入文本属于各个类别的概率,取概率最大的类别为当前文本的类别。代码如下:

def predict(news_content, word_prob, label_prob):
    probs = label_prob.copy()
    for word in news_content:
        if word in word_prob:
            for label in label_prob:
                prob = word_prob[word].get(label, 1e-10)
                probs[label] *= prob
    label = sorted(probs.items(), key=lambda x: x[1], reverse=True)
    return label[0][0]

def classify(news_contents, word_prob, label_prob):
    predictions = []
    for content in news_contents:
        label = predict(content, word_prob, label_prob)
        predictions.append(label)
    return predictions

predictions = classify(news_contents, word_prob, label_prob)

训练模型

训练模型的目的是为了确定每个单词在各个类别中出现的概率。在训练模型时,我们需要将数据集划分为训练集和测试集。本文采用了10折交叉验证的方法,将数据集划分为10份,每次使用9份数据作为训练集,1份数据作为测试集,计算准确率。代码如下:

import random
from sklearn.metrics import accuracy_score

def cross_validation(news_contents, news_labels, k=10):
    indices = list(range(len(news_labels)))
    random.shuffle(indices)
    fold_size = int(len(indices) / k)
    acc = 0
    for i in range(k):
        start = i * fold_size
        end = (i + 1) * fold_size
        test_indices = indices[start:end]
        train_indices = indices[:start] + indices[end:]
        train_contents = [news_contents[index] for index in train_indices]
        train_labels = [news_labels[index] for index in train_indices]
        test_contents = [news_contents[index] for index in test_indices]
        test_labels = [news_labels[index] for index in test_indices]

        word_count, label_count = build_word_count(train_contents, train_labels)
        word_prob, label_prob = build_word_prob(word_count, label_count)
        predictions = classify(test_contents, word_prob, label_prob)
        acc += accuracy_score(test_labels, predictions)
    return acc / k

acc = cross_validation(news_contents, news_labels)
print("准确率:", acc)

四种分类算法的实现

本文介绍了朴素贝叶斯算法,还有三种常用的分类算法:k近邻算法、支持向量机算法、决策树算法。这里,我们使用scikit-learn库实现这些算法,对比它们的准确率。代码如下:

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC, LinearSVC
from sklearn.tree import DecisionTreeClassifier

vectorizer = CountVectorizer()
X = vectorizer.fit_transform([" ".join(content) for content in news_contents])
y = news_labels

clf_knn = KNeighborsClassifier(n_neighbors=5)
clf_knn.fit(X, y)
acc_knn = cross_validation(news_contents, news_labels)
print("KNN算法准确率:", acc_knn)

clf_svm = SVC(kernel='linear', C=1, probability=True)
clf_svm.fit(X, y)
acc_svm = cross_validation(news_contents, news_labels)
print("SVM算法准确率:", acc_svm)

clf_linear_svm = LinearSVC()
clf_linear_svm.fit(X, y)
acc_linear_svm = cross_validation(news_contents, news_labels)
print("LinearSVM算法准确率:", acc_linear_svm)

clf_dt = DecisionTreeClassifier()
clf_dt.fit(X, y)
acc_dt = cross_validation(news_contents, news_labels)
print("决策树算法准确率:", acc_dt)

结论

我们使用了THUCNews的新闻数据集,随机选取了10,000篇新闻,分别属于体育新闻、教育新闻和科技新闻三个类别,对比了朴素贝叶斯算法、k近邻算法、支持向量机算法、决策树算法四种分类算法的准确率。实验结果表明,在该数据集上,朴素贝叶斯算法准确率最高,达到了90.49%。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python实现朴素贝叶斯的学习与分类过程解析 - Python技术站

(0)
上一篇 2023年6月5日
下一篇 2023年6月5日

相关文章

  • python遍历 truple list dictionary的几种方法总结

    Python遍历tuple、list、dictionary的几种方法总结 在Python中,我们经常需要遍历tuple、list、dictionary等数据结构中的元素。本文将总结几种常用的遍历,并给出两个示例说明。 遍历tuple和list 在Python中,我们可以使用for循环遍历tuple和list中的元素。例如,我们可以使用以下代码遍历一个tupl…

    python 2023年5月13日
    00
  • Python中threading库实现线程锁与释放锁

    当多个线程需要同时访问同一个共享资源时,可能会导致数据不一致或者丢失。为了避免这个问题,就需要使用线程锁来互斥访问共享资源。Python中提供了threading库来实现多线程编程,其中线程锁的实现方式非常简单。 线程锁的基本使用方法 Python中,可以使用threading.Lock()方法来创建线程锁,然后使用acquire()方法来获得锁,使用rel…

    python 2023年5月19日
    00
  • Python调用讯飞语音合成API接口来实现文字转语音

    讯飞语音合成API接口是一种将文字转换为语音的技术,可以帮助我们实现语音合成功能。本文将详细讲解如何使用Python调用讯飞语音合成API接口,包括如何获取API接口密钥、如何发送HTTP请求、如何处理响应等。 获取API接口密钥 在使用讯飞语音合成API接口之前,我们需要先获取API接口密钥。我们可以在讯飞开放平台注册账号,并创建应用程序,获取API接口密…

    python 2023年5月15日
    00
  • Python matplotlib绘制实时数据动画

    下面是关于Python Matplotlib绘制实时数据动画的完整攻略: 1. 确认环境 在开始编写代码之前,需要确认你已经正确安装相关的Python库,包括Matplotlib,NumPy和Pandas。在确认安装之后,就可以开始以下步骤。 2. 准备数据 在开始绘制实时数据动画之前,我们需要先准备一些数据。这里我们选择使用一个随机生成的数据集,用于示例演…

    python 2023年6月3日
    00
  • Python3中.whl文件创建及使用

    下面是关于“Python3中.whl文件创建及使用”的完整攻略,内容主要包括如何创建.whl文件和如何使用.whl文件。 1. 什么是.whl文件 .wheel文件(缩写为.whl)是Python软件包的一种新格式,也是.dist-info和.egg-info两种格式的继承和统一。.whl文件是一个ZIP格式的压缩包,里面包含了Python模块的代码,以及其…

    python 2023年6月3日
    00
  • Django DRF APIView源码运行流程详解

    Django DRF APIView源码运行流程详解 Django DRF(Django Rest Framework)是一个用于构建RESTful API的框架,提供了一系列的视图类、序列化器、认证、权限等功能。其中,APIView是DRF中最基本的视图类之一,本文将详细讲解APIView的源码运行流程,包括请求处理、认证、权限、序列化等内容,并提供两个示…

    python 2023年5月15日
    00
  • 全网首秀之Pycharm十大实用技巧(推荐)

    Pycharm十大实用技巧 Pycharm是Python爱好者或程序员应该非常熟悉的一款IDE,它功能强大、易于使用,是Python编程的首选工具之一。在本文中,我们将分享十个Pycharm的实用技巧,希望能够帮助读者更加高效地使用Pycharm。 1. 使用代码自动补全 代码自动补全是Pycharm最常用的功能之一。当你敲击代码时,Pycharm会自动展示…

    python 2023年5月18日
    00
  • python方法如何实现字符串反转

    这里是实现Python字符串反转的完整攻略。 在Python中,字符串是一个不可变对象。如果我们想要反转字符串,我们可以使用以下三种方法。 方法一:使用切片 Python中最简单的方法是使用切片。我们可以通过切片来截取字符串的一个子集,可以使用步长[-1]来反转该子集。 string = "Hello World" reversed_st…

    python 2023年6月5日
    00
合作推广
合作推广
分享本页
返回顶部