在此之前,我们探讨了通过分析文本来了解文本或语料库的构成,比如通过词性标注(POS)和命名实体识别(NER)来揭示文档中的词汇类型;而主题模型则能揭示隐藏在文本中的潜在主题。然而,开发人员通常利用主题模型进行文档聚类,但这种方法并非主题模型的主要优势所在,且效果可能不尽人意。这是因为主题建模的核心目标在于发现语料库中的隐藏主题,而非对文档进行聚类。尽管如此,执行主题建模后,我们可以了解到文档主要由哪些主题构成,但这还不够用于有效的聚类。
接下来,我们将介绍两种更适合定量分析的机器学习方法:聚类和分类。聚类是一种常见的机器学习任务,它通过识别数据点之间的相似性来进行分组。聚类任务的目标是将相似的数据点归为一组,而不考虑这些数据点的具体类别。聚类是一种无监督学习方法,在分配数据点到不同的组之前,我们并不知道这些数据点所属的具体类别。
另一方面,分类任务则是通过训练已知类别的样本数据来预测未知样本的类别。例如,可以将电子邮件分为垃圾邮件或非垃圾邮件,或将新闻文章归入特定类别。这两种方法在机器学习领域都有广泛应用,其中一个著名的数据集是鸢尾花数据集(Iris),它包含花的花瓣长度和类别信息。另一个广泛使用的数据集是MNIST,它包含了手写数字图像,用于训练模型来识别图像中的数字。
文本聚类遵循传统聚类方法的原则,但由于文本数据的高维度特性,处理起来更加复杂。例如,鸢尾花数据集只有四个特征可用于区分类别,而文本数据则需要处理整个词汇表。为了应对这一挑战,我们需要采用一些技术手段,如奇异值分解(SVD)、潜在狄利克雷分配(LDA)和潜在语义索引(LSI)来降低维度。
在之前的章节中,我们已经使用了Gensim和spaCy等工具进行计算语言学的任务。现在,我们将转向scikit-learn这一传统的机器学习库。接下来,我们将探讨Word2Vec和Doc2Vec这两种将单词和文档表示为向量的新方法。这些方法相较于以往的算法更为复杂,我们将在后续章节中详细介绍它们的应用。
聚类前的关键准备工作包括预处理,如去除停用词和词干化,以及将文档转换为向量表示。我们将使用scikit-learn来完成这些任务。在这里,我们选择了20 Newsgroups数据集,这是一个常用的文本分类数据集。我们可以通过以下代码加载和处理该数据集:
```python from sklearn.datasets import fetch20newsgroups from sklearn.featureextraction.text import TfidfVectorizer from sklearn.decomposition import TruncatedSVD from sklearn.preprocessing import Normalizer from sklearn.pipeline import Pipeline
categories = ['alt.atheism', 'talk.religion.misc', 'comp.graphics', 'sci.space'] dataset = fetch20newsgroups(subset='all', categories=categories, shuffle=True, randomstate=42) labels = dataset.target true_k = len(np.unique(labels))
vectorizer = TfidfVectorizer(maxdf=0.5, mindf=2, stopwords='english', useidf=True) X = vectorizer.fit_transform(dataset.data)
ncomponents = 5 svd = TruncatedSVD(ncomponents) normalizer = Normalizer(copy=False) lsa = makepipeline(svd, normalizer) X = lsa.fittransform(X) ```
这段代码展示了如何加载数据集、进行TF-IDF转换以及应用奇异值分解(SVD)和正则化来降维,从而得到适合聚类的向量表示。
K-means是一种经典的聚类算法,它通过减少聚类中心点与组内其他点的距离来实现聚类效果。使用scikit-learn的K-means模块可以很方便地实现这一算法。以下是使用scikit-learn进行K-means聚类的代码:
```python from sklearn.cluster import KMeans
km = KMeans(nclusters=truek, init='k-means++', maxiter=100, ninit=1) km.fit(X)
terms = vectorizer.getfeaturenames() originalspacecentroids = svd.inversetransform(km.clustercenters) ordercentroids = originalspacecentroids.argsort()[:, ::-1]
for i in range(truek): print(f"Cluster {i}:") for ind in ordercentroids[i, :10]: print(f" {terms[ind]}") ```
这段代码展示了如何训练K-means模型并输出每个聚类的关键词,这些关键词可以帮助我们理解每个聚类的特征。
层次聚类是一种将数据点逐步合并成更大群组的聚类方法。我们将使用Ward算法和SciPy库来实现层次聚类。以下是使用SciPy进行层次聚类的代码:
```python from scipy.cluster.hierarchy import ward, dendrogram import matplotlib.pyplot as plt
dist = 1 - cosine_similarity(X)
linkage_matrix = ward(dist)
plt.figure(figsize=(10, 15)) dendrogram(linkage_matrix, orientation="right") plt.show() ```
这段代码展示了如何通过Ward算法进行层次聚类,并通过树形图可视化聚类结果。
分类是一种有监督的学习任务,它通过已知类别的训练数据来预测未知样本的类别。我们将使用Naive Bayes和SVM两种分类器来演示文本分类的过程。以下是使用这两种分类器进行文本分类的代码片段:
```python from sklearn.naive_bayes import GaussianNB from sklearn.svm import SVC
gnb = GaussianNB() gnb.fit(X, labels)
svm = SVC() svm.fit(X, labels)
predictedgnb = gnb.predict(Xtest) predictedsvm = svm.predict(Xtest) ```
这段代码展示了如何使用Naive Bayes和SVM分类器进行文本分类,并预测未知文档的类别。
通过以上介绍,我们掌握了如何使用聚类和分类算法对文本数据进行分析。我们不仅学习了如何使用K-means和层次聚类进行聚类,还学习了如何使用Naive Bayes和SVM进行文本分类。此外,我们还探讨了如何使用scikit-learn工具来实现这些算法,并通过具体示例展示了这些方法的实际应用。未来,我们将继续探索更多高级技术和工具,以提升文本数据处理的能力。