NLP--基于聚类的方法,对影评文本分类,并对几种聚类方法进行比较,以及与分类的方法的效果进行比较。

【方法原理】

Sklearn的cluster提供了kmeans,Agglomerative(层级聚类中的聚合方法,另一个是分裂)和DBSCAN聚类函数(属密度聚类)。

 KMeans均值算法表示以空间中k个点为中心进行聚类,对靠近的点归类。
1、从数据集(或者数据空间范围内)D中随机取k(预先人为设定)个元素,作为k个类的各自的初始中心。
2、分别计算剩下的元素到k个类中心的距离,依据距离大小,将这些元素分别划归到距离最近的类中。
3、根据聚类结果,重新计算k个类各自的中心。计算方法一般是取类中所有元素各自维度的算术平均数。
 DBSCAN的核心思想是:密度较高的点(不是距离相近的点)连成一片,进而生成同一个类。
算法实现:
1、对每个数据点,做以eps(预先设定)为半径的圆,如果圆内的点数多于阈值MinPts(预先设定),则称该点为核心点或者高密度点。把圈内的所有点连接起来,形成一个链路。链路上所有点即为一个类。
2、如果圈内点数少于MinPts,则称为低密度的点,或者离群点,异常点。
 层次聚类(Hierarchical Clustering)是一种聚类算法,通过计算不同类别数据点间的相似度来创建一棵有层次的嵌套聚类树。在聚类树中,不同类别的原始数据点是树的最低层,树的顶层是一个聚类的根节点。

聚类效果评估:
1)兰德指数
表达的是从两个集合中随机选择一对元素,是相同的概率。
ARI值的范围是[-1,1],负的结果都是较差的,说明标签是独立分布的,相似分布的ARI结果是正的,1是最佳结果,说明两种标签的分布完全一致;
随机均匀的标签分布的ARI值接近0;
2)轮廓系数
样本i的轮廓系数根据样本i的簇内不相似度a (i) 和簇间不相似度b(i)定义。
核心思想是判断:类间距离与类内距离的相对大小,如果类间距离>类内距离,则说明聚类结果好,反之,则不好。
s(i)接近1,则说明样本i聚类合理;接近-1,则说明样本i该分类到另外的簇;近似0,则说明在两个簇的边界上

【结果】

在这里插入图片描述

【代码】

import nltk
from nltk.corpus import movie_reviews
from pylab import plot,show
from numpy import array
from numpy.random import rand
from scipy.cluster.vq import kmeans,vq,whiten
import numpy as np
import random

documents = [(list(movie_reviews.words(fileid)), category) for category in movie_reviews.categories() for fileid in movie_reviews.fileids(category)]  #转化为词列表的影评,与标签,组成二元组
random.shuffle(documents)	

all_words = nltk.FreqDist(w.lower() for w in movie_reviews.words())	 #建立全部影评的词频表
all_words=all_words.most_common(2000)			#词频表按频率排序
stopwords = nltk.corpus.stopwords.words('english')
word_features  =[w for (w,f) in all_words if w not in stopwords] 		#特征词为词频表中前2000词

features = np.zeros([len(documents),len(word_features)],dtype=float)
#np.zeros((数组形状),dtype,older)--返回一个给定形状和类型的用0填充的数组
#(形状:(5,)(5,5);older: C表示行优先,F表示列优先(可选参数))
for n in range(len(documents)):
        document_words = set(documents[n][0])
        for  m in range(len(word_features)):
                if word_features[m] in document_words:
                        features[n,m] = 1

target=[c for (d,c) in documents]

'''Kmeans聚类'''
##1)Kmeans的Scipy实现
data=whiten(features)
#Whiten:通过除以标准差,归一化各维度的变化尺度。在Kmeans算法实施前做为预处理,使每个特征的作用相同。处理后的向量变为‘白噪声’。
centroids,_ = kmeans(data,2)
idx,_ = vq(data,centroids)

target1=[1 if x =='pos' else 0 for x in target]
a=sum(target1==idx)/len(target1)
print('scipy_eu=',max(a,1-a))

##2)Kmeans的NLTK实现。NLTK,Bio都可以选择距离函数
from nltk.cluster import KMeansClusterer,cosine_distance
clus=KMeansClusterer(2,cosine_distance)#分为两类,距离函数用余弦相似度
results=clus.cluster(data,True,trace=False)


##3)Kmeans的Bio实现
#from Bio.Cluster import kcluster
#clusterid, error, nfound = kcluster(data,2,dist='c')

'''层级聚类(聚合Agglomerative)'''
import scipy
from scipy.cluster.hierarchy import linkage,fcluster
agg=linkage(data,method='single',metric='euclidean')
#获取集群信息
max_d=50#选择临界距离决定集群数量(应该画图看出吧)
clusters=fcluster(agg, max_d, criterion='distance')
#print(clusters)

'''密度聚类(DBSCAN)'''
from sklearn.cluster import DBSCAN
#eps为距离阈值ϵ,min_samples为邻域样本数阈值MinPts,X为数据
y_pred = DBSCAN(eps = 50, min_samples = 3,metric='euclidean').fit(data)
labels=y_pred.labels_       #聚类标签
print(labels[:100])

##聚类效果评估
print("兰德指数ARI:")
from sklearn import metrics 
print("Kmeans_ARI:%s"%metrics.adjusted_rand_score(np.array(target1),results))
print("Agglomerative_ARI:%s"%metrics.adjusted_rand_score(np.array(target1),clusters))
print("DBSCAN_ARI:%s"%metrics.adjusted_rand_score(np.array(target1),labels))

print("轮廓系数:")
from sklearn.metrics import silhouette_score
print("1)使用欧式距离:")
sc_score = silhouette_score(data, results, metric='euclidean')
print("Kmeans:",sc_score)
sc_score = silhouette_score(data, clusters, metric='euclidean')
print("Agglomerative:",sc_score)
sc_score = silhouette_score(data, labels, metric='euclidean')
print("DBSCAN:",sc_score)
print("2)使用余弦距离:")
sc_score = silhouette_score(data, results, metric='cosine')
print("Kmeans:",sc_score)
sc_score = silhouette_score(data, clusters, metric='cosine')
print("Agglomerative:",sc_score)
sc_score = silhouette_score(data, labels, metric='cosine')
print("DBSCAN:",sc_score)
  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值