import os import sys sys.path.append(os.getcwd()) import multiprocessing from time import time import pandas as pd from gensim.models import Word2Vec from config import subjects_keywords_path, ltp_model_path from tqdm import tqdm import jieba from ltp import LTP import torch from config import JIEBA_TOKEN, LTP_TOKEN, user_dict_path, logger from config import subjects_data_path, subject_faiss_w2v_path from config import word2vec_dim # 训练召回用的word2vec词向量,实践课程包含字段:"subject_name","sub_discipline_name","tag_names" tqdm.pandas() ltp = LTP(ltp_model_path) if torch.cuda.is_available(): ltp.to("cuda") # 加载用户自定义词典 if os.path.exists(subjects_keywords_path): jieba.load_userdict(subjects_keywords_path) with open(subjects_keywords_path, 'r', encoding='utf-8') as f: user_dict_words = f.read().split() ltp.add_words(user_dict_words) if os.path.exists(user_dict_path): with open(user_dict_path, 'r', encoding='utf-8') as f: user_dict_words = f.read().split() ltp.add_words(user_dict_words) for word in user_dict_words: jieba.add_word(word) def tokenizer(sent, token_method=JIEBA_TOKEN): """ 中文分词,支持jieba和ltp两种方式 """ if token_method == JIEBA_TOKEN: seg = jieba.cut(sent) result = ' '.join(seg) elif token_method == LTP_TOKEN: content = [] content.append(sent) seg = ltp.pipeline(content, tasks=['cws'])['cws'] result = '' for word in seg[0]: if result == '': result = word else: result = result + ' ' + word return result def read_data(file_path): """ 读取数据并分词 """ logger.info("Loading train data") train = pd.read_csv(file_path, sep='\t', encoding='utf-8') # 准备数据 subject_name = train["subject_name"] sub_dis_name = train["sub_discipline_name"] tags_name = train["tag_names"] subject_name.fillna(value="",inplace=True) sub_dis_name.fillna(value="",inplace=True) tags_name.fillna(value="",inplace=True) subject_text = subject_name+sub_dis_name+tags_name logger.info("Starting tokenize...") train['token_content'] = subject_text.progress_apply(tokenizer) return train def train_w2v(train, to_file): # 所有有句子 sentences = [row.split() for row in train['token_content']] # cpu的核数 cores = multiprocessing.cpu_count() w2v_model = Word2Vec(min_count=1, # min_count为1确保一些专业词不成为OOV词 window=5, vector_size=word2vec_dim, sample=6e-5, alpha=0.03, min_alpha=0.0007, negative=15, workers=cores//2, epochs=30) t = time() w2v_model.build_vocab(sentences) logger.info('Time to build vocab: {} mins'.format(round((time() - t) / 60, 2))) t = time() w2v_model.train(sentences, total_examples=w2v_model.corpus_count, epochs=30, report_delay=1) logger.info('Time to train word2vec: {} mins'.format(round((time() - t) / 60, 2))) if not os.path.exists(os.path.dirname(to_file)): os.mkdir(os.path.dirname(to_file)) w2v_model.save(to_file) logger.info('train word2vec finished.') if __name__ == "__main__": train = read_data(subjects_data_path) train_w2v(train, subject_faiss_w2v_path)