版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lily960427/article/details/78341138
语料库:是文献引用关系的语料库,将文献分成10类
包含3个txt,一个是文档ID+文档标题信息,一个是文档ID之间的引用关系,一个是文档类别
语料库下载:m10
doc2vec和word2vec不同,直接是对文档进行训练,得到的就是一个个文档向量。
主要分为三步,一步就是提取文档信息,一步进行训练,最后分类。
第一步提取比较简单 主要就是提取文档标题信息做words,然后doc2需要给每一个文档打tags然后一起投入训练(用文档的ID也是可以的,这里用的数字1,2,3…..)
原本gensim.doc2vec内有 LabeledSentence使用,这里用的是namedtuple结构,其实差不多,每一个元素就是文档标题words+文档tags+文档的类别。
def readdata(path):
fileindex={}
fileinfor=[]
labels=set()
f1=open(path+'/docs.txt',encoding='utf-8')
f2=open(path+'/labels.txt',encoding='utf-8')
i=0
for l1 in f1:
tokens=ut.to_unicode(l1.lower()).split()
words=tokens[1:] #文档信息
tags=[i]# ID
i=i+1
l2=f2.readline()
tokens2=ut.to_unicode(l2).split()
label=tokens2[1] #文档类别
labels.add(label)
fileinfor.append(NetworkSentence(words,tags,label)) #文档信息+文档ID+文档类别+文档index
return fileinfor,list(labels)
第二步就是训练doc2模型 通过shuffle语料库,来提高模型准确率
其中参数dm=0代表用的pv-dbow模型
(这里hs=1,用的是基于 Hierarchical Softmax 的模型,效果好很多,如果Hs=0,即采用负样本采样模型,结果不是很好,但是和论文中结果相似……)
def traindo2vec(docs):
model = Doc2Vec(dm=0, size=300, dm_mean=0, window=8,hs=1, negative=2,min_count=5, workers=4) # PV-DBOW
print('Building Vocabulary')
model.build_vocab(docs)
for i in range(9):
print("刷新 %d" %i)
shuffle(docs model.train(docs,total_examples=model.corpus_count,epochs=model.iter)
return model
最后训练出的每一个文档是一个向量,放在model.docvecs中,即docvecs[0]就是第一个文档的文档向量,因此我们的训练和测试向量得到如下:
path='data/M10'
docs,classlabels=readdata(path)
do2model=traindo2vec(docs)
train, test = train_test_split(docs, train_size=0.7, random_state=0) # 随机划分训练集和测试集
print("共有%d个文件" %len(docs))
print("共有%d个类别" %len(classlabels))
#docvecs 每个文档一个向量 通过tags定位向量在模型的位置
train_vec=[do2model.docvecs[doc.tags[0]] for doc in train]
test_vec = [do2model.docvecs[doc.tags[0]] for doc in test]
train_y = [doc.label for doc in train]
test_y = [doc.label for doc in test]
最后就是训练啦
print('练集有: %d个 , 测试集有:%d 个' %(len(train_vec),len(test_vec)))
from sklearn import svm
from sklearn.metrics import f1_score
from sklearn.metrics import accuracy_score
clf = LinearSVC()
clf.fit(train_vec, train_y)
result = clf.predict(test_vec)
print(result)
macro_f1 = f1_score(test_y, result,pos_label=None, average='macro')
micro_f1 = f1_score(test_y, result,pos_label=None, average='micro')
acc = accuracy_score(test_y, result)
print(acc)
print(macro_f1,micro_f1)
最后的结果(Hs=1采用哈夫曼树的时候)
只有文档标题信息,效果一般
将DeepWalk 和DOC2结合还不错大概有72%