电子科技大学 计算机学院 综合课程设计 报告.docx
- 文档编号:9625620
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:15
- 大小:169.79KB
电子科技大学 计算机学院 综合课程设计 报告.docx
《电子科技大学 计算机学院 综合课程设计 报告.docx》由会员分享,可在线阅读,更多相关《电子科技大学 计算机学院 综合课程设计 报告.docx(15页珍藏版)》请在冰豆网上搜索。
电子科技大学计算机学院综合课程设计报告
摘要
本系统以一个大规模网络爬虫程序所获取的网络评论数据为基础,使用了词向量,用户画像等技术,构建了一个基于影评的推荐系统。
主要的工作分为两部分,首先是研究分析了豆瓣电影网站是如何防御网络爬虫程序已经应对策略,其次根据网络爬虫程序获取的大量数据构建了一个推荐系统。
关键词:
大规模爬虫,用户画像,推荐系统
第一章绪论
1.1背景与意义
随着中国移动互联网的迅速发展,网民数量也在大规模增长,用户在社交与电商网站上的活跃程度日趋增加。
随着用户群体的增加,用户在网络上留下的行为数据呈现指数级增长。
面对庞大的用户群体以及如此大量的行为数据,如何从中快速、准确、有效的获取到有价值的数据,分析出用户的行为习惯以及偏好,在大规模内容的场景下,为用户提供精准的推荐服务,是现在大数据研究领域的一个热点和重点。
网络爬虫是大规模数据获取的必要程序。
由于网络上数据的高潜在商业价值,商业公司均会对其进行保密,即使能够直接获取的数据也会给出层层限制。
在互联网发展的二十余年里,网络爬虫程序设计和网站反爬虫程序设计共同进步发展。
如何有效的进行大规模网络数据爬取,同样是在工程领域的一个热点和重点。
1.2本系统的总体设计构思
首先通过设计一个高性能网络爬虫,对部分数据进行爬取。
在数据集上进行清洗,选择一些高质量的活跃用户,设计算法,提取特征,进行回测,调整特征的选择。
之后再在大规模数据集上进行运算。
1.3本系统的主要贡献与创新
本论文以大规模爬虫获取实时豆瓣电影数据为基础,实现了用户画像系统与推荐系统,根据历史数据得到的用户群体行为分析报告,并根据用户行为以及评论数据实现了智能化的电影推荐。
第二章大规模数据获取
在大规模互联网社群站点中,由于网站运营策略以及一些涉及到潜在商业价值的考虑,运营公司通常会设置一些特殊的访问流量识别措施阻止外界使用程序大规模获取数据。
对于网络爬虫程序设计者来说,必须要识别并且进行一定的特殊设计,才能高效的大规模并行获取数据。
2.1网络爬虫程序的原理
网络爬虫程序,也叫网络蜘蛛,在工程界通用简称“爬虫”,是一种可以自动实现模拟真实用户对网络资源访问并进行数据记录的程序。
爬虫程序一般会选择记录目标站点的索引数据,以及所关注的主要内容的完整记录。
2.2网络爬虫程序的设计方案
网络爬虫的形式多种多样,从早期的C、C++设计,到现在主流的Python、Java设计都有其辉煌的历史。
早期网络站点大部分内容、形式单一,静态网页居多,网络中富文本内容较少,计算机资源较少。
使用C、C++编写的程序占用资源小,运行速度快,进行网络通讯的方式灵活,加之语言本身使用广泛,受到大量爬虫程序员的青睐。
随着全球互联网产业、互联网基础设施的高速发展,谷歌、XX等搜索引擎的崛起,互联网上的资源爆炸性增长,基于各种目的,越来越多的程序员开始设计自己的网络爬虫程序。
此时C、C++语言的一些缺点显现出来,集中在编码的不通用,设计繁琐,缺乏高度抽象的类库等。
加之大规模数据存储平台的出现,C、C++爬虫程序日渐减少。
爬虫程序主要的任务在于:
访问网络资源,解析返回结果,对资源进行合理存储。
由于高度抽象以及简洁的语法,Python以及Java等一下代的更加工程化的语言被大家所青睐。
网络爬虫的开发极具灵活性,由于现代前端技术的成熟,爬虫程序所获取的内容可能随时变化,无法使用传统的软件工程方法进行设计开发,通常的做法是迭代式的对网络站点进行交替的探测、开发。
网络爬虫的主要模块功能比较固定,遇到的异常情况繁杂,需要有完善的异常处理机制。
在对大规模数据设计的爬虫中尤其重要。
Python在网络爬虫类程序的开发效率上有着无可比拟的先天优势,在文本分析、异常处理方面同样有着大量的简洁的设计,使得开发网络爬虫程序的方便程度与灵活程度大大提升。
加之有许多专门为Python语言设计的网络访问库,数据库访问框架,浏览器模拟器,文本解析器的存在,使得这门语言有着一个完备的网络爬虫程序开发生态环境。
本文选择使用Python3语言实现一个网络爬虫程序,对豆瓣电影网上Top250电影榜单上共计一千四百余万条用户对电源的短评进行完全的爬取。
在爬取数据的过程中,使用结构化序列化的方式进行数据的存储。
2.3豆瓣电影网站爬虫可行性分析
2.3.1豆瓣电影网站页面分析
编写网络爬虫程序,首先要对目标站点进行页面分析。
第一个参考页面:
豆瓣Top250电影榜单
第二个参考页面:
豆瓣任意电影页面
第三个参考页面:
豆瓣任意电影短评页面
使用Chrome浏览器的开发者模式观察页面。
所有关键信息都以静态方式给出,不需要模拟用户鼠标键盘行为与用户观察延时行为。
我们可以直接解析,通过发出Get请求得到的返回页面。
榜单页面可解析信息如下:
总数,排行榜名称,排行榜排名,电影中文名,电影英文名,电影id,电影导演,电影主演,电影封面
电影详情页面可解析信息如下:
电影id,电影中文名,电影别名,电影豆瓣评分,看过人数,想看人数,评分人数,5张海报图,条目分类,导演,主演,编剧,官方网站,豆瓣小站,上映时间日期,年代,语言,电影时长,影片类型,制片国家和地区,简介,长评数量,短评数量。
电影短评页面可解析信息如下:
短评数量,每条短评。
对于每条短评:
短评id,发布日期,上传用户,短评内容,短评评分,有用数。
通过轮询请求以上页面,我们可以获得几乎所有豆瓣电影公开的数据。
2.3.2豆瓣电影网站反爬虫策略分析
豆瓣电影作为国内电影领域最大的在线交流平台,拥有着大量的电影数据以及观众用户数据,一直被广大程序员以及数据分析人员作为目标数据站点使用网络爬虫获取数据。
该网站的反爬虫策略已经比较完善,例如对单个IP地址并发访问量的限制,单个IP时间段内访问次数限制,用户浏览器Cookie检测,用户访问页面连续性检测,等等。
经过长时间访问的实验,以及编写网络爬虫程序的经验,总结出了如下规律:
1.当发起Get请求是不带上Cookie,连续访问次数稍多,豆瓣网站将直接对操作的IP进行封禁。
此时无论如何操作都将返回HTTP403的结果。
需要等待半小时至一小时IP才会解除封禁。
2.使用Cookie进行访问。
第一次发起Get请求任意一个豆瓣页面,豆瓣都会返回一个名为bid的Cookie。
之后带上这个Cookie请求页面,可以在约2秒一次访问频率上,5分钟不封禁的结果。
但此时的封禁是对于该Cookie的,只要清空该Cookie,又可获得一个新的Cookie进行访问。
IP地址是不会被封禁的。
3.若保持低频率访问豆瓣页面,比如在10秒一次的基础上,不论如何都不会被封禁。
2.3.3豆瓣电影网站爬虫策略的设计
1.首先进行多次次无Cookie的请求,获取多个bid,对这多个bid进行保存,并且进行访问次数的统计。
2.对于每次的Get请求,随机在bid池中获取一个bid随请求发出,并根据返回结果更新次数统计。
若该请求返回HTTP403或者bid使用次数到达100次,即将该次访问操作回滚,将该bid抛弃
3.在池中bid数量小于一个阈值时,进行一轮无Cookie请求,更新bid池
在之后的访问试验中,对bid进行测试时,发现豆瓣电影并没有对某个bid的第一次使用进行合法性判断。
于是修改访问策略为:
每次访问前对bid进行随机,并随请求发出,若失败则直接重新随机bid到成功为止。
2.4网络爬虫性能优化
经过第一轮对电影榜单数据的统计,得到短评总数有一千四百万条。
传统单线程爬取完全无法获取所有的短评信息。
针对网络爬虫这种IO密集型的应用场景,多线程、多进程能够很好的解决并发访问的问题。
使用Python3中的multiprossesing库对访问进行多线程加速。
同时使用time库对访问频率进行控制。
由于单次请求返回时间的不确定性(页面大小,网络情况),我们统计一段时间内Get次数,若超过阈值则在每个请求完成之后进行一个sleep操作以降低总体速度。
针对单IP访问数量的限制,建立了一个IP代理池,部署在一台阿里云服务器上,全天候自动在各大代理网站上刺探可用的HTTP/HTTPS代理服务器。
网络爬虫程序可直接调用接口获取一个代理IP。
若某个IP连续请求失败次数超过阈值,可以立即更换代理IP,以躲过豆瓣晚上对爬虫的限制。
针对爬虫需要全天候运行的特点,使用Git作为源代码管理工具,分别管理开发分支与稳定版本分支,将稳定版分支实时同步到一台阿里云服务器上,并合理设计数据序列化保存格式,实现全天候运行的能力。
2.5本章小结
本章内容从工程的第一个需求出发,逐步迭代开发了一个具有针对目标站点完备功能和高运行效率的网络爬虫程序。
在连续运行4天后爬取了豆瓣电影Top250榜单中所有电影共计一千四百余万条影评信息,并构建初步的影评数据库。
第三章影评分析推荐系统
3.1推荐系统综述
互联网的出现和普及给用户带来了大量的信息,满足了用户在信息时代对信息的需求,但随着网络的迅速发展而带来的网上信息量的大幅增长,使得用户在面对大量信息时无法从中获得对自己真正有用的那部分信息,对信息的使用效率反而降低了,这就是所谓的信息超载(informationoverload)问题。
信息超载问题一个非常有潜力的办法是个性化推荐系统,它是根据用户的信息需求、兴趣等,将用户感兴趣的信息、产品等推荐给用户的个性化信息推荐系统。
和搜索引擎相比推荐系统通过研究用户的兴趣偏好,进行个性化计算,由系统发现用户的兴趣点,从而引导用户发现自己的信息需求。
一个好的推荐系统不仅能为用户提供个性化的服务,还能和用户之间建立密切关系,让用户对推荐产生依赖。
3.1.1推荐系统的概念和定义
推荐系统的定义有不少,但被广泛接受的推荐系统的概念和定义Resnick和Varian在1997年给出的:
“它是利用电子商务网站向客户提供商品信息和建议,帮助用户决定应该购买什么产品,模拟销售人员帮助客户完成购买过程”。
推荐系统有3个重要的模块:
用户建模模块、推荐对象建模模块、推荐算法模块。
通用的推荐系统模型流程如图所示。
推荐系统把用户模型中兴趣需求信息和推荐对象模型中的特征信息匹配,同时使用相应的推荐算法进行计算筛选,找到用户可能感兴趣的推荐对象,然后推荐给用户。
3.1.2推荐系统的形式化定义
推荐系统的形式化定义如下:
设C是所有用户的集合,S是所有可以推荐给用户的对象的集合。
实际上,C和S集合的规模通常很大,如上百万的顾客以及上亿种歌曲等。
设效用函数
可以计算对象s对用户c的推荐度(如提供商的可靠性(vendorreliability)和产品的可得性(productavailability)等),即
,R是一定范围内的全序的非负实数,推荐要研究的问题就是找到推荐度R最大的那些对象S*,如式:
从上述模型看来,推荐系统的构建有三个主要步骤:
对用户(服务)对象建模(即用户画像),对推荐对象建模,在(离)线推荐算法。
3.2推荐系统用户模型设计
在所有通过网络爬虫程序获取的数据当中,可以作为用户画像的有两个方向的数据:
1.每个用户对电影的评分
2.每个用户对电影的文字短评
根据以上信息,我们可以以上数据构成多维度模型对用户的喜好进行刻画。
下文将介绍文本分析以及
3.2.1文本分析简介
在自然语言处理领域,传统的词汇语义相似度方法主要是依靠本体词典或知识库的规则方法,利用统计语言模型在大规模语料库上进行分析处理.但是由于词典和知识库大多依赖人工构建,其实时性和扩展性都比较差,因此在互联网文本和专业领域文本处理中很难发挥出作用,在传统研究方法中,词汇通常用one-hot编码形式表示,即假设词表大小为V,第k个词表示为一个维数为V的向量,除了第k维为1,其他维均为0.一方面,这种表示方法无法刻画两个词语义上相似性,如“电脑”和“计算机”两个词汇,虽然它们在语义有着相似性,但是由于它们在词表中的位置不同,one-hot表示是正交的。
另一方面,这种方法容易造成数据稀疏问题。
不同的词作为完全不同的特征应用于统计模型中时,由于不常见的词出现的次数在训练数据中比较少,从而导致对应特征的估计存在偏差。
为了解决这个问题,Collober等人提出利用神经网络语言模型自动学习词汇向量化表示。
其基本思想是:
一个词的含义是由它的上下文决定的。
将词表中的每一个词随机初始化为一个高维向量,用大量语料进行训练,保证相似的词有相近的向量表示,称之为词向量(wordembedding),虽然词向量也是一个高维向量,但与one-hot向量表示不同,可以通过计算词向量的余弦相似度衡量词汇语义上的相似度。
基于这种思路,Mikolov等人提出了两种词向量计算模型,一种是从周围词预测中心词的连续词袋模型(CBOW)。
另一种是通过中心词预测周围词的Skip-gram模型,并开发出结合这两种词向量计算模型的开源工具包word2vec。
3.2.2文本分析操作
使用word2vec工具包,通过使用网络上大量语料库进行训练,我们可以获得一个泛化能力极强的中文词向量模型。
这里使用了维基百科以及搜狗实验室公开的语料库进行了训练。
过程中使用了Jieba分词工具,并对数据进行清洗,获得接近2亿词汇量的已分词数据。
在一台双路E5-2683v3服务器上,使用三十分钟训练出一个合理的词向量模型,并进行保存。
对每一条评论,同样使用Jieba分词,并对文本进行清洗,去除不合法字符,并对每个词汇转化为对应的向量进行求和,最后根据向量数量取平均值,获得一个“句子向量”,代表某个用户的“语言习惯”。
至此,对每个用户,在文本分析方面,获得了一个400维度的向量。
3.3推荐系统推荐对象模型设计
3.3.1评分机制建模
对于每部影片,网络爬虫程序可以直接获得站点所有历史用户对该电影的总平均评分,以及所有评分的百分比分布情况。
根据用户短评上所附带的评分(星星数量)减去这一电影的平均打分,即可得出对应这部电影的特征量。
这样我们获得了一个直接且独立的250维度向量。
注意,若用户未看过某一部电影,则对应位置设置0。
3.3.2影片分类特征建模
对于每部影片,网络爬虫程序可以直接获得该影片所属类型。
例如喜剧、爱情、恐怖、悬疑等等。
根据生活经验,用户对某一类型电影的喜好极有可能反映出该用户的整个喜好倾向。
影片的类型特征对于单一的对某一部影片的喜好来说,很可能更有代表性。
这样我们获得了一个直接且独立的36维度向量。
3.4推荐系统算法
3.4.1协同过滤算法
协同过滤,简单来说是利用某兴趣相投、拥有共同经验之群体的喜好来推荐用户感兴趣的信息,个人通过合作的机制给予信息相当程度的回应(如评分)并记录下来以达到过滤的目的进而帮助别人筛选信息,回应不一定局限于特别感兴趣的,特别不感兴趣信息的纪录也相当重要。
协同过滤又可分为评比或者群体过滤。
其后成为电子商务当中很重要的一环,即根据某顾客以往的购买行为以及从具有相似购买行为的顾客群的购买行为去推荐这个顾客其“可能喜欢的品项”,也就是借由社区的喜好提供个人化的信息、商品等的推荐服务。
3.4.2基于项目的协同过滤算法
传统的以用户为基础的协同推荐算法随着用户数量的增多,计算的时间就会变长,所以在2001年Sarwar提出了基于项目的协同过滤推荐算法(Item-basedCollaborativeFilteringAlgorithms)。
以项目为基础的协同过滤方法有一个基本的假设“能够引起用户兴趣的项目,必定与其之前评分高的项目相似”,通过计算项目之间的相似性来代替用户之间的相似性。
方法步骤:
先计算已评价项目和待预测项目的相似度,并以相似度作为权重,加权各已评价项目的分数,得到待预测项目的预测值。
例如:
要对项目A和项目B进行相似性计算,要先找出同时对A和B打过分的组合,对这些组合进行相似度计算,常用的算法同以用户为基础(User-based)的协同过滤。
以项目为基础的协同过滤不用考虑用户间的差别,所以精度比较差。
但是却不需要用户的历史数据,或是进行用户识别。
对于项目来讲,它们之间的相似性要稳定很多,因此可以离线完成工作量最大的相似性计算步骤,从而降低了在线计算量,提高推荐效率,尤其是在用户多于项目的情形下尤为显著。
3.5推荐系统推荐关键算法部分
3.5.1距离定义部分
在推荐系统中常见的四种距离:
欧式距离、曼哈顿距离、cos距离、pearson距离。
defeuclidean_dis(rating1,rating2):
"""计算2个打分序列间的欧式距离.输入的rating1和rating2都是打分dict
格式为{'电影id1':
1.0,'电影idn':
5.0}"""
distance=0
commonRatings=False
forkeyinrating1:
ifkeyinrating2:
distance+=(rating1[key]-rating2[key])^2
commonRatings=True
#两个打分序列之间有公共打分电影
ifcommonRatings:
returndistance
#无公共打分电影
else:
return-1
defmanhattan_dis(rating1,rating2):
distance=0
commonRatings=False
forkeyinrating1:
ifkeyinrating2:
distance+=abs(rating1[key]-rating2[key])
commonRatings=True
#两个打分序列之间有公共打分电影
ifcommonRatings:
returndistance
#无公共打分电影
else:
return-1
defcos_dis(rating1,rating2):
distance=0
dot_product_1=0
dot_product_2=0
commonRatings=False
forscoreinrating1.values():
dot_product_1+=score^2
forscoreinrating2.values():
dot_product_2+=score^2
forkeyinrating1:
ifkeyinrating2:
distance+=rating1[key]*rating2[key]
commonRatings=True
#两个打分序列之间有公共打分电影
ifcommonRatings:
return1-distance/sqrt(dot_product_1*dot_product_2)
#无公共打分电影
else:
return-1
defpearson_dis(rating1,rating2):
sum_xy=0
sum_x=0
sum_y=0
sum_x2=0
sum_y2=0
n=0
forkeyinrating1:
ifkeyinrating2:
n+=1
x=rating1[key]
y=rating2[key]
sum_xy+=x*y
sum_x+=x
sum_y+=y
sum_x2+=pow(x,2)
sum_y2+=pow(y,2)
#nowcomputedenominator
denominator=sqrt(sum_x2-pow(sum_x,2)/n)*sqrt(sum_y2-pow(sum_y,2)/n)
ifdenominator==0:
return0
else:
return(sum_xy-(sum_x*sum_y)/n)/denominator
3.5.2近邻查找部分
#查找最近邻
defcomputeNearestNeighbor(username,users):
"""在给定username的情况下,计算其他用户和它的距离并排序"""
distances=[]
foruserinusers:
ifuser!
=username:
#distance=manhattan_dis(users[user],users[username])
distance=pearson_dis(users[user],users[username])
distances.append((distance,user))
#根据距离排序,距离越近,排得越靠前
distances.sort()
returndistances
#推荐
defrecommend(username,users):
"""对指定的user推荐电影"""
#找到最近邻
nearest=computeNearestNeighbor(username,users)[0][1]
recommendations=[]
#找到最近邻看过,但是我们没看过的电影,计算推荐
neighborRatings=users[nearest]
userRatings=users[username]
forartistinneighborRatings:
ifnotartistinuserRatings:
recommendations.append((artist,neighborRatings[artist]))
results=sorted(recommendations,key=lambdaartistTuple:
artistTuple[1],reverse=True)
forresultinresults:
print(result[0],result[1])
3.5.3评分向量的构建
#构建电影评分标准向量
vec_std=[]
movie_pos={}
forindex,iteminenumerate(movie_data):
movie_pos[item['id']]=index
vec_std.append(item['rating']['average']/2)
logging.debug('%s的评分为%f',item['title'],item['rating']['average'])
vec_std=np.array(vec_std)
第四章课程设计总结与展望
4.1总结
本次课程设计以国内访问量排名第一的电影资讯评论站点“豆瓣电影”的用户数据为基础,构建了一个基于语义分析的协同过滤推荐系统。
该系统建立在使用高性能网络爬虫程序获得的热门电影的逾一千四百万真实用户影评之上,实现了一个多维度评价用户的推荐系统。
并可以分析生成一个统计结果。
4.2后续工作展望
在数据的获取存储方面,后续可进行数据库或分布式数据库的改进。
在评价机制方面,由于现有数据量少,电影数量少,推荐系统使用基于项目的协同过滤算法。
若爬虫继续运行获取全站大量数据,用户、电影数量快速增长,还可以进行一些在线的推荐
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 电子科技大学 计算机学院 综合课程设计 报告 计算机 学院 综合 课程设计