【machine learning】KMeans算法(Python版)

一、概述

刚开始想要学习LDA主题模型的建模方法,学习的过程中发现应用到了EM算法,所以还是打算由浅及深地进行,发现EM算法虽然简单只有E步和M步的不断迭代,但其应用却很广泛,比较有名的有GMM算法和本博文要将的KMeans算法。作为数据挖掘十大经典算法之一,EM算法定义为:在统计中被用于寻找,依赖于不可观察的隐性变量的概率模型中,参数的最大似然估计。这在之后的博客中将有所体现。

建议学习顺序如下:EM->KMeans->GMM->EM->LDA

废话少说,进入正题。聚类是一种无监督的学习,它将相似的对象归到同一个簇中。它有点像全自动分类。聚类方法几乎可以应用于所有对象,簇内的对象越相似,聚类的效果越好。之所以称之为K-均值是因为它可以发现K个不同的簇,且每个簇的中心采用簇中所含值的均值计算而成。下面会逐步介绍该算法的更多细节。本博文代码参考书本Machine Learning in Action(《机器学习实战》)

聚类分析试图将相似对象归人同一簇,将不相似对象归到不同簇。相似这一概念取决于所选择的相似度计算方法。到底使用哪种相似度计算方法取决于具体应用。

二、KMeans算法理念

  • K-均值算法的工作流程是这样的
    首先,随机确定K个初始点作为质心。然后将数据集中的每个点分配到一个簇中,具体来讲,为每个点找距其最近的质心,并将其分配给该质心所对应的簇。这一步完成之后,每个簇的质心更新为该簇所有点的平均值。迭代的停止条件由相邻两次迭代结果中与质心的距离之差小于某个精度值。

  • K-均值聚类的一般流程
    (1)收集数据:使用任意方法。
    ⑵准备数据:需要数值型数据来计算距离,也可以将标称型数据映射为二值型数据再用于距离计算。
    (3)分析数据:使用任意方法。
    (4)训练算法:不适用于无监督学习,即无监督学习没有训练过程。
    (5)测试算法:应用聚类算法、观察结果。可以使用量化的误差指标如误差平方和(后面会介绍)来评价算法的结果。
    (6)使用算法:可以用于所希望的任何应用。通常情况下,簇质心可以代表整个簇的数据来做出决策。

  • 与EM算法的对照关系
    在EM算法中有一个流程是这样的:固定θ,调整Q(z)使下界J(z,Q)上升至与L(θ)在此点θ处相等,然后固定Q(z),调整θ使下界J(z,Q)达到最大值(θt到θt+1),然后再固定θ,调整Q(z)……直到收敛到似然函数L(θ)的最大值,最终获得θ。
    每一类质心的位置对应EM算法中的初始化分布参数θ
    数据点属于的类对应EM算法中的隐藏变量Q(Z)
    每个簇的质心更新为该簇所有点的平均值对应EM算法中使L(θ)的值最大的方法,即簇中数据总体属于该簇的可能性最大的θ取值
    现在只能通俗这么说,具体的L(θ)计算需要在二维展开,求导,之后判断θ取值为平均值能是L(θ)导数为零。简单的分析如下:
    这里写图片描述
    这里参考了博文
    相比之下,GMM更有概率分布的影子,所以与EM对照关系更清晰。

  • 伪代码

创建k个点作为起始质心(经常是随机选择)
当任意一个点的簇分配结果发生改变时
    对数据集中的每个数据点
       对每个质心
          计算质心与数据点之间的距离
       将数据点分配到距其最近的簇
    对每一个簇,计算簇中所有点的均值并将均值作为质心

三、常规KMeans程序分析

程序所需按照包:numpy,matplotlib(其实依赖pylab包等)

KMeans.py

#! /usr/bin/env python
#coding=utf-8
from numpy import *
import pylab

def loadDataSet(fileName):      #general function to parse tab -delimited floats
    dataMat = []                #assume last column is target value
    fr = open(fileName)
    for line in fr.readlines():
        curLine = line.strip().split('\t')
        fltLine = map(float,curLine) #map all elements to float()
        dataMat.append(fltLine)
    return dataMat

# 计算欧氏距离
def distEclud(vecA, vecB):
    return sqrt(sum(power(vecA - vecB, 2))) #la.norm(vecA-vecB)

# 根据dataSet产生k行数据,列数与dataSet一样,且每一列数据介于dataSet对应列最大值和最大值之间
def randCent(dataSet, k):
    n = shape(dataSet)[1]
    centroids = mat(zeros((k,n)))#create centroid mat
    for j in range(n):#create random cluster centers, within bounds of each dimension
        minJ = min(dataSet[:,j]) 
        rangeJ = float(
<think>我们正在处理一个关于使用Python实现KMeans聚类算法用于文本筛选的问题。文本数据通常需要先转换为数值向量(例如使用TF-IDF)才能进行聚类KMeans聚类可以将相似的文本聚集在一起,从而实现文本筛选的目的,例如将相似的文档分组,或者从大量文本中筛选出代表性文本。 步骤概述: 1. 文本预处理:清洗文本,去除停用词等。 2. 文本向量化:使用TF-IDF或词袋模型将文本转换为数值向量。 3. 应用KMeans聚类:选择合适的聚类数目,进行聚类。 4. 分析聚类结果:查看每个聚类的主题,或从每个聚类中选取代表性文本。 我们将使用sklearn库中的KMeans,以及TfidfVectorizer。 注意:由于文本数据通常维度很高,我们可能需要降维(如PCA)来可视化,但聚类本身可以直接在高维空间进行。 根据引用[2]和引用[3],我们可以获取每个聚类的样本点。引用[2]展示了如何获取每个类别的数据。 下面我们给出一个完整的示例,括数据预处理、向量化、聚类和结果提取。</think>### Python实现KMeans聚类算法用于文本筛选 KMeans聚类算法可有效处理文本数据,通过将相似文档分组实现文本筛选。以下是完整实现流程: #### 1. 文本预处理 ```python import re import nltk from nltk.corpus import stopwords from nltk.stem import PorterStemmer nltk.download('stopwords') def preprocess(text): # 小写化+去除非字母字符 text = re.sub(r'[^a-zA-Z]', ' ', text.lower()) # 移除停用词 stop_words = set(stopwords.words('english')) words = [word for word in text.split() if word not in stop_words] # 词干提取 stemmer = PorterStemmer() return ' '.join(stemmer.stem(word) for word in words) # 示例文本 documents = ["Machine learning is fascinating", "Python programming for data science", "Deep learning algorithms"] processed_docs = [preprocess(doc) for doc in documents] ``` #### 2. 文本向量化(TF-IDF) ```python from sklearn.feature_extraction.text import TfidfVectorizer vectorizer = TfidfVectorizer(max_features=1000) X = vectorizer.fit_transform(processed_docs) ``` #### 3. KMeans聚类实现 ```python from sklearn.cluster import KMeans # 确定最佳聚类数(肘部法则) wcss = [] for i in range(1, 11): kmeans = KMeans(n_clusters=i, init='k-means++', max_iter=300, random_state=42) kmeans.fit(X) wcss.append(kmeans.inertia_) # 根据肘部法则选择k值(此处假设k=3) k = 3 kmeans = KMeans(n_clusters=k, init='k-means++', max_iter=300, n_init=10) clusters = kmeans.fit_predict(X) ``` #### 4. 聚类结果分析 ```python import pandas as pd # 创建结果DataFrame result_df = pd.DataFrame({ 'Document': documents, 'Cluster': clusters, 'Processed': processed_docs }) # 获取每个聚类的文档 for cluster_id in range(k): cluster_docs = result_df[result_df['Cluster'] == cluster_id] print(f"\nCluster {cluster_id} ({len(cluster_docs)} documents):") print(cluster_docs['Document'].tolist()) ``` #### 5. 筛选特定聚类文档 ```python # 筛选特定聚类(例如聚类0) target_cluster = 0 filtered_docs = result_df[result_df['Cluster'] == target_cluster]['Document'].tolist() print("\n筛选结果(聚类0):") for doc in filtered_docs: print(f"- {doc}") ``` #### 6. 可视化(可选) ```python from sklearn.decomposition import PCA import matplotlib.pyplot as plt # 降维可视化 pca = PCA(n_components=2) scatter_plot_points = pca.fit_transform(X.toarray()) plt.scatter(scatter_plot_points[:,0], scatter_plot_points[:,1], c=clusters, cmap='viridis', s=50) plt.title('文本聚类可视化') plt.show() ``` ### 关键应用场景 1. **主题发现**:自动识别文档集合中的主要主题 2. **异常检测**:识别不属于任何主要聚类的离群文档 3. **文档分类**:自动组织大量文本文档 4. **信息检索**:提升搜索结果的相关性 5. **内容推荐**:基于相似内容推荐文档 ### 性能优化建议 1. 使用`MiniBatchKMeans`处理大规模文本数据 2. 调整TF-IDF参数(`max_df`, `min_df`) 3. 尝试不同文本表示方法(如Word2Vec) 4. 使用轮廓系数验证聚类质量: ```python from sklearn.metrics import silhouette_score score = silhouette_score(X, clusters) ``` ### 注意事项 - 预处理阶段对最终结果影响显著 - 高维文本数据可能需要降维处理 - 聚类数量$k$的选择需要结合领域知识 - 文本长度差异大时考虑归一化处理 通过调整聚类数量$k$和文本预处理参数,可针对特定文本筛选需求优化结果[^1][^2]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值