14

利用 Doc2Vec 对 Quora 问题标签聚类

 5 years ago
source link: https://www.leiphone.com/news/201809/4blXULGE2KNYGqHY.html?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

7fE3QfE.jpg!web

本文为 AI 研习社编译的技术博客,原标题:

Clustering Quora Question Tags with Doc2Vec.

翻译 | nick李、csnoooong    校对 | 凡江    整理 | 志豪

原文链接:https://medium.com/@samriddhisinha/clustering-quora-question-tags-with-doc2vec-d4fb3c5177f7

  引言

Quora是一个流行的知识分享平台,我常常在Quora上分享我的想法。这个平台是基于问答的形式,它因其简易的设计和平滑的用户体验而出名。

当新的问题被添加到Quora时,这些问题由机器人自动基于问题的上下文进行标记并稍后由用户进行编辑。这些标签反映了问题被归入的话题类别。如下是一个问题的基本概貌。

RVJnmay.png!web

最近我在寻找合适的数据集,然后我偶然看到了Quora里的一个这个页面: Programming Challenges。我选择了这个叫做Answered的二分类问题挑战。其中,包括了近10000个问题(训练集和测试集总计)。每个问题和其话题标签以及其他的一些信息被以JSON格式储存。下图是一个JSON的示例。

3q6vMrM.png!web

示例问题JSON

    动手干吧

第一个任务就是要从JSON文件中读取数据。训练集总共大约有9000个问题,而测试集总共约1000个问题。

import json f = open("answered_data_10k.in").read().split("\n")train_set = f[1:9001]test_set = f[9002:-1]train = [json.loads(i) for i in train_set]test = [json.loads(i) for i in test_set]questions = train + test

接下来就要提取出所有数据集中的主题标签。在JSON文件中,主题存储在键"key"中。不同的问题有不同数量的主题标签。单个问题所允许存在的最大标签数为26。同时也存在没有关联主题标签的问题。

# Create the list of topics topic_list = []for question in questions:if len(question["topics"]) > 0:for topic in question["topics"]:topic_list = topic_list + [topic["name"]]topic_list = list(set(topic_list))print(len(topic_list))

在这个挑战所提供的数据中,一共有8762个主题标签。

在提取出主题标签之后,我们需要将具有相同标签的问题聚类。在动手之前,我们先对数据进行分析,因为如果直接对8762个进行聚类将会很困难而且聚类的质量也难以保证。

因此我们限定了每一个主题下的最小问题数来解决这个问题。拥有多于1个问题的主题有3275个。拥有5个问题的主题恰好有900个,这个数量相对更适合进行聚类。

最终,我们决定将主题下的最小问题数规定为5个,这主要有两个原因。首先是为了更好地用向量来表示主题,其次因为具有较少问题的主题大多数情况下是和无关的问题所关联的。

#Assigning question to topics.question_list = []final_topic_list = []for topic in topic_list:temp = []for question in questions:context = [i["name"] for i in question["topics"]]if topic in context:temp.append(question['question_text']) if len(temp) >= 5:question_list.append(temp)final_topic_list.append(topic)topic_list = final_topic_list

接下来,我们写一个函数,通过转换为小写、去除标点符号和停用词来正则化每个段落。每个话题下有五到多个问题。我们把每个话题下的问题的集合当做一个文档。

这样,我们先遍历话题标签,然后把问题聚集成段落,再把段落正则化化。然后我们把段落和段落的话题标签喂给Gensim的TaggedDocument函数,进行进一步的正则化。

from nltk import word_tokenizefrom nltk.corpus import stopwordsfrom gensim import modelsfrom gensim.models.doc2vec import TaggedDocument#Function for normalizing paragraphs.def normalize(string):lst = word_tokenize(string)lst =[word.lower() for word in lst if word.isalpha()]lst = [w for w in lst if not w in stopwords.words('english')]return(lst)# Aggregate questions under each topic tag as a paragraph. # Normalize the paragraph # Feed the normalized paragraph along with the topic tag into Gensim's Tagged Document function. # Append the return value to docs.docs = []for index, item in enumerate(topic_list):question = " ".join(question_list[index])question = normalize(question)docs.append(TaggedDocument(words=question, tags=[item]))

为Gensim的DocVec准备数据

接下来我们训练Doc2Vec模型。

应该调整vector_size和window,直到结果是最优的。

import gensimmodel = gensim.models.Doc2Vec(vector_size= 200, window= 3, min_count= 0, workers=4, epochs= 40)model.build_vocab(docs)model.train(docs, total_examples=model.corpus_count, epochs=model.iter)

Doc2Vec Training

Doc2Vec模型训练好后,我们就用KMeans算法聚类了文档向量。簇的数量从100到50之间进行了检查。接近100的簇数会导致大簇被切分成小簇,而簇数等于50时会使得没有相关性的簇被组合成大簇。在仔细评估聚簇结果后,最后选择60作为簇数。

from sklearn.cluster import KMeansfrom sklearn import metricsimport pylab as plimport matplotlib.pyplot as pltfrom sklearn.decomposition import PCAkmeans_model = KMeans(n_clusters= 60, init='k-means++', max_iter=100) X = kmeans_model.fit(model.docvecs.doctag_syn0)labels= kmeans_model.labels_.tolist()l = kmeans_model.fit_predict(model.docvecs.doctag_syn0)#map each centroid to its topic tagword_centroid_map = dict(zip( model.docvecs.offset2doctag, l))#Print Cluster Listfor cluster in range(0,100): print("\nCluster %d" % cluster)words = []for i in range(0,len(word_centroid_map.values())):if(list(word_centroid_map.values())[i] == cluster ):words.append(list(word_centroid_map.keys())[i])print(words)

拟合KMeans模型并取回簇的列表

......

想要继续阅读文章,并且查看该篇文章更多代码、链接和参考文献?

戳链接: http://www.gair.link/page/TextTranslation/840

AI研习社每日更新精彩内容,点击文末【阅读原文】即可观看更多精彩内容: 雷锋网 (公众号:雷锋网) 雷锋网雷雷锋网

基于 NLTK 和 SpaCy 的命名实体识别功能实现

AI初学者必须要了解的术语盘点

从 App 描述介绍文字中发掘 Python 文本数据预处理实例

通过摇滚乐队来学习 TensorFlow,Word2Vec 模型和 TSNE 算法

等你来译:

如何用Anchors来为你的模型可解释性立足

如何用机器学习来处理假新闻

通过 Spotify 上面的播放列表,我们分析了 50 位音乐家,结果发现——

机器学习当中的数学闪光:如何直观地理解 LDA

ZnEVJvE.jpg!web

雷锋网原创文章,未经授权禁止转载。详情见 转载须知

vQnueq3.jpg!web

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK