当前位置:   article > 正文

人工智能导论实验三:分类算法实验_分类算法实验报告

分类算法实验报告

实验三:分类算法实验
一.实验目的
4. 掌握分类算法的算法思想:朴素贝叶斯算法,决策树算法,人工神经网络,支持向量机;
5. 编写朴素贝叶斯算法进行分类操作。
二、实验平台
课程实训平台https://www.educoder.net/paths/369
三、实验内容及步骤
实训内容:机器学习 — 朴素贝叶斯分类器
实验步骤:
第1关 条件概率;
第2关 贝叶斯公式;
第3关 朴素贝叶斯分类算法流程;
第4关 拉普拉斯平滑;
第5关 新闻文本主题分类
四、思考题:
1.如何在参数学习或者其他方面提高算法的分类性能?
五、实验报告要求
1.对算法的原理进行说明;
2.对实验过程进行描述;
3.对实验结果进行分析。

实验三:分类算法实验
一、实验目的
1.掌握分类算法的算法思想:朴素贝叶斯算法,决策树算法,人工神经网络,支持向量机;
2.编写朴素贝叶斯算法进行分类操作。
二、实验内容及步骤
实训内容:机器学习 — 朴素贝叶斯分类器
实验步骤:
第1关 条件概率;
第2关 贝叶斯公式;
第3关 朴素贝叶斯分类算法流程;
第4关 拉普拉斯平滑;
第5关 新闻文本主题分类
三、实验原理
1.
条件概率
指的是某一事件A发生的可能性,表示为P(A)。而条件概率指的是某一事件A已经发生了条件下,另一事件B发生的可能性,表示为P(B|A)。

怎样计算条件概率
设A,B是两个事件,且P(A)>0,称P(B|A)=P(AB)/P(A)为在事件A发生的条件下,事件B发生的条件概率。(其中P(AB)表示事件A和事件B同时发生的概率)。

乘法定理
将条件概率的公式两边同时乘以P(A),就变成了乘法定理,即P(AB)=P(B|A)*P(A)。
2.
全概率公式
当为了达到某种目的,但是达到目的有很多种方式,如果想知道通过所有方式能够达到目的的概率是多少的话,就需要用到全概率公式(上面的例子就是这种情况!)。全概率公式的定义如下:
若事件B1,B2,…,Bn两两互不相容,并且其概率和为1。那么对于任意一个事件C都满足:

贝叶斯公式
已知事件已经发生了,但想要计算引发该事件的各种原因的概率时,我们就需要用到贝叶斯公式。贝叶斯公式定义如下,其中A表示已经发生的事件,Bi为导致事件A发生的第i个原因:

分子部分是乘法定理,分母部分是全概率公式(分母等于P(A))。进行一个简单的数学变换(两边同时乘以分母,再两边同时除以P(Bi)):

这个公式是朴素贝叶斯分类算法的核心数学公式。
3.
朴素贝叶斯分类算法的预测流程
朴素贝叶斯分类算法的预测思想和引例中挑西瓜的思想一样,会根据以往的经验计算出待预测数据分别为所有类别的概率,然后挑选其中概率最高的类别作为分类结果。

朴素贝叶斯分类算法的训练流程
训练的流程非常简单,主要是计算各种条件概率。
4.
拉普拉斯平滑
假设N表示训练数据集总共有多少种类别,Ni表示训练数据集中第i列总共有多少种取值。则训练过程中在算类别的概率时分子加1,分母加N,算条件概率时分子加1,分母加Ni。
5.
数据简介
本关使用的是20newsgroups数据集,20newsgroups数据集是用于文本分类、文本挖据和信息检索研究的国际标准数据集之一。数据集收集了18846篇新闻组文档,均匀分为20个不同主题(比如电脑硬件、中东等主题)的新闻组集合。

部分数据如下
From: Mamatha Devineni Ratnam mr47+@andrew.cmu.edu
Subject: Pens fans reactions
Organization: Post Office, Carnegie Mellon, Pittsburgh, PA
Lines: 12
NNTP-Posting-Host: po4.andrew.cmu.edu
I am sure some bashers of Pens fans are pretty confused about the lack
of any kind of posts about the recent Pens massacre of the Devils. Actually,
I am bit puzzled too and a bit relieved. However, I am going to put an end
to non-PIttsburghers relief with a bit of praise for the Pens. Man, they
are killing those Devils worse than I thought. Jagr just showed you why
he is much better than his regular season stats. He is also a lot
fo fun to watch in the playoffs. Bowman should let JAgr have a lot of
fun in the next couple of games since the Pens are going to beat the pulp out of Jersey anyway. I was very disappointed not to see the Islanders lose the final
regular season game. PENS RULE!!!
其中新闻文本对应的主题标签,已经用0-19这20个数字表示。

文本向量化
由于数据集中每一条数据都是很长的一个字符串,所以我们需要对数据进行向量化的处理。例如,I have a apple! I have a pen!可能需要将该字符串转换成向量如[10, 7, 0, 1, 2, 6, 22, 100, 8, 0, 1, 0]。

sklearn提供了实现词频向量化功能的CountVectorizer类。想要对数据进行向量化,代码如下
from sklearn.feature_ext\fraction.text import CountVectorizer
#实例化向量化对象
vec = CountVectorizer()
#将训练集中的新闻向量化
X_train = vec.fit_transform(X_train)
#将测试集中的新闻向量化
X_test = vec.transform(X_test)
但是仅仅通过统计词频的方式来将文本转换成向量会出现一个问题:长的文章词语出现的次数会比短的文章要多,而实际上两篇文章可能谈论的都是同一个主题。

为了解决这个问题,我们可以使用tf-idf来构建文本向量,sklearn中已经提供了tf-idf的接口,示例代码如下
from sklearn.feature_ext\fraction.text import TfidfTransformer
#实例化tf-idf对象
tfidf = TfidfTransformer()
#将训练集中的词频向量用tf-idf进行转换
X_train = tfidf.fit_transform(X_train_count_vectorizer)
#将测试集中的词频向量用tf-idf进行转换
X_test = vec.transform(X_test_count_vectorizer)
MultinomialNB
MultinomialNB是sklearn中多项分布数据的朴素贝叶斯算法的实现,并且是用于文本分类的经典朴素贝叶斯算法。在本关中建议使用MultinomialNB来实现文本分类功能。

在MultinomialNB实例化时alpha是一个常用的参数。

alpha: 平滑因子。当等于1时,做的是拉普拉斯平滑;当小于1时做的是Lidstone平滑;当等于0时,不做任何平滑处理。
MultinomialNB类中的fit函数实现了朴素贝叶斯分类算法训练模型的功能,predict函数实现了法模型预测的功能。

其中fit函数的参数如下
X:大小为[样本数量,特征数量]的ndarry,存放训练样本
Y:值为整型,大小为[样本数量]的ndarray,存放训练样本的分类标签

而predict函数有一个向量输入
X:大小为[样本数量,特征数量]的ndarry,存放预测样本

MultinomialNB的使用代码如下
clf = MultinomialNB()
clf.fit(X_train, Y_train)
result = clf.predict(X_test)
四、实验过程
3.
self.label_prob表示每种类别在数据中出现的概率
self.condition_prob表示每种类别确定的条件下各个特征出现的概率
fit对模型进行训练,需要将各种概率分别保存在self.label_prob和self.condition_prob中
feature:训练集数据,类型为ndarray;
label:训练集标签,类型为ndarray;
return:无返回。
predict对数据进行预测,返回预测结果
feature:测试数据集所有特征组成的ndarray。(PS:feature中有多条数据);
return:模型预测的结果。(PS:feature中有多少条数据,就需要返回长度为多少的list或者ndarry)。
4.
self.label_prob表示每种类别在数据中出现的概率
self.condition_prob表示每种类别确定的条件下各个特征出现的概率
fit对模型进行训练,需要将各种概率分别保存在self.label_prob和self.condition_prob中
feature:训练集数据,类型为ndarray;
label:训练集标签,类型为ndarray;
return:无返回。
5.
news_predict训练模型并进行预测,返回预测结果
train_sample:原始训练样本,类型为ndarray;
train_label:训练标签,类型为ndarray;
test_sample:原始测试样本,类型为ndarray。
五、实验代码
3.

import numpy as np

class NaiveBayesClassifier(object):
    def __init__(self):
        self.label_prob = {}
        self.condition_prob = {}
    def fit(self, feature, label):
        row_num=len(feature)
        col_num=len(feature[0])
        for c in label:
            if c in self.label_prob:
                self.label_prob[c]+=1
            else:
                self.label_prob[c]=1
        for key in self.label_prob.keys():
            self.label_prob[key]/=row_num
            self.condition_prob[key]={}
            for i in range(col_num):
                self.condition_prob[key][i]={}
                for k in np.unique(feature[:,i],axis=0):
                    self.condition_prob[key][i][k]=0
        for i in range(len(feature)):
            for j in range(len(feature[i])):
                if feature[i][j]in self.condition_prob[label[i]]:
                    self.condition_prob[label[i]][j][feature[i][j]]+=1
                else:
                    self.condition_prob[label[i]][j][feature[i][j]]=1
        for label_key in self.condition_prob.keys():
            for k in self.condition_prob[label_key].keys():
                total=0
                for v in self.condition_prob[label_key][k].values():
                    total+=v
                for kk in self.condition_prob[label_key][k].keys():
                    self.condition_prob[label_key][k][kk]/=total
    def predict(self, feature):
        result=[]
        for i,f in enumerate(feature):
            prob=np.zeros(len(self.label_prob.keys()))
            ii=0
            for label,label_prob in self.label_prob.items():
                prob[ii]=label_prob
                for j in range(len(feature[0])):
                    prob[ii]*=self.condition_prob[label][j][f[j]]
                ii+=1
            result.append(list(self.label_prob.keys())[np.argmax(prob)])
        return np.array(result)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
import numpy as np


class NaiveBayesClassifier(object):
    def __init__(self):
        self.label_prob = {}
        self.condition_prob = {}
    def fit(self, feature, label):
        row_num=len(feature)
        col_num=len(feature[0])
        unique_label_count=len(set(label))
        for c in label:
            if c in self.label_prob:
                self.label_prob[c]+=1
            else:
                self.label_prob[c]=1
        for key in self.label_prob.keys():
            self.label_prob[key]+=1
            self.label_prob[key]/=(unique_label_count+row_num)
            self.condition_prob[key]={}
            for i in range(col_num):
                self.condition_prob[key][i]={}
                for k in np.unique(feature[:,i],axis=0):
                    self.condition_prob[key][i][k]=1
        for i in range(len(feature)):
            for j in range(len(feature[i])):
                if feature[i][j]in self.condition_prob[label[i]]:
                    self.condition_prob[label[i]][j][feature[i][j]]+=1
        for label_key in self.condition_prob.keys():
            for k in self.condition_prob[label_key].keys():
                total=len(self.condition_prob[label_key].keys())
                for v in self.condition_prob[label_key][k].values():
                    total+=v
                for kk in self.condition_prob[label_key][k].keys():
                    self.condition_prob[label_key][k][kk]/=total 
    def predict(self, feature):
        result = []
        for i, f in enumerate(feature):
            prob = np.zeros(len(self.label_prob.keys()))
            ii = 0
            for label, label_prob in self.label_prob.items():
                prob[ii] = label_prob
                for j in range(len(feature[0])):
                    prob[ii] *= self.condition_prob[label][j][f[j]]
                ii += 1
            result.append(list(self.label_prob.keys())[np.argmax(prob)])
        return np.array(result)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import TfidfTransformer


def news_predict(train_sample, train_label, test_sample):
    vec=CountVectorizer()
    train_sample=vec.fit_transform(train_sample)
    test_sample=vec.transform(test_sample)
    tfidf=TfidfTransformer()
    train_sample=tfidf.fit_transform(train_sample)
    test_sample=tfidf.transform(test_sample)
    mnb=MultinomialNB(alpha=0.01)
    mnb.fit(train_sample,train_label)
    predict=mnb.predict(test_sample)
    return predict
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

六、结果分析
均通过样例测试,说明正确。
七、思考题:
如何在参数学习或者其他方面提高算法的分类性能?
1.选择大的训练集进行测试。
2.考虑所有的错分样本,并且对于所有的错分样本建立一个全局目标函数,然后采用经典的优化理论来修正分类器。
3.将“概念”进行推广,不仅仅可以使用类中心来作为“概念”,也可以使用其他的代表比如贝叶斯的类概率和词概率。
4. 适当的修改学习率或者增加迭代次数来减少误差。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/354635
推荐阅读
相关标签
  

闽ICP备14008679号