[計算言語学の実験]負のサンプリング(SGNS)ベクトルベースの学習と評価とのスキップ・グラムの中国の言葉

I.概要

トレーニングコーパス出典:ウィキメディアhttps://dumps.wikimedia.org/backup-index.html中国のデータ

Word2vecトレーニングワードを有するベクター、およびファイルに学習された2つのワード類似ように、2つの単語間pku_sim_test.txtコサイン距離でライン毎に算出ベクター、および出力を有するワード。

第二に、データの準備と前処理

ダウンロードコーパス:https://dumps.wikimedia.org/zhwiki/20191120/zhwiki-20191120-pages-articles-multistream.xml.bz2

コーパス記事エキス

ダウンロードが完了したら、解凍GETは多くの記事を含むXMLファイル、である、ログ情報がたくさんあります。この実験は、それだけで記事内のxmlファイルを抽出する必要があります。
XMLファイルには手段をWikiExtractorで記事に抽出することができます。まずWikiExtractorプロジェクト全体のクローンまたは:(は500Mの各ファイルのサイズを分割し、次のようにコマンドを実行するには、ローカル、コマンドラインウィンドウにダウンロード)

> git init
> git clone https://github.com/attardi/wikiextractor
> python .\wikiextractor\WikiExtractor.py -b 500M -o zhwiki zhwiki-20190401-pages-articles-multistream.xml.bz2

使用WikiExtractor抽出記事は、いくつかのファイルが含まれている指定されたディレクトリのフォルダ内のAAを生成します。

簡体字と繁体字の変換

簡体字と繁体内部の記事の内容の百科事典ウィキペディアコーパスが混乱しているので、私たちは単純化し、すべての伝統的な文字に変換する必要があります。ここでは、変換するのにOpenCCを使用しています。
OpenCCプロジェクト住所:https://github.com/BYVoid/OpenCC(t2s.json:繁体字ターン簡体)OpenCCがローカルコンピュータにインストールした後、コマンドを実行します

> opencc -i .\zhwiki\AA\wiki_00
-o .\zhwiki\BB\wiki_00
-c D:\opencc-1.0.4-win32\opencc-1.0.4\share\opencc\t2s.json

記事およびワードの内容を抽出するための正規表現

SegmentWords.pyカレントディレクトリコード操作を3つの段階で行った:
(1)フィルタタグ:抽出WikiExtractor物品を使用して、多数の成り 、したがって、これらは正規表現で無関係なコンテンツを削除する必要があります。
(2)は、単語と単語を無効にする:ストップワードのワードも除去する必要がある場合、物品の単語は、jiebaによって運ばれます。
ファイルを保存する(3)マージ:ファイルに保存された分割後の記事を、各列は、各単語の間にスペースで区切ら物品を表します。

Jiebaプロジェクト住所:https://github.com/fxsjy/jieba

#segmentWords.py

import logging
import jieba
import os
import re

def get_stopwords():
    logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s',level=logging.INFO)
    #加载停用词表
    stopword_set = set()
    with open("./stop_words/stopwords.txt",'r',encoding="utf-8") as stopwords:
        for stopword in stopwords:
            stopword_set.add(stopword.strip("\n"))
    return stopword_set

'''
使用正则表达式解析文本
'''
def parse_zhwiki(read_file_path,save_file_path):
    #过滤掉<doc>
    regex_str = "[^<doc.*>$]|[^</doc>$]"
    file = open(read_file_path,"r",encoding="utf-8")
    #写文件
    output = open(save_file_path,"w+",encoding="utf-8")
    content_line = file.readline()
    #获取停用词表
    stopwords = get_stopwords()
     #定义一个字符串变量,表示一篇文章的分词结果
    article_contents = ""
    cnt = 0
    while content_line:
        match_obj = re.match(regex_str,content_line)
        content_line = content_line.strip("\n")
        if len(content_line) > 0:
            if match_obj:
                #使用jieba进行分词
                words = jieba.cut(content_line,cut_all=False)
                for word in words:
                    if word not in stopwords:
                        article_contents += word+" "
            else:
                if len(article_contents) > 0:
                    output.write(article_contents+"\n")
                    article_contents = ""
        cnt += 1
        if (cnt % 10000 == 0):
            print("已处理", cnt/10000, "万行")
        content_line = file.readline()
    output.close()

'''
将维基百科语料库进行分类
'''
def generate_corpus():
    zhwiki_path = "./zhwiki/BB"
    save_path = "./zhwiki/BB"
    for i in range(3):
        print("开始处理第", i, "个文件")
        file_path = os.path.join(zhwiki_path,str("wiki_0%s"%str(i)))
        parse_zhwiki(file_path,os.path.join(save_path,"wiki_corpus0%s"%str(i)))


'''
合并分词后的文件
'''
def merge_corpus():
    output = open("./zhwiki/BB/wiki_corpus","w",encoding="utf-8")
    input = "./zhwiki/BB"
    for i in range(3):
        print("开始合并第", i, "个文件")
        file_path = os.path.join(input,str("wiki_corpus0%s"%str(i)))
        file = open(file_path,"r",encoding="utf-8")
        line = file.readline()
        while line:
            output.writelines(line)
            line = file.readline()
        file.close()
    output.close()

if __name__ == "__main__":
    # # wiki数据处理
    print("开始正则,jieba处理数据")
    generate_corpus()

    # 文件合并
    print("开始合并文件")
    merge_corpus()

    # 打印数据 显示
    input_file = "./zhwiki/BB/wiki_corpus"
    file = open(input_file,"r",encoding="utf-8")
    line = file.readline()
    num = 1
    while line:
        print(line)
        line = file.readline()
        num += 1
        if num > 10:
            break

トレーニングのword2vecモデル

カレントディレクトリのパラメータ設定にtrain.py word2vec(サイズ= 100、ウィンドウ= 5、SG = 1、HS = 0、陰性= 5)、(、ウィンドウ2の前後100ビクトリア、SGNS)を実験の要件を満たします。

#train.py

import logging
from gensim.models import word2vec

def main():
    logging.basicConfig(format="%(asctime)s:%(levelname)s:%(message)s",level=logging.INFO)
    sentences = word2vec.LineSentence("./zhwiki/BB/wiki_corpus")
    # size:单词向量的维度
    # window: 窗口大小
    # sg=1: 使用skip-gram
    # hs=0: 使用negative sample
    model = word2vec.Word2Vec(sentences, size=100, window=5, sg=1, hs=0, negative=5)
    # 保存模型  必须3个一起用
    # model.save("./model/wiki_corpus.bin")
    # model.save("./model/wiki_corpus.model")

    # 训练为一个单独二进制压缩文件  可独立使用
    model.wv.save_word2vec_format("./model/wiki_corpus_binary.bin", binary=True)

if __name__ == "__main__":
    main()

二つの単語の類似度を計算します

Compute.pyカレントディレクトリ・コードは、以下のステップを行った:
(1)読み取りモデルが訓練されると、そのファイルが類似pku_sim_test.txtを算出する
(2)文字列\ T \ Nスライスデリミタリスト形式、および類似度計算
ファイルresult.txtとして結果を保存(3)

#compute.py

import re
from gensim.models import KeyedVectors

def main():
    # 读取模型以及待计算数据
    model = KeyedVectors.load_word2vec_format("./model/wiki_corpus_binary.bin", binary=True)
    f = open('./pku_sim_test.txt', encoding='utf-8')
    out = open('result.txt', 'w', encoding='utf-8')
    
    # 字符串切分为列表
    wordlist = []
    while True:
        line = f.readline()
        if not line:
            break
        wordlist.append(re.split(r'[\t\n]', line))
    
    # 计算相似度
    cnt = 0
    resTotal = 0.0
    for i in range(len(wordlist)):
        words = wordlist[i]
        try:
            res = model.similarity(words[0], words[1])
        except KeyError:
            words[2] = 'OOV'
            wordlist[i] = words
            print(words)
            continue

        words[2] = str("%.4f"%res)
        wordlist[i] = words
        print(words)
        cnt += 1
        resTotal += res

    print("查到的比例为:%.4f"%(cnt/len(wordlist)))
    print("平均相似度为:%.4f"%(resTotal/cnt))
    
    # 结果保存
    lines = []
    for i in range(len(wordlist)):
        line = wordlist[i]
        oneline = line[0] + '\t' + line[1] + '\t' + line[2] + '\n'
        lines.append(oneline)
    out.writelines(lines)
    f.close()
    out.close()
    

if __name__ == '__main__':
    main()

おすすめ

転載: www.cnblogs.com/yanqiang/p/12109901.html