Doc2vec对M10语料库进行多分类 python

版权声明:本文为博主原创文章,未经博主允许不得转载。 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%
这里写图片描述

猜你喜欢

转载自blog.csdn.net/lily960427/article/details/78341138