大数据量下文本聚类的最佳选择---“降维+MiniBatchKeans”

接上前面的工作,对分词后的文本数据聚类。
面临的问题:17万多的数据转化为词向量,使用的是tf-idf方法,得到的向量维度是(174021,128021)。聚200个类花费时间为18个小时。
解决方案:
1、通过统计发现17万多文章中有90%+的词汇仅在0.1%的文章中出现过,然而这样的词汇因为过于生僻是没有意义的;因而对TfidfVectorizer函数中的min_df参数进行限定,保留出现频率大于0.1%小于90%的词汇,作为文本向量化表示的内容,得到1740211251维度大小的矩阵;
2、对矩阵进行降维,综合其它变量,将维度降到100,得到174021
100的矩阵。此时降维后的文本向量可表达原文本特征的59%;
3、对文本向量进行MiniBatchKmeans聚类,Mini Batch是原始数据集中的子集,这个子集是在每次训练迭代时抽取的样本。
算法步骤为:
在这里插入图片描述
经多方调整,每次输入模型的数据量为20480(但是我感觉2048和20480的差别不大)
4、最后调整聚类的类别数,可通过两个指标的变化情况:
(1)SSE(绘制SSE的变化曲线,拐点即为最佳类别数;计算原则是同一簇内的点尽可能紧密);
(2)轮廓系数(越接近于1越好;计算原则是同一个簇尽可能紧密,不同簇尽可能远离同一个簇尽可能紧密,不同簇尽可能远离)。
(**但是很奇怪的是不知道我的为啥他俩是反过来的,哭唧唧)
在这里插入图片描述
在这里插入图片描述


以下是计算代码:

from sklearn.pipeline import  make_pipeline
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.decomposition import TruncatedSVD
from sklearn.preprocessing import Normalizer
from sklearn.cluster import MiniBatchKMeans,KMeans
from sklearn import metrics
import matplotlib.pyplot as plt
import numpy as np
import codecs
import csv
from collections import Counter

##-------------第一步:读取数据-------------------
file=open(u'/Users/sunmengge/Desktop/scopus_content/scopus_fenci/fenci.csv','rb')
#file=open('data/jour data test 99.txt','rb')
file_cont=file.readlines()
corpus=[]
corpus1 = []
for text in file_cont:
    words=text.decode().strip().split('|')
    corpus.append(' '.join(words))
    for word in list(set(words)):
        corpus1.append(word)
print(corpus1)
counter1 = Counter(corpus1)
print(counter1)
dic = dict(counter1)

##----------第二步:文本向量化----------------------
vector_tfidf = TfidfVectorizer(max_df=0.7,min_df=0.01)##0.8表示某词汇在80%的文档中均出现过 这样的词汇没意义不要;0.2表示在低于20%的文档中出现过的词汇 太生僻也不要
##通过统计发现 大部分的词汇仅在0.1%-1%的文档中出现过 这种情况下维度为174021,1251,降维到500时可解释率为74.8%
tfidf = vector_tfidf.fit_transform(corpus)
print(tfidf.shape)##显示维度为(174021,128021)

##---------第三步:SVD(pca)降维及正则化处理---------
svd = TruncatedSVD(100)
normalizer = Normalizer(copy=False)
lsa = make_pipeline(svd,normalizer)
tfidf_lsa = lsa.fit_transform(tfidf)
explained_variance = svd.explained_variance_ratio_.sum()##降维后对原数据的方差贡献率,维度为1000时可解释率为55.13%
print(explained_variance)
print(tfidf_lsa.shape)##显示维度为(174021,100)

##---------第四步:文本聚类 得到每一类别的中心点及每条数据的标签-------------------------
#实例化
num_cluster = 600
minikm_tfidf_lsa = MiniBatchKMeans(n_clusters=num_cluster, init='k-means++',init_size=1024, batch_size=20480).fit(tfidf_lsa)
label = minikm_tfidf_lsa.labels_
centroid = minikm_tfidf_lsa.cluster_centers_
minikm_tfidf_lsa.fit_predict(tfidf_lsa)  # 输出的结果就是,每篇文章被分配的类别
np.savetxt(u'/Users/sunmengge/Desktop/scopus_content/aero_conf_cluster_center_600.txt', minikm_tfidf_lsa.cluster_centers_) #输出各个聚类簇的质心
num_clusters = []
cluster = minikm_tfidf_lsa.labels_.tolist()  # 按照文章顺序,输出每篇文章的label,并存储到列表中[2,5,1,6,3,4]
print(len(cluster))
result = codecs.open(u'/Users/sunmengge/Desktop/scopus_content/aero_conf_cluster_label_600.txt', 'w')
for label in cluster:
    result.write(str(label) + '\n')
result.close()


##--------第五步:输出模型的效果----------------------
res = minikm_tfidf_lsa.fit_predict(tfidf_lsa)
print(metrics.silhouette_score(tfidf_lsa,label,metric = 'euclidean'))

##------第六步:所有类别中前20个关键词及词频展示----------------------------
print("Top terms per cluster:")
original_space_centroids = svd.inverse_transform(minikm_tfidf_lsa.cluster_centers_)
order_centroids = original_space_centroids.argsort()[:, ::-1]

terms = vector_tfidf.get_feature_names()
print(order_centroids)
print(terms)
res = open("re2.csv", "w", encoding='utf-8', newline='')
writer = csv.writer(res)

for i in range(num_cluster):
    temp = []
    print("Cluster %d:" % i, end='')
    temp.append(i)
    for ind in order_centroids[i, :20]:
        # print(ind)
        print(' %s' % terms[ind], end='')
        count = 0
        for i,v in dic.items():
            if i ==str(terms[ind]):
                count = v
        print(count)
        temp.append((terms[ind],count))
    writer.writerow(temp)
    print()

##------第七步:绘制SSE曲线,判定最佳类别数---------------
def find_optimal_clusters(max_k):
    iters = range(200,max_k+50,50)
    sse = []
    for k in iters:
        print(k)
        minikm_tfidf_lsa = MiniBatchKMeans(n_clusters=k, init="k-means++",init_size=1024,batch_size=20480,random_state=42)\
            .fit(tfidf_lsa)
        sse.append(minikm_tfidf_lsa.inertia_)
        print(sse)
        label = minikm_tfidf_lsa.labels_
        print(metrics.silhouette_score(tfidf_lsa, label, metric='euclidean'))
    f,ax = plt.subplots(1,1)
    ax.plot(iters,sse,marker = 'o')
    ax.set_xticks(iters)
    ax.set_title('sse by cluster center plot')
find_optimal_clusters(1000)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值