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

yizhihongxing

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自动化办公之Excel拆分与自动发邮件

    请听我详细讲解Python自动化办公之Excel拆分与自动发邮件的完整实例教程。 简介 本实例教程旨在通过Python实现Excel拆分与自动发邮件,实现自动化办公的目标。具体来说,我们可以通过Python实现以下功能: 从Excel文件中读取数据进行拆分。 每个子文件生成后自动以邮件发送给相关人员。 函数化该过程,以适应不同场景的需求。 实现步骤 安装依赖…

    python 2023年5月13日
    00
  • 简单介绍Python中的try和finally和with方法

    以下是“简单介绍Python中的try和finally和with方法”的完整攻略,其中包括了try语句、finally语句和with语句使用方法和两个示例。这些示例可以帮助我们更地理解如何在Python中使用try和finally和with方法来处理异常和资源管理。 简单介绍Python中的try和finally和with方法 Python中,try和fin…

    python 2023年5月13日
    00
  • python实现requests发送/上传多个文件的示例

    下面是关于“python实现requests发送/上传多个文件的示例”的完整攻略。 环境准备 在使用requests库发送或上传多个文件之前,需要保证你已经安装了requests库和os库。你可以在命令行中输入以下命令进行安装: pip install requests 发送/上传单个文件 在使用requests库发送或上传多个文件之前,我们先来看一下如何发…

    python 2023年5月14日
    00
  • python 使用fileinput读取文件

    使用Python的fileinput模块可以方便地读取多个文件的内容,可以使用标准输入(stdin)或命令行参数指定的文件列表。下面是具体的步骤和示例说明: 步骤 导入fileinput模块: import fileinput 创建fileinput实例: file = fileinput.input(files=None, inplace=False, b…

    python 2023年6月3日
    00
  • Python下的twisted框架入门指引

    以下是详细讲解“Python下的twisted框架入门指引”的完整攻略,包含两个示例说明。 1. Twisted框架简介 Twisted是一个基Python的事件驱动网络框架,它提了异步I/O、网络协议、线程、进程和分布式应用等功能。Tw框架的核心是事件循环,它可以同时处理多个连接和请求,提高了网络应用的性能和可扩展。 2 Twisted框架安装 在使用Tw…

    python 2023年5月14日
    00
  • Python 找出英文单词列表(list)中最长单词链

    Python找出英文单词列表(list)中最长单词链的攻略如下: 基本思路 定义一个变量max_len,用于记录最长单词链的长度,初始值为0。 定义变量cur_len,用于记录当前单词链的长度,初始值为0。 定义一个变量cur_word,用于记录当前单词链的最后一个单词,值为None。 遍历单词列表,对于每个单词,判断它是否当前单词链的下一个单词,如果是,则…

    python 2023年5月13日
    00
  • 详解Python PIL logical_xor()和invert()方法

    Python PIL库中的logical_xor()和invert()方法都是用于图像处理中的像素操作。 logical_xor()方法是一个逻辑异或操作,将两个图像模式为 “1” 的像素值按照异或逻辑进行操作。具体来说,对于两个像素A和B,如果它们的值相等,则异或结果为0,否则为1。该方法通常用于比较两个二进制图像的差异,并生成一个新的二进制图像来标记差异…

    python-answer 2023年3月25日
    00
  • 如何进行Python代码的调试?

    调试是程序开发中最基本的操作之一,也是非常重要的一环。Python作为一种高级编程语言,具备强大的调试功能,可以帮助我们快速地定位bug并修复它们。代码调试可以使用Python内置的pdb调试器或者第三方工具,如PyCharm和VS Code。 下面是一个详细的调试攻略,以及两个示例说明。 调试步骤 确认需要调试的代码文件。 导入pdb模块,并设置断点。 执…

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