数据挖掘(九)

数据挖掘(九)

文章目录

    • 数据挖掘(九)
      • 获取新闻文章
        • 使用Web API获取数据
      • 从任意网站抽取文本
        • 寻找任意网站网页中的主要内容
      • 示例代码1
      • 新闻语料聚类
        • k-means算法
        • 评估结果
        • 从簇中抽取主题信息
      • 聚类融合
        • 证据累积
        • 工作原理
      • 线上学习

已知目标类别的学习任务,叫做监督学习。不知道类别的情况下进行数据挖掘,这叫做无监督学习,偏重于探索、发现隐藏在数据里的信息,而不是用模型来分类。

获取新闻文章

本文讨论构建一个按照主题为最新的新闻报道分组的系统。

使用Web API获取数据
  1. 使用Web API采集数据,我们需要注意授权方法、请求频率限制和API端点。
  • 授权方法时数据提供方用来管理数据采集方的。数据提供方以此来了解谁正在采集数据,确保采集方抓取数据的频率没有超出上限,同时对采集方都采集了哪些数据可以做到监视。对于多数网站来说,普通个人账号就能用来采集数据,但也有部分网站要求采集方使用正式的开发者账号。
  • 采集频率限制规定了采集方在约定时间内的最大请求次数,特别是对于免费提供的服务。在使用数据获取接口时,一定要了解不同的网站可能有着不同的规定。即使同一个网站,不同的API调用也有不同的采集频率限制。
  • API端点是指用来抽取信息的实际网址。不同网站提供不同的接口,大部分Web API提供Restful接口。

从任意网站抽取文本

我们从Hao123收集的网址所指向的网站分属不同的网站组织。当我们尝试用程序获取里面的实际内容时,可能遇到各种困难,比如有很多逻辑是在后台运行的,调用JS库,应用样式表,用AJAX加载广告,在侧边栏增加很多内容等,这些功能增加了网站的复杂程度,增加了自动采集信息的难度。

寻找任意网站网页中的主要内容
  1. 首先访问每个链接,下载各个网页,把它们保存到数据文件夹中事先建好的用于存放原始网页的文件夹raw,然后我们从这些原始网页中获取有用的信息。我们使用MD5散列算法为每篇报道创建一个唯一的文件名。散列函数将输入转换为一个看似随机产生的字符串。对于相同的输入,散列函数返回相同的结果,并且散列函数是单向函数,根据散列值无法得到原来的值。
import os
import hashlib
import requestsstories = [['“旅行者”来做客,“美食”多样!唯美生态画卷颜值不断被“刷新”', 'http://baijiahao.baidu.com/s?id=1815151290164989110', '12'], ['网友称镇卫生院有人“吃空饷”,相关人员应被追责;珠海金湾区卫健局:重复领取', 'http://baijiahao.baidu.com/s?id=1815068325137550619', '14'],['泼天流量说来就来,这次大学生“夜袭开封”', 'http://baijiahao.baidu.com/s?id=1815025933758571293', '18']]
data_folder = os.path.join(os.getcwd(), 'data_mining', 'news', 'raws')
# 对于网页下载失败的网站,直接跳过,维护计数器统计下载失败的次数,如果是系统本身的问题阻止下载,我们需要解决问题。如果失败次数过多,我们就需要找出到底是什么问题并解决
number_errors = 0
# 遍历每篇新闻报道
for title, url, score in stories:# 对标题进行散列操作output_filename = hashlib.md5(url.encode()).hexdigest()fullpath = os.path.join(data_folder, output_filename + '.txt')try: # 下载网页保存到输出文件夹response = requests.get(url)data = response.textwith open(fullpath, 'w') as outf:outf.write(data)except Exception as e:number_errors += 1# 如果异常过多,调用raise处理异常中断机制print(e)
  1. 获得原始网页后,我们需要找出每个网页中的新闻报道内容,有些在线资源使用数据挖掘方法来解决这个问题。从网页中抽取文本代码可以使用lxml包解析HTML文件,lxml的HTML解析器容错能力强,可以处理不规范的HTML代码。文本抽取首先遍历HTML文件的每个节点,抽取其中的文本内容;其次跳过JS、样式和注释节点,这些系欸但不太可能包含对我有有价值的信息。最后确保文本内容长度至少为100字符。文本抽取函数在任何子节点上调用自己来抽取子节点中的文本内容,最后返回拼接在一起的所有子节点的文本。如果一个节点没有任何子节点,文本抽取函数返回该节点的文本内容,如果该节点不包含任何内容,就返回空字符串。
# 获得raws文件夹中的所有文件名
filenames = [os.path.join(data_folder, filename) for filename in os.listdir(data_folder)]
from lxml import etree, html
# 存放不可能包含新闻报道内容的节点
skip_node_types = ['script', 'head', 'style', etree.Comment]
# 把html文件解析成lxml etree对象
def get_text_from_file(filename):with open(filename) as inf:html_tree = html.parse(inf)# 调用getroot()函数获取树的根节点,这样以这个节点作为入参,能处理包括根节点在内的所有节点return get_text_from_node(html_tree.getroot())
# 对每个子节点递归调用文本抽取函数,把返回后的文本内容拼接在一起
def get_text_from_node(node):if len(node) == 0:if node.text and len(node.text) > 100:return node.textelse:return ''results = (get_text_from_node(child) for child in node if child.tag not in skip_node_types)# 防止返回空行return '\n'.join(r for r in results if len(r) > 1)
# 从文件中抽取文本
for filename in os.listdir(data_folder):text = get_text_from_file(os.path.join(data_folder, filename))with open(os.path.join(data_folder, filename), 'w') as outf:outf.write(text)

示例代码1

import os
import hashlib
import requests
from lxml import etree, htmlstories = [['“旅行者”来做客,“美食”多样!唯美生态画卷颜值不断被“刷新”', 'http://baijiahao.baidu.com/s?id=1815151290164989110', '12'], ['网友称镇卫生院有人“吃空饷”,相关人员应被追责;珠海金湾区卫健局:重复领取', 'http://baijiahao.baidu.com/s?id=1815068325137550619', '14'],['泼天流量说来就来,这次大学生“夜袭开封”', 'http://baijiahao.baidu.com/s?id=1815025933758571293', '18']]
data_folder = os.path.join(os.getcwd(), 'data_mining', 'news', 'raws')
number_errors = 0
for title, url, score in stories:print(title, url, score)output_filename = hashlib.md5(url.encode()).hexdigest()fullpath = os.path.join(data_folder, output_filename + '.txt')try: response = requests.get(url)response.encoding = 'utf-8'data = response.text  with open(fullpath, 'w') as outf:outf.write(data)except Exception as e:number_errors += 1print(e)
documents = [open(os.path.join(data_folder, filename), encoding='utf-8').read() for filename in os.listdir(data_folder)]    
skip_node_types = ['script', 'head', 'style', etree.Comment]
def get_text_from_file(filename):with open(filename, encoding='utf-8') as inf:html_tree = html.parse(inf)return get_text_from_node(html_tree.getroot())
def get_text_from_node(node):if len(node) == 0:if node.text and len(node.text) > 100:return node.textelse:return ''results = (get_text_from_node(child) for child in node if child.tag not in skip_node_types)return '\n'.join(r for r in results if len(r) > 1)
for filename in os.listdir(data_folder):text = get_text_from_file(os.path.join(data_folder, filename))with open(os.path.join(data_folder, filename), 'w', encoding='utf-8') as outf:outf.write(text)

新闻语料聚类

我们可以通过聚类发现新闻语料中潜藏的趋势。我们使用经典的机器学习算法k均值算法k-means。聚类属于无监督学习。假设我们使用500篇新闻报道组成的数据集,人工查看这些文章的主题费时费力,即使使用概括统计方法也不容易。聚类分析可以按照主题把它们分成不同的簇,然后可以按簇研究它们的主题。

k-means算法

k-means聚类算法迭代寻找最能够代表数据的聚类质心点。算法开始时使用从训练数据中随机选取的几个数据点作为质心点。k-means中的k表示寻找多少个质心点,同时也是算法将会找到的簇的数量。

  1. k-means算法分为两步,一是为每个数据点分配簇标签,二是更新各簇的质心点。一个数据点对应数据集中一条数据,把数据集看成样本,一条数据可以看作是一个个体。我们在分簇时为数据集中的个体设置一个标签,把它和最近的质心点联系起来。对于距离质心点1最近的个体,我们为它们分配标签1,以此类推。标签相同的个体属于同一个簇。更新环节计算各簇内所有数据点的均值,更新质心点。k-means算法会重复上述步骤,每次更新质心点时,所有质心点将会小范围移动。这个过程会执行知道条件不再满足位置。
  2. k-means算法只有一个参数,在很多数据挖掘问题上效果很好,所以仍然被频繁使用。scikit-learn实现了k-means算法。创建数据分析流水线,第一步是特征抽取,第二步是调用k-means算法。
from sklearn.cluster import KMeans
# 这个向量化工具根据词语出现在多少篇文档中对词语计数进行加权,出现在较多文档中的词语权重较低。用文档集数量除以词语出现在的文档的数量,然后取对数
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.pipeline import Pipeline
from collections import Counter
# 参数max_df=0.4表示忽略出现在40%及以上的文档中的词语,可以用来剔除本身不含有主题相关含义的词语
documents = [open(os.path.join(data_folder, filename), encoding='utf-8').read() for filename in os.listdir(data_folder)]   
n_clusters = 2
pipeline = Pipeline([('feature_extraction', TfidfVectorizer(max_df=0.4)), ('clusterer', KMeans(n_clusters))])
pipeline.fit(documents)
# labels变量包含每个数据点的簇标签
labels = pipeline.predict(documents)
# 使用Counter类来查看每个簇有多少个数据点
c = Counter(labels)
for cluster_number in range(n_clusters):print('Cluster {} contains {} samples'.format(cluster_number, c[cluster_number]))
评估结果
  1. 聚类分析主要是探索性分析,因此很难有效地评估聚类算法结果的好坏。评估算法结果最直接的方式是根据它要学习的标准对其进行评价。对于k均值算法,寻找新质心点的标准是最小化每个数据点到最近质心点的距离,这叫做算法的惯性权重。
# 任何经过训练的KMeans实例都有惯性权重,可以用来确定分多少簇合适
pipeline.named_steps['clusterer'].inertia_
# n_cluster_values依次取2到20之间的值,每取一个值,k-means算法运行10此,每次运行算法都记录惯性权重,每次仅训练X矩阵一次
inertia_scores = []
n_cluster_values = list(range(2, 20))
for n_clusters in n_cluster_values:cur_inertia_scores = []X = TfidfVectorizer(max_df=0.4).fit_transform(documents)for i in range(40):km = KMeans(n_clusters).fit(X)cur_inertia_scores.append(km.inertia_)inertia_scores.append(cur_inertia_scores)
# 变量inertia_scores存储了n_clusters取2到20每个值时所对应的惯性权重,把惯性权重和簇的数量做成图。随着簇数量增加,质心点和其他数据点位置的调整逐渐减少,惯性权重应该逐渐降低
from matplotlib import pyplot as plt
inertia_means = np.mean(inertia_scores, axis=1)
inertia_stderr = np.std(inertia_scores, axis=1)
fig = plt.figure(figsize=(40,20))
plt.errorbar(n_cluster_values, inertia_means, inertia_stderr, color='green')
plt.show()
从簇中抽取主题信息
  1. 我们尝试找到每个簇的主题,首先从特征提取这一步抽取词表。其次k均值算法可以用来简化特征。特征简化的方法有很多种,比如主要成分分析、潜在语义索引等,这些方法还能用来创建新特征。
# 从流水线的特征提取这一步抽取词条
terms = pipeline.named_steps['feature_extraction'].get_feature_names()
# 计算每簇所包含的个体数量
c = Counter(labels)
# 遍历所有的簇,输出每簇所包含的个体数量
for cluster_number in range(n_clusters):print("Cluster {} contains {} samples".format(cluster_number, c[cluster_number]))print("  Most important terms")# 从质心点找出特征值最大的5个特征centroid = pipeline.named_steps['clusterer'].cluster_centers_[cluster_number]most_important = centroid.argsort()for i in range(5):term_index = most_important[-(i+1)]print("  {0}) {1} (score: {2:.4f})".format(i+1, terms[term_index], centroid[term_index]))

聚类融合

聚类算法可以进行融合,融合后得到的算法能够平滑算法多次运行所得到的不同结果。多次运行k均值算法得到结果因为最初选择的质心点不同而不同。聚类融合方法可以降低参数选择对最终结果的影响。

证据累积
  1. 基本的融合方法是对数据进行多次聚类,每次都记录各个数据点的簇标签,然后计算每两个数据点被分到同一个簇的次数。这就是证据累积算法的精髓。第一步是使用k-means等低水平的聚类算法对数据集进行多次聚类,记录每次跌倒两个数据点出现在同一簇的频率,将结果保存到共协矩阵中。第二步是是用另一种聚类算法,分级聚类对第一步得到的共协矩阵进行聚类分析。
from scipy.sparse import csr_matrix
# 遍历所有标签,记录具有相同标签的两个数据点的位置,创建共协矩阵
def create_coassociation_matrix(labels):rows = []cols = []unique_labels = set(labels)for label in unique_labels:indices = np.where(labels == label)[0]for index1 in indices:for index2 in indices:rows.append(index1)cols.append(index2)data = np.ones((len(rows),))return csr_matrix((data, (rows, cols)), dtype='float')
C = create_coassociation_matrix(labels)
  1. 对共协矩阵进行分级聚类。我们需要找到该矩阵的最小生成树MST,删除权重低于阈值的边。
from scipy.sparse.csgraph import minimum_spanning_tree
# 矩阵C中值越高表示一组数据点被分到同一簇的次数越多,这个值表示相似度
mst = minimum_spanning_tree(C)
pipeline.fit(documents)
label2s = pipeline.predict(documents)
C2 = create_coassociation_matrix(labels2)
C_sum = (C + C2)/2
mst = minimum_spanning_tree(-C_sum)
# 删除两个矩阵中都没有出现的边
mst.data[mst.data > -1] = 0
mst.eliminate_zeros()
# 找到所有的连通分支,寻找移除低权重的边以后仍然连接在一起的节点
from scipy.sparse.csgraph import connected_components
number_of_clusters, labels = connected_components(mst)
工作原理
  1. k-means算法不考虑特征的权重,假定所有的特征取值范围相同,寻找的是圆形簇。证据累积算法的工作原理是重新把特征映射到新空间,每次运行k-means算法相当于使用转换器对特征进行一次转换。证据累积算法只关心数据点之间的距离而不是它们在原来特征空间的位置。对于没有规范化过的特征,仍然存在问题。我们使用tf-idf规范特征值,从而使特征具有相同的值域。
from sklearn.base import BaseEstimator, ClusterMixin
# 创建证据累积算法类
class EAC(BaseEstimator, ClusterMixin):# k-means算法运行次数,用来删除边的阈值和每次运行算法要找到的簇的数量,指定取值范围def __init__(self, n_clusterings=10, cut_threshold=0.5, n_clusters_range=(3, 10)):self.n_clusterings = n_clusteringsself.cut_threshold = cut_thresholdself.n_clusters_range = n_clusters_rangedef fit(self, X, y=None):# 使用低水平聚类把每次迭代得到的共协矩阵加起来,为了节省内存,我们使用生成器,仅在需要时创建共协矩阵C = sum((create_coassociation_matrix(self._single_clustering(X))for i in range(self.n_clusterings)))mst = minimum_spanning_tree(-C)mst.data[mst.data > -self.cut_threshold] = 0mst.eliminate_zeros()self.n_components, self.labels_ = connected_components(mst)return selfdef _single_clustering(self, X):n_clusters = np.random.randint(*self.n_clusters_range)km = KMeans(n_clusters=n_clusters)return km.fit_predict(X)def fit_predict(self, X):self.fit(X)return self.labels_

线上学习

线上学习是指用新数据增量地改进模型。支持线上学习的算法可以先用一条或少量数据进行训练,随着更多新数据的添加,更新模型。标准的k-means算法不支持线上学习。线上学习算法在只有几条新数据的情况下就能做到部分更新已有模型。神经网络算法使支持线上学习的标准例子。随着一条心数据插入到神经网络后,网络中的权重根据学习速率进行更新,学习速率通常使一个很小的值。神经网络还可以按照批模式来训练,每次只用一组数据进行训练。我们可以用一个数据点或少量数据点来轻微更新k-means中的质心点。

  1. scikit-learn提供了MiniBatchKBeans算法用来实现线上学习功能。
from sklearn.cluster import MiniBatchKMeans
# 从数据集中抽取特征,创建矩阵X
vec = TfidfVectorizer(max_df=0.4)
X = vec.fit_transform(documents)
mbkm = MiniBatchKBeans(random_state=14, n_clusters=3)
# 随机从X矩阵中选择数据,模拟来自外部的新数据
batch_size = 10
for iteration in range(int(X.shape[0] / batch_size)):start = batch_size * iterationend = batch_size * (iteration + 1)mbkm.partial_fit(X[start:end])
# 获得原始数据集的聚类结果
labels_mbkm = mbkm.predict(X)
mbkm.inertia_

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/470908.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文件夹被占用了无法删除怎么办?强制粉碎文件夹你可以这样操作

在日常使用电脑的过程中,我们可能会遇到一些难以删除的文件夹,这不仅影响了我们的工作效率,还可能隐藏着潜在的安全风险。本文简鹿办公将向您介绍为什么某些文件夹无法直接删除,以及如何利用360安全卫士极速版等工具彻底粉碎这些顽…

Python 随笔

转移字符 \a 用于触发系统蜂鸣器(要在shell上才行) print里面用 括起来的内容位置是 """ """括起来啥样,输出啥样 任何值都可以当作i条件: 是直接把两…

某app最新版 vmp算法分析一

本系列预计3篇 某app使用了一种X开头的HTTP 签名。该应用程序对服务器的请求在其标头中有6个x签名。该应用程序通常使用此签名来确保数据的安全性和完整性。代号花露水. 6个x签名都来自古希腊神话中的某个神. 分别是蛇发女妖(G),柯罗诺斯(K,时间之神),拉顿(L),阿尔戈斯(A),赫…

AI制作ppt

1,kimi: 实际上也是AiPPT.cn这个网站(但是有实际次数限制) 2,其余专业AI ppt生成网站: (1)gamma:https://gamma.app/ 大概能制作7~10页左右 free的ppt,其余要…

【插件】多断言 插件pytest-assume

背景 assert 断言一旦失败,后续的断言不能被执行 有个插件,pytest-assume的插件,可以提供多断言的方式 安装 pip3 install pytest-assume用法 pytest.assume(表达式,f’提示message’) pytest.assume(表达式,f‘提示message’) pytest.ass…

SpringCloud学习笔记

SpringCloud 在微服务中,不同的服务板块是分开的,有自己的数据库。但是在业务中可能存在服务板块中互相调用的情况,比如订单服务中需要获取用户信息,这时候不能再自己的板块中直接进行查询,否则违反了微服务的理念&am…

HBase理论_背景特点及数据单元及与Hive对比

本文结合了个人的笔记以及工作中实践经验以及参考HBase官网,我尽可能把自己的知识点呈现出来,如果有误,还请指正。 1. HBase背景 HBase作为面向列的数据库运行在HDFS之上,HDFS缺乏随机读写操作,HBase正是为此而出现。…

MoneyPrinterTurbo – 开源的AI短视频生成工具

MoneyPrinterTurbo是什么 MoneyPrinterTurbo是开源的AI短视频生成工具,能自动化地根据用户提供的视频主题或关键词生成视频文案、素材、字幕和背景音乐,合成高清短视频。工具支持API和Web界面操作,具备自定义文案、多种视频尺寸、批量视频生…

[CKS] K8S NetworkPolicy Set Up

最近准备花一周的时间准备CKS考试,在准备考试中发现有一个题目关于不安全项目修复的题目。 ​ 专栏其他文章: [CKS] Create/Read/Mount a Secret in K8S-CSDN博客[CKS] Audit Log Policy-CSDN博客 -[CKS] 利用falco进行容器日志捕捉和安全监控-CSDN博客[CKS] K8S Ne…

DataWorks on EMR StarRocks,打造标准湖仓新范式

在大数据领域,数据仓库和实时分析系统扮演着至关重要的角色。DataWorks 基于大数据引擎,为数据仓库/数据湖/湖仓一体等解决方案提供统一的全链路大数据开发治理平台,为用户带来智能化的数据开发和分析体验。而阿里云提供的 EMR Serverless St…

设计模式之责任链模式(Chain Of Responsibility)

一、责任链模式介绍 1、责任链模式介绍 职责链模式(chain of responsibility pattern) 定义: 避免将一个请求的发送者与接收者耦合在 一起,让多个对象都有机会处理请求。将接收请求的对象连接成一条链,并且沿着这条链 传递请求,直到有一个对…

Qt_day4_Qt_UI设计

目录 Qt_UI设计 1. Designer 设计师(掌握) 2. Layout 布局(重点) 2.1 基本使用 2.2 高级用法 2.3 代码布局(了解) 3. Designer与C的关系(熟悉) 4. 基本组件(掌握…

Unity学习笔记(4):人物和基本组件

文章目录 前言开发环境新增角色添加组件RigidBody 2D全局项目设置Edit 给地图添加碰撞体 总结 前言 今天不加班,有空闲时间。争取一天学一课,养成习惯 开发环境 Unity 6windows 11vs studio 2022Unity2022.2 最新教程《勇士传说》入门到进阶&#xff…

Elastic Observability 8.16:增强的 OpenTelemetry 支持、高级日志分析和简化的入门流程

作者:来自 Elastic Luca Wintergerst, Alex Fedotyev, Vinay Chandrasekhar, Miguel Luna Elastic Observability 8.16 宣布了几个关键功能: Amazon Bedrock 集成 LLM 可观察性为基于 Amazon Bedrock 构建的 LLM 应用程序添加了全面的监控功能。这种新的…

Bugku CTF_Web——文件上传

Bugku CTF_Web——文件上传 进入靶场 My name is margin,give me a image file not a php抓个包上传试试 改成png也上传失败 应该校验了文件头 增加了文件头也不行 试了一下 把文件类型改成gif可以上传 但是还是不能连接 将Content-Type改大小写 再把文件后缀名改成php4 成…

车-路-站-网”信息耦合的汽车有序充电

电动汽车作为一种环保、的交通工具,正逐渐成为未来交通的发展趋势。然而,大规模电动汽车的无序充电可能导致电网负荷波动、电压下降等问题,影响电网的安全稳定运行。为了解决这些问题,需要制定有效的电动汽车有序充电策略&#xf…

Microsoft 365 Exchange如何设置可信发件IP白名单

1、 进入到 Microsoft 365 admin center 管理中心 ,点击 管理中心 下的 安全 在弹出的新页面中,依次点击 策略和规则 – 威胁策略 – 反垃圾邮件 再单击 连接筛选器策略(默认) – 编辑连接筛选器策略 2、在 IP 允许列表 中添加可信邮件 IP 段&#xff0…

什么岗位需要学习 OpenGL ES ?说说 3.X 的新特性

什么是 OpenGL ES OpenGL ES 是一种为嵌入式系统和移动设备设计的3D图形API(应用程序编程接口)。它是标准 OpenGL 3D 图形库的一个子集,专门为资源受限的环境(如手机、平板电脑、游戏机和其他便携式设备)进行了优化。 由于其在移动设备上的广泛适用性,OpenGL ES是学习移…

力扣104 : 二叉树最大深度

补:二叉树的最大深度 描述: 给定一个二叉树 root ,返回其最大深度。二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 何解? 树一般常用递归:递到叶子节点开始倒着处理

免费,WPS Office教育考试专用版

WPS Office教育考试专用版,不仅满足了考试需求,更为教育信息化注入新动力。 https://pan.quark.cn/s/609ef85ae6d4