python机器学习——朴素贝叶斯算法笔记详细记录

简介: 朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法。最为广泛的两种分类模型是决策树模型(Decision Tree Model)和朴素贝叶斯模型(Naive Bayesian Model,NBM)。和决策树模型相比,朴素贝叶斯分类器(Naive Bayes Classifier 或 NBC)发源于古典数学理论,有着坚实的数学基础,以及稳定的分类效率。同时,NBC模型所需估计的参数很少,对缺失数据不太敏感,算法也比较简单。

@[TOC]

朴素贝叶斯算法

本篇主要介绍朴素贝叶斯算法及应用案例。

以Tatinic数据集为例进行应用,同时介绍数据处理,数据集的划分,算法效果评估等内容。

一、简介

朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法 。

最为广泛的两种分类模型是决策树模型(Decision Tree Model)和朴素贝叶斯模型(Naive Bayesian Model,NBM)。

和决策树模型相比,朴素贝叶斯分类器(Naive Bayes Classifier 或 NBC)发源于古典数学理论,有着坚实的数学基础,以及稳定的分类效率。同时,NBC模型所需估计的参数很少,对缺失数据不太敏感,算法也比较简单。

朴素贝叶斯算法(Naive Bayesian algorithm) 是应用最为广泛的分类算法之一。

朴素贝叶斯方法是在贝叶斯算法的基础上进行了相应的简化,即假定给定目标值时属性之间相互条件独立。

也就是说没有哪个属性变量对于决策结果来说占有着较大的比重,也没有哪个属性变量对于决策结果占有着较小的比重。

虽然这个简化方式在一定程度上降低了贝叶斯分类算法的分类效果,但是在实际的应用场景中,极大地简化了贝叶斯方法的复杂性。

二、原理

设有样本数据集D = {d~1~ ,d~2~,···,d~n~ },对应样本集的特征属性集为X={x~1~,x~2~,···,x~d~},类变量为Y={y~1~,y~2~,···,y~m~},即D可以分成y~m~类别。其中x~1~,x~2~,···,x~d~相互随机独立,则Y的先验概率P~prior~ = P(Y),Y的后验概率P~post~ = P(Y|X),则由朴素贝叶斯算法可得,后验概率可以由先验概率P~prior~ = P(Y)、证据P(X)、类条件概率P(X|Y)计算出:

$$ P(X|Y)=\frac{P(Y)P(X|Y)}{P(X)} $$

朴素贝叶斯基于各特征相互独立,在给定类别为y的情况下,上式可以进一步表示为下式:

$$ P(X|Y=y)=\prod^{d}_{i=1}P(x_i|Y=y) $$

由以上两式可以算出后验概率为:

$$ P_{post}=P(Y|X)=\frac{P(y)\prod^{d}_{i=1}P(x_i|Y)}{P(X)} $$

由于P(X)的大小是固定不变的,因此在比较后验概率时,只比较上式的分子部分即可。

因此可以得到一个样本数据属于类别y~i~的朴素贝叶斯计算公式如下:

$$ P(y_i|x_1,x_2,···,x_d)=\frac{p(y_i)\prod^{d}_{j=1}P(x_j|y_i)}{\prod^{d}_{j=1}P(x_j)} $$

 注意,一般只比较分子部分,这一点在后面会有一个在Titanic上应用的小讨论

三、原理分析(实例)

这里用一个实际案例来说明比较抽象的公式。

以瓜树的案例来计算说明:

目标:对下例进行分类

计算过程:

那么,我自己的理解就是:

​ 先在训练集中计算标签为0和1的先验概率,再分别计算每个特征在标签为0和1的条件概率。

​ 预测过程中,将预测数据每个特征在标签为1时的条件概率之积与预测为1的概率直接相乘,记为P(1)

​ 再将预测数据每个特征在标签为0时的条件概率之积与预测为0的概率直接相乘,记作P(0)

​ 比较P(1)与P(0),哪个大就预测数据的标签为0或1.

四、在Titanic数据集上的应用

1.数据集介绍

数据有如下特征:

继续观察每个特征下的具体情况:

我们会发现:

Age,Cabin,Embarked存在空值,需要进行处理

继续看整体生存状况

再综合我们的常识可以得到结论:

女性的存活率高于男性

Pclass1,2,3的生存率依次降低,这有可能与不同层的乘船人的社会地位,富裕程度有关

年龄上来说,小孩先走,存活率较高

Fare分布差异很大。

Parch 代表同船的父母或子女,SipSp代表同船的兄弟姐妹,这都是两个表现亲人的关系,显然这类因素会对存活率产生影响

那么结合上面的分析的,可以做出如下处理:

对于不重要的特征舍弃掉,简化后面的计算,同时将SibSp和Parch两项合并。

数据中很多为连续型和字符型数据,我们需要进行数值化,离散化处理。

年龄中位数28,缺失值补充为28。并且以25和31为界限分为三类

sibsp&parch按照有无分为两类

生还共计342人。其中全体票价和生还票价均值均约为32。

​ 生还者票价高于32的126人

死亡共计549人。其中票价低于32的464人

​ 票价低于32共计680人,死亡率0.68

票价低于64的共计773人,死亡512人 选择以64为分界点

附上此部分分析代码:

# 以下是最初的数据分析
    # train_set, category = loadDataset('titanic.csv')
    # print(category)
    # print(train_set)
    # k = [0, 0, 0, 0, 0, 0]
    # min = train_set[0][3]
    # max = 0
    # age = []
    # for data in train_set:
    #     for i in range(len(category)):
    #         if data[i] is None:
    #             k[i] += 1
    #     if data[3] is not None:
    #         if data[3] < min:
    #             min = data[3]
    #         if data[3] > max:
    #             max = data[3]
    #         age.append(data[3])
    #
    # age = sorted(age)
    #
    # print(category)
    # print(k)
    # print(min)
    # print(max)
    # print(age)
    # print((len(train_set)-k[3])/2)  #357
    # print(age[int((len(train_set)-k[3])/2)])    # 28
    # print(len(age)/3)
    # print(age[297])     # 25
    # print(age[297*2])   # 31
    # for data in train_set:
    #     if data[3] is None:
    #         data[3] = 28
    # print(train_set)
    # s = 0
    # for data in train_set:
    #     if data[-1] < 64:
    #         s += 1
    #
    # print(s)
    # 以上是最初的数据分析

2.导入相关库

import csv
import numpy as np
import matplotlib.pyplot as plt

3.读入数据和数据处理

此部分函数实现以下内容:

  1. 读入数据集
  2. 删除分析中的不重要特征
  3. 转换数据格式为float
  4. 数据离散化:
性别以0,1区分 #此处其实更好的方法是one—hot处理,读者可以自行研究

年龄以25,31(60)为界限进行离散 #此处再优化分析时会在此说明

sibsp和parcg加和后以2为界限,离散化

fare以64为界限离散化

def loadDataset(filename):
    with open(filename, 'r') as f:
        lines = csv.reader(f)
        data_set = list(lines)
    if filename != 'titanic.csv':
        for i in range(len(data_set)):
            del(data_set[i][0])
    # 整理数据
    for i in range(len(data_set)):
        del(data_set[i][0])
        del(data_set[i][2])
        data_set[i][4] += data_set[i][5]
        del(data_set[i][5])
        del(data_set[i][5])
        del(data_set[i][6])
        del(data_set[i][-1])

    category = data_set[0]

    del (data_set[0])
    # 转换数据格式
    for data in data_set:
        data[0] = int(data[0])
        data[1] = int(data[1])
        if data[3] != '':
            data[3] = float(data[3])
        else:
            data[3] = None
        data[4] = float(data[4])
        data[5] = float(data[5])
    # 补全缺失值 转换记录方式 分类
    for data in data_set:
        if data[3] is None:
            data[3] = 28
        # male : 1, female : 0
        if data[2] == 'male':
            data[2] = 1
        else:
            data[2] = 0
        # age <25 为0, 25<=age<31为1,age>=31为2
        if data[3] < 25:
            data[3] = 0
        elif data[3] >= 21 and data[3] < 60: # 但是测试得60分界准确率最高???!!!
            data[3] = 1
        else:
            data[3] = 2
        # sibsp&parcg以2为界限,小于为0,大于为1
        if data[4] < 2:
            data[4] = 0
        else:
            data[4] = 1
        # fare以64为界限
        if data[-1] < 64:
            data[-1] = 0
        else:
            data[-1] = 1


    return data_set, category

这一部分读入数据要根据自己手中的数据来写,无法直接应用

4.训练集和测试集的划分

常⽤有hold-out,cross validation,bootstrapping⽅法

hold—out

Hold-Out 是基本的划分方法,字面意思就是“留出来一部分”,即将数据集直接按照一定比例划分。

例如常用的 “2/8” 与 “3/7”,含义为训练集 80% 或 70%,相应的测试集占 20% 或 30%.

Hold-Out 的缺点较为明显,即在验证集上计算的出来的 最后评估指标与原始数据的顺序有很大关系。

import random
import csv
import pandas as pd

def loadDataset(filename, split, trainingSet = [], testSet = []):
     with open(filename, 'r') as f:
         lines = csv.reader(f)
         dataset = list(lines)
         for x in range(len(dataset)-1):
             if random.random() < split:  #将数据集随机划分
                 trainingSet.append(dataset[x])
             else:
                 testSet.append(dataset[x])


if __name__ == "__main__":
    train = []
    test = []
    loadDataset('', 0.7, train, test)
    print(train)
    print(test)

    train2 = pd.DataFrame(data=train)
    train2.to_csv('')

    test2 = pd.DataFrame(data=test)
    test2.to_csv('')

cross validation

简单交叉验证

将原始数据随机分为两组,一组做为训练集,一组做为验证集,利用训练集训练分类器,然后利用验证集验证模型,记录最后的分类准确率为此分类器的性能指标。

好处:处理简单,只需随机把原始数据分为两组即可

坏处:没有达到交叉的思想,由于是随机的将原始数据分组,所以最后验证集分类准确率的高低与原始数据的分组有很大的关系,得到的结果并不具有说服性。

2-折交叉验证(2-fold Cross Validation,记为2-CV)

做法是将数据集分成两个相等大小的子集,进行两次的分类器训练。在第一次中,一个子集作为训练集,另一个便作为测试集;在第二次训练中,则将训练集与测试集对换,

其并不常用:

主要原因是训练集样本数太少,不足以代表母体样本的分布,导致te测试阶段辨识率容易出现明显落差。

K-折交叉验证(K-fold Cross Validation,记为K-CV)

将原始数据分成K组(一般是均分),将每个子集数据分别做一次验证集,其余的K-1组子集数据作为训练集,这样会得到K个模型,用这K个模型最终的验证集的分类准确率的平均数作为此K-CV下分类器的性能指标。K一般大于等于2,实际操作时一般从3开始取,只有在原始数据集合数据量小的时候才会尝试取2。

应用最多,K-CV可以有效的避免过拟合与欠拟合的发生,最后得到的结果也比较具有说服性。

常见为十折交叉验证

  • 将数据集分成十份,轮流将其中9份作为训练数据,1份作为测试数据,进行试验。每次试验都会得出相应的正确率。
  • 10次的结果的正确率的平均值作为对算法精度的估计,一般还需要进行多次10折交叉验证(例如10次10折交叉验证),再求其均值,作为对算法准确性的估计
import csv
import pandas as pd

with open('titanic.csv', 'r') as f:
    lines = csv.reader(f)
    data_set = list(lines)
del(data_set[0])
length = len(data_set)//10
print(length)
data = []
for i in range(10):
    data.append(data_set[i*length:(i+1)*length])
data.append(data_set[10*length:])

print(data_set)
print(data)

bootstrapping(自助法)

最常用的一种Bootstrap自助法,假设给定的数据集包含d个样本。该数据集有放回地抽样m次,产生m个样本的训练集。这样原数据样本中的某些样本很可能在该样本集中出现多次。没有进入该训练集的样本最终形成检验集(测试集)。 显然每个样本被选中的概率是1/m,因此未被选中的概率就是(1-1/m),这样一个样本在训练集中没出现的概率就是m次都未被选中的概率,即(1-1/m)^m^。当m趋于无穷大时,这一概率就将趋近于e^-1=0.368,所以留在训练集中的样本大概就占原来数据集的63.2%。

例如:人工样本为1,2,3;只有三个样本,则可以从随机变量X,分布为P(X=k)=1/3, k=1,2,3; 这样的经验分布中用计算机根据上述分布自动产生样本,如产生5个样本:1 2 3 2 1;也可以是:3 3 2 1 1

自助法在数据集较小、难以有效划分训练集测试集时很有用;此外,自助法能从初始数据集中产生多个不同的训练集,这对集成学习等方法有很大的好处。然而,自助法产生的数据集改变了初始数据集的分布,这会引入估计偏差。因此,在初始数据量足够时,留出法和交叉验证法更常用一些。

#自助法
import numpy as np
#任意设置一个数据集
X = [1, 4, 3, 23, 4, 6, 7, 8, 9, 45, 67, 89, 34, 54, 76, 98, 43, 52]

#通过产生的随机数获得抽取样本的序号
bootstrapping = []
for i in range(len(X)):
    bootstrapping.append(np.floor(np.random.random()*len(X)))
#通过序号获得原始数据集中的数据
D_1 = []
for i in range(len(X)):
    D_1.append(X[int(bootstrapping[i])])

5.朴素贝叶斯计算

这部分没什么好说的,按照公式计算就好

class NaiveBayes:
    def __init__(self):
        pass

    def train(self, data):
        length = len(data)
        p = []
        for i in range(len(data[0])):
            p.append([])
        # 计算先验概率
        sur = 0
        for i in data:
            if i[0] == 1:
                sur += 1

        death = length - sur
        p1 = sur/length
        p0 = 1 - p1
        p[0].append(p1)
        p[0].append(p0)

        print(p)

        # 计算pclass的条件概率
        a1 = 0
        a0 = 0
        b1 = 0
        b0 = 0
        c1 = 0
        c0 = 0
        for i in data:
            if i[0] == 1 and i[1] == 1:
                a1 += 1
            elif i[0] == 0 and i[1] == 1:
                a0 += 1
            elif i[0] == 1 and i[1] == 2:
                b1 += 1
            elif i[0] == 0 and i[1] == 2:
                b0 += 1
            elif i[0] == 1 and i[1] == 3:
                c1 += 1
            elif i[0] == 0 and i[1] == 3:
                c0 += 1
        p[1].append(a1 / sur)
        p[1].append(a0 / death)
        p[1].append(b1 / sur)
        p[1].append(b0 / death)
        p[1].append(c1 / sur)
        p[1].append(c0 / death)

        # 计算sex的条件概率
        m1 = 0
        m0 = 0
        f1 = 0
        f0 = 0
        for i in data:
            if i[0] == 1 and i[2] == 1:
                m1 += 1
            elif i[0] == 0 and i[2] == 1:
                m0 += 1
            elif i[0] == 1 and i[2] == 0:
                f1 += 1
            elif i[0] == 0 and i[2] == 0:
                f0 += 1
        p[2].append(m1 / sur)
        p[2].append(m0 / death)
        p[2].append(f1 / sur)
        p[2].append(f0 / death)

        # 计算age的条件概率
        a1 = 0
        a0 = 0
        b1 = 0
        b0 = 0
        c1 = 0
        c0 = 0
        for i in data:
            if i[0] == 1 and i[3] == 1:
                a1 += 1
            elif i[0] == 0 and i[3] == 1:
                a0 += 1
            elif i[0] == 1 and i[3] == 2:
                b1 += 1
            elif i[0] == 0 and i[3] == 2:
                b0 += 1
            elif i[0] == 1 and i[3] == 3:
                c1 += 1
            elif i[0] == 0 and i[3] == 3:
                c0 += 1
        p[3].append(a1 / sur)
        p[3].append(a0 / death)
        p[3].append(b1 / sur)
        p[3].append(b0 / death)
        p[3].append(c1 / sur)
        p[3].append(c0 / death)

        # 计算sibsp&parch条件概率
        m1 = 0
        m0 = 0
        f1 = 0
        f0 = 0
        for i in data:
            if i[0] == 1 and i[4] == 1:
                m1 += 1
            elif i[0] == 0 and i[4] == 1:
                m0 += 1
            elif i[0] == 1 and i[4] == 0:
                f1 += 1
            elif i[0] == 0 and i[4] == 0:
                f0 += 1
        p[4].append(m1 / sur)
        p[4].append(m0 / death)
        p[4].append(f1 / sur)
        p[4].append(f0 / death)

        m1 = 0
        m0 = 0
        f1 = 0
        f0 = 0
        for i in data:
            if i[0] == 1 and i[5] == 1:
                m1 += 1
            elif i[0] == 0 and i[5] == 1:
                m0 += 1
            elif i[0] == 1 and i[5] == 0:
                f1 += 1
            elif i[0] == 0 and i[5] == 0:
                f0 += 1
        p[5].append(m1 / sur)
        p[5].append(m0 / death)
        p[5].append(f1 / sur)
        p[5].append(f0 / death)

        return p

    def predict(self, t_data, p):
        result = []
        pp = []
        for data in t_data:
            p1 = p[0][0]
            p0 = p[0][1]
            # pclass
            if data[1] == 1:
                p1 *= p[1][0]
                p0 *= p[1][1]
            elif data[1] == 2:
                p1 *= p[1][2]
                p0 *= p[1][3]
            elif data[1] == 3:
                p1 *= p[1][4]
                p0 *= p[1][5]
            # sex
            if data[2] == 1:
                p1 *= p[2][0]
                p0 *= p[2][1]
            else:
                p1 *= p[2][2]
                p0 *= p[2][3]

            # age
            if data[3] == 0:
                p1 *= p[3][0]
                p0 *= p[3][1]
            elif data[3] == 1:
                p1 *= p[3][2]
                p0 *= p[3][3]
            else:
                p1 *= p[3][4]
                p0 *= p[3][5]

            #sibsp&parch
            if data[4] == 1:
                p1 *= p[4][0]
                p0 *= p[4][1]
            else:
                p1 *= p[4][2]
                p0 *= p[4][3]

            # fare
            if data[5] == 1:
                p1 *= p[5][0]
                p0 *= p[5][1]
            else:
                p1 *= p[5][2]
                p0 *= p[5][3]

            pp.append(p1)

            if p1 >= p0:
                result.append(1)
            else:
                result.append(0)
        return pp, result

6.模型评估1

此处评估标准选取ROC_AUC

先给出混淆矩阵:

ROC 图像:

纵轴为 TPR 真正例率,预测为正且实际为正的样本占所有正例样本的比例。

横轴为 FPR 假正例率,预测为正但实际为负的样本占所有负例样本的比例。

$$ TPR = \frac{TP}{TP+FN} $$

$$ FPR = \frac{FP}{TN+FP} $$

ROC图像分析

  • 第一个点,(0,1),即 FPR=0, TPR=1,这意味着 FN(false negative)=0,并且FP(false positive)=0。这意味着分类器很完美,因为它将所有的样本都正确分类。
  • 第二个点,(1,0),即 FPR=1,TPR=0,这个分类器是最糟糕的,因为它成功避开了所有的正确答案。
  • 第三个点,(0,0),即 FPR=TPR=0,即 FP(false positive)=TP(true positive)=0,此时分类器将所有的样本都预测为负样本(negative)。
  • 第四个点(1,1),分类器将所有的样本都预测为正样本。
  • 对角线上的点表示分类器将一半的样本猜测为正样本,另外一半的样本猜测为负样本。

因此,ROC 曲线越接近左上角,分类器的性能越好。

怎么画ROC曲线

  • 按 Score 从大到小排列
  • 依次将每个 Score 设定为阈值,然后这 20 个样本的标签会变化,当它的 score 大于或等于当前阈值时,则为正样本,否则为负样本。
  • 这样对每个阈值,可以计算一组 FPR 和 TPR,此例一共可以得到 20 组。
  • 当阈值设置为 1 和 0 时, 可以得到 ROC 曲线上的 (0,0) 和 (1,1) 两个点。

怎么计算AUC

$$ AUC = \frac{1}{2}\sum^{m-1}_{i=1}(x_{i+1}-x_i)·(y_i+y_{i+1}) $$

def roc_auc(p, test, result):
    tp = 0
    tn = 0
    for i in test:
        if i[0] == 1:
            tp += 1
        else:
            tn += 1

    for i in range(len(test)):
        test[i] = test[i][0]
        p[i] = [p[i]]
        p[i].append(test[i])
        p[i].append(result[i])

    p = sorted(p, reverse=True)
    print(p)
    tpr = [0]
    fpr = [0]
    length = len(p)

    for i in range(1, length):
        if p[i][1] == 1:
            fpr.append(fpr[i-1])
            tpr.append(tpr[i-1]+1/tp)

        elif p[i][1] == 0:
            fpr.append(fpr[i-1]+1/tn)
            tpr.append(tpr[i-1])

    tpr.append(1)
    fpr.append(1)

    print(fpr)
    print(tpr)

    auc = 0
    for i in range(len(fpr)-1):
        auc += (fpr[i+1]-fpr[i])*(tpr[i]+tpr[i+1])
    auc = auc/2

    print(auc)

    fpr = np.array(fpr)
    tpr = np.array(tpr)

    plt.title("ROC curve of %s (AUC = %.4f)" % ('svm', auc))
    plt.xlabel("False Positive Rate")
    plt.ylabel("True Positive Rate")

    plt.plot(fpr, tpr)
    plt.show()

7.模型评估2——F1_score

F1分数(F1 Score)中,是统计学中用来衡量二分类模型精确度的一种指标。它同时兼顾了分类模型的精确率和召回率。F1分数可以看作是模型精确率和召回率的一种调和平均,它的最大值是1,最小值是0。

$$ F1 = \frac{2*P*R}{P+R}=\frac{2*TP}{样例总数+TP-TN} $$

 tp = 0
    tn = 0
    for i in range(len(result)):
        if test[i][0] == result[i] == 1:
            tp += 1
        if test[i][0] == result[i] == 0:
            tn += 1

    print(tp)
    print(tn)

    f1 = (2*tp)/(len(test)+tp-tn)
    print(f1)

    roc_auc(pp, test, result)

8.评估结果

准确率:74.5%

F1 : 0.678

9.完整代码

import csv
import numpy as np
import matplotlib.pyplot as plt

# 0PassengerId:乘客的ID                               不重要
# 1Survived:乘客是否获救,Key:0=没获救,1=已获救
# 2Pclass:乘客船舱等级(1/2/3三个等级舱位)
# 3Name:乘客姓名                                       不重要
# 4Sex:性别
# 5Age:年龄
# 6SibSp:乘客在船上的兄弟姐妹/配偶数量
# 7Parch:乘客在船上的父母/孩子数量
# 8Ticket:船票号                                         不重要
# 9Fare:船票价
# 10Cabin:客舱号码                                        不重要
# 11Embarked:登船的港口                                   不重要

# 数据分析得: 年龄中位数28,缺失值补充为28。并且以25和31为界限分为三类
#             sibsp&parch按照有无分为两类
#            生还共计342人。其中全体票价和生还票价均值均约为32。
#               生还者票价高于32的126人
#            死亡共计549人。其中票价低于32的464人
#           票价低于32共计680人,死亡率0.68
#           票价低于64的共计773人,死亡512人  选择以64为分界点


def loadDataset(filename):
    with open(filename, 'r') as f:
        lines = csv.reader(f)
        data_set = list(lines)
    if filename != 'titanic.csv':
        for i in range(len(data_set)):
            del(data_set[i][0])
    # 整理数据
    for i in range(len(data_set)):
        del(data_set[i][0])
        del(data_set[i][2])
        data_set[i][4] += data_set[i][5]
        del(data_set[i][5])
        del(data_set[i][5])
        del(data_set[i][6])
        del(data_set[i][-1])

    category = data_set[0]

    del (data_set[0])
    # 转换数据格式
    for data in data_set:
        data[0] = int(data[0])
        data[1] = int(data[1])
        if data[3] != '':
            data[3] = float(data[3])
        else:
            data[3] = None
        data[4] = float(data[4])
        data[5] = float(data[5])
    # 补全缺失值 转换记录方式 分类
    for data in data_set:
        if data[3] is None:
            data[3] = 28
        # male : 1, female : 0
        if data[2] == 'male':
            data[2] = 1
        else:
            data[2] = 0
        # age <25 为0, 25<=age<31为1,age>=31为2
        if data[3] < 25:
            data[3] = 0
        elif data[3] >= 21 and data[3] < 60: # 但是测试得60分界准确率最高???!!!
            data[3] = 1
        else:
            data[3] = 2
        # sibsp&parcg以2为界限,小于为0,大于为1
        if data[4] < 2:
            data[4] = 0
        else:
            data[4] = 1
        # fare以64为界限
        if data[-1] < 64:
            data[-1] = 0
        else:
            data[-1] = 1


    return data_set, category


class NaiveBayes:
    def __init__(self):
        pass

    def train(self, data):
        length = len(data)
        p = []
        for i in range(len(data[0])):
            p.append([])
        # 计算先验概率
        sur = 0
        for i in data:
            if i[0] == 1:
                sur += 1

        death = length - sur
        p1 = sur/length
        p0 = 1 - p1
        p[0].append(p1)
        p[0].append(p0)

        print(p)

        # 计算pclass的条件概率
        a1 = 0
        a0 = 0
        b1 = 0
        b0 = 0
        c1 = 0
        c0 = 0
        for i in data:
            if i[0] == 1 and i[1] == 1:
                a1 += 1
            elif i[0] == 0 and i[1] == 1:
                a0 += 1
            elif i[0] == 1 and i[1] == 2:
                b1 += 1
            elif i[0] == 0 and i[1] == 2:
                b0 += 1
            elif i[0] == 1 and i[1] == 3:
                c1 += 1
            elif i[0] == 0 and i[1] == 3:
                c0 += 1
        p[1].append(a1 / sur)
        p[1].append(a0 / death)
        p[1].append(b1 / sur)
        p[1].append(b0 / death)
        p[1].append(c1 / sur)
        p[1].append(c0 / death)

        # 计算sex的条件概率
        m1 = 0
        m0 = 0
        f1 = 0
        f0 = 0
        for i in data:
            if i[0] == 1 and i[2] == 1:
                m1 += 1
            elif i[0] == 0 and i[2] == 1:
                m0 += 1
            elif i[0] == 1 and i[2] == 0:
                f1 += 1
            elif i[0] == 0 and i[2] == 0:
                f0 += 1
        p[2].append(m1 / sur)
        p[2].append(m0 / death)
        p[2].append(f1 / sur)
        p[2].append(f0 / death)

        # 计算age的条件概率
        a1 = 0
        a0 = 0
        b1 = 0
        b0 = 0
        c1 = 0
        c0 = 0
        for i in data:
            if i[0] == 1 and i[3] == 1:
                a1 += 1
            elif i[0] == 0 and i[3] == 1:
                a0 += 1
            elif i[0] == 1 and i[3] == 2:
                b1 += 1
            elif i[0] == 0 and i[3] == 2:
                b0 += 1
            elif i[0] == 1 and i[3] == 3:
                c1 += 1
            elif i[0] == 0 and i[3] == 3:
                c0 += 1
        p[3].append(a1 / sur)
        p[3].append(a0 / death)
        p[3].append(b1 / sur)
        p[3].append(b0 / death)
        p[3].append(c1 / sur)
        p[3].append(c0 / death)

        # 计算sibsp&parch条件概率
        m1 = 0
        m0 = 0
        f1 = 0
        f0 = 0
        for i in data:
            if i[0] == 1 and i[4] == 1:
                m1 += 1
            elif i[0] == 0 and i[4] == 1:
                m0 += 1
            elif i[0] == 1 and i[4] == 0:
                f1 += 1
            elif i[0] == 0 and i[4] == 0:
                f0 += 1
        p[4].append(m1 / sur)
        p[4].append(m0 / death)
        p[4].append(f1 / sur)
        p[4].append(f0 / death)

        m1 = 0
        m0 = 0
        f1 = 0
        f0 = 0
        for i in data:
            if i[0] == 1 and i[5] == 1:
                m1 += 1
            elif i[0] == 0 and i[5] == 1:
                m0 += 1
            elif i[0] == 1 and i[5] == 0:
                f1 += 1
            elif i[0] == 0 and i[5] == 0:
                f0 += 1
        p[5].append(m1 / sur)
        p[5].append(m0 / death)
        p[5].append(f1 / sur)
        p[5].append(f0 / death)

        return p

    def predict(self, t_data, p):
        result = []
        pp = []
        for data in t_data:
            p1 = p[0][0]
            p0 = p[0][1]
            # pclass
            if data[1] == 1:
                p1 *= p[1][0]
                p0 *= p[1][1]
            elif data[1] == 2:
                p1 *= p[1][2]
                p0 *= p[1][3]
            elif data[1] == 3:
                p1 *= p[1][4]
                p0 *= p[1][5]
            # sex
            if data[2] == 1:
                p1 *= p[2][0]
                p0 *= p[2][1]
            else:
                p1 *= p[2][2]
                p0 *= p[2][3]

            # age
            if data[3] == 0:
                p1 *= p[3][0]
                p0 *= p[3][1]
            elif data[3] == 1:
                p1 *= p[3][2]
                p0 *= p[3][3]
            else:
                p1 *= p[3][4]
                p0 *= p[3][5]

            #sibsp&parch
            if data[4] == 1:
                p1 *= p[4][0]
                p0 *= p[4][1]
            else:
                p1 *= p[4][2]
                p0 *= p[4][3]

            # fare
            if data[5] == 1:
                p1 *= p[5][0]
                p0 *= p[5][1]
            else:
                p1 *= p[5][2]
                p0 *= p[5][3]

            pp.append(p1)

            if p1 >= p0:
                result.append(1)
            else:
                result.append(0)
        return pp, result


def roc_auc(p, test, result):
    tp = 0
    tn = 0
    for i in test:
        if i[0] == 1:
            tp += 1
        else:
            tn += 1

    for i in range(len(test)):
        test[i] = test[i][0]
        p[i] = [p[i]]
        p[i].append(test[i])
        p[i].append(result[i])

    p = sorted(p, reverse=True)
    print(p)
    tpr = [0]
    fpr = [0]
    length = len(p)

    for i in range(1, length):
        if p[i][1] == 1:
            fpr.append(fpr[i-1])
            tpr.append(tpr[i-1]+1/tp)

        elif p[i][1] == 0:
            fpr.append(fpr[i-1]+1/tn)
            tpr.append(tpr[i-1])

    tpr.append(1)
    fpr.append(1)

    print(fpr)
    print(tpr)

    auc = 0
    for i in range(len(fpr)-1):
        auc += (fpr[i+1]-fpr[i])*(tpr[i]+tpr[i+1])
    auc = auc/2

    print(auc)

    fpr = np.array(fpr)
    tpr = np.array(tpr)

    plt.title("ROC curve of %s (AUC = %.4f)" % ('svm', auc))
    plt.xlabel("False Positive Rate")
    plt.ylabel("True Positive Rate")

    plt.plot(fpr, tpr)
    plt.show()




if __name__ == "__main__":
    # 以下是最初的数据分析
    # train_set, category = loadDataset('titanic.csv')
    # print(category)
    # print(train_set)
    # k = [0, 0, 0, 0, 0, 0]
    # min = train_set[0][3]
    # max = 0
    # age = []
    # for data in train_set:
    #     for i in range(len(category)):
    #         if data[i] is None:
    #             k[i] += 1
    #     if data[3] is not None:
    #         if data[3] < min:
    #             min = data[3]
    #         if data[3] > max:
    #             max = data[3]
    #         age.append(data[3])
    #
    # age = sorted(age)
    #
    # print(category)
    # print(k)
    # print(min)
    # print(max)
    # print(age)
    # print((len(train_set)-k[3])/2)  #357
    # print(age[int((len(train_set)-k[3])/2)])    # 28
    # print(len(age)/3)
    # print(age[297])     # 25
    # print(age[297*2])   # 31
    # for data in train_set:
    #     if data[3] is None:
    #         data[3] = 28
    # print(train_set)
    # s = 0
    # for data in train_set:
    #     if data[-1] < 64:
    #         s += 1
    #
    # print(s)
    # 以上是最初的数据分析





    train_set, category = loadDataset('titanic_train.csv')
    test_set, category = loadDataset('titanic_test.csv')

    print(category)
    print(train_set)

    bayes = NaiveBayes()

    p = bayes.train(train_set)
    print(p)

    pp, result = bayes.predict(test_set, p)
    print(result)
    count = 0
    for i in range(len(result)):
        if test_set[i][0] == result[i]:
            count += 1

    accuracy = count/len(test_set)
    print(accuracy)



    # # 十折交叉验证
    # data_set, category = loadDataset('titanic.csv')
    #
    # length = len(data_set) // 10
    # print(length)
    # data = []
    # for i in range(10):
    #     data.append(data_set[i * length:(i + 1) * length])
    # data.append(data_set[10 * length:])
    #
    # sum = 0
    #
    # for i in range(9):
    #     p = bayes.train(data[i])
    #     print(p)
    #
    #     pp, result = bayes.predict(data[9], p)
    #     print(result)
    #     count = 0
    #     for i in range(len(result)):
    #         if test_set[i][0] == result[i]:
    #             count += 1
    #     sum += count/len(data[9])
    #
    # print(sum/10)


    # 自助法
    data_set, category = loadDataset('titanic.csv')
    bootstrapping = []
    for i in range(len(data_set)):
         bootstrapping.append(np.floor(np.random.random()*len(data_set)))

    test = []
    for i in range(len(data_set)):
         test.append(data_set[int(bootstrapping[i])])

    p = bayes.train(data_set)
    print(p)

    pp, result = bayes.predict(test, p)
    print(result)
    count = 0
    for i in range(len(result)):
        if test[i][0] == result[i]:
            count += 1

    accuracy = count / len(test)
    print(accuracy)

    #基于自助法计算F1-score
    tp = 0
    tn = 0
    for i in range(len(result)):
        if test[i][0] == result[i] == 1:
            tp += 1
        if test[i][0] == result[i] == 0:
            tn += 1

    print(tp)
    print(tn)

    f1 = (2*tp)/(len(test)+tp-tn)
    print(f1)

    roc_auc(pp, test, result)

五、模型优化与提升

  1. 性别数值化更好的方法是one—hot处理
  2. 年龄离散化的标准。后续再测试的过程中发现,年龄的离散化标准对模型的准确率影响极大,这一点可以在探索后进行优化进而提升模型效果
  3. 对于贝叶斯的概率计算时,原方法是只计算分子进行比较。但是我们可以换一种方法,计算完整的概率值,然后与0.5进行比较,然后分类。这种方法再结合更加合适的年龄划分标准可以是本地的准确率达到90%以上,在kaggle上也可以达到80%以上

这几种优化思路提供给读者自行探索尝试。

import csv
import numpy as np
import matplotlib.pyplot as plt

# 0PassengerId:乘客的ID                               不重要
# 1Survived:乘客是否获救,Key:0=没获救,1=已获救
# 2Pclass:乘客船舱等级(1/2/3三个等级舱位)
# 3Name:乘客姓名                                       不重要
# 4Sex:性别
# 5Age:年龄
# 6SibSp:乘客在船上的兄弟姐妹/配偶数量
# 7Parch:乘客在船上的父母/孩子数量
# 8Ticket:船票号                                         不重要
# 9Fare:船票价
# 10Cabin:客舱号码                                        不重要
# 11Embarked:登船的港口                                   不重要

# 数据分析得: 年龄中位数28,缺失值补充为28。并且以25和31为界限分为三类
#             sibsp&parch按照有无分为两类
#            生还共计342人。其中全体票价和生还票价均值均约为32。
#               生还者票价高于32的126人
#            死亡共计549人。其中票价低于32的464人
#           票价低于32共计680人,死亡率0.68
#           票价低于64的共计773人,死亡512人  选择以64为分界点


def loadDataset(filename):
    with open(filename, 'r') as f:
        lines = csv.reader(f)
        data_set = list(lines)
    if filename != 'data/data43004/titanic.csv':
        for i in range(len(data_set)):
            del(data_set[i][0])
    # 整理数据
    for i in range(len(data_set)):
        del(data_set[i][0])
        del(data_set[i][2])
        data_set[i][4] += data_set[i][5]
        del(data_set[i][5])
        del(data_set[i][5])
        del(data_set[i][6])
        del(data_set[i][-1])

    category = data_set[0]

    del (data_set[0])
    # 转换数据格式
    for data in data_set:
        data[0] = int(data[0])
        data[1] = int(data[1])
        if data[3] != '':
            data[3] = float(data[3])
        else:
            data[3] = None
        data[4] = float(data[4])
        data[5] = float(data[5])
    # 补全缺失值 转换记录方式 分类
    for data in data_set:
        if data[3] is None:
            data[3] = 28
        # male : 1, female : 0
        if data[2] == 'male':
            data[2] = 1
        else:
            data[2] = 0
        # age <25 为0, 25<=age<31为1,age>=31为2
        if data[3] < 25:
            data[3] = 0
        elif data[3] >= 21 and data[3] < 60: # 但是测试得60分界准确率最高???!!!
            data[3] = 1
        else:
            data[3] = 2
        # sibsp&parcg以2为界限,小于为0,大于为1
        if data[4] < 2:
            data[4] = 0
        else:
            data[4] = 1
        # fare以64为界限
        if data[-1] < 64:
            data[-1] = 0
        else:
            data[-1] = 1


    return data_set, category


class NaiveBayes:
    def __init__(self):
        pass

    def train(self, data):
        length = len(data)
        p = []
        for i in range(len(data[0])):
            p.append([])
        # 计算先验概率
        sur = 0
        for i in data:
            if i[0] == 1:
                sur += 1

        death = length - sur
        p1 = sur/length
        p0 = 1 - p1
        p[0].append(p1)
        p[0].append(p0)

        print(p)

        # 计算pclass的条件概率
        a1 = 0
        a0 = 0
        b1 = 0
        b0 = 0
        c1 = 0
        c0 = 0
        for i in data:
            if i[0] == 1 and i[1] == 1:
                a1 += 1
            elif i[0] == 0 and i[1] == 1:
                a0 += 1
            elif i[0] == 1 and i[1] == 2:
                b1 += 1
            elif i[0] == 0 and i[1] == 2:
                b0 += 1
            elif i[0] == 1 and i[1] == 3:
                c1 += 1
            elif i[0] == 0 and i[1] == 3:
                c0 += 1
        p[1].append(a1 / sur)
        p[1].append(a0 / death)
        p[1].append(b1 / sur)
        p[1].append(b0 / death)
        p[1].append(c1 / sur)
        p[1].append(c0 / death)

        # 计算sex的条件概率
        m1 = 0
        m0 = 0
        f1 = 0
        f0 = 0
        for i in data:
            if i[0] == 1 and i[2] == 1:
                m1 += 1
            elif i[0] == 0 and i[2] == 1:
                m0 += 1
            elif i[0] == 1 and i[2] == 0:
                f1 += 1
            elif i[0] == 0 and i[2] == 0:
                f0 += 1
        p[2].append(m1 / sur)
        p[2].append(m0 / death)
        p[2].append(f1 / sur)
        p[2].append(f0 / death)

        # 计算age的条件概率
        a1 = 0
        a0 = 0
        b1 = 0
        b0 = 0
        c1 = 0
        c0 = 0
        for i in data:
            if i[0] == 1 and i[3] == 1:
                a1 += 1
            elif i[0] == 0 and i[3] == 1:
                a0 += 1
            elif i[0] == 1 and i[3] == 2:
                b1 += 1
            elif i[0] == 0 and i[3] == 2:
                b0 += 1
            elif i[0] == 1 and i[3] == 3:
                c1 += 1
            elif i[0] == 0 and i[3] == 3:
                c0 += 1
        p[3].append(a1 / sur)
        p[3].append(a0 / death)
        p[3].append(b1 / sur)
        p[3].append(b0 / death)
        p[3].append(c1 / sur)
        p[3].append(c0 / death)

        # 计算sibsp&parch条件概率
        m1 = 0
        m0 = 0
        f1 = 0
        f0 = 0
        for i in data:
            if i[0] == 1 and i[4] == 1:
                m1 += 1
            elif i[0] == 0 and i[4] == 1:
                m0 += 1
            elif i[0] == 1 and i[4] == 0:
                f1 += 1
            elif i[0] == 0 and i[4] == 0:
                f0 += 1
        p[4].append(m1 / sur)
        p[4].append(m0 / death)
        p[4].append(f1 / sur)
        p[4].append(f0 / death)

        m1 = 0
        m0 = 0
        f1 = 0
        f0 = 0
        for i in data:
            if i[0] == 1 and i[5] == 1:
                m1 += 1
            elif i[0] == 0 and i[5] == 1:
                m0 += 1
            elif i[0] == 1 and i[5] == 0:
                f1 += 1
            elif i[0] == 0 and i[5] == 0:
                f0 += 1
        p[5].append(m1 / sur)
        p[5].append(m0 / death)
        p[5].append(f1 / sur)
        p[5].append(f0 / death)

        return p

    def predict(self, t_data, p):
        result = []
        pp = []
        for data in t_data:
            p1 = p[0][0]
            p0 = p[0][1]
            # pclass
            if data[1] == 1:
                p1 *= p[1][0]
                p0 *= p[1][1]
            elif data[1] == 2:
                p1 *= p[1][2]
                p0 *= p[1][3]
            elif data[1] == 3:
                p1 *= p[1][4]
                p0 *= p[1][5]
            # sex
            if data[2] == 1:
                p1 *= p[2][0]
                p0 *= p[2][1]
            else:
                p1 *= p[2][2]
                p0 *= p[2][3]

            # age
            if data[3] == 0:
                p1 *= p[3][0]
                p0 *= p[3][1]
            elif data[3] == 1:
                p1 *= p[3][2]
                p0 *= p[3][3]
            else:
                p1 *= p[3][4]
                p0 *= p[3][5]

            #sibsp&parch
            if data[4] == 1:
                p1 *= p[4][0]
                p0 *= p[4][1]
            else:
                p1 *= p[4][2]
                p0 *= p[4][3]

            # fare
            if data[5] == 1:
                p1 *= p[5][0]
                p0 *= p[5][1]
            else:
                p1 *= p[5][2]
                p0 *= p[5][3]

            pp.append(p1)

            if p1 >= p0:
                result.append(1)
            else:
                result.append(0)
        return pp, result


def roc_auc(p, test, result):
    tp = 0
    tn = 0
    for i in test:
        if i[0] == 1:
            tp += 1
        else:
            tn += 1

    for i in range(len(test)):
        test[i] = test[i][0]
        p[i] = [p[i]]
        p[i].append(test[i])
        p[i].append(result[i])

    p = sorted(p, reverse=True)
    print(p)
    tpr = [0]
    fpr = [0]
    length = len(p)

    for i in range(1, length):
        if p[i][1] == 1:
            fpr.append(fpr[i-1])
            tpr.append(tpr[i-1]+1/tp)

        elif p[i][1] == 0:
            fpr.append(fpr[i-1]+1/tn)
            tpr.append(tpr[i-1])

    tpr.append(1)
    fpr.append(1)

    print(fpr)
    print(tpr)

    auc = 0
    for i in range(len(fpr)-1):
        auc += (fpr[i+1]-fpr[i])*(tpr[i]+tpr[i+1])
    auc = auc/2

    print(auc)

    fpr = np.array(fpr)
    tpr = np.array(tpr)

    plt.title("ROC curve of %s (AUC = %.4f)" % ('svm', auc))
    plt.xlabel("False Positive Rate")
    plt.ylabel("True Positive Rate")

    plt.plot(fpr, tpr)
    plt.show()




if __name__ == "__main__":
    # 以下是最初的数据分析
    # train_set, category = loadDataset('titanic.csv')
    # print(category)
    # print(train_set)
    # k = [0, 0, 0, 0, 0, 0]
    # min = train_set[0][3]
    # max = 0
    # age = []
    # for data in train_set:
    #     for i in range(len(category)):
    #         if data[i] is None:
    #             k[i] += 1
    #     if data[3] is not None:
    #         if data[3] < min:
    #             min = data[3]
    #         if data[3] > max:
    #             max = data[3]
    #         age.append(data[3])
    #
    # age = sorted(age)
    #
    # print(category)
    # print(k)
    # print(min)
    # print(max)
    # print(age)
    # print((len(train_set)-k[3])/2)  #357
    # print(age[int((len(train_set)-k[3])/2)])    # 28
    # print(len(age)/3)
    # print(age[297])     # 25
    # print(age[297*2])   # 31
    # for data in train_set:
    #     if data[3] is None:
    #         data[3] = 28
    # print(train_set)
    # s = 0
    # for data in train_set:
    #     if data[-1] < 64:
    #         s += 1
    #
    # print(s)
    # 以上是最初的数据分析





    train_set, category = loadDataset('data/data43004/titanic_train.csv')
    test_set, category = loadDataset('data/data43004/titanic_test.csv')

    print(category)
    print(train_set)

    bayes = NaiveBayes()

    p = bayes.train(train_set)
    print(p)

    pp, result = bayes.predict(test_set, p)
    print(result)
    count = 0
    for i in range(len(result)):
        if test_set[i][0] == result[i]:
            count += 1

    accuracy = count/len(test_set)
    print(accuracy)



    # # 十折交叉验证
    # data_set, category = loadDataset('titanic.csv')
    #
    # length = len(data_set) // 10
    # print(length)
    # data = []
    # for i in range(10):
    #     data.append(data_set[i * length:(i + 1) * length])
    # data.append(data_set[10 * length:])
    #
    # sum = 0
    #
    # for i in range(9):
    #     p = bayes.train(data[i])
    #     print(p)
    #
    #     pp, result = bayes.predict(data[9], p)
    #     print(result)
    #     count = 0
    #     for i in range(len(result)):
    #         if test_set[i][0] == result[i]:
    #             count += 1
    #     sum += count/len(data[9])
    #
    # print(sum/10)


    # 自助法
    data_set, category = loadDataset('data/data43004/titanic.csv')
    bootstrapping = []
    for i in range(len(data_set)):
         bootstrapping.append(np.floor(np.random.random()*len(data_set)))

    test = []
    for i in range(len(data_set)):
         test.append(data_set[int(bootstrapping[i])])

    p = bayes.train(data_set)
    print(p)

    pp, result = bayes.predict(test, p)
    print(result)
    count = 0
    for i in range(len(result)):
        if test[i][0] == result[i]:
            count += 1

    accuracy = count / len(test)
    print(accuracy)

    #基于自助法计算F1-score
    tp = 0
    tn = 0
    for i in range(len(result)):
        if test[i][0] == result[i] == 1:
            tp += 1
        if test[i][0] == result[i] == 0:
            tn += 1

    print(tp)
    print(tn)

    f1 = (2*tp)/(len(test)+tp-tn)
    print(f1)

    roc_auc(pp, test, result)

相关文章
|
6天前
|
机器学习/深度学习 数据采集 算法
Python机器学习:Scikit-learn库的高效使用技巧
【10月更文挑战第28天】Scikit-learn 是 Python 中最受欢迎的机器学习库之一,以其简洁的 API、丰富的算法和良好的文档支持而受到开发者喜爱。本文介绍了 Scikit-learn 的高效使用技巧,包括数据预处理(如使用 Pipeline 和 ColumnTransformer)、模型选择与评估(如交叉验证和 GridSearchCV)以及模型持久化(如使用 joblib)。通过这些技巧,你可以在机器学习项目中事半功倍。
17 3
|
10天前
|
机器学习/深度学习 人工智能 算法
机器学习基础:使用Python和Scikit-learn入门
机器学习基础:使用Python和Scikit-learn入门
20 1
|
11天前
|
机器学习/深度学习 人工智能 算法
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
车辆车型识别,使用Python作为主要编程语言,通过收集多种车辆车型图像数据集,然后基于TensorFlow搭建卷积网络算法模型,并对数据集进行训练,最后得到一个识别精度较高的模型文件。再基于Django搭建web网页端操作界面,实现用户上传一张车辆图片识别其类型。
33 0
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
|
16天前
|
机器学习/深度学习 算法 Java
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
|
22天前
|
机器学习/深度学习 人工智能 算法
机器学习基础:使用Python和Scikit-learn入门
【10月更文挑战第12天】本文介绍了如何使用Python和Scikit-learn进行机器学习的基础知识和入门实践。首先概述了机器学习的基本概念,包括监督学习、无监督学习和强化学习。接着详细讲解了Python和Scikit-learn的安装、数据处理、模型训练和评估等步骤,并提供了代码示例。通过本文,读者可以掌握机器学习的基本流程,并为深入学习打下坚实基础。
16 1
|
22天前
|
机器学习/深度学习 API 计算机视觉
基于Python_opencv人脸录入、识别系统(应用dlib机器学习库)(下)
基于Python_opencv人脸录入、识别系统(应用dlib机器学习库)(下)
18 2
|
22天前
|
机器学习/深度学习 存储 算法
基于Python_opencv人脸录入、识别系统(应用dlib机器学习库)(上)
基于Python_opencv人脸录入、识别系统(应用dlib机器学习库)(上)
26 1
|
15天前
|
算法 安全 数据安全/隐私保护
基于game-based算法的动态频谱访问matlab仿真
本算法展示了在认知无线电网络中,通过游戏理论优化动态频谱访问,提高频谱利用率和物理层安全性。程序运行效果包括负载因子、传输功率、信噪比对用户效用和保密率的影响分析。软件版本:Matlab 2022a。完整代码包含详细中文注释和操作视频。
|
1天前
|
算法 调度
基于遗传模拟退火混合优化算法的车间作业最优调度matlab仿真,输出甘特图
车间作业调度问题(JSSP)通过遗传算法(GA)和模拟退火算法(SA)优化多个作业在并行工作中心上的加工顺序和时间,以最小化总完成时间和机器闲置时间。MATLAB2022a版本运行测试,展示了有效性和可行性。核心程序采用作业列表表示法,结合遗传操作和模拟退火过程,提高算法性能。
|
2天前
|
存储 算法 决策智能
基于免疫算法的TSP问题求解matlab仿真
旅行商问题(TSP)是一个经典的组合优化问题,目标是寻找经过每个城市恰好一次并返回起点的最短回路。本文介绍了一种基于免疫算法(IA)的解决方案,该算法模拟生物免疫系统的运作机制,通过克隆选择、变异和免疫记忆等步骤,有效解决了TSP问题。程序使用MATLAB 2022a版本运行,展示了良好的优化效果。