K-Means是常用的聚类算法,与其他聚类算法相比,其时间复杂度低,聚类的效果也还不错,这里简单介绍一下k-means算法,下图是一个手写体数据集聚类的结果。
基本思想
k-means算法需要事先指定簇的个数k,算法开始随机选择k个记录点作为中心点,然后遍历整个数据集的各条记录,将每条记录归到离它最近的中心点所在的簇中,之后以各个簇的记录的均值中心点取代之前的中心点,然后不断迭代,直到收敛,算法描述如下:
上面说的收敛,可以看出两方面,一是每条记录所归属的簇不再变化,二是优化目标变化不大。算法的时间复杂度是O(K*N*T),k是中心点个数,N数据集的大小,T是迭代次数。
优化目标
k-means的损失函数是平方误差:
RSSk=∑x∈ωk|x?u(ωk)|2
RSS=∑k=1KRSSk
其中$\omega _k$表示第k个簇,$u(\omega _k)$表示第k个簇的中心点,$RSS_k$是第k个簇的损失函数,$RSS$表示整体的损失函数。优化目标就是选择恰当的记录归属方案,使得整体的损失函数最小。
中心点的选择
k-meams算法的能够保证收敛,但不能保证收敛于全局最优点,当初始中心点选取不好时,只能达到局部最优点,整个聚类的效果也会比较差。可以采用以下方法:k-means中心点
1、选择彼此距离尽可能远的那些点作为中心点;
2、先采用层次进行初步聚类输出k个簇,以簇的中心点的作为k-means的中心点的输入。
3、多次随机选择中心点训练k-means,选择效果最好的聚类结果
k值的选取
k-means的误差函数有一个很大缺陷,就是随着簇的个数增加,误差函数趋近于0,最极端的情况是每个记录各为一个单独的簇,此时数据记录的误差为0,但是这样聚类结果并不是我们想要的,可以引入结构风险对模型的复杂度进行惩罚:
K=mink[RSSmin(k)+λk]
$\lambda$是平衡训练误差与簇的个数的参数,但是现在的问题又变成了如何选取$\lambda$了,有研究[参考文献1]指出,在数据集满足高斯分布时,$\lambda=2m$,其中m是向量的维度。
另一种方法是按递增的顺序尝试不同的k值,同时画出其对应的误差值,通过寻求拐点来找到一个较好的k值,详情见下面的文本聚类的例子。
k-means文本聚类
我爬取了36KR的部分文章,共1456篇,分词后使用sklearn进行k-means聚类。分词后数据记录如下:
使用TF-IDF进行特征词的选取,下图是中心点的个数从3到80对应的误差值的曲线:
从上图中在k=10处出现一个较明显的拐点,因此选择k=10作为中心点的个数,下面是10个簇的数据集的个数。
{0: 152, 1: 239, 2: 142, 3: 61, 4: 119, 5: 44, 6: 71, 7: 394, 8: 141, 9: 93}
簇标签生成
聚类完成后,我们需要一些标签来描述簇,聚类完后,相当于每个类都用一个类标,这时候可以用TFIDF、互信息、卡方等方法来选取特征词作为标签。关于卡方和互信息特征提取可以看我之前的文章文本特征选择,下面是10个类的tfidf标签结果。
Cluster 0: 商家 商品 物流 品牌 支付 导购 网站 购物 平台 订单
Cluster 1: 投资 融资 美元 公司 资本 市场 获得 国内 中国 去年
Cluster 2: 手机 智能 硬件 设备 电视 运动 数据 功能 健康 使用
Cluster 3: 数据 平台 市场 学生 app 移动 信息 公司 医生 教育
Cluster 4: 企业 招聘 人才 平台 公司 it 移动 网站 安全 信息
Cluster 5: 社交 好友 交友 宠物 功能 活动 朋友 基于 分享 游戏
Cluster 6: 记账 理财 贷款 银行 金融 p2p 投资 互联网 基金 公司
Cluster 7: 任务 协作 企业 销售 沟通 工作 项目 管理 工具 成员
Cluster 8: 旅行 旅游 酒店 预订 信息 城市 投资 开放 app 需求
Cluster 9: 视频 内容 游戏 音乐 图片 照片 广告 阅读 分享 功能
实现代码
#!--encoding=utf-8
from __future__ import print_function
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.feature_extraction.text import HashingVectorizer
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans, MiniBatchKMeans
def loadDataset():
'''导入文本数据集'''
f = open('36krout.txt','r')
dataset = []
lastPage = None
for line in f.readlines():
if '< title >' in line and '< / title >' in line:
if lastPage:
dataset.append(lastPage)
lastPage = line
else:
lastPage += line
if lastPage:
dataset.append(lastPage)
f.close()
return dataset
def transform(dataset,n_features=1000):
vectorizer = TfidfVectorizer(max_df=0.5, max_features=n_features, min_df=2,use_idf=True)
X = vectorizer.fit_transform(dataset)
return X,vectorizer
def train(X,vectorizer,true_k=10,minibatch = False,showLable = False):
#使用采样数据还是原始数据训练k-means,
if minibatch:
km = MiniBatchKMeans(n_clusters=true_k, init='k-means++', n_init=1,
init_size=1000, batch_size=1000, verbose=False)
else:
km = KMeans(n_clusters=true_k, init='k-means++', max_iter=300, n_init=1,
verbose=False)
km.fit(X)
if showLable:
print("Top terms per cluster:")
order_centroids = km.cluster_centers_.argsort()[:, ::-1]
terms = vectorizer.get_feature_names()
print (vectorizer.get_stop_words())
for i in range(true_k):
print("Cluster %d:" % i, end='')
for ind in order_centroids[i, :10]:
print(' %s' % terms[ind], end='')
print()
result = list(km.predict(X))
print ('Cluster distribution:')
print (dict([(i, result.count(i)) for i in result]))
return -km.score(X)
def test():
'''测试选择最优参数'''
dataset = loadDataset()
print("%d documents" % len(dataset))
X,vectorizer = transform(dataset,n_features=500)
true_ks = []
scores = []
for i in xrange(3,80,1):
score = train(X,vectorizer,true_k=i)/len(dataset)
print (i,score)
true_ks.append(i)
scores.append(score)
plt.figure(figsize=(8,4))
plt.plot(true_ks,scores,label="error",color="red",linewidth=1)
plt.xlabel("n_features")
plt.ylabel("error")
plt.legend()
plt.show()
def out():
'''在最优参数下输出聚类结果'''
dataset = loadDataset()
X,vectorizer = transform(dataset,n_features=500)
score = train(X,vectorizer,true_k=10,showLable=True)/len(dataset)
print (score)
#test()
out()
B. 已计算出个文本间的余弦相似度值,怎么用kmeans聚类
K-MEANS算法: k-means 算法接受输入量 k ;然后将n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较校聚类相似度是利用各聚类中对象的均值所获得一个“中心对象
C. k-means聚类算法的java代码实现文本聚类
K-MEANS算法:
k-means 算法接受输入量 k ;然后将n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。聚类相似度是利用各聚类中对象的均值所获得一个“中心对象”(引力中心)来进行计算的。
k-means 算法的工作过程说明如下:首先从n个数据对象任意选择 k 个对象作为初始聚类中心;而对于所剩下其它对象,则根据它们与这些聚类中心的相似度(距离),分别将它们分配给与其最相似的(聚类中心所代表的)聚类;然后再计算每个所获新聚类的聚类中心(该聚类中所有对象的均值);不断重复这一过程直到标准测度函数开始收敛为止。一般都采用均方差作为标准测度函数. k个聚类具有以下特点:各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。
具体如下:
输入:k, data[n];
(1) 选择k个初始中心点,例如c[0]=data[0],…c[k-1]=data[k-1];
(2) 对于data[0]….data[n], 分别与c[0]…c[n-1]比较,假定与c[i]差值最少,就标记为i;
(3) 对于所有标记为i点,重新计算c[i]=/标记为i的个数;
(4) 重复(2)(3),直到所有c[i]值的变化小于给定阈值。
算法实现起来应该很容易,就不帮你编写代码了。
D. kmeans聚类算法是什么
kmeans聚类算法是将样本聚类成k个簇(cluster)。
K-Means算法的思想很简单,对于给定的样本集,按照样本之间的距离大小,将样本集划分为K个簇。让簇内的点尽量紧密的连在一起,而让簇间的距离尽量的大。在实际K-Mean算法中,我们一般会多次运行图c和图d,才能达到最终的比较优的类别。
用数据表达式表示
假设簇划分为$(C_1,C_2,...C_k)$,则我们的目标是最小化平方误差E:$$ E = sumlimits_{i=1}^ksumlimits_{x in C_i} ||x-mu_i||_2^2$$。
其中$mu_i$是簇$C_i$的均值向量,有时也称为质心,表达式为:$$mu_i = frac{1}{|C_i|}sumlimits_{x in C_i}x$$。
E. k-means 聚类算法处理什么类型数据
这个问题其实是无解的,数据不同,算法的分类效果、实际运行时间也是不同。若单从运算速度而言,k-means比层次更快。原因是K-means是找中心,然后计算距离;层次是逐个样本逐层合并,层次的算法复杂度更高。更重要的是,在大数量下,K-means算法和层次聚类算法的分类效果真的只能用见仁见智来形容了。
F. 对比传统K-Means等聚类算法,LDA主题模型在文本聚类上有何优缺点
K-means 算法属于聚类分析方法中一种基本的且应用最广泛的划分算法,它是一种已知聚类类别数的聚类算法。指定类别数为K,对样本集合进行聚类,聚类的结果由K 个聚类中心来表达,基于给定的聚类目标函数(或者说是聚类效果判别准则),算法采用迭代更新的方法,每一次迭代过程都是向目标函数值减小的方向进行,最终的聚类结果使目标函数值取得极小值,达到较优的聚类效果。使用平均误差准则函数E作为聚类结果好坏的衡量标准之一,保证了算法运行结果的可靠性和有效性。
-
G. kmeans聚类算法是什么
K-means算法是最为经典的基于划分的聚类方法,是十大经典数据挖掘算法之一。K-means算法的基本思想是:以空间中k个点为中心进行聚类,对最靠近他们的对象归类。通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果。
聚类属于无监督学习,以往的回归、朴素贝叶斯、SVM等都是有类别标签y的,也就是说样例中已经给出了样例的分类。而聚类的样本中却没有给定y,只有特征x,比如假设宇宙中的星星可以表示成三维空间中的点集。
(7)文本聚类算法kmeans扩展阅读:
k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。聚类相似度是利用各聚类中对象的均值所获得一个“中心对象”(引力中心)来进行计算的。
(1)适当选择c个类的初始中心;
(2)在第k次迭代中,对任意一个样本,求其到c个中心的距离,将该样本归到距离最短的中心所在的类;
(3)利用均值等方法更新该类的中心值;
(4)对于所有的c个聚类中心,如果利用(2)(3)的迭代法更新后,值保持不变,则迭代结束,否则继续迭代。
H. k-means算法是聚类算法还是分类算法
一,k-means聚类算法原理
k-means
算法接受参数
k
;然后将事先输入的n个数据对象划分为
k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小.聚类相似度是利用各聚类中对象的均值所获得一个“中心对
象”(引力中心)来进行计算的.
k-means算法是最为经典的基于划分的聚类方法,是十大经典数据挖掘算法之一.k-means算法的基本思想是:以空间中k个点为中心进行聚类,对最靠近他们的对象归类.通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果.
假设要把样本集分为c个类别,算法描述如下:
(1)适当选择c个类的初始中心;
(2)在第k次迭代中,对任意一个样本,求其到c个中心的距离,将该样本归到距离最短的中心所在的类;
(3)利用均值等方法更新该类的中心值;
(4)对于所有的c个聚类中心,如果利用(2)(3)的迭代法更新后,值保持不变,则迭代结束,否则继续迭代.
该算法的最大优势在于简洁和快速.算法的关键在于初始中心的选择和距离公式.
I. 文本聚类 一个文本的中心怎么表示
最简单的来说文本聚类就是从很多文档中把一些 内容相似的文档聚为一类。文本聚类主要是依据着名的聚类假设:同类的文本相似度较大,而不同类的文本相似度较小。作
为一种无监督的机器学习方法,聚
类由于不需要训练过程,以及不需要预先对文本手工标注类别,因此具有一定的灵活性和较高的自动化处理能力,已经成为对文本信息进行有效地组织、摘要和导航
的重要手段,为越来越多的研究人员所关注。一个文本表现为一个由文字和标点符号组成的字符串,由字或字符组成词,由词组成短语,进而形成句、段、节、章、
篇的结构。要使计算机能够高效地处理真是文本,就必须找到一种理想的形式化表示方法,这种表示一方面要能够真实地反应文档的内容(主题、领域或结构等),
另一方面,要有对不同文档的区分能力。目前文本表示通常采用向量空间模型(vector space model,VSM)。
VSM法即向量空间模型
(Vector Space
Model)法,由Salton等人于60年代末提出。这是最早也是最出名的信息检索方面的数学模型。其基本思想是将文档表示为加权的特征向
量:D=D(T1,W1;T2,W2;…;Tn,Wn),然后通过计算文本相似度的方法来确定待分样本的类别。当文本被表示为空间向量模型的时候,文本的
相似度就可以借助特征向量之间的内积来表示。最简单来说一个文档可以看成是由若干个单词组成的,每个单词转化成权值以后,
每个权值可以看成向量中的一个分量,那么一个文档可以看成是n维空间中的一个向量,这就是向量空间模型的由来。单词对应的权值可以通过TF-IDF加权技 术计算出来。
TF-IDF(term frequency–inverse document frequency)是一种用于资讯检索与文本挖掘的常用加权技术。TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的
其中一份文件的重要程
度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。TF-IDF加权的各种形式
常被搜索引擎应用,作为文件与用户查询之间相关程度
的度量或评级。除了TF-IDF以外,互联网上的搜寻引擎还会使用基于连结分析的评级方法,以确定文件在搜寻结果中出现的顺序。
原理:
以上式子中 ni,j 是该词在文件dj中的出现次 数,而分母则是在文件dj中所 有字词的出现次数之和。
逆向文件频率(inverse document frequency,IDF)是一个词语普遍重要性的度量。某一特定词语的IDF,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取对数得到:
其中
|D|:语料库中的文件总数
: 包含词语ti的文件数目(即的
文件数目)
然后
某一特定文件内的高词语频率,以及该词语在整个文件集合中的低文件频率,可以产生出高权重的TF-IDF。因此,TF-IDF倾向于过滤掉常见的词 语,保留重要的词语。
例子
有很多不同的数学公式可以用来计
算TF-IDF。这边的例子以上述的数学公式来计算。词频
(TF)
是一词语出现的次数除以该文件的总词语数。假如一篇文件的总词语数是100个,而词语“母牛”出现了3次,那么“母牛”一词在该文件中的词频就是
0.03 (3/100)。一个计算文件频率 (DF)
的方法是测定有多少份文件出现过“母牛”一词,然后除以文件集里包含的文件总数。所以,如果“母牛”一词在1,000份文件出现过,而文件总数是
10,000,000份的话,其逆向文件频率就是
9.21 ( ln(10,000,000 / 1,000) )。最后的TF-IDF的分数为0.28( 0.03 * 9.21)。
TF-IDF权重计算方法经常会和余
弦相似度(cosine similarity)一同使用于向 量空间模型中,用以判断两份文件之间的相
似性。学过向量代数的人都知道,向量实际上是多维空间中有方向的线段。如果两个向量的方向一致,即夹角接近零,那么这两个向量就相近。而要确定两 个向量方向是否一致,这就要用到余弦定理计算向量的夹角了。
余弦定理对我们每个人都不陌生,它描述了三角形中任何一个夹角和三个边的关系,换句话说,给定三角形的三条边,我们可以用余弦定理求出三角形各个角的角 度。假定三角形的三条边为 a, b 和 c,对应的三个角为 A, B 和 C,那么角 A 的余弦 --
如果我们将三角形的两边 b 和 c 看成是两个向量,那么上述公式等价于
其中分母表示两个向量 b 和 c 的长度,分子表示两个向量的内积。举一个具体的例子,假如文本 X 和文本 Y 对应向量分别是
x1,x2,...,x64000 和
y1,y2,...,y64000,
那么它们夹角的余弦等于,
当两条文本向量夹角的余弦等于一时,这两个文本完全重复(用这个办法可以删除重复的网页);当夹角的余弦接近于一时,两个文本相似,从而可以归成一类;夹 角的余弦越小,两个文本越不相关。
我们在中学学习余弦定理时,恐怕很难想象它可以用来对文本进行分类。
最后我们在对文本进行聚类时要用到数据挖掘中的Kmeans算法,聚类算法有很多种,这篇文章主要介绍Kmeans算法。K-MEANS算法:
k-means 算法接受输入量 k ;然后将n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。聚类相似度是利用各聚类中对象的均值所获得一个“中心对 象”(引力中心)来进行计算的。
k-means 算法的工作过程说明如下:
首先从n个 数据对象任意选择 k
个对象作为初始聚类中心;而对于所剩下其它对象,则根据它们与这些聚类中心的相似度(距离),分别将它们分配给与其最相似的(聚类中心所代表的)聚类;然
后再计算每个所获新聚类的聚类中心(该聚类中所有对象的均值);不断重复这一过程直到标准测度函数开始收敛为止。一般都采用均方差作为标准测度函数.
k个聚类具有以下特点:各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。
处理流程:
( 1 ) 从 c 个 数据对象任意选择 k 个
对象作为初始聚类中心;
( 2 ) 循 环( 3 ) 到( 4 )
直到每个聚类不再发生变化为止;
( 3 ) 根 据每个聚类对象的均值(中心对象),计算每个对象与这些中心对象的距离;并根据最小距离重新对相应对象进行划分;
( 4 ) 重 新计算每个(有变化)聚类的均值(中心对象)
到这里这个文本聚类的小程序的核心思想就讲完了,总的来说大致步骤如 下:
(1)对各个文本分词,去除停用词
(2)通过TF-IDF方法获得文本向量的权值(每个文本向量的维数是 相同的,是所有文本单词的数目,这些单词如果有重复那只算一次,所以如果文本越多,向量的维数将会越大)
(3)通过K-means算法对文本进行分类
本人的文本小程序的结 果还算令人满意,对下面的实验用例的聚类结果还算是理想,但是每次执行的结果都不一样。其实聚类的结果受好多种因素制约,提取特征的算法,随机初始化函 数,kmeans算法的实现等,都有优化的地方,不信你把输入的数据的顺序改改,聚类结果就不一样了,或者把随机数的种子变一下,结果也不一样,k-
means算法加入一些变异系数的调整,结果也不一样,提取特征的地方不用TF/IDF权重算法用别的,结果肯定也不一样。
实验用例:
奥运拳击入场券基本分罄邹市明夺冠对手浮出水面
股民要清楚自己的目的
印花税之股民四季
杭州股民放鞭炮庆祝印花税下调
残疾女青年入围奥运游泳比赛创奥运历史两项第一
介绍一个ASP.netMVC系列教程
在asp.net中实现观察者模式,或有更好的方法(续)
输大钱的股民给我们启迪
Asp.Net页面执行流程分析
运动员行李将"后上先下"奥运相关人员行李实名制
asp.net控件开发显示控件内容
奥运票务网上成功订票后应及时到银行代售网点付款
某心理健康站开张后首个咨询者是位新股民
ASP.NET自定义控件复杂属性声明持久性浅析
以下是我在网上参考的资料:
http://www.cnblogs.com/onlytiancai/archive/2008/05/10/1191557.html
http://hi..com/zhumzhu/blog/item/fc49ef3d19b0a4c09f3d62a3.html