机器学习实战(一):Document clustering 文档聚类

简介: 文档聚类是指根据文档的文本和语义背景将其归入不同的组别。它是一种无监督的技术,因为我们没有文件的标签,它在信息检索和搜索引擎中得到了应用。

3607bb7ab9874e2f80f8a10584c2b7cf.png


1. 简介


 文档聚类是指根据文档的文本和语义背景将其归入不同的组别。它是一种无监督的技术,因为我们没有文件的标签,它在信息检索和搜索引擎中得到了应用。


 为了根据文档的内容进行分类,我决定使用K-手段算法。由于项目是没有标签的,这显然是一个无监督的学习问题,最好的解决方案之一应该是K-Means。当然,我们可以使用不同的算法,如高斯混合模型,甚至深度学习方法,如自动编码器。我将使用python与Jupyter笔记本,将代码和结果与文档结合起来。


 我在Anaconda环境下开发代码,并使用了以下依赖:


  • Pandas 库用于数据处理


  • Sklearn库用于机器学习和预处理


  • Matplotlib 库用于绘图


  • Ntlk库用于自然语言算法


  • BeautifulSoup库用于从 xml 文件中解析文本并删除类别


2.数据解析


 函数parseXML使用xml.etree.ElementTree来解析数据。我决定只使用项目的标题和描述来进行聚类,这与语义学最相关。由于描述不是原始文本,我们用BeautifulSoup库提取文本,我已经提到过。此外,我们还放弃了那些描述非常小的项目,因为它们影响了最终的聚类。我们可以认为它们都属于一个额外的聚类。当然,还有一些方法可以包括它们,但我暂时没有使用它们。


import xml.etree.ElementTree as ET
import pandas as pd
import nltk
from sklearn.cluster import KMeans
from sklearn.externals import joblib
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
nltk.download('punkt')
from bs4 import BeautifulSoup
from nltk import SnowballStemmer
import re
def parseXML(xmlfile):
    tree = ET.parse(xmlfile)
    root = tree.getroot()
    titles=[]
    descriptions=[]
    for item in root.findall('./channel/item'):
        for child in item:
            if(child.tag=='title' ):
                titles.append(child.text)
            if (child.tag == 'description' ):
                soup = BeautifulSoup(str(child.text).encode('utf8','ignore'), "lxml")
                strtext=soup.text.replace(u'\xa0', u' ').replace('\n',' ')
                descriptions.append(strtext)
    return titles,descriptions
#remove items with short descriptions
bef_titles,bef_descriptions = parseXML('data.source.rss-feeds.xml')
print('Count of items before dropping:' ,len(bef_titles))
titles=[]
descriptions=[]
for i in range(len(bef_titles)):
    if ( len(bef_descriptions[i]) > 500):
        titles.append(bef_titles[i])
        descriptions.append(bef_descriptions[i])
print('Count of items after:' ,len(titles))


[nltk_data] Downloading package punkt to
[nltk_data]     C:\Users\sergi\AppData\Roaming\nltk_data...
[nltk_data]   Package punkt is already up-to-date!
Count of items before dropping: 1662
Count of items after: 1130


3. 符号化和词根化


 下一步是将文本标记为单词,删除任何形态词缀,并删除冠词和介词等常用词。这可以通过ntlk的内置功能来完成。最后,我们得到两个不同的词汇表(一个标记化和词干化,一个只有标记化),我们将它们合并到一个pandas数据框架中。


def tokenize_and_stem(text):
    #tokenize
    tokens = [word for sent in nltk.sent_tokenize(text) for word in nltk.word_tokenize(sent)]
    filtered_tokens = []
    #keep only letters
    for token in tokens:
        if re.search('[a-zA-Z]', token):
            filtered_tokens.append(token)
    #stemming
    stems = [stemmer.stem(t) for t in filtered_tokens]
    return stems
def tokenize_only(text):
    tokens = [word.lower() for sent in nltk.sent_tokenize(text) for word in nltk.word_tokenize(sent)]
    filtered_tokens = []
    for token in tokens:
        if re.search('[a-zA-Z]', token):
            filtered_tokens.append(token)
    return filtered_tokens


# nltk's English stopwords and stemmer
stemmer = SnowballStemmer("english")
#create steam and tokenized voucabularies
totalvocab_stemmed = []
totalvocab_tokenized = []
for i in descriptions:
    allwords_stemmed = tokenize_and_stem(i)
    totalvocab_stemmed.extend(allwords_stemmed)
    allwords_tokenized = tokenize_only(i)
    totalvocab_tokenized.extend(allwords_tokenized)
vocab_frame = pd.DataFrame({'words': totalvocab_tokenized}, index=totalvocab_stemmed)
print('there are ' + str(vocab_frame.shape[0]) + ' items in vocab_frame')
there are 481437 items in vocab_frame


4. 词向量化


 在我们将数据加载到K-手段算法之前,必须对其进行向量化。最流行的技术是Tdidf向量器,它根据文档中的单词频率创建一个矩阵,这就是我们要使用的技术。值得一提的是,作为未来的工作,word2vec和doc2vec可能会更有效地表示项目之间的关系。


#Tf-idf
tfidf_vectorizer = TfidfVectorizer(max_df=0.8, max_features=200000,min_df=0.2, stop_words='english',
                                 use_idf=True, tokenizer=tokenize_and_stem, ngram_range=(1,3))
tfidf_matrix = tfidf_vectorizer.fit_transform(descriptions)
print('Td idf Matrix shape: ',tfidf_matrix.shape)
terms = tfidf_vectorizer.get_feature_names()
#calculate the distance matrix . I will use them in the visualization of the cluster.
dist = 1 - cosine_similarity(tfidf_matrix)


Td idf Matrix shape:  (1130, 74)


5.K means


 实际的聚类发生在这里,K means在Td-idf矩阵的基础上产生5个聚类。我们可以很容易地预测,这将不是一个最佳的解决方案,因为它只考虑到了文件中每个词的频率。


num_clusters = 5
km = KMeans(n_clusters=num_clusters)
km.fit(tfidf_matrix)
clusters = km.labels_.tolist()


 为了展示集群,我创建了一个由集群索引的pandas Dataframe。每个聚类的前6个词呈现在下面。我们注意到,这个聚类远非完美,因为有些词在一个以上的聚类中。另外,集群的语义内容之间也没有明确的区别。我们可以很容易地看到,与工作有关的词汇包括在多个聚类中。


items = { 'title': titles, 'description': descriptions}
frame = pd.DataFrame(items, index = [clusters] , columns = [ 'title','cluster'])
print("Top terms per cluster:")
# sort cluster centers by proximity to centroid
order_centroids = km.cluster_centers_.argsort()[:, ::-1]
for i in range(num_clusters):
    print("Cluster %d words:" % i, end='')
    for ind in order_centroids[i, :6]:  # replace 6 with n words per cluster
        print(' %s' % vocab_frame.ix[terms[ind].split(' ')].values.tolist()[0][0], end=',')
    print()
    #print("Cluster %d titles:" % i, end='')
    #for title in frame.ix[i]['title'].values.tolist():
       #print(' %s,' % title, end='')


Top terms per cluster:
Cluster 0 words: labour, employability, european, social, work, eu,
Cluster 1 words: occupational, sectors, skill, employability, services, workers,
Cluster 2 words: skill, job, labour, develop, market, cedefop,
Cluster 3 words: education, training, learning, vocational, education, cedefop,
Cluster 4 words: rates, unemployment, area, employability, increasingly, stated,


6.绘图


 为了实现聚类的可视化,我们应该首先降低其维度。我们用sklearn.manifold库中的t-SNE(t-Distributed Stochastic Neighbor Embedding)来实现。另一种方法是使用PCA或MDS(Multi-Demiensional Scaling)。


 绘图是用matplotlib库完成的。


import os  # for os.path.basename
import matplotlib.pyplot as plt
import matplotlib as mpl
from sklearn.manifold import TSNE
tsne = TSNE(n_components=2, verbose=1, perplexity=40, n_iter=300)
# dist is the distance matrix
pos = tsne.fit_transform(dist)
xs, ys = pos[:, 0], pos[:, 1]
cluster_colors = {0: '#1b9e77', 1: '#d95f02', 2: '#7570b3', 3: '#e7298a', 4: '#66a61e'}
cluster_names = {0: 'A',1: 'B',  2: 'C', 3: 'D',  4: 'E'}


[t-SNE] Computing pairwise distances...
[t-SNE] Computing 121 nearest neighbors...
[t-SNE] Computed conditional probabilities for sample 1000 / 1130
[t-SNE] Computed conditional probabilities for sample 1130 / 1130
[t-SNE] Mean sigma: 1.785805
[t-SNE] KL divergence after 100 iterations with early exaggeration: 0.947952
[t-SNE] Error after 125 iterations: 0.947952


%matplotlib inline
df = pd.DataFrame(dict(x=xs, y=ys, label=clusters, title=titles))
groups = df.groupby('label')
fig, ax = plt.subplots(figsize=(16,8) )
for name, group in groups:
    ax.plot(group.x, group.y, marker='o', linestyle='', ms=12,
            label=cluster_names[name], color=cluster_colors[name], mec='none')
ax.legend(numpoints=1)
#we do not present the tiles of items to not make the graph overwhelming
#for i in range(len(df)):
    #ax.text(df.ix[i]['x'], df.ix[i]['y'], df.ix[i]['title'], size=4)
plt.show()


93967ef823b34f8bb7fa692db76a0c79.png


 我们可以发现结果并不像我们最初想象的那样糟糕。虽然有一些部分的重叠,但各组是相当有区别的。然而,毫无疑问,我们可以进一步优化它们。


 我们应该注意,只有几个字的项目没有在图中显示出来。我还注意到,有一些项目是用不同于英语的语言写的。我们目前没有处理它们,因此,它们的分类实际上是随机的。图中有一些错位的点。


 此外,在数据清理和预处理方面还有很多工作要做。一种方法是优化tdidf矢量化的参数,使用doc2vec进行矢量化。或者我们可以使用另一种技术,如亲和传播、频谱聚类或最近的方法,如HDBSCAN和变异自动编码器。

目录
相关文章
|
6天前
|
机器学习/深度学习 数据采集 搜索推荐
机器学习多场景实战(一)
机器学习已广泛应用,从个性化推荐到金融风控,数据指标是评估其效果的关键。数据指标包括活跃用户(DAU, MAU, WAU)衡量用户粘性,新增用户量和注册转化率评估营销效果,留存率(次日、7日、30日)反映用户吸引力,行为指标如PV(页面浏览量)、UV(独立访客)和转化率分析用户行为。产品数据指标如GMV、ARPU、ARPPU和付费率关注业务变现,推广付费指标(CPM, CPC, CPA等)则关乎广告效率。找到北极星指标,如月销售额或用户留存,可指导业务发展。案例中涉及电商销售数据,计算月销售金额、环比、销量、新用户占比、激活率和留存率以评估业务表现。
|
6天前
|
机器学习/深度学习 搜索推荐 数据挖掘
机器学习多场景实战(二 )
这是一个关于机器学习应用于电商平台用户行为分析的概要,包括以下几个关键点: 1. **月活跃用户分析**:通过购买记录确定活跃用户,计算每月活跃用户数。 2. **月客单价**:定义为月度总销售额除以月活跃用户数,衡量平均每位活跃用户的消费金额。 3. **新用户占比**:基于用户首次购买和最近购买时间判断新老用户,计算每月新用户的购买比例。 4. **激活率计算**:定义为当月与上月都有购买行为的用户数占上月购买用户数的比例,反映用户留存情况。 5. **Pandas数据操作**:使用Pandas库进行数据集合并(concat和merge),以及计算不同维度的组合。
|
9天前
|
机器学习/深度学习 数据挖掘
机器学习之聚类——模糊聚类FCM
机器学习之聚类——模糊聚类FCM
20 4
|
7天前
|
机器学习/深度学习 算法 搜索推荐
机器学习中的聚类
**文章摘要:** 本文介绍了聚类算法的基本概念、应用、实现流程和评估方法。聚类是一种无监督学习技术,用于将数据分为相似的组,如K-means、层次聚类、DBSCAN和谱聚类。K-means算法通过迭代优化质心,将数据点分配到最近的簇,直至质心不再变化。模型评估包括误差平方和(SSE)、肘部方法(确定最佳簇数)和轮廓系数法(Silhouette Coefficient),以量化聚类的紧密度和分离度。应用场景涵盖用户画像、广告推荐和图像分割等。在Python的sklearn库中,可以使用KMeans API进行聚类操作。
|
9天前
|
机器学习/深度学习 人工智能 Java
【Sping Boot与机器学习融合:构建赋能AI的微服务应用实战】
【Sping Boot与机器学习融合:构建赋能AI的微服务应用实战】
15 1
|
1天前
|
机器学习/深度学习 分布式计算 算法
在机器学习项目中,选择算法涉及问题类型识别(如回归、分类、聚类、强化学习)
【6月更文挑战第28天】在机器学习项目中,选择算法涉及问题类型识别(如回归、分类、聚类、强化学习)、数据规模与特性(大数据可能适合分布式算法或深度学习)、性能需求(准确性、速度、可解释性)、资源限制(计算与内存)、领域知识应用以及实验验证(交叉验证、模型比较)。迭代过程包括数据探索、模型构建、评估和优化,结合业务需求进行决策。
5 0
|
1天前
|
机器学习/深度学习 算法 数据可视化
技术心得记录:机器学习笔记之聚类算法层次聚类HierarchicalClustering
技术心得记录:机器学习笔记之聚类算法层次聚类HierarchicalClustering
|
7天前
|
机器学习/深度学习 算法 搜索推荐
机器学习聚类算法
聚类算法是无监督学习技术,用于发现数据集中的自然群体,如用户画像、广告推荐等。常见的聚类算法包括K-Means,它基于距离分配样本至簇,适合球形分布;层次聚类则通过合并或分裂形成簇,能发现任意形状的簇;DBSCAN依据密度来聚类,对噪声鲁棒。KMeans API中`sklearn.cluster.KMeans(n_clusters=8)`用于指定簇的数量。评估聚类效果可使用轮廓系数、SSE等指标,Elbow方法帮助选择合适的K值。
|
8天前
|
机器学习/深度学习 算法 数据挖掘
机器学习之聚类——MeanShift算法和图像矢量量化
机器学习之聚类——MeanShift算法和图像矢量量化
9 0
|
8天前
|
机器学习/深度学习 算法 数据挖掘
机器学习之聚类——从教授的等式到凸聚类
机器学习之聚类——从教授的等式到凸聚类
9 0

热门文章

最新文章