本文目录:
新闻预料预处理(全角转换成半角,xml格式提取内容,分词)
word2vec训练词向量(gensim生成并保存模型)
本文使用的是搜狗新闻语料库,原始语料是类似下图中xml格式,首先需要提取中语料中正真的新闻内容,就是中对应的文本。还需要过滤一些特殊字符,以及半角和全角的转换问题。
语料的下载,官方地址:https://www.sogou.com/labs/resource/cs.php ,需要填一些信息。
百度云盘的备份,链接:https://pan.baidu.com/s/1n1IQxsb2Kbi2IHz9Cst7mg 提取码:r1n2
下面看一下详细的处理过程。首先是一个全角转半角的辅助程序,全角和半角转换的详细情况请参考:
Python实现全角与半角相互转换:https://blog.csdn.net/huanghaocs/article/details/90384163
def is_Qnumber(uchar):
"""判断一个unicode是否是全角数字"""
if uchar >= u'\uff10' and uchar <= u'\uff19':
return True
else:
return False
def is_Qalphabet(uchar):
"""判断一个unicode是否是全角英文字母"""
if (uchar >= u'\uff21' and uchar <= u'\uff3a') or (uchar >= u'\uff41' and uchar <= u'\uff5a'):
return True
else:
return False
def Q2B(uchar):
"""单个字符 全角转半角"""
inside_code = ord(uchar)
if inside_code == 0x3000:
inside_code = 0x0020
else:
inside_code -= 0xfee0
if inside_code < 0x0020 or inside_code > 0x7e: #转完之后不是半角字符返回原来的字符
return uchar
return chr(inside_code)
def stringQ2B(ustring):
"""把字符串全角转半角"""
return "".join([Q2B(uchar) for uchar in ustring])
def stringpartQ2B(ustring):
"""把字符串中数字和字母全角转半角"""
return "".join([Q2B(uchar) if is_Qnumber(uchar) or is_Qalphabet(uchar) else uchar for uchar in ustring])
具体处理过程,首先读取xml格式语料,然后提取content部分内容,去除符号标记,最后保存语料为文本格式,也可以选择分词后在保存,分词后保存可以直接用于word2vec模型训练词向量。
import codecs
import re
import jieba
from tqdm import tqdm
file_path = r'/path/news_tensite_xml.dat' # 原始语料
save_path = r'/path/SougouNews_Dataset.txt' # 处理后只有文章内容的语料
seg_save_path = r'/path/SougouNews_Dataset_Seg.txt' # 文章内容分词后的语料
# read file
print("read news dataset:", file_path)
with codecs.open(file_path, encoding='GB2312', errors="ignore") as fr:
news_data = fr.read()
# extract the text between and
print("extract news content ...")
news_content = re.findall('.* ', news_data)
# write to text file without segment
print("write content to text file ...")
with codecs.open(save_path, 'w', encoding='utf8') as fw:
# 注意tqdm只是一个进度条 也可以不需要
for item in tqdm(news_content):
item = re.sub(r'| |\s', '', item)
# item = stringQ2B(item) # 全部全角转半角
item = stringpartQ2B(item) # 只有数字字母全角转半角
if item != "":
fw.write(item + '\n')
下面是对语料分词后写入文件,这里使用的是jieba分词工具,也可以选择其它分词工具。
# segment and write to text file
with codecs.open(seg_save_path, 'w', encoding='utf8') as fw:
for content in tqdm(news_content):
content = re.sub(r'| |\s', '', content)
# content = stringQ2B(content) # 全部全角转半角
item = stringpartQ2B(item) # 只有数字字母全角转半角
if content != "":
# 这里分词调用的是jieba 也可以使用其它分词工具
content_seg = jieba.cut(content.strip())
fw.write(" ".join(content_seg) + "\n")
对语料预处理完后,可以使用已经分词的语料训练word2vec,这里分词后的语料是可以加上自己整理的其它语料,这样可以更加丰富我们的语料库。
word2vec模型的原理这里不再讲解,另一篇博客已经详细介绍,这里是给个实例,基于上面处理好的语料训练词向量,使用的工具是gensim中自带的word2vec模型。
import logging
import gensim.models as word2vec
from gensim.models.word2vec import LineSentence
def train_word2vec(dataset_path, model_path, size=100, window=5, binary=True):
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
# 把语料变成句子集合
sentences = LineSentence(dataset_path)
# 训练word2vec模型
model = word2vec.Word2Vec(sentences, size=size, window=window, min_count=5, workers=4, iter=10)
# 保存word2vec模型
if binary:
model.wv.save_word2vec_format(model_path, binary=True)
else:
model.wv.save_word2vec_format(model_path, binary=False)
def load_word2vec_model(w2v_path):
# load word2vec
model = word2vec.KeyedVectors.load_word2vec_format(w2v_path, binary=True)
return model
def calculate_most_similar(model, word):
similar_words = model.most_similar(word)
print(word)
for term in similar_words:
print(term[0], term[1])
dataset_path = "/path/SougouNews_Dataset_Seg.txt"
save_model_path = "word2vec_model.bin" # save_binary=True
# save_model_path = "word2vec_model.txt" # save_binary=False
train_word2vec(dataset_path, save_model_path, size=100, window=5, binary=True)
word2vec模型训练完后,可以计算词语之间的相似度,以及与每次词最相似的词。也可以做为其它NLP相关任务的词向量预训练输入。