【人工智能】机器学习及与智能数据处理Python使用朴素贝叶斯算法对垃圾短信数据集进行分类

简介: 朴素贝叶斯算法输入:样本集合D={(x_1,y_1),(x_2,y_2)~(x_m,y_m); 待预测样本x; 样本标记的所有可能取值{c_1,c_2,c_3~c_k}; 样本输入变量X的每个属性变量X^i的所有可能取值{a_i1,a_i2,~,a_iAi}; 输出:待预测样本x所属的类别

朴素贝叶斯算法

输入:样本集合D={(x_1,y_1),(x_2,y_2)~(x_m,y_m);

       待预测样本x;
       样本标记的所有可能取值{c_1,c_2,c_3~c_k};
       样本输入变量X的每个属性变量X^i的所有可能取值{a_i1,a_i2,~,a_iAi};

输出:待预测样本x所属的类别
1.计算标记为c_k的样本出现概率。
在这里插入图片描述

2.计算标记c_k的样本,其X^i分量的属性值为a_ip的概率。

在这里插入图片描述

3.根据上面的估计值计算x属于y_k的概率值,并选择概率最大的作为输出。

在这里插入图片描述

1.使用sklearn的朴素贝叶斯算法对垃圾短信数据集进行分类

要求:

(1)划分训练集和测试集(测试集占20%)
(2)对测试集的预测类别标签和真实标签进行对比
(3)掌握特征提取方法
(4)输出分类的准确率

代码:

from sklearn.feature_extraction.text import CountVectorizer as CV
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB as NB
import pandas as pd
# 加载SMS垃圾短息数据集
with open('SMSSpamCollection.txt', 'r', encoding='utf8') as f:
    sms = [line.split('\t') for line in f]
y, x = zip(*sms)
# SMS垃圾短息数据集的特征提取
y = [label == 'spam' for label in y]
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)
counter = CV(token_pattern='[a-zA-Z]{2,}')
x_train = counter.fit_transform(x_train)
x_test = counter.transform(x_test)
# 朴素贝叶斯分类器的构造与训练
model = NB()
model.fit(x_train, y_train)
train_score = model.score(x_train, y_train)
test_score = model.score(x_test, y_test)
print('train score:', train_score)
print('test score:', test_score)
# 对测试集的预测类别标签和真实标签进行对比
y_predict = model.predict(x_test)
print('测试集的预测类别标签与真实标签的对比:\n', pd.concat([pd.DataFrame(x_test), pd.DataFrame(y_test), pd.DataFrame(y_predict)], axis=1))

结果:

在这里插入图片描述

2.自己写朴素贝叶斯算法对垃圾短信数据集进行分类

代码:

# coding = utf-8
import pandas as pd
import numpy as np
import random
import math


class bayesianClassifier(object):
    def __init__(self, ratio=0.7):

        self.trainset = []
        self.testset = []
        self.ratio = ratio

    def loadData(self, filepath):
        """
        :param filepath: csv
        :return: list
        """
        data_df = pd.read_csv(filepath)
        data_list = np.array(data_df).tolist()
        print("Loaded {0} samples secessfully.".format(len(data_list)))
        self.trainset, self.testset = self.splitData(data_list)
        return data_list

    def splitData(self, data_list):
        """
        :param data_list:all data with list type
        :param ratio: train date's ratio
        :return: list type of trainset and testset
        """
        train_size = int(len(data_list) * self.ratio)
        random.shuffle(data_list)
        self.trainset = data_list[:train_size]
        self.testset = data_list[train_size:]
        return self.trainset, self.testset

    def seprateByClass(self, dataset):
        """
        :param dataset: train data with list type
        :return: seprate_dict:separated data by class;
                info_dict:Number of samples per class(category)
        """
        seprate_dict = {}
        info_dict = {}
        for vector in dataset:
            if vector[-1] not in seprate_dict:
                seprate_dict[vector[-1]] = []
                info_dict[vector[-1]] = 0
            seprate_dict[vector[-1]].append(vector)
            info_dict[vector[-1]] += 1
        return seprate_dict, info_dict

    def mean(self, number_list):
        number_list = [float(x) for x in number_list]  # str to number
        return sum(number_list) / float(len(number_list))

    def var(self, number_list):
        number_list = [float(x) for x in number_list]
        avg = self.mean(number_list)
        var = sum([math.pow((x - avg), 2) for x in number_list]) / float(len(number_list) - 1)
        return var

    def summarizeAttribute(self, dataset):
        """
        calculate mean and var of per attribution in one class
        :param dataset: train data with list type
        :return: len(attribution)'s tuple ,that's (mean,var)  with per attribution
        """
        dataset = np.delete(dataset, -1, axis=1)  # delete label
        summaries = [(self.mean(attr), self.var(attr)) for attr in zip(*dataset)]
        return summaries

    def summarizeByClass(self, dataset):
        """
        calculate all class with per attribution
        :param dataset: train data with list type
        :return: num:len(class)*len(attribution)
                {class1:[(mean1,var1),(),...],class2:[(),(),...]...}
        """
        dataset_separated, dataset_info = self.seprateByClass(dataset)
        summarize_by_class = {}
        for classValue, vector in dataset_separated.items():
            summarize_by_class[classValue] = self.summarizeAttribute(vector)
        return summarize_by_class

    def calulateClassPriorProb(self, dataset, dataset_info):
        """
        calculate every class's prior probability
        :param dataset: train data with list type
        :param dataset_info: Number of samples per class(category)
        :return: dict type with every class's prior probability
        """
        dataset_prior_prob = {}
        sample_sum = len(dataset)
        for class_value, sample_nums in dataset_info.items():
            dataset_prior_prob[class_value] = sample_nums / float(sample_sum)
        return dataset_prior_prob

    def calculateProb(self, x, mean, var):
        """
        Continuous value using probability density function as class conditional probability
        :param x: one sample's one attribution
        :param mean: trainset's one attribution's mean
        :param var: trainset's one attribution's var
        :return: one sample's one attribution's class conditional probability
        """
        exponent = math.exp(math.pow((x - mean), 2) / (-2 * var))
        p = (1 / math.sqrt(2 * math.pi * var)) * exponent
        return p

    def calculateClassProb(self, input_data, train_Summary_by_class):
        """
        calculate class conditional probability through multiply
        every attribution's class conditional probability per class
        :param input_data: one sample vectors
        :param train_Summary_by_class: every class with every attribution's (mean,var)
        :return: dict type , class conditional probability per class of this input data belongs to which class
        """
        prob = {}
        p = 1
        for class_value, summary in train_Summary_by_class.items():
            prob[class_value] = 1
            for i in range(len(summary)):
                mean, var = summary[i]
                x = input_data[i]
                p = self.calculateProb(x, mean, var)
            prob[class_value] *= p
        return prob

    def bayesianPredictOneSample(self, input_data):
        """
        :param input_data: one sample without label
        :return: predicted class
        """
        train_separated, train_info = self.seprateByClass(self.trainset)
        prior_prob = self.calulateClassPriorProb(self.trainset, train_info)
        train_Summary_by_class = self.summarizeByClass(self.trainset)
        classprob_dict = self.calculateClassProb(input_data, train_Summary_by_class)
        result = {}
        for class_value, class_prob in classprob_dict.items():
            p = class_prob * prior_prob[class_value]
            result[class_value] = p
        return max(result, key=result.get)

    def calculateAccByBeyesian(self, ratio=0.7):
        """
        :param dataset: list type,test data
        :return: acc
        """
        self.ratio = ratio
        correct = 0
        for vector in self.testset:
            input_data = vector[:-1]
            label = vector[-1]
            result = self.bayesianPredictOneSample(input_data)
            if result == label:
                correct += 1
        return correct / len(self.testset)


if __name__ == "__main__":
    bys = bayesianClassifier()
    data_samples = bys.loadData('IrisData.csv')
    print("Accuracy is:", bys.calculateAccByBeyesian(ratio=0.7))

结果:

在这里插入图片描述

目录
相关文章
|
4月前
|
Java 数据处理 索引
(Pandas)Python做数据处理必选框架之一!(二):附带案例分析;刨析DataFrame结构和其属性;学会访问具体元素;判断元素是否存在;元素求和、求标准值、方差、去重、删除、排序...
DataFrame结构 每一列都属于Series类型,不同列之间数据类型可以不一样,但同一列的值类型必须一致。 DataFrame拥有一个总的 idx记录列,该列记录了每一行的索引 在DataFrame中,若列之间的元素个数不匹配,且使用Series填充时,在DataFrame里空值会显示为NaN;当列之间元素个数不匹配,并且不使用Series填充,会报错。在指定了index 属性显示情况下,会按照index的位置进行排序,默认是 [0,1,2,3,...] 从0索引开始正序排序行。
385 0
|
4月前
|
存储 Java 数据处理
(numpy)Python做数据处理必备框架!(一):认识numpy;从概念层面开始学习ndarray数组:形状、数组转置、数值范围、矩阵...
Numpy是什么? numpy是Python中科学计算的基础包。 它是一个Python库,提供多维数组对象、各种派生对象(例如掩码数组和矩阵)以及用于对数组进行快速操作的各种方法,包括数学、逻辑、形状操作、排序、选择、I/0 、离散傅里叶变换、基本线性代数、基本统计运算、随机模拟等等。 Numpy能做什么? numpy的部分功能如下: ndarray,一个具有矢量算术运算和复杂广播能力的快速且节省空间的多维数组 用于对整组数据进行快速运算的标准数学函数(无需编写循环)。 用于读写磁盘数据的工具以及用于操作内存映射文件的工具。 线性代数、随机数生成以及傅里叶变换功能。 用于集成由C、C++
458 1
|
4月前
|
Java 数据挖掘 数据处理
(Pandas)Python做数据处理必选框架之一!(一):介绍Pandas中的两个数据结构;刨析Series:如何访问数据;数据去重、取众数、总和、标准差、方差、平均值等;判断缺失值、获取索引...
Pandas 是一个开源的数据分析和数据处理库,它是基于 Python 编程语言的。 Pandas 提供了易于使用的数据结构和数据分析工具,特别适用于处理结构化数据,如表格型数据(类似于Excel表格)。 Pandas 是数据科学和分析领域中常用的工具之一,它使得用户能够轻松地从各种数据源中导入数据,并对数据进行高效的操作和分析。 Pandas 主要引入了两种新的数据结构:Series 和 DataFrame。
577 0
|
4月前
|
Java 数据处理 索引
(numpy)Python做数据处理必备框架!(二):ndarray切片的使用与运算;常见的ndarray函数:平方根、正余弦、自然对数、指数、幂等运算;统计函数:方差、均值、极差;比较函数...
ndarray切片 索引从0开始 索引/切片类型 描述/用法 基本索引 通过整数索引直接访问元素。 行/列切片 使用冒号:切片语法选择行或列的子集 连续切片 从起始索引到结束索引按步长切片 使用slice函数 通过slice(start,stop,strp)定义切片规则 布尔索引 通过布尔条件筛选满足条件的元素。支持逻辑运算符 &、|。
280 0
|
7月前
|
人工智能 算法 搜索推荐
电商API的“AI革命”:全球万亿市场如何被算法重新定义?
AI+电商API正引领智能商业变革,通过智能推荐、动态定价与自动化运营三大核心场景,大幅提升转化率、利润率与用户体验。2025年,75%电商API将具备个性化能力,90%业务实现智能决策,AI与API的深度融合将成为未来电商竞争的关键基石。
|
5月前
|
机器学习/深度学习 人工智能 算法
当AI提示词遇见精密算法:TimeGuessr如何用数学魔法打造文化游戏新体验
TimeGuessr融合AI与历史文化,首创时间与空间双维度评分体系,结合分段惩罚、Haversine距离计算与加权算法,辅以连击、速度与完美奖励机制,实现公平且富挑战性的游戏体验。
|
7月前
|
机器学习/深度学习 人工智能 算法
AI-Compass RLHF人类反馈强化学习技术栈:集成TRL、OpenRLHF、veRL等框架,涵盖PPO、DPO算法实现大模型人类价值对齐
AI-Compass RLHF人类反馈强化学习技术栈:集成TRL、OpenRLHF、veRL等框架,涵盖PPO、DPO算法实现大模型人类价值对齐
 AI-Compass RLHF人类反馈强化学习技术栈:集成TRL、OpenRLHF、veRL等框架,涵盖PPO、DPO算法实现大模型人类价值对齐
|
7月前
|
机器学习/深度学习 人工智能 算法
AI-Compass 强化学习模块:理论到实战完整RL技术生态,涵盖10+主流框架、多智能体算法、游戏AI与金融量化应用
AI-Compass 强化学习模块:理论到实战完整RL技术生态,涵盖10+主流框架、多智能体算法、游戏AI与金融量化应用

推荐镜像

更多