基于朴素贝叶斯自动过滤垃圾广告

Python进阶学习交流
关注

交叉训练

交叉训练简单点说就是在同一份样本中选择部分作为测试样本,剩余的作为训练样本。这里一共有5574条数据,抽取1000条作为测试样本(testdata)

trainset = [i for i in range(len(txt_class))]

testset = []

testclass = []

for i in range(1000):

number = int(random.choice(trainset))

testset.append(words_vec(dataset[number], wordlist))

testclass.append(txt_class[number])

trainset.remove(number)

trainMat = [];

trainclass = []

for i in trainset:

trainMat.append(words_vec(dataset[i], wordlist))

trainclass.append(txt_class[i])

在这段代码中,trainset是训练样本的编号,testset是测试样本的数据集,testclass表示测试样本是否为垃圾广告,trainmat是训练样本数据集,trainclass表示训练样本是否为垃圾广告。

构造训练器

现在来计算P(y1|x),P(y2|x)

def train(trainmatrix,traincategory):

numword=len(trainmatrix[0])

numtrain=len(trainmatrix)

pa=sum(traincategory)/float(len(trainmatrix))

p0num,p1num=ones(numword),ones(numword)

p0dem,p1dem=2.0,2.0

for i in range(numtrain):

if traincategory[i]==1:

p1num+=trainmatrix[i]

p1dem+=sum(trainmatrix[i])

else:

p0num+=trainmatrix[i]
          p0dem+=sum(trainmatrix[i])

p1vect= log(p1num / p1dem)

p0vect = log(p0num / p0dem)

return p1vect,p0vect,pap0num,p1num表示在类别0和类别1下各个单词出现的总数;p1dem,p0dem表示类别0和类别1的单词总数;p0vect和p1vect代表P(xi|y0)以及P(xi|y1);这里进行Log变化避免下溢;同时进行了拉普拉斯平滑处理,即p0num,p1num的初始变量为ones()。p1dem,p0dem则为2(一共有两种结果,垃圾广告和有用广告,所以为2)

构造分类器

def classify(vec,p0vec,p1vec,pclass1):

p1=sum(vec*p1vec)+log(pclass1)

p0=sum(vec*p0vec)+log(1.0-pclass1)

if p1>p0:

return 1

else:

return 0

验证训练模型精确度

由于在进行交叉训练时测试样本是随机抽取的,所以训练准确度一直都不一样,为了让结果具有代表性,再构造一个循环,进行n次训练,取误差的平均值。

def mul(num):

totalerror = 0

for times in range(num):

#通过交叉训练获得训练样本和测试样本

p1vect, p0vect, pa = train(trainMat, trainclass)

error=0

for i in range(len(testset)):

if classify(array(testset[i]), p0vect, p1vect, pa) != testclass[i]:

error += 1

print('the accurate is', 1 - error / float(len(testset)))

totalerror+=error / float(len(testset))

print('after %d times the accurate of bayes is %f'%(num,1-float(totalerror)/num))

这个模型的准确度还是非常高的,平均精确度达到93.64%。

词袋模型

请大家思考一个问题,在垃圾广告中有没有一些词会频繁提到呢?如果频繁的出现这个词,是不是代表这则广告为垃圾广告的概率要增加?现在为止只是将某一个词语是否出现当作一个特征,这被称为词集模型。如果一个词出现次数不止一次,将它出现的次数作为一个特征就称为词袋模型。这两个模型的不同点在于词语出现与否和出现次数,将函数word_vec稍稍修改即可:

def words_vec(txt,wordlist):

returnvec=[0]*len(wordlist)

for word in txt:

if word in wordlist:

returnvec[list(wordlist).index(word)]=1+returnvec[list(wordlist).index(word)]

return returnvec

基于词袋模型的平均准确度高达93.63%;尽管比词集模型小了0.01%;但是其中一个准确率达到了95.5%;两个模型都是很不错的呢。

如果是中文的话使用jieba就可以分词噢。

声明: 本文由入驻OFweek维科号的作者撰写,观点仅代表作者本人,不代表OFweek立场。如有侵权或其他问题,请联系举报。
侵权投诉

下载OFweek,一手掌握高科技全行业资讯

还不是OFweek会员,马上注册
打开app,查看更多精彩资讯 >
  • 长按识别二维码
  • 进入OFweek阅读全文
长按图片进行保存