python爬取恶意数据集_机器学习实战0:评论爬虫+贝叶斯模型标注恶意评论+分布式形式...

一 引言

本程序是一个完整的机器学习过程,先编写基于python的爬虫脚本,爬取目标论坛网站的评论到本地存储,然后使用贝叶斯分类模型对评论进行分类,预测新 的评论是否为垃圾评论。如果遇到大数据量的问题,可以把贝叶斯算法写成mapreduce模式,map负责把数据集划分成键值对格式,类序号为key,属 性向量为value,reduce进行汇总每类的先验概率和条件概率,主server汇总所有类的统计量。

二 爬虫脚本

1 编写爬虫脚本,爬取目标论坛的评论。其中,headers是必须的,因为我们需要伪装成浏览器在访问论坛的服务器。使用requests包获取指定url的数据流。

mport requestsfrombs4 import BeautifulSoup

import re

import json

import time

headers={'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3','Accept-Encoding': 'gzip, deflate, br','Connection': 'keep-alive','Cookie': '__cfduid=d653bf931cbde10f9243b63e991f70dc41466778585; loid=a5WUnHRHlleKL9OSSR; loidcreated=2016-06-24T14%3A29%3A45.413Z; _recent_srs=t5_2qu49; _ga=GA1.2.54465388.1466778724; pc=ne; __utma=55650728.54465388.1466778724.1466778728.1466843492.2; __utmz=55650728.1466778728.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmb=55650728.0.10.1466843492; __utmc=55650728','Host': 'www.reddit.com','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0',

}url= 'https://www.reddit.com/r/AskReddit/comments/4qfh01/what_are_some_classes_you_must_take_in/'r= requests.get(url,headers=headers)

r.encoding= r.apparent_encoding

2 使用BeautifulSoup解析爬去的html文件,css定位我们需要的字段,输出到本地文件comments.txt保存即可。

soup =BeautifulSoup(r.text)

res= soup.select("div.md")

comments=[]for item1 in res[1:]:

comments.append(item1.contents)

print comments

fd= open('comments.txt','w+')

p_soup=BeautifulSoup(str(comments))

res2= p_soup.findAll('p')for item2 inres2:

ct= str(item2.contents).encode('utf-8')

print ct[3:-2]

fd.write(ct[3:-2] + '\n')

fd.close()

三 实战1 -文本分类(应用过滤恶意留言等)

下面是二分类问题,文档只能属于0和1两个类别,

1 载入数据集:本地读取文件comments.txt中爬虫爬取的评论。

from numpy import *

def loadDataSet():

fd = open('comments.txt')

postingList = []

classVec = []

for line in fd.readlines():

tmp = line.split()

postingList.append(tmp[1:])

classVec.append(int(tmp[0]))

return postingList,classVec

2 创建词汇表:利用集合结构内元素的唯一性,创建一个包含所有词汇的词表。

def createVocabList(dataSet):

vocabSet = set([])  #create empty set

for document in dataSet:

vocabSet = vocabSet | set(document) #union of the two sets

return list(vocabSet)

3 把输入文本根据词表转化为计算机可处理的01向量形式:

eq,测试文本1: ['love', 'my', 'dalmation']

词汇表:['cute', 'love', 'help', 'garbage', 'quit', 'I', 'problems', 'is', 'park', 'stop', 'flea', 'dalmation', 'licks', 'food', 'not', 'him', 'buying', 'posting', 'has', 'worthless', 'ate', 'to', 'maybe', 'please', 'dog', 'how', 'stupid', 'so', 'take', 'mr', 'steak', 'my']

向量化结果:[0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1]

def setOfWords2Vec(vocabList, inputSet):

returnVec = [0]*len(vocabList)

for word in inputSet:

if word in vocabList:

returnVec[vocabList.index(word)] = 1

else: print "the word: %s is not in my Vocabulary!" % word

return returnVec

4训练模型:在训练样本中计算先验概率 p(Ci) 和 条件概率 p(x,y | Ci),本实例有0和1两个类别,所以返回p(x,y | 0),p(x,y | 1)和p(Ci)。

此处有两个改进的地方:

(1)若有的类别没有出现,其概率就是0,会十分影响分类器的性能。所以采取各类别默认1次累加,总类别(两类)次数2,这样不影响相对大小。

(2)若很小是数字相乘,则结果会更小,再四舍五入存在误差,而且会造成下溢出。采取取log,乘法变为加法,并且相对大小趋势不变。

def trainNB0(trainMatrix,trainCategory):

numTrainDocs = len(trainMatrix)

numWords = len(trainMatrix[0])

pAbusive = sum(trainCategory)/float(numTrainDocs)

p0Num = ones(numWords); p1Num = ones(numWords)      #change to ones()

p0Denom = 2.0; p1Denom = 2.0                        #change to 2.0

for i in range(numTrainDocs):

if trainCategory[i] == 1:

p1Num += trainMatrix[i]

p1Denom += sum(trainMatrix[i])

else:

p0Num += trainMatrix[i]

p0Denom += sum(trainMatrix[i])

p1Vect = log(p1Num/p1Denom)          #change to log()

p0Vect = log(p0Num/p0Denom)          #change to log()

return p0Vect,p1Vect,pAbusive

5 分类:根据计算后,哪个类别的概率大,则属于哪个类别。

def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):p1 = sum(vec2Classify * p1Vec) + log(pClass1) #element-wise mult

p0 = sum(vec2Classify * p0Vec) + log(1.0 -pClass1)

if p1 >p0:

return 1

else:

return 0

6 测试函数:

加载数据集+提炼词表;

训练模型:根据六条训练集计算先验概率和条件概率;

测试模型:对训练两条测试文本进行分类。

def testingNB():

listOPosts,listClasses = loadDataSet()

myVocabList = createVocabList(listOPosts)

trainMat=[]

for postinDoc in listOPosts:

trainMat.append(setOfWords2Vec(myVocabList, postinDoc))

p0V,p1V,pAb = trainNB0(array(trainMat),array(listClasses))

testEntry = ['friends', 'my', 'take']

thisDoc = array(setOfWords2Vec(myVocabList, testEntry))

print testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb)

testEntry = ['stupid', 'garbage']

thisDoc = array(setOfWords2Vec(myVocabList, testEntry))

print testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb)

缺点:词表只能记录词汇是否出现,不能体现这个词汇出现的次数。改进方法:采用词袋模型,见下面垃圾邮件分类实战。

结果图:['friends', 'wish', 'classes'] 被分到 正常评论类;

['stupid', 'garbage'] 被分到垃圾评论类;分类结果正确。

四 算法的MapReduce形式

本人正在把这个贝叶斯分类算法转换成分布式算法,初步思想是,可以把贝叶斯算法写成mapreduce模式,map负责把数据集划分成键值对格式,类序号为key,属 性向量为value,reduce进行汇总每类的先验概率和条件概率,主server汇总所有类的统计量。

1 mapper程序

if __name__ == '__main__':for line insys.stdin:

line=line.strip()

word=line.split()

key= word[0]

value= ''

for item in word[1:]:

value+= item+ ' 'print"%s\t%s"%(key,value)

2 本次mapper测试结果,键值对成功分离:  执行命令$ cat data.txt | python bayes_mapper.py

1 0.270252528981 0.102916847315

0 0.772917922479 0.182969066019

1 0.817848764874 0.743666751784

0 0.197846533796 0.835258987261

1 0.174895157684 0.31219280438

1 0.16756664003 0.529593388634

1 0.56918073026 0.0624409762296

1 0.292857532814 0.152683257148

0 0.971077138206 0.712432682621

0 0.775544377315 0.163165909954

3 reducer程序,正在编写,下次更新

备注:数据集生成脚本

#!/usr/bin/python

import sys

import randomif __name__ == '__main__':if len(sys.argv) < 3:

row= 5col= 5

else:

row= int(sys.argv[1])

col= int(sys.argv[2])for r in range(0,row):

tmp= str(random.randint(0,1))for c in range(0,col):

num= random.uniform(0,1)

tmp+= ' ' +str(num)

print tmp

生成数据集如下:

1 0.270252528981 0.102916847315

0 0.772917922479 0.182969066019

1 0.817848764874 0.743666751784

0 0.197846533796 0.835258987261

1 0.174895157684 0.31219280438

1 0.16756664003 0.529593388634

1 0.56918073026 0.0624409762296

1 0.292857532814 0.152683257148

0 0.971077138206 0.712432682621

0 0.775544377315 0.163165909954

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.项目代码功能经验证ok,确保稳定可靠运行。欢迎下载使用!在使用过程中,如有问题或建议,请及时私信沟通,帮助解答。 2.主要针对各个计算机相关专业,包括计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师或企业员工使用。 3.项目具有丰富的拓展空间,不仅可作为入门进阶,也可直接作为毕设、课程设计、大作业、初期项目立项演示等用途。 基于机器学习贝叶斯算法实现垃圾邮件分类python源码+项目说明+数据集.zip Python3 - pandas - 用于保存自定义测试集下训练邮件内的单词 - pyecharts>=1.0.0 - 个人喜欢用pyecharts来做图,如果你希望使用其他作图工具,可以自动修改draw_result()函数,如果您不希望作图,可以手动注释掉bayesian.draw_result()这条语句,位于751行。注意的是,pyecharts最后保存出来的是html文件 - snapshot_selenium - 将pyecharts保存的html文件生成图片,您需要使用到chromedriver,请手动下载,如果不下载的话,您可以注释掉所有make_snapshot()语句,或者忽略终端报出来的错误 - skleran - 贝叶斯分类器是自己实现的,但SVM调用的是现成的库函数 - nltk - 用于去停用词和词性还原,需要下载一些包,您可以去官网下载,或者在百度云里下载:链接:https://pan.baidu.com/s/1_eU5sTe2bMWMJaqxA7IO8w 提取码:0pc9 ,您可以不用下载所有的包,只需要下载corpora中的stopwords和wordnet、stemmers中的porter_test和rslp、taggers中的averaged_perceptron_tagger。然后将这些文件放于C:\Users\xxxxx\AppData\Roaming\nltk_data即可) 参数解释: ``` --model:模型的选择,默认为5 - 单使用伯努利模型为1 - 单使用多项式模型为2 - 单使用SVM为3 - 三个模型同时测试,并且你已经将邮件的测试集和训练集准备好的,为4 - 三个模型同时测试,并且邮件的训练集和测试集为随机生成,为5 --train_path:训练集(或总文件)的路径,默认为'train' --test_path:测试集路径,默认为'test' --test_times:测试的次数,每次测试随机生成的测试集均不一样,默认为1 --test_file_num:每一类进行测试的邮件数目,默认为5 注意,train和test文件夹下,各自建立子文件夹spam和ham来分别存放垃圾邮件和正常邮件 ``` - 使用方法为: ``` python bayes.py --model 5 --test_times 70 ``` ```python python bayes.py --model 5 --train_path 'train' --test_times 70 --test_file_num 5 ``` ```python python bayes.py --model 5 --train_path 'train' --test_path 'test' --test_file_num 5 ``` - 结果: 如果你使用第一条命令来进行训练和测试,那么你将会得到三个模型测试后的正确率、错误邮件个数,以及三个模型对应的识别错误的邮件分布情况,如下所示: ![正确率](README.assets/正确率.png) ![错误邮件个数](README.assets/错误邮件个数.png) ![SVM-邮件错误识别](README.assets/SVM-邮件错误识别.png) ![伯努利模型-邮件错误识别](README.assets/伯努利模型-邮件错误识别.png) ![多项式模型-邮件错误识别](README.assets/多项式模型-邮件错误识别.png) 除此之外,在终端上,你可以看到用来作出这些图片的数据。
您的问题是关于Python识别虚假新闻的分类器,那么您可以使用机器学习算法中的朴素贝叶斯分类器MultinomialNB来预测新闻的类别。下面是一个简单的Python代码示例,演示如何使用MultinomialNB分类器来识别虚假新闻: 首先,您需要准备好数据集,其中包括已标记的真实新闻和虚假新闻。接下来,您需要将数据集分成训练集和测试集,以便评估分类器的性能。 ```python import pandas as pd from sklearn.feature_extraction.text import CountVectorizer from sklearn.naive_bayes import MultinomialNB from sklearn.model_selection import train_test_split # 读取数据集 df = pd.read_csv('news_dataset.csv') # 将文本数据转换为数字向量 vectorizer = CountVectorizer(stop_words='english') X = vectorizer.fit_transform(df['text']) # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, df['label'], test_size=0.2, random_state=42) # 建立朴素贝叶斯分类器 clf = MultinomialNB() # 训练模型 clf.fit(X_train, y_train) # 测试模型 accuracy = clf.score(X_test, y_test) print('Accuracy:', accuracy) ``` 在上面的代码中,我们首先使用CountVectorizer将文本数据转换为数字向量。然后,我们使用train_test_split函数将数据集分成训练集和测试集。接下来,我们建立一个MultinomialNB分类器,并使用fit函数训练模型。最后,我们使用score函数在测试集上评估模型的准确性。 需要注意的是,上述代码仅提供了一个简单的示例,您需要根据您的数据集和需求进行修改和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值