基于朴素贝叶斯自动过滤垃圾广告
交叉训练
交叉训练简单点说就是在同一份样本中选择部分作为测试样本,剩余的作为训练样本。这里一共有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就可以分词噢。
最新活动更多
-
11月28日立即报名>>> 2024工程师系列—工业电子技术在线会议
-
12月19日立即报名>> 【线下会议】OFweek 2024(第九届)物联网产业大会
-
即日-12.26火热报名中>> OFweek2024中国智造CIO在线峰会
-
即日-2025.8.1立即下载>> 《2024智能制造产业高端化、智能化、绿色化发展蓝皮书》
-
精彩回顾立即查看>> 2024 智能家居出海论坛
-
精彩回顾立即查看>> 【在线会议】多物理场仿真助跑新能源汽车
推荐专题
发表评论
请输入评论内容...
请输入评论/评论长度6~500个字
暂无评论
暂无评论