程序员的数学基础课
黄申
LinkedIn 资深数据科学家
83374 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 58 讲
导读 (1讲)
基础思想篇 (18讲)
程序员的数学基础课
15
15
1.0x
00:00/00:00
登录|注册

36 | 文本聚类:如何过滤冗余的新闻?

实现步骤
思想
实现自己的K均值聚类
K值的选择
向量空间模型和聚类算法的结合
TfidfTransformer
CountVectorizer
Scikit-learn库
代表性文章的选择
K均值算法对文档集合进行聚类
文档集合转换成向量
K均值聚类算法
非监督学习
文本检索中的应用
相似度的机制
思考题
总结
Python中的K均值算法
使用向量空间进行聚类
聚类算法
向量空间模型
如何过滤冗余的新闻?

该思维导图由 AI 生成,仅供参考

你好,我是黄申。
前两节,我讲了向量空间模型,以及如何在信息检索领域中运用向量空间模型。向量空间模型提供了衡量向量之间的距离或者相似度的机制,而这种机制可以衡量查询和被查询数据之间的相似程度,而对于文本检索来说,查询和文档之间的相似程度可作为文档的相关性。
实际上,除了文档的相关性,距离或者相似度还可以用在机器学习的算法中。今天,我们就来聊聊如何在聚类算法中使用向量空间模型,并最终实现过滤重复文章。

聚类算法

在概率统计模块中,我们介绍了分类(Classification/Categorization)和回归(Regression)这两种监督式学习(Supervised Learning)。监督式学习通过训练资料学习并建立一个模型,并依此模型对新的实例进行预测。
不过,在实际场景中,我们常常会遇到另一种更为复杂的情况。这时候不存在任何关于样本的先验知识,而是需要机器在没人指导的情形下,去将很多东西进行归类。由于缺乏训练样本,这种学习被称为“非监督学习”(Unsupervised Learning),也就是我们通常所说的聚类(Clustering)。在这种学习体系中,系统必须通过一种有效的方法发现样本的内在相似性,并把数据对象以群组(Cluster)的形式进行划分。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了如何使用向量空间模型和聚类算法来过滤冗余的新闻。文章首先介绍了K均值聚类算法的核心思想,即通过不断迭代、调整聚类质心的算法。然后,结合向量空间模型,详细讲解了如何在文本聚类中使用K均值算法,包括将文档集合转换成向量形式、计算相似度以及选取代表文章等步骤。接着,文章展示了在Python中使用sklearn库实现K均值算法的示例代码,并介绍了CountVectorizer和TfidfTransformer的使用方法。通过本文,读者可以了解到如何利用向量空间模型和聚类算法来处理大量新闻数据,从而过滤掉重复冗余的内容,帮助读者快速获取新的信息内容。文章还提到了K均值聚类的实际应用和参数选择的难点,以及鼓励读者尝试实现自己的K均值聚类并使用夹角余弦作为相似度的度量。整体而言,本文通过简洁清晰的语言和实际代码示例,帮助读者快速了解了向量空间模型和K均值算法的结合应用,以及在实际项目中可能遇到的挑战和解决思路。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《程序员的数学基础课》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(12)

  • 最新
  • 精选
  • mickey
    # encoding=utf-8 from sklearn.feature_extraction.text import CountVectorizer #模拟文档集合 corpus = ['I like great basketball game', 'This video game is the best action game I have ever played', 'I really really like basketball', 'How about this movie? Is the plot great?', 'Do you like RPG game?', 'You can try this FPS game', 'The movie is really great, so great! I enjoy the plot'] #把文本中的词语转换为词典和相应的向量 vectorizer = CountVectorizer() vectors = vectorizer.fit_transform(corpus) from sklearn.feature_extraction.text import TfidfTransformer #构建tfidf的值 transformer = TfidfTransformer() tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus)) # 输出每个文档的向量 tfidf_array = tfidf.toarray() words = vectorizer.get_feature_names() from Bio.Cluster import kcluster #进行聚类,使用向量间的夹角余弦作为相似度的度量 clusterid, error, nfound = kcluster(tfidf_array, nclusters=3, dist='u') print(clusterid) ''' Kmeans 的欧式距离:[0 2 0 1 2 2 1] Bio 的夹角余弦:[2 0 0 2 0 2 1] '''

    作者回复: 尝试了不同的方法👍

    2019-03-08
    2
    7
  • 余泽锋
    请问一下老师,余弦夹角本质上可以说是归一化的欧式距离么?

    作者回复: 可以这么认为

    2019-04-09
    2
    6
  • zhengfan
    黄老师您好。 您在k均值算法介绍后附的图示,似乎呈现出“恰巧把初选质心点选在了不同群组中”的效果。而作为k均值算法的第一步,最初质心的选择是完全随机的。也就是很有可能这些初选质心是在同一个群组中。请问这种情况如何处理?

    作者回复: 很好的问题,作为非监督式学习,这是个很大的缺陷,实际运用中通常试验不同的初始值,或者采用层次化聚类,先细分很多小的类,然后根据相似度进行聚集

    2020-06-02
    3
  • Joe
    老师,现在很多机器学习的算法都有现成的库了,如sklearn等。但是直接调库,总觉得停留在表面。请问有没有必要自己手动去实现一些经典的机器学习算法呢?

    作者回复: 这是一个好问题,可以参照专栏中的一些介绍,尝试实现某些算法,加强印象,甚至于将来可以根据具体的应用,对算法实现进行优化。

    2019-03-14
    2
    3
  • Paul Shan
    kmeans方法用的是利用几何信息将空间点归类的方法,最终的结果是归好类的点集质心之间的距离远,但是集合内点之间距离近的效果,可以类比于软件开发中的高内聚低耦合原则来记忆。

    作者回复: 嗯,这个比喻好👍

    2019-09-26
    1
  • Bindy🌲
    老师,这里如果是中文,是不是要做分词呢

    作者回复: 是的,如果是中文,肯定要做分词的。

    2019-04-10
    1
  • 建强
    我自己写了一个用向量夹角的余弦做聚类的算法,但不论怎么调整,聚类结果和欧氏距离算法都不一样,是不是和初始质心选择有关,还是程序中的算法有问题,需要请教老师,篇幅有限,部分程序代码如下: # 用样本拟合聚类算法模型 def fit(self, sample_matrix): #检查分类个数是否大于待分类的样本数 if self.n_clusters > len(sample_matrix): raise ValueError('cluster numbers must less than or equal to sample numbers') # 初始化质心,取前n个样本的向量作为质心 self.cluster_centers_ = np.array([sample_matrix[0]]) for j in range(1, self.n_clusters): self.cluster_centers_ = np.r_[self.cluster_centers_, [sample_matrix[j]]] # 迭代计算各样本与质心的夹角,并更新分组,直到新质心与旧质心之间的差距小于指定精度 k = 0 cluster = {} while True: cluster.clear() for i in range(len(sample_matrix)): max_cos = 0 nearest_label = None for j in range(self.n_clusters): cos = self.__cos(sample_matrix[i],self.cluster_centers_[j]) if max_cos < cos: max_cos = cos nearest_label = j cluster.setdefault(nearest_label,[]) cluster[nearest_label].append(i) #保存老的质心,计算新的质心 old_cluster_centers = self.cluster_centers_.copy() for j in range(self.n_clusters): self.cluster_centers_[j] = 0 for i in cluster[j]: self.cluster_centers_[j] += sample_matrix[i] self.cluster_centers_[j] = self.cluster_centers_[j] / len(cluster[j]) # 用方差比较新老质心之间的差距 if self.__variance(self.cluster_centers_, old_cluster_centers) <= self.precision: break; k+=1 # 根据计算结果给样本归类 self.labels_ = list('0' * len(sample_matrix)) for j in range(self.n_clusters): for i in cluster[j]: self.labels_[i] = j self.labels_ = np.array(self.labels_) =================聚类结果========== 每个文档所属的分组 [0 1 2 1 0 1 0]

    作者回复: 从程序片段看,逻辑上没有什么问题,可能是和初始质心的选取有关,另外欧氏距离和余弦夹角也可能导致结果的不同,因为余弦夹角相当于做了归一化

    2020-09-23
    2
  • Eleven
    看到这里就有点吃力了,工作中没有涉及到这块东西...

    作者回复: 坚持就会有收获

    2020-06-28
    2
  • 骑行的掌柜J
    我这里向量间使用欧式距离得到的是:[1 0 1 2 1 0 2] 而向量间用夹角余弦得到的是:[2 1 2 1 0 0 1] scikit-learn没有相应的夹角余弦包,所以要用后面这个Biopython。 建议大家可以去Biopython官网看看相关用法,用anaconda安装Biopython的指令是 : conda install -c conda-forge biopython 这是中文文档地址:https://biopython-cn.readthedocs.io/zh_CN/latest/cn/chr15.html 这是英文的:https://biopython.org/wiki/Download

    作者回复: 感谢提供这么多信息给大家

    2020-06-19
  • Joe
    def customKmeans(vec_array, n_clusters=3, epochs=50): ''' @description: 手动实现kmeans,以向量间的夹角余弦作为相似度 根据上述tf-idf得到的7条文本向量tfidf_array,进行聚类算法 @param {type} vec_array- 向量组, n_clusters-聚类数目, epochs- 训练次数 @return: cluster_labels- 分类标签 ''' # 初始化质心的位置 cluster_centers = [] cluster_centers_indx = [] while (len(cluster_centers_indx) < n_clusters): indx = random.randint(0, len(vec_array)-1) if indx not in cluster_centers_indx: cluster_centers_indx.append(indx) cluster_centers.append(vec_array[indx]) # 初始化向量类别 cluster_labels = [0] * len(vec_array) max_similarity = [-1] * len(vec_array) epoch = 0 while(epoch < epochs): # 计算每个向量与质心的相似性,并将其归纳到最近的质心集群中 for i in range(0, len(vec_array)): max_similarity[i] = computeCosine(vec_array[i], cluster_centers[0]) for j in range(1, n_clusters): temp = computeCosine(vec_array[i], cluster_centers[j]) if (temp > max_similarity[i]): max_similarity[i] = temp cluster_labels[i] = j # 更新质心位置 for i in range(0, n_clusters): # 找到集群对应原向量的下标 indxs = [indx for indx, cluster in enumerate( cluster_labels) if cluster == i] # 根据集群向量的平均值更新质点位置 cluster_centers[i] = np.average( [vec_array[indx] for indx in indxs], axis=0) # 当满足迭代次数或平均最大相似性时退出算法 epoch += 1 if (np.average(max_similarity) > 0.9): break return cluster_labels def computeCosine(vec1, vec2): # 计算向量间的余弦值 vecCosine = np.dot(vec1, vec2) / \ (np.linalg.norm(vec1) * np.linalg.norm(vec2)) return vecCosine # 应用customkmeans labels = customKmeans(tfidf_array, n_clusters=3, epochs=1000) print(labels) 输出结果: [0 2 0 1 2 2 1]
    2019-03-15
    8
收起评论
显示
设置
留言
12
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部