中文信息处理实验7——基于Word2Vec的文本表示

目录

实验目的:

实验要求:

实验内容及原理:

参考代码:

实验结果:


实验目的:

        加深对汉语文本信息处理基础理论及方法的认识和了解,锻炼和提高分析问题、解决问题的能力。通过对具体项目的任务分析、数据准备、算法设计和编码实现以及测试评价几个环节的练习,基本掌握实现一个自然语言处理系统的基本过程。

实验要求:

基于Word2Vec的文本表示

实验内容及原理:

实验说明:
        该子任务使用gensim工具包中的Word2Vec模型。
        要求熟练掌握工具包安装、数据读取、模型训练、参数调整、结果保存、模型加载以及词向量获取相关内容。

主要流程如下:

1)gensim安装(https://radimrehurek.com/gensim/) 。请自行配置pip和anaconda环境,可使用以下两种方式进行安装。
pip安装:Run in your terminal (recommended)
pip install --upgrade gensim
conda安装: Run in your Anaconda Prompt
conda install -c conda-forge gensim

2)详细阅读word2vec模型的说明文档
(https://radimrehurek.com/gensim/models/word2vec. html),了解各函数的基本使用方法和参数意义。
3)对给定的实验数据进行分词,不需要去除停用词。

4)加载分词后的实验数据,分别使用cbow和skip-gram两种模型将所有词汇训练成词向量,维度N=64。

5)将训练好的词向量模型保存到文件中。

6)重新加载已经训练完成的模型,输入任意在训练集中的词汇wi可以输出其词向量wi表示。

7)对给定语料库内的所有的句子,将其分词后从(5)中已经训练完成的模型中获取其所有词汇的词向量表示。利用实验五的方法,计算句子S中每个词汇wi的tfidf值并进行归一化(归一化可使用公式Eq.1) ,以该归一化tfidf值作为wi的权重对句子的所有词向量wi表示进行加权求和,作为该句子的向量表示(公式Eq.2)。以“句子id类别标签(pos为1,neg为0)向量表示”的形式存在文件当中。
 

实验数据:

        实验数据采用htl_del_4000宾馆情感分析数据进行处理,所有数据已按照情感极性划分为褒(pos)贬(neg)两类,各2000篇,每个文本文件为一篇文章,实验数据需要先进行分词,分词方法不限。

参考代码:

import csv
import gensim
import jieba
import numpy as np
import os

from gensim.models import word2vec

content = open('./cn_stopwords.txt', 'r',encoding='utf-8').read()
#转化为CSV文件
def ToCSV(file1,file2):
    with open(file1, 'w', newline='', encoding='utf-8') as cf:
        writer = csv.writer(cf)
        writer.writerow(["id", "标签","向量"])
        with open(file2, 'r', encoding='utf-8') as f:
            l = f.readlines()
            for s in l:
                l1 = s.split(' ')  # l1[0]为文档id,l1[1]为标签,l1[2:]为向量
                writer.writerow([l1[0], l1[1],l1[2:]])

def funn(): #对给定的数据进行分词
    # 当前文件的路径
    dir = os.path.dirname(__file__)
    # 拼接文件路径
    neg_folder = os.path.join(dir, './htl_del_4000/' + "neg")
    pos_folder = os.path.join(dir, './htl_del_4000/' + "pos")
    # 遍历所有文件
    neg_li = os.listdir(neg_folder)  # li储存neg的句子文本
    pos_li = os.listdir(pos_folder)  # li_1储存pos的句子文本
    with open("./临时.txt","w+",encoding="utf-8") as file:
        num_neg=0
        num_pos=0
        for x in neg_li:
            with open("./htl_del_4000/neg/"+x,"r", encoding="gbk", errors='ignore') as f:
                content=f.read()
                num_neg+=1
                words=[]
                # words=jieba.cut(content)
                words_split=" ".join(jieba.cut(content)).split()
                # words=" ".join(words_split)
                for w in words_split:
                    # if w not in stop_words:
                        words.append(w)
                words=" ".join(words)
                # print(words)
                file.writelines(words+"\n")
        for x in pos_li:
            with open("./htl_del_4000/pos/"+x,"r", encoding="gbk", errors='ignore') as f:
                content=f.read()
                num_pos+=1
                words=[]
                # words=jieba.cut(content)
                words_split=" ".join(jieba.cut(content)).split()
                # words=" ".join(words_split)
                for w in words_split:
                    # if w not in stop_words: #不去除停用词可以注释掉
                        words.append(w)
                words=" ".join(words)
                # print(words)
                file.writelines(words+"\n")
    return num_neg,num_pos

def Get_WordVector():
    #用word2vec建立词向量
    sens = word2vec.LineSentence("./临时.txt")
    # sens:句子,min_count:词频小于设定值的词扔掉,window:一次取的词数,size:词向量的维度,sg:使用CBOW/Skip,hs:若为1采用树优化,worker:CPU并行数量,iter:最大迭代次数
    model_CBOW = gensim.models.word2vec.Word2Vec(sens, min_count=0, window=5,vector_size=64, sg=0, hs=0, negative=5, workers=8, epochs=200) #用CBOW处理
    model_skipgram = gensim.models.word2vec.Word2Vec(sens, min_count=0, window=5,vector_size=64, sg=1, hs=0, negative=5, workers=8, epochs=200) #用skip-gram处理
    #保存为txt
    model_CBOW.wv.save_word2vec_format("词向量(cbow).txt",binary=False)
    model_skipgram.wv.save_word2vec_format("词向量(skip-gram).txt",binary=False)
def calw(docs):
    tfidf=[]
    words_stats = {}
    docs_num = len(docs)
    for ws in docs: #ws=sentense
        for w in ws: #w=words
            if w not in words_stats:
                words_stats[w] = {}
                words_stats[w]['df'] = 0
                words_stats[w]['idf'] = 0
            # words_stats[w]['cf'] += 1
        for w in set(ws):
            words_stats[w]['df'] += 1
    for w, winfo in words_stats.items():
        words_stats[w]['idf'] = np.log((1. + docs_num) / (1. + winfo['df']))
        tfidf.append(words_stats[w]['idf'])
    return tfidf
def ca(docs):
    tfidf=[]
    words_stats = {}
    docs_num = len(docs)
    for ws in docs: #ws=sentense
        for w in ws: #w=words
            w=''
    return tfidf
#softmax归一化函数
def softmax(x):
    e_x = np.exp(x)
    return e_x / e_x.sum()
def final():
    docs = []
    num_of_files = 0
    for x in l1:  # 文件挨个计算
        with open("./htl_del_4000/neg/" + x, "r", encoding="gbk", errors='ignore') as f:
            content = f.read()
            words = jieba.cut(content)
            num_sentense = 0
            temp_doc = [x.replace(".", '').replace('neg', '').replace('txt', '') + "-" + str(num_sentense),
                        "0"]  # 1表示pos;0表示neg(num_sentense的0表示该文档下的第一个句子)
            for i in words:
                if i == "。" or i == ";" or i == ".":
                    num_sentense += 1
                    temp_doc.append(i)
                    docs.append(temp_doc)
                    temp_doc = [x.replace(".", '').replace('neg', '').replace('txt', '') + "-" + str(num_sentense), "0"]
                    num_of_files += 1
                    continue
                elif i != "\r" and i != "\r\n" and i != "\n":
                    temp_doc.append(i)
            else:
                if len(temp_doc) > 3:
                    docs.append(temp_doc)
                    num_of_files += 1
    num_of_files_1 = 0
    for x in l2:
        with open("./htl_del_4000/pos/" + x, "r", encoding="gbk", errors='ignore') as f1:
            content = f1.read()
            words = jieba.cut(content)
            num_sentense = 0
            temp_doc = [x.replace(".", '').replace('pos', '').replace('txt', '') + "-" + str(num_sentense),
                        "1"]  # 1表示pos;0表示neg(num_sentense的0表示该文档下的第一个句子)
            for i in words:
                if i == "。" or i == ";" or i == ".":
                    num_sentense += 1
                    temp_doc.append(i)
                    docs.append(temp_doc)
                    temp_doc = [x.replace(".", '').replace('pos', '').replace('txt', '') + "-" + str(num_sentense), "1"]
                    num_of_files_1 += 1
                    continue
                elif i != "\r" and i != "\r\n" and i != "\n":
                    temp_doc.append(i)
            else:
                if len(temp_doc) > 3:
                    docs.append(temp_doc)
                    num_of_files_1 += 1
    return docs
def prosm(sen_docs, file):
    tfidf = []
    for sentense in sen_docs:
        if len(sentense)<4: #因为文档中有"..."出现,所以上一步会有空列表出现,这一步把他们都去掉
            continue
        x = calw(sentense[2:])
        res = softmax(x)
        tfidf.append(sentense[:2] + (res * np.array(x)).tolist()) #(res * np.array(x)).tolist()加权求和得到句子的表示向量
    with open(file, "w+", encoding="utf-8") as f:
        for sentense in range(len(tfidf)):
            for value in range(len(tfidf[sentense])):
                f.write(str(tfidf[sentense][value]))
                if (value != (len(tfidf[sentense]) - 1)):
                    f.write(' ')
            f.write('\n')

if __name__=="__main__":
    funn()
    Get_WordVector()#建立词向量
    # 将数据加载到列表
    fname1 = 'neg'
    fname2 = 'pos'
    # 当前文件的路径
    dir = os.path.dirname(__file__)
    x = 200
    softmax(x)
    # 拼接文件路径
    f1 = os.path.join(dir, './htl_del_4000/' + fname1)
    f2 = os.path.join(dir, './htl_del_4000/', fname2)
    # 遍历所有文件
    l1 = os.listdir(f1)  # l1储存neg的句子文本
    l2 = os.listdir(f2)  # l2储存pos的句子文本
    l1.sort()
    l2.sort()
    docs=final()
    calw(docs)
    ca(docs)
    prosm(docs,"表示.txt")
    ToCSV("Word2Vec.csv", "表示.txt")
    print("任务完成!")

实验结果:

1.词向量

 

 2.文本表示

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值