朴素贝叶斯——实现贴吧精品贴的预测

首先是爬取了我们学校贴吧的贴吧数据,每个帖子都有是否是精品贴的标签。

根据帖子标题信息,实现了贴吧精品贴和普通贴的分类。错误率在10%左右。

切词用的是jieba吧,没有过滤点停用词和标点符号,因为标点符号其实也是可以算是区分帖子是否是精品贴的而一个重要特征;其实还可以增加几个特征,比如第一页是否含有音频、视频、图片的数量等等,有些重要的特征维度甚至可以多覆盖几个维度。分类的效果可能会更好。但是目前光看标题正确率已经达到了90%,说明朴素贝叶斯还真不错。

训练算法部分用的是朴素贝叶斯方法。测试部分,还是用的留出法。

先是爬虫部分代码:

  1 __author__ = ‘Oscar_Yang‘
  2 # -*- coding= utf-8 -*-
  3 """
  4 本次目的
  5 1、抓取列表页,标题
  6 2、计算提拔关键词
  7 """
  8 # 导入相关模块。
  9 import re, requests, json, random, time, jieba,pymongo
 10 import urllib.request
 11 from bs4 import BeautifulSoup
 12 """连接mongodb"""
 13 client = pymongo.MongoClient("localhost",27017)
 14 db_tieba = client["db_tieba"]
 15 # sheet_tieba_ysu_good = db_tieba_ysu_good["sheet_tieba_ysu_good"]
 16 # sheet_tieba_dq = db_tieba_dq["sheet_tieba_dq_test"]
 17 # sheet_tieba_dbdx = db_tieba["sheet_tieba_dbdx"]
 18 sheet_tieba = db_tieba["sheet_tieba_ysu_914"]
 19
 20 """设置代理"""
 21 # resp = requests.get("http://tor1024.com/static/proxy_pool.txt")
 22 # ips_txt = resp.text.strip().split("\n")
 23 # # print(ips_txt)
 24 # ips = []
 25 # for i in ips_txt:
 26 #     try:
 27 #         k = json.loads(i)
 28 #         ips.append(k)
 29 #     except Exception as e:
 30 #         print(e)
 31
 32 header = {
 33     "User-Agent": ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36‘,
 34     "Cookie": ‘XXX‘
 35 }
 36
 37
 38 # 定义获取base_urls的函数
 39
 40 def get_base_urls():
 41     urls = ["http://tieba.baidu.com/f?kw=%E7%87%95%E5%B1%B1%E5%A4%A7%E5%AD%A6&ie=utf-8&pn={}".format(str(i)) for i in range(0, 383400, 50)]
 42     return urls
 43 def get_base_good_urls():
 44     urls=["http://tieba.baidu.com/f?kw=%E9%87%8C%E4%BB%81%E5%AD%A6%E9%99%A2&ie=utf-8&pn={}".format(str(i)) for i in range(0,10000,50)]
 45     return urls
 46 def get_last_reply_time(detail_url):
 47     web_data = requests.get(detail_url)
 48     web_data.encoding = "utf-8"
 49     soup = BeautifulSoup(web_data.text, "lxml")
 50     detail_page_num = soup.find_all(class_="red")[1].text
 51     detail_page_last_url=detail_url+"?pn={}".format(detail_page_num)
 52     web_data1 = requests.get(detail_page_last_url)
 53     web_data1.encoding = "utf-8"
 54     soup1 = BeautifulSoup(web_data1.text, "lxml")
 55     last_post_time_data_0 = soup1.find_all(class_="l_post j_l_post l_post_bright  ")
 56     last_post_time_data = last_post_time_data_0[len(last_post_time_data_0)-1].get("data-field")
 57     last_reply_post_time = last_post_time_data[int(last_post_time_data.find("date")) + 7:int(last_post_time_data.find("vote_crypt") - 3)]
 58     return last_post_time_data
 59
 60 def get_detail_data(detail_url):
 61     res = requests.get(detail_url)
 62     res.encoding = "utf-8"
 63     soup = BeautifulSoup(res.text,"lxml")
 64     post_time_data = soup.find_all(class_=‘l_post j_l_post l_post_bright noborder ‘)[0].get("data-field")
 65     author_dengji = soup.select("div.d_author > ul > li.l_badge > div > a > div.d_badge_lv")[0].text
 66     author_lable = soup.select("div.d_badge_title")[0].text
 67     reply_nus = soup.find_all(class_="red")[0].text
 68     title = soup.select("div.core_title.core_title_theme_bright > h1")[0].text
 69     author_name = soup.select("div.d_author > ul > li.d_name > a")[0].text
 70     authon_contents = soup.find_all(class_="d_post_content j_d_post_content  clearfix")
 71     jingyan_scores = post_time_data[int(post_time_data.find("cur_score"))+11:int(post_time_data.find("bawu"))-2]
 72     post_time = post_time_data[int(post_time_data.find("date")) + 7:int(post_time_data.find("vote_crypt")) - 3]
 73     phone_is = post_time_data[int(post_time_data.find("open_type")) + 12:int(post_time_data.find("date")) - 2]
 74     sex_is = post_time_data[int(post_time_data.find("user_sex")) + 10:int(post_time_data.find("user_sex")) + 11]
 75     pic_num_firstpage = soup.find_all(class_="BDE_Image")
 76     voice_num = soup.find_all(class_="voice_player_inner")
 77     video_num = soup.find_all(class_="BDE_Flash")
 78     detail_page_num = soup.find_all(class_="red")[1].text
 79     contents = []
 80     for i in range(len(authon_contents)):
 81         contents.append(authon_contents[i].text.strip())
 82     data={
 83         "nick_name":author_name,
 84         "post_time":post_time,
 85         "vehicle":phone_is,
 86         "level":author_dengji,
 87         "honored_name":author_lable,
 88         "reply_num":reply_nus,
 89         "title":title,
 90         "sex":sex_is,
 91         "jingyan_scores":jingyan_scores,
 92         "pic_num":len(pic_num_firstpage),
 93         "video_num":len(video_num),
 94         "voice_num":len(voice_num),
 95         "detail_page_num":detail_page_num,
 96         "contents":contents,
 97         "tiezi_url":detail_url
 98     }
 99     #print(data)
100     # sheet_tieba_ysu_good.insert_one(data)
101     # sheet_tieba_dbdx.insert_one(data)
102     # sheet_tieba_dq.insert_one(data)
103     sheet_tieba.insert_one(data)
104     #data1file(data)
105 def data1file(s):
106     path = r"C:\Users\Oscar\Desktop\数据.txt"
107     file = open(path, "a",encoding="utf-8")
108     file.write("\n")
109     file.write(str(s))
110     file.close()
111
112 def get_detail_urls(url):
113     detail_links = []
114     res = requests.get(url)
115     res.encoding = "utf-8"
116     soup = BeautifulSoup(res.text, ‘lxml‘)
117     link_tags = soup.select("#thread_list div.threadlist_title.pull_left.j_th_tit > a")
118     for link_tag in link_tags:
119         detail_links.append("http://tieba.baidu.com/" + link_tag.get("href"))
120     return detail_links
121     # print(detail_links)
122
123 # 获取列表页数据
124 def get_data(url):
125     web_data = requests.get(url)
126     web_data.encoding = "utf-8"
127     soup = BeautifulSoup(web_data.text, "lxml")
128     titles = soup.select(‘#thread_list div.threadlist_title.pull_left.j_th_tit > a‘)
129     reply_nums = soup.select("div > div.col2_left.j_threadlist_li_left > span")
130     zhurens = soup.select("div.threadlist_author.pull_right > span.tb_icon_author > span.frs-author-name-wrap > a")
131     link_tags = soup.select(‘#thread_list div.threadlist_title.pull_left.j_th_tit > a‘)
132     #time.sleep(random.randint(1, 2))
133     for title, reply_num, link_tag, zhuren in zip(titles, reply_nums, link_tags, zhurens):
134         data = {
135             "标题": title.get_text(),
136             "回复数": reply_num.text,
137             "主人": zhuren.get_text(),
138             "原文链接": "http://tieba.baidu.com/" + link_tag.get("href")
139
140         }
141         print(data)
142
143 def get_counts():
144     f = open(r‘C:\Users\Oscar\Desktop\1.txt‘, ‘r‘, encoding=‘utf-8‘)
145     sentence = f.read()
146     #words = jieba.cut(sentence, cut_all=True)
147     #words = jieba.cut(sentence, cut_all=False)
148     words = jieba.cut_for_search(sentence)
149     tf = {}
150     for word in words:
151         print(word)
152         word = ‘‘.join(word.split())
153         if word in tf:
154             tf[word] += 1
155         else:
156             tf[word] = 1
157     return tf
158
159 def top_counts_sorted(tf, n=50):
160     value_key_pairs = sorted([(count, tz) for tz, count in tf.items()], reverse=True)
161     print(value_key_pairs[:n])
162
163 # top_counts_sorted(get_counts())
164 if __name__ == ‘__main__‘:
165     count=0
166
167     for base_url in get_base_urls():
168         count = count + 1
169         detail_urls = get_detail_urls(base_url)
170         for detail_url in detail_urls:
171             try:
172                 get_detail_data(detail_url)
173             except Exception as e:
174                 print(e)
175                 # pass
176         #time.sleep(random.randint(1,3))
177         print("完成了第{}页的抓取".format(count))

爬取后的数据存入到mongodb了,我最终导出到txt了。精品贴的标题和普通的贴的标题分别放在两个txt了,如下图所示(0.txt,1.txt)

下面是 朴素贝叶斯的部分,没有包在类中,几个函数就行了,包括文件处理函数,创建单词表函数,训练函数,分类函数,主函数。

  1 def text_split(textlist):
  2     import re
  3     word_cut = jieba.cut(textlist, cut_all=False)  # 精确模式,返回的结构是一个可迭代的genertor
  4     word_list = list(word_cut)  # genertor转化为list,每个词unicode格式
  5     return word_list
  6
  7
  8 # 创建单词表
  9 def createVocabList(dataSet):
 10     vocabSet = set([])  # 创建一个空的集合
 11     for document in dataSet:
 12         vocabSet = vocabSet | set(document)  # union of the two sets
 13     return list(vocabSet)
 14
 15
 16 def trainNB0(trainMatrix, trainCategory):
 17     numTrainDocs = len(trainMatrix)  # 训练矩阵的行数
 18     numWords = len(trainMatrix[0])  # 字母表的维度,即训练矩阵的列数
 19     pAbusive = sum(trainCategory) / float(numTrainDocs)  # 先验信息
 20     p0Num = ones(numWords);
 21     p1Num = ones(numWords)  # 改为 ones()
 22     p0Denom = 2.0;
 23     p1Denom = 2.0  # 改成 2.0
 24     for i in range(numTrainDocs):
 25         if trainCategory[i] == 1:
 26             p1Num += trainMatrix[i]
 27             p1Denom += sum(trainMatrix[i])
 28         else:
 29             p0Num += trainMatrix[i]
 30             p0Denom += sum(trainMatrix[i])
 31     p1Vect = log(p1Num / p1Denom)  # 改为 log()
 32     p0Vect = log(p0Num / p0Denom)  # 改为 log()
 33     return p0Vect, p1Vect, pAbusive
 34     # 返回先验信息PAbusive,返回确定分类的条件下的每个单词出现的概率(此时概率为频率)
 35
 36
 37 def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
 38     p1 = sum(vec2Classify * p1Vec) + log(pClass1)  # 此时p1vec为对原始数组分别取对数之后的矩阵了,利用log(a*b)=sum(log(a)+log(b))再sum求和
 39     # pClass1为先验概率,此时p1就是最终的概率值。同理p0,根据后验概率最大准则,判别
 40     p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)
 41     if p1 > p0:
 42         return 1
 43     else:
 44         return 0
 45
 46
 47 # 定义词袋模型,词出现几次算几次
 48 def bagOfWords2VecMN(vocabList, inputSet):
 49     returnVec = [0] * len(vocabList)  # 初始化矩阵
 50     for word in inputSet:
 51         if word in vocabList:
 52             returnVec[vocabList.index(word)] += 1
 53     return returnVec
 54
 55
 56 def spamTest():
 57     """"
 58     文本矩阵化,构建文本矩阵和分类矩阵;
 59     注意:由于有个文本的编码解码有问题,我给直接过滤掉了,所以最后矩阵有49行而不是50行
 60     """
 61     docList = [];classList = [];fullText = []
 62     path=r"C:\Users\Oscar\Desktop\data\1.txt"
 63     with open(path,encoding="utf8") as f:
 64         i=0
 65         while i<1046:
 66             a=f.readline()
 67             word_list=text_split(a)
 68             docList.append(word_list)
 69             classList.append(1)
 70             fullText.extend(docList)
 71             i=i+1
 72     path=r"C:\Users\Oscar\Desktop\data\0.txt"
 73     with open(path,encoding="utf8") as f:
 74         i=0
 75         while i<1546:
 76             a=f.readline()
 77             word_list=text_split(a)
 78             docList.append(word_list)
 79             classList.append(0)
 80             fullText.extend(docList)
 81             i=i+1
 82     vocabList = createVocabList(docList)  # 创建词汇表
 83
 84     trainingSet = list(range(2500))
 85     testSet = []  # 随机的构建测试集和训练集,留存交叉验证的方法
 86     for i in range(10):  # 测试集大小为10,训练集大小为49-10=39
 87         randIndex = int(random.uniform(0, len(trainingSet)))
 88         testSet.append(trainingSet[randIndex])
 89         trainingSet.pop(randIndex)
 90
 91     trainMat = []
 92     trainClasses = []
 93     for docIndex in trainingSet:
 94         trainMat.append(bagOfWords2VecMN(vocabList, docList[docIndex]))
 95         trainClasses.append(classList[docIndex])
 96     p0V, p1V, pSpam = trainNB0(array(trainMat), array(trainClasses))
 97
 98     errorCount = 0
 99     for docIndex in testSet:  # classify the remaining items
100         wordVector = bagOfWords2VecMN(vocabList, docList[docIndex])
101         if classifyNB(array(wordVector), p0V, p1V, pSpam) != classList[docIndex]:
102             errorCount += 1
103             print("分类错误的帖子是", docList[docIndex],"正确的类应该是",classList[docIndex])
104     print(‘错误率为: ‘, float(errorCount) / len(testSet))
105     # return vocabList,fullText
106
107
108 if __name__ == ‘__main__‘:
109     spamTest()

时间: 2024-10-12 19:01:54

朴素贝叶斯——实现贴吧精品贴的预测的相关文章

4.朴素贝叶斯法

朴素贝叶斯(naive Bayes) 法是基于贝叶斯定理与特征条件独立假设的分类方法.对于给定的训练数据集, 首先基于特征条件独立假设学习输入/输出的联合概率分布: 然后基于此模型, 对给定的输入x, 利用贝叶斯定理求出后验概率最大的输出y. 朴素贝叶斯法实现简单, 学习与预测的效率都很高, 是一种常用的方法. 1. 朴素贝叶斯法的学习与分类基本方法训练数据集: 由X和Y的联合概率分布P(X,Y)独立同分布产生朴素贝叶斯通过训练数据集学习联合概率分布P(X,Y) ,      即先验概率分布:

机器学习实战教程(五):朴素贝叶斯实战篇之新浪新闻分类

原文链接: Jack-Cui,https://cuijiahua.com/blog/2017/11/ml_5_bayes_2.html 一.前言 上篇文章机器学习实战教程(四):朴素贝叶斯基础篇之言论过滤器讲解了朴素贝叶斯的基础知识.本篇文章将在此基础上进行扩展,你将看到以下内容: 拉普拉斯平滑 垃圾邮件过滤(Python3) 新浪新闻分类(sklearn) 二.朴素贝叶斯改进之拉普拉斯平滑 上篇文章提到过,算法存在一定的问题,需要进行改进.那么需要改进的地方在哪里呢?利用贝叶斯分类器对文档进行

机器学习实战教程(四):朴素贝叶斯基础篇之言论过滤器

原文链接: Jack-Cui,https://cuijiahua.com/blog/2017/11/ml_4_bayes_1.html 一.前言 朴素贝叶斯算法是有监督的学习算法,解决的是分类问题,如客户是否流失.是否值得投资.信用等级评定等多分类问题.该算法的优点在于简单易懂.学习效率高.在某些领域的分类问题中能够与决策树.神经网络相媲美.但由于该算法以自变量之间的独立(条件特征独立)性和连续变量的正态性假设为前提,就会导致算法精度在某种程度上受影响. 本篇文章将从朴素贝叶斯推断原理开始讲起,

《机器学习实战》笔记——朴素贝叶斯

运用贝叶斯公式(朴素贝叶斯假设每个特征每个特征都是独立的)可以解决的问题有,已知某些特征,用来判断某情况发生的可能性大小,设置可能性最大的情况作为预测值. 是一种监督算法. 广泛应用于垃圾邮件检测等等. 1 # _*_coding:utf-8_*_ 2 from numpy import * 3 4 # 4-1 词表到向量的转换函数(实验样本) 5 def loadDataSet(): 6 postingList = [['my', 'dog', 'has', 'flea', 'problems

关于朴素贝叶斯

朴素贝叶斯或者说基于贝叶斯理论的决策方法都是生成式模型.那么什么是生成式模型呢?生成式模型和判别式模型的概念分别是什么?大体来说,给定数据集x,可以直接通过建模P(c|x)来预测c,这样得到的是判别式模型.像BP网络,支持向量机,决策树都属于判别式模型.如果先对联合概率分布P(x,c)建模,然后再由此获得P(c|x),这样得到的生成式模型,例如朴素贝叶斯. 朴素贝叶斯应用的先决条件是"属性条件独立假设",即已知类别,假设所有属性相互独立.

我理解的朴素贝叶斯模型

我理解的朴素贝叶斯模型 我想说:"任何事件都是条件概率."为什么呢?因为我认为,任何事件的发生都不是完全偶然的,它都会以其他事件的发生为基础.换句话说,条件概率就是在其他事件发生的基础上,某事件发生的概率. 条件概率是朴素贝叶斯模型的基础. 假设,你的xx公司正在面临着用户流失的压力.虽然,你能计算用户整体流失的概率(流失用户数/用户总数).但这个数字并没有多大意义,因为资源是有限的,利用这个数字你只能撒胡椒面似的把钱撒在所有用户上,显然不经济.你非常想根据用户的某种行为,精确地估计一

NLP系列(4)_朴素贝叶斯实战与进阶(转)

http://blog.csdn.net/han_xiaoyang/article/details/50629608 作者: 寒小阳 && 龙心尘 时间:2016年2月. 出处:http://blog.csdn.net/han_xiaoyang/article/details/50629608 http://blog.csdn.net/longxinchen_ml/article/details/50629613 声明:版权所有,转载请联系作者并注明出处 1.引言 前两篇博文介绍了朴素贝叶

朴素贝叶斯

一.随机变量 可以取不同的值,不同的值有不同的概率. 看到随机变量取任何值,都要想到背后有个概率,如果是连续变量,在每一点的概率是0,连续型随机变量通常只考虑概率密度. 机器学习就是通过一堆随机变量预测另一个随机变量,先假设随机变量之间的概率分布,然后从数据中估计分布的参数. 任何概率模型的假设都是简化,不能完全刻画数据,并且每个模型都有其适用范围,比如朴素贝叶斯对于文本分类效果好. 二.贝叶斯定理 贝叶斯定理给出了从一种条件概率P(B|A)怎么推到另一种条件概率P(A|B): 这个东西有什么用

机器学习实战读书笔记(四)基于概率论的分类方法:朴素贝叶斯

4.1 基于贝叶斯决策理论的分类方法 朴素贝叶斯 优点:在数据较少的情况下仍然有效,可以处理多类别问题 缺点:对于输入数据的准备方式较为敏感 适用数据类型:标称型数据 贝叶斯决策理论的核心思想:选择具有最高概率的决策. 4.2 条件概率 4.3 使用条件概率来分类 4.4 使用朴素贝叶斯进行文档分类 朴素贝叶斯的一般过程: 1.收集数据 2.准备数据 3.分析数据 4.训练算法 5.测试算法 6.使用算法 朴素贝叶斯分类器中的另一个假设是,每个特征同等重要. 4.5 使用Python进行文本分类