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日

相关文章

  • Python3中的re.findall()方法及re.compile()

    下面我们来详细讲解一下Python3中的re.findall()方法以及re.compile()。 re.findall()方法 re.findall()方法是Python中re模块提供的一种正则表达式匹配函数。它的作用是在一个字符串中查找所有匹配某个正则表达式的子串,并返回一个列表。 re.findall()方法的语法如下: re.findall(patt…

    python 2023年5月14日
    00
  • python 包之 re 正则匹配教程分享

    Python包之re正则匹配教程分享 正则表达式是一种强大的文本处理工具,可以用于各种文本处理任务,如数据清洗、文本分析、信息提取等。在Python中,可以使用re块来操作正则表达式。本攻略将详细讲解Python包之re正则匹配的基本语法、常用函数和应用巧,帮助读者快速掌握正则表达式的用法。 正则表达式的基本语法 正则表达式由普通字符和元字符组成,用于匹配文…

    python 2023年5月14日
    00
  • python re.match函数的具体使用

    在Python中,re模块提供了很多函数来进行正则表达式匹配。其中,re.match()函数用于尝试从字符串的起始位置匹配一个模式。本文将详细介绍re.match()函数的具体使用方法,包括函数参数、返回值、示例说明等。 函数参数 re.match()函数的语法如下: re.match(pattern, string, flags=0) 其中,pattern…

    python 2023年5月14日
    00
  • Python验证的50个常见正则表达式

    Python验证的50个常见正则表达式 正则表达式是一种用于描述字符串模式的语言,可以用于匹配、查找、替换和割字符串。在Python中,模块提供了正表达式持方便进行字符串的处理。本文将详细解Python验证的50个常见正则表达式,包括正则表达语法、模块的常用函数以及示例说明。 正则表达式语法 正则表达式语法是一组特殊字符符号用于描述字符串模式。下面是一些常用…

    python 2023年5月14日
    00
  • python常规方法实现数组的全排列

    以下是“Python常规方法实现数组的全排列”的完整攻略。 1. 什么是全排列 全排列是指将一个集合中的元素进行排列,使得每个元素都出现一次,且顺序不同。例如,集合{1, 2, 3}的全排列为{1, 2, 3}、{1, 3, 2}、{2, 1, 3}、{2, 3, 1}、{3, 1, 2}和{3, 2, 1}。 2. Python常规方法实现数组的全排列 P…

    python 2023年5月13日
    00
  • Python any()函数的使用方法

    Python any()函数的使用方法 简介 在Python中,any()是一个内置函数,用于检查可迭代对象中是否有至少一个元素为True。 语法 any(iterable) 参数解释: iterable:可迭代对象(如列表、元组、集合、字典) 返回值: 如果可迭代对象中至少有一个元素为True,则返回True;否则返回False。 示例1:检查列表中是否存…

    python 2023年6月5日
    00
  • Python 字符串去除空格的五种方法

    当我们使用Python处理字符串时,经常会遇到字符串中包含空格的情况。这时候,我们通常需要去除这些空格。本文将详细讲解Python字符串去除空格的五种方法。 方法一:使用strip()去除空格 strip()是Python内置的字符串方法,可以去除字符串前后的空格,代码如下: string = " hello, world! " new_…

    python 2023年6月5日
    00
  • 当函数使用 LLDB Python 返回时如何设置断点?

    【问题标题】:How to set breakpoints when a function returns with LLDB Python?当函数使用 LLDB Python 返回时如何设置断点? 【发布时间】:2023-04-05 21:26:02 【问题描述】: 我是 LLDB 调试器的新手。我想问一下我们是否有一些方法可以使用 Python API …

    Python开发 2023年4月6日
    00
合作推广
合作推广
分享本页
返回顶部