您好,欢迎访问三七文档
聚类分析理论前提经典机器学习算法k-means(k均值)k-means算法k-means聚类算法迭代寻找最能够代表数据的聚类质心点。算法开始时使用从训练数据中随机选取的几个数据点作为质心点。k-means中的k表示寻找多少个质心点,同时也是算法将会找到的簇的数量。例如,把k设置为3,数据集所有数据将会被分成3个簇。k-means算法分为两个步骤:•为每一个数据点分配簇标签,更新各簇的质心点。分簇这一步中,我们为数据集的每个个体设置一个标签,把它和最近的质心点联系起来。对于距离质心点1最近的个体,我们为它们分配标签1,距离质心点2最近的个体,分配标签2,以此类推。标签相同的个体属于同一个簇,所有带有标签1的数据点属于簇1(只是暂时的,数据点所属的簇会随着算法的运行发生变化)。•更新环节,计算各簇内所有数据点的均值,更新质心点。聚类属于无监督学习,我们使用聚类算法探索隐藏在数据里的奥秘。理论前提经典机器学习算法k-means(k均值)k-means算法对于k-means算法,寻找新质心点的标准是,最小化每个数据点到最近质心点的距离。这叫作算法的惯性权重(inertia),任何经过训练的KMeans实例都有该属性。k-means算法会重复上述两个步骤;每次更新质心点时,所有质心点将会小范围移动。这会轻微改变每个数据点在簇内的位置,从而引发下一次迭代时质心点的变动。这个过程会重复执行直到条件不再满足时为止。通常是在迭代一定次数后,或者当质心点的整体移动量很小时,就可以终止算法的运行。有时可以等算法自行终止运行,这表明簇已经相当稳定——数据点所属的簇不再变动,质心点也不再改变时。实验准备获取数据集本次数据来源:数据资源宝库reddit。已经提供数据集,有兴趣自行上网获得数据的可以看后面获取数据的PPT,没有可以忽略。【即如果不考虑自行获取数据,跳转到第10页PPT】相关Python库:•os•Lxml•Numpy•collections•pandas•Hashlib•Sklearn•matplotlib获取新闻文章本章将构建一个按照主题为最新的新闻报道分组的系统。你可以运行几周(或更长时间)以了解这段时间新闻趋势的变化。系统首先从流行的链接聚合网站reddit寻找新闻报道的链接。reddit存储了大量其他网站的链接,还提供讨论区。网站收集的链接按照类别进行分类,这些类别被统称为subreddit,比如有电视节目、趣味图片等类别。本章关注的是新闻这一类链接。本章使用/r/worldnews类别的链接,但是我们所编写的代码也可以用来抓取其他类别的语料。获取数据数据资源宝库reddit链接聚合网站reddit()拥有几亿用户,虽然英文版主要面向美国。每个用户都可以发布他们感兴趣的网站的链接,同时为该链接指定标题。其他用户对其点赞,表示他们喜欢这个链接的内容,也可以投反对票,表示不喜欢。点赞最高的链接将被移到网页的最上面,没有多少人喜欢的将不会显示。随着时间的推移,先前发表的链接也将不再显示(根据喜欢数来定)。分享的链接被点赞后,用户将会获得叫作karma的积分,这也是为了激励用户只分享好故事。使用我们前面获取到的令牌,就可以获取一个栏目的一系列链接。/r/subredditnameAPI端点默认返回所指定栏目的热门文章。我们会使用/r/chinasubreddit:接下来,需要设置头部,这样才能指定授权令牌,设置独一无二的用户代理,争取不会被过分限制请求次数。代码如下:调用response的json方法,将会得到包含reddit返回信息的一个Python字典。它包含给定栏目的25条广播,对它们进行遍历,输出每条广播的标题。广播的相关内容存储在字典键为data的那一项中。代码如下:我们数据集的每条广播都来自/r/worldnews栏目的热度列表。上节讲解了连接reddit网站和抽取广播内容的方法。我们来创建一个函数,把这两个步骤整合起来,抽取指定栏目每条广播的标题、链接和喜欢数。•subreddit=worldnews“•url={}.format(subreddit)•headers={Authorization:bearer{}.format(token['access_token']),User-Agent:USER_AGENT}•response=requests.get(url,headers=headers)•forstoryinresult['data']['children']:•print(story['data']['title'])获取数据我们遍历世界新闻栏目,最多一次获取100篇新闻报道。我们还可以使用分页,reddit最多允许我们读多少页,我们就读多少页。但是我们这里最多读5页。•fromtimeimportsleep•defget_links(subreddit,token,n_pages=5):•stories=[]•after=None•forpage_numberinrange(n_pages):•result={}•url={}limit=100.format(subreddit)•headers={Authorization:bearer{}.format(token['access_token']),User-Agent:USER_AGENT}•ifafter:•url+=&after={}.format(after)•response=requests.get(url,headers=headers)•result=response.json()•after=result['data']['after']•sleep(2)•stories.extend([(story['data']['title'],story['data']['url'],story['data']['score'])forstoryinresult['data']['children']])•returnstories获取数据获取数据我们首先需要访问每个链接,下载各个网页,将它们保存到Data文件夹中事先建好的用于存放原始网页的文件夹raw。后面,我们就要从这些原始网页中获取有用的信息。先把全部网页都保存下来,比起后面时不时地下载网页方便多了。首先,指定存放原始网页的目录。•importos•data_folder=os.path.join(os.path.expanduser(~),Data,•websites,raw)后面我们要用MD5散列算法为每篇报道创建一个唯一的文件名,所以先导入hashlib。•importhashlib如果所有网页都能成功下载,计数器输出值应该为0:•number_errors=0接下来,遍历每一篇新闻报道:•fortitle,url,scoreinstories:对报道的标题进行散列操作,作为输出文件名,以保证唯一性。因为reddit网站不要求文章标题具有唯一性,因此两篇报道可能使用相同的标题,这就会导致数据集中两条数据之间的冲突。我们使用MD5算法对报道的URL进行散列操作。现在人们发现MD5也不是绝对可靠的,但是就我们这么小的数据规模来说不太可能出问题(出现碰撞情况),即使出现这样的问题,也不用太担心。获取数据•output_filename=hashlib.md5(url.encode()).hexdigest()•fullpath=os.path.join(data_folder,output_filename+.txt)接下来下载网页,保存到输出文件夹中。•try:response=requests.get(url)data=response.textwithopen(fullpath,'w')asoutf:outf.write(data)•exceptExceptionase:number_errors+=1print(e)如果下载网页时出现问题,跳过问题网站,继续下载下一个网站的网页。上述代码能够完成我们收集到的95%的网站下载任务,对本章的应用来说足够了,因为我们寻找的是大体趋势而不是做精准研究。•exceptExceptionase:number_errors+=1print(e)如果错误很多,把上面print(e)那一行改为raise,调用异常中断机制,以便修改问题。现在,我们原始网页文件夹raw中有很多网页,查看这些网页(用文本编辑器打开),你会发现新闻报道的内容湮没在HTML、JavaScript、CSS以及其他内容之中。因为我们只对报道本身感兴趣,就需要一种从不同网站的网页中抽取内容的方法。获取数据获得原始网页后,我们需要找出每个网页中的新闻报道内容。有一些在线资源使用数据挖掘方法来解决这个问题。一般来说,很少需要用到这些复杂的算法,当然使用它们能得到更为精确的结果。这也是数据挖掘艺术的一部分——知道什么时候用,什么时候不用。首先,获取到raw文件夹中的所有文件名:•filenames=[os.path.join(data_folder,filename)forfilenameinos.listdir(data_folder)]接着,创建输出文件夹,新闻报道内容抽取出来后,将保存到该文件夹下。•text_output_folder=os.path.join(os.path.expanduser(~),Data,websites,textonly)实验过程importosimporthashlibfromlxmlimportetreeimportlxml.htmlasLHfromsklearn.clusterimportKMeansfromsklearn.feature_extraction.textimportTfidfVectorizerfromsklearn.pipelineimportPipelinefromcollectionsimportCounterimportmatplotlib.pyplotaspltimportnumpyasnp加载库lxml包解析HTML文件scikit-learn实现了k-means算法,直接从cluster模块导入TfidfVectorizer向量化工具根据词语出现在多少篇文档中,对词语计数进行加权MD5散列算法相关库无论是否自行获取数据,都应当加载库实验过程#如果使用提供数据,请从此处开始,包含以下data_folder=os.path.join(../,Data,websites,textonly)#如果自行获取数据,请从此处开始skip_node_types=[script,head,style,etree.Comment]创建列表,存放这些不可能包含新闻报道内容的节点。#函数的最后一行,调用getroot()函数,获取到树的根节点,而不是整棵树etreedefget_text_from_file(filename):withopen(filename,encoding='utf-8')asinf:html_tree=LH.parse(inf)returnget_text_from_node(html_tree.getroot())创建函数,该函数为了从文件中抽取数据第一步:提取数据#文本抽取函数get_text_from_node以节点作为参数,它能处理包括根节点在内的所有节点,便于递归调用。defget_text_from_node(node):ifnodeisNone:returniflen(node)==0:#Nochildren,justreturntextfromthisitem#检查文本长度是否达到100个字符ifnode.textandlen(node.text)100:returnnode.textelse:returnresults=(get_text
本文标题:数据挖掘-聚类分析
链接地址:https://www.777doc.com/doc-3832803 .html