【注】本文演示怎样用python编程实现k-means聚类。如果想直接使用聚类功能,请使用集搜客数据管家软件,已经集成了聚类功能。使用方法参看《文本聚类分析软件的安装和使用方法》 1 背景介绍 1.1 实验目的 上个月发布了《社交媒体话题文本分词后用sklearn的kmeans算法做聚类分析》,我们将采集得到的知乎二舅话题的excel,导入到Gooseeker文本分词和情感分析软件,经自动分词后,导出“分词效果表”excel。基于自动分词的“分词效果表”,我们在python下使用sklearn库进行k-means聚类实验,并做了两个实验: - 实验1. 人工直接设置K值为3进行实验
- 实验2. 使用“手肘法”人工观察拐点,取K值为7。
下图就是基于“手肘法”观察拐点并确定K值后的输出图:
在那个notebook里,我们总结指出:可视化输出的图看起来稍显杂乱,可能是数据样本本身不适合聚类,也可能是聚类算法选择不合适或者参数设置不合适,或者文档向量降维算法选择不合适等等,需要多次实验,改变设置,找到比较好的处理效果。 基于原始文本自动分词得到的结果,词的数量很大,很多词没有分析价值,除了增加处理的难度,而且会干扰分析结果的合理性,所以,通常我们要进行特征选择,可以手工选择,也可以自动选择。 今天的实验,我们使用同样的知乎二舅话题的excel,导入到Gooseeker文本分词和情感分析软件,自动分词后,进行人工选词(而不使用sklearn的自动特征选择算法),然后导出“选词匹配表”excel,对其用sklearn进行聚类分析。 手工选词的时候,可以只选名词,或者只选动词,或者选其他词性,可以分别探索和观察一下分析结果的不同。 本notebook实验内容: - 使用GooSeeker文本分词和情感分析软件将文本进行分词并进行人工选词,导出选词匹配数据表。人工拣选的词我们称为“打标词”。在excel表的“打标词”这一列,词与词之间使用逗号加空格作为分隔符。
- (不再使用用sklearn的特征工程函数对选词结果进行特征选择,所以,删掉本步骤)
- 基于手工选的特征词进行聚类分析
- 为了在二维空间可视化,利用sklearn的降维算法,将被分析数据的维度降到2维,在二维空间展示聚类结果
1.2 实验数据来源 使用知乎_独立话题动态内容采集这个快捷采集,爬取知乎上关于二舅话题的讨论,导出excel。 1.3 实验数据预处理:中文文本分词和选词 将采集得到的知乎二舅话题的excel,导入到Gooseeker文本分词和情感分析软件,经自动分词并人工选词后,导出“选词匹配表”excel。
1.4 本notebook使用方法 基本操作顺序是: - 在GooSeeker分词和文本分析软件上创建分析任务并导入包含原始内容的excel
- 在自动分词完成后进行人工选词,然后导出选词匹配表
- 将导出的选词匹配表放在本notebook的data/raw文件夹中
- 从头到尾执行本notebook的单元
注意:每个notebook项目目录都预先规划好了,具体参看Jupyter Notebook项目目录规划参考。如果要做多个分析项目,把整个模板目录专门拷贝一份给每个分析项目。 2 第三方库 本notebook使用了sklearn库做k-means算法实验。 如果未安装,请先使用下面的命令安装sklearnm库,再运行实验本notebook: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple sklearn #国内安装使用清华的源,速度快
3 准备程序环境 导入必要的Python程序包,设定要分析的文件名变量。在这一系列notebook中,我们都使用以下变量对应GooSeeker分词结果表: - file_word_freq:词频表
- file_seg_effect: 分词效果表
- file_word_choice_matrix: 选词矩阵表
- file_word_choice_match: 选词匹配表
- file_word_choice_result: 选词结果表
- file_co_word_matrix: 共词矩阵表
3.1 导入程序包并声明变量 import pandas as pd import os import numpy as np from sklearn.cluster import KMeans, MiniBatchKMeans from sklearn.decomposition import PCA from sklearn.decomposition import TruncatedSVD from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.feature_extraction.text import HashingVectorizer from sklearn.feature_extraction.text import TfidfTransformer from sklearn.pipeline import make_pipeline from sklearn.preprocessing import Normalizer from sklearn import metrics from time import time %xmode Verbose import warnings warnings.filterwarnings("ignore", category=DeprecationWarning) # 存原始数据的目录 raw_data_dir = os.path.join(os.getcwd(), '..\\..\\data\\raw') # 存处理后的数据的目录 processed_data_dir = os.path.join(os.getcwd(), '..\\..\\data\\processed') filename_temp = pd.Series(['选词匹配']) file_seg_effect = ''
输出结果可能如下: Exception reporting mode: Verbose
3.2 检测data\raw目录下是否有选词匹配 以下的演示以GooSeeker分词和文本分析软件生成的选词匹配excel表为例,需要把选词匹配放到本notebook的data/raw文件夹下,如果没有数据表,下面代码执行后将提示“不存在” # 0:'词频', 1:'分词效果', 2:'选词矩阵', 3:'选词匹配', 4:'选词结果', 5:'共词矩阵' print(raw_data_dir + '\r\n') for item_filename in os.listdir(raw_data_dir): if filename_temp[0] in item_filename: file_seg_effect = item_filename continue if file_seg_effect: print("选词匹配excel表:", "data\\raw\\", file_seg_effect) else: print("选词匹配excel表:不存在")
输出结果类似下面的样子: C:\Users\work\workspace_219\notebook\知乎话题文本分词并选词后用sklearn做kmeans算法实验\notebook\eda\..\..\data\raw 选词匹配excel表: data\raw\ 选词匹配-知乎-二舅.xlsx
4 读入选词匹配并观察 4.1 读取选词匹配表 df = pd.read_excel(os.path.join(raw_data_dir, file_seg_effect))
输出结果可能会有这样的告警,不用管: C:\ProgramData\Anaconda3\lib\site-packages\openpyxl\styles\stylesheet.py:214: UserWarning: Workbook contains no default style, apply openpyxl's default warn("Workbook contains no default style, apply openpyxl's default")
4.2 查看前10行数据 使用df.head()函数查看dataframe的前n行数据 df.head(10)
4.3 使用“打标词”这一列作为实验数据 “打标词”这一列是我们在文本自动分词的基础上进行人工筛选后得到的词汇,通过观察可以看到,“打标词”是在词之间插入了逗号+空格. 【注意】:本Notebook我们使用“打标词”这一列作为实验数据,利用sklearn抽取特征词。 df['打标词'] df['已分词内容'] = df['打标词'] df['已分词内容']
4.4 去掉词与词之间的逗号,保留空格 由于后续的操作默认将空格作为词与词直接的分隔符,所以我们把“已分词内容”这一列的逗号去掉 df['已分词内容']=df['已分词内容'].str.replace(',',' ') df['已分词内容']
4.5 去掉值为NULL的行 dropna(axis = 0, how ='any') df = df.dropna(axis = 0, how ='any')
4.6 查看有多少篇文档 print("%d 篇文档" % len(df['已分词内容']))
输出结果如下: 767 篇文档
5 特征选择 原始数据经过分词切分以后,得到的词的数量很大,很多词没有分析价值,除了增加处理的难度,而且会干扰分析结果的合理性,所以,需要进行特征选择,可以手工选择,也可以自动选择。我们在本次实验中,利用GooSeeker分词软件的选词功能进行手工选择,以提高分析结果的合理程度。 将文档转换成文档向量(向量中每个坐标代表一个词,整个向量代表一个文档在空间中的位置和方向)的时候,我们依然使用TfidfVectorizer。其实跟上一篇《社交媒体话题文本分词后用sklearn的kmeans算法做聚类分析》不同,我们不再依靠自动的特征选择算法,而是选用了手工选特征词,那么向量化方法其实可选用的方法就更多更自由了。 每个文档都要变成一个文档向量,向量中每个词就是我们此前手工选的词。sklearn有很多生成文档向量的方法,这些方法给向量的每个元素赋值(相当于空间中的坐标值)有所不同。 - 最简单可能是sklearn.feature_extraction.DictVectorizer,每个坐标的值只能是0或者1;
- 进一步可以使用sklearn.feature_extraction.text.CountVectorizer,坐标值就是词频;
- 再进一步使用feature_extraction.text.TfidfVectorizer,坐标值是IF-IDF,同时可以根据得到的tf-idf值进一步筛选掉一些数值很低的词。 我们继续使用feature_extraction.text.TfidfVectorizer,读者有兴趣的话可以使用其他的做一下对比。
- 从df['已分词内容']字段抽取特征:仅仅利用空格作为间隔符,把选词结果切分成一个个特征词,并且统计词频和文档频率,并计算tf-idf,作为坐标值。结束时显示耗时多少及样本数量和特征数量。下面我们限定了文档频率:一方面不要文档频率过高的词,那样会引入很多没有意义的噪音词;另一方面不要文档频率过低的词,会造成过拟合而产生分析偏差。相反,实验3不修改任何参数,都用缺省参数,也是可以的,这样就表示完全赞同手工选的词,不再利用其他统计值做进一步筛选。
具体参看TfidfVectorizer的API t0 = time() #vectorizer = TfidfVectorizer(max_df=0.7, min_df=0.005, stop_words=None,ngram_range=(1, 2)) vectorizer = TfidfVectorizer(max_df=0.7, min_df=0.005, stop_words=None) X = vectorizer.fit_transform(df['已分词内容'].values.astype('U')) print("完成所耗费时间: %fs" % (time() - t0)) print("样本数量: %d, 特征数量: %d" % X.shape) print('特征抽取完成!')
输出结果如下: 完成所耗费时间: 0.033902s 样本数量: 767, 特征数量: 135 特征抽取完成!
6 实验一:人工设置K值为3 也就是限定为只分成三类 true_k = 3 #聚类数量
6.1 对文本进行kmeans聚类 labels = df['已分词内容'] km = KMeans(n_clusters=true_k, init='k-means++', max_iter=300, n_init=5)
print("对稀疏数据(Sparse Data) 采用 %s" % km) t0 = time() km.fit(X) print("完成所耗费时间:%0.3fs" % (time() - t0)) print()
print("Homogeneity值: %0.3f" % metrics.homogeneity_score(labels, km.labels_)) print("Completeness值: %0.3f" % metrics.completeness_score(labels, km.labels_)) print("V-measure值: %0.3f" % metrics.v_measure_score(labels, km.labels_)) print("Adjusted Rand-Index值: %.3f" % metrics.adjusted_rand_score(labels, km.labels_)) print("Silhouette Coefficient值: %0.3f" % metrics.silhouette_score(X, km.labels_, sample_size=1000))
print()
#用训练好的聚类模型反推文档的所属的主题类别 label_prediction = km.predict(X) label_prediction = list(label_prediction)
输出结果如下: 对稀疏数据(Sparse Data) 采用 KMeans(n_clusters=3, n_init=5) 完成所耗费时间:0.137s
Homogeneity值: 0.140 Completeness值: 1.000 V-measure值: 0.246 Adjusted Rand-Index值: 0.001 Silhouette Coefficient值: 0.022
6.2 输出每个簇群去重后的关键词 目的是为了观察每一类中哪些词对聚类打分有贡献,也可以根据词义了解类别代表的意义。 print("每个聚类的TOP关键词:") order_centroids = km.cluster_centers_.argsort()[:, ::-1]
# 由于sklearn存在不同版本,这里检测后再调用get_feature_names_out或者get_feature_names if hasattr(vectorizer,'get_feature_names_out'): terms = vectorizer.get_feature_names_out() elif hasattr(vectorizer,'get_feature_names'): terms = vectorizer.get_feature_names()
for i in range(true_k): print("簇群 %d " % (i+1), end='') print("该簇群所含文档占比为",'%.4f%%' % (int(label_prediction.count(i))/int(len(df['已分词内容'])))) print("簇群关键词:") wordset = [] for ind in order_centroids[i, :20]: wordset.append(terms[ind].replace(' ','')) for word in wordset: print(' %s ' % word, end='') print('\n------------------------------------------------------------------------------------------------')
输出结果如下:
6.3 可视化 6.3.1 降维 被分析的数据是高维数据,聚类结果无法直接可视化展示出来,那么,首先要将高维数据降维成2维或者3维数据。降维必然造成信息损失,到底选择哪个降维算法好,可以多尝试几个,进行对比。 我们使用TruncatedSVD将文档向量从130多维空间降维到2维空间,TruncatedSVD利用奇异值分解算法,属于主成分分析,比较适合处理我们当前使用的数据结构。但是要注意,主成分分析相当于坐标变换,得到的新的坐标不再对应到具体某个词,是组合出来的一个新的量。TruncateSVD介绍参看sklearn官网 labels=km.labels_.tolist() #l = km.fit_predict(X) svd = TruncatedSVD(n_components=2).fit(X) datapoint = svd.transform(X)
6.3.2 使用matplotlib进行可视化画图 import matplotlib.pyplot as plt %matplotlib inline plt.figure(figsize=(12, 10)) label1 = [ '#FFFF00', '#008008', '#0000FF','#800080','#FFF5EE','#98FB98','#A0522D', '#FF7F00','#FFC125','#FFFFFF','#FFFAFA','#FFF68F','#FFEFD5','#FFE4E1', '#FFDEAD','#FFC1C1','#FFB90F','#FFA54F','#FF8C00','#C0FF3E','#FF6EB4', '#FF4500','#FF3030','#8A2BE2','#87CEEB','#8470FF','#828282','#7EC0EE', '#7CFC00','#7A8B8B','#79CDCD','#76EE00'] color = [label1[i] for i in labels] plt.scatter(datapoint[:, 0], datapoint[:, 1], c=color) centroids = km.cluster_centers_ centroidpoint = svd.transform(centroids) plt.scatter(centroidpoint[:, 0], centroidpoint[:, 1], marker='^', s=150, c='#000000') plt.show()
图中的黑色三角是每个簇群的中心,不同的颜色代表不同的簇群。分的界限还算清晰。 7 实验二:使用“手肘法”确定最佳的K值 7.1 执行“手肘法” 在《Jupyter Notebook使用Python做K-Means聚类分析》中,我们介绍过“手肘法”确定最佳的K的大小:通过观察明显的拐点来确定最佳的K值。 我们在此也实验下: import matplotlib.pyplot as plt %matplotlib inline plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False n_clusters= 10 wcss = [] for i in range(1,n_clusters): km = KMeans(n_clusters=i, init='k-means++', max_iter=300, n_init=2) km.fit(X) wcss.append(km.inertia_) plt.plot(range(1,n_clusters),wcss) plt.title('肘 部 方 法') plt.xlabel('聚类的数量') plt.ylabel('wcss') plt.show()
手肘法是一个经验方法,而且肉眼观察也因人而异,特别是遇到模棱两可的时候。从上面的图来看,似乎没有一个明显的“肘部”。我们人为指定K值为6 # 把人工观察手肘法图的拐点作为K值 true_k = 6 #聚类数量
7.2 对文本进行kmeans聚类 labels = df['已分词内容'] km = KMeans(n_clusters=true_k, init='k-means++', max_iter=300, n_init=5) print("对稀疏数据(Sparse Data) 采用 %s" % km) t0 = time() km.fit(X) print("完成所耗费时间:%0.3fs" % (time() - t0)) print() print("Homogeneity值: %0.3f" % metrics.homogeneity_score(labels, km.labels_)) print("Completeness值: %0.3f" % metrics.completeness_score(labels, km.labels_)) print("V-measure值: %0.3f" % metrics.v_measure_score(labels, km.labels_)) print("Adjusted Rand-Index值: %.3f" % metrics.adjusted_rand_score(labels, km.labels_)) print("Silhouette Coefficient值: %0.3f" % metrics.silhouette_score(X, km.labels_, sample_size=1000)) print() #用训练好的聚类模型反推文档的所属的主题类别 label_prediction = km.predict(X) label_prediction = list(label_prediction)
输出结果如下: 对稀疏数据(Sparse Data) 采用 KMeans(n_clusters=6, n_init=5) 完成所耗费时间:0.384s
Homogeneity值: 0.244 Completeness值: 1.000 V-measure值: 0.393 Adjusted Rand-Index值: 0.002 Silhouette Coefficient值: 0.032
7.3 输出每个簇群去重后的关键词 print("每个聚类的TOP关键词:") order_centroids = km.cluster_centers_.argsort()[:, ::-1] # 由于sklearn存在不同版本,这里检测后再调用get_feature_names_out或者get_feature_names if hasattr(vectorizer,'get_feature_names_out'): terms = vectorizer.get_feature_names_out() elif hasattr(vectorizer,'get_feature_names'): terms = vectorizer.get_feature_names() for i in range(true_k): print("簇群 %d " % (i+1), end='') print("该簇群所含文档占比为",'%.4f%%' % (int(label_prediction.count(i))/int(len(df['已分词内容'])))) print("簇群关键词:") wordset = [] for ind in order_centroids[i, :20]: wordset.append(terms[ind].replace(' ','')) for word in wordset: print(' %s ' % word, end='') print('\n------------------------------------------------------------------------------------------------')
7.4 可视化 7.4.1 降维 labels=km.labels_.tolist() #l = km.fit_predict(X) svd = TruncatedSVD(n_components=2).fit(X) datapoint = svd.transform(X)
7.4.2 使用matplotlib进行可视化画图 import matplotlib.pyplot as plt %matplotlib inline plt.figure(figsize=(12, 10)) label1 = [ '#FFFF00', '#008008', '#0000FF','#800080','#FFF5EE','#98FB98','#A0522D', '#FF7F00','#FFC125','#FFFFFF','#FFFAFA','#FFF68F','#FFEFD5','#FFE4E1', '#FFDEAD','#FFC1C1','#FFB90F','#FFA54F','#FF8C00','#C0FF3E','#FF6EB4', '#FF4500','#FF3030','#8A2BE2','#87CEEB','#8470FF','#828282','#7EC0EE', '#7CFC00','#7A8B8B','#79CDCD','#76EE00'] color = [label1[i] for i in labels] plt.scatter(datapoint[:, 0], datapoint[:, 1], c=color) centroids = km.cluster_centers_ centroidpoint = svd.transform(centroids) plt.scatter(centroidpoint[:, 0], centroidpoint[:, 1], marker='^', s=150, c='#000000') plt.show()
图中的黑色三角是每个簇群的中心,不同的颜色代表不同的簇群。 8 实验三 该数据集只有700多条数据,选词太多的话,有些词出现的频率会太低。这个实验我们采取一个策略: - 只选名词(也可以只选其他词性的词,他们会体现不同的分析角度)
- 观察词频和文频(该词出现在多少文档中),剔除掉低频词
- 不选“二舅”这个词,因为所有文本都是跟这个主题有关
8.1 加载选词匹配表 将选词匹配excel表加载到DataFrame中。 这次实验的所有程序代码的变量名都加一个后缀_hf,表示这次实验“高频词”,以便与前面的实验不冲突。 file_seg_effect_hf = os.path.join(os.getcwd(), '../../data/raw/高频名词.xlsx') df_hf = pd.read_excel(file_seg_effect_hf) df_hf.head(10)
8.2 简单清洗数据 在df中创建一个新列,替换掉选词结果中的逗号,滤除掉空数据,以便进一步转换成文档向量。 df_hf['已分词内容']=df_hf['打标词'].str.replace(',',' ').dropna(axis = 0, how ='any') df_hf['已分词内容']
8.3 转换成文档向量 t0_hf = time() vectorizer_hf = TfidfVectorizer() X_hf = vectorizer_hf.fit_transform(df_hf['已分词内容'].values.astype('U')) print("完成所耗费时间: %fs" % (time() - t0_hf)) print("样本数量: %d, 特征数量: %d" % X_hf.shape) print('特征抽取完成!')
输出结果如下: 完成所耗费时间: 0.024976s 样本数量: 687, 特征数量: 100 特征抽取完成!
8.4 聚类成3类 labels_hf = df_hf['已分词内容'] km_hf = KMeans(n_clusters=3, init='k-means++', max_iter=300, n_init=5) print("对稀疏数据(Sparse Data) 采用 %s" % km_hf) t0_hf = time() km_hf.fit(X_hf) print("完成所耗费时间:%0.3fs" % (time() - t0_hf)) print() print("Homogeneity值: %0.3f" % metrics.homogeneity_score(labels_hf, km_hf.labels_)) print("Completeness值: %0.3f" % metrics.completeness_score(labels_hf, km_hf.labels_)) print("V-measure值: %0.3f" % metrics.v_measure_score(labels_hf, km_hf.labels_)) print("Adjusted Rand-Index值: %.3f" % metrics.adjusted_rand_score(labels_hf, km_hf.labels_)) print("Silhouette Coefficient值: %0.3f" % metrics.silhouette_score(X_hf, km_hf.labels_, sample_size=1000)) print() #用训练好的聚类模型反推文档的所属的主题类别 label_prediction_hf = km_hf.predict(X_hf) label_prediction_hf = list(label_prediction_hf)
输出结果如下: 对稀疏数据(Sparse Data) 采用 KMeans(n_clusters=3, n_init=5) 完成所耗费时间:0.188s
Homogeneity值: 0.111 Completeness值: 1.000 V-measure值: 0.200 Adjusted Rand-Index值: 0.001 Silhouette Coefficient值: 0.032
8.5 输出每个簇群去重后的关键词 目的是为了观察每一类中哪些词对聚类打分有贡献,也可以根据词义了解类别代表的意义。 print("每个聚类的TOP关键词:") order_centroids_hf = km_hf.cluster_centers_.argsort()[:, ::-1] # 由于sklearn存在不同版本,这里检测后再调用get_feature_names_out或者get_feature_names if hasattr(vectorizer_hf,'get_feature_names_out'): terms_hf = vectorizer_hf.get_feature_names_out() elif hasattr(vectorizer_hf,'get_feature_names'): terms_hf = vectorizer_hf.get_feature_names() for i in range(3): print("簇群 %d " % (i+1), end='') print("该簇群所含文档占比为",'%.4f%%' % (int(label_prediction_hf.count(i))/int(len(df_hf['已分词内容'])))) print("簇群关键词:") wordset = [] for ind in order_centroids_hf[i, :20]: wordset.append(terms_hf[ind].replace(' ','')) for word in wordset: print(' %s ' % word, end='') print('\n------------------------------------------------------------------------------------------------')
8.6 可视化 import matplotlib.pyplot as plt %matplotlib inline # 用svd(奇异值分解)方法降维,也就是把维度下降到2个主成分上。 labels_hf = km_hf.labels_.tolist() #print(labels_hf) #l = km.fit_predict(X) svd_hf = TruncatedSVD(n_components=2).fit(X_hf) datapoint_hf = svd_hf.transform(X_hf) plt.figure(figsize=(12, 10)) label1 = [ '#FFFF00', '#008008', '#0000FF','#800080','#FFF5EE','#98FB98','#A0522D', '#FF7F00','#FFC125','#FFFFFF','#FFFAFA','#FFF68F','#FFEFD5','#FFE4E1', '#FFDEAD','#FFC1C1','#FFB90F','#FFA54F','#FF8C00','#C0FF3E','#FF6EB4', '#FF4500','#FF3030','#8A2BE2','#87CEEB','#8470FF','#828282','#7EC0EE', '#7CFC00','#7A8B8B','#79CDCD','#76EE00'] # 给每个数据点上色 color_hf = [label1[i] for i in labels_hf] plt.scatter(datapoint_hf[:, 0], datapoint_hf[:, 1], c=color_hf) # 画中心点 centroids_hf = km_hf.cluster_centers_ centroidpoint_hf = svd_hf.transform(centroids_hf) plt.scatter(centroidpoint_hf[:, 0], centroidpoint_hf[:, 1], marker='^', s=150, c='#000000') plt.show()
9 总结 本Notebook使用Gooseeker文本分词和情感分析软件导出的选词匹配excel表格,在python下使用sklearn库进行k-means聚类,实验有3个: - 实验1. 人工直接设置K值为3进行实验
- 实验2. 使用“手肘法”人工观察拐点,取K值为6
- 实验3. 利用GooSeeker分词和情感分析软件手工选词可以选择某种词性的功能,只选择高频名词。
对于可视化输出的图,可能不同实验者会有不同的解读。总的来说,解读聚类结果是比较难的,因为一个文档被向量化以后变成了一个高位空间的向量,高维空间是不能直观解读的。我们只能看这么多维度中贡献最大的维度是什么,根据维度代表的词,猜测是什么含义。 但是,使用GooSeeker分词和情感分析软件的手工选词功能,作用是十分明显的,通过人脑判断,特征选择是最准确的。下面分别截图对比一下两者的区别(注意,聚类计算的时候,每次结果会有稍许变化,本notebook上面的计算过程得到的图会跟下面这个历史截图不一样)。第一张图是自动特征选择的结果;第二张图是手工选词的结果。
上图对比可见,手工选词效果提升很大。 即便这样,在自动聚类计算之后的结果解读仍然是一个很大的挑战,需要阅读已经标记了类别的文本内容,理解每一类代表了什么。 另外,由于知乎回答有长有短,而且差距极大,针对每个回答这种粒度做分析和比较,不是很合适,可以考虑段落级分析,也许还可以更细到句子级,这要看分析目的是怎样的,可能参考一些内容分析和质性研究的方法是有益的。 后续我们会使用不同数据源的数据(比如:微博,知乎,新闻等),使用sklearn进行多种算法的实验,在实验中总结和改进。 10. 源代码下载 下载notebook源代码请进入:对分词并选词后的社交媒体话题文本用sklearn的kmeans做聚类分析 |