发布时间:2025-12-09 18:57:56 浏览次数:17
我们下载好搜狗新闻的语料库之后,会发现我们的数据是这样的:
</doc><doc><url>http://news.163.com/12/0727/13/87E4GD4600014JB5.html</url><docno>c3a2c1b2db10c944-b345d9a362314a50</docno><contenttitle>宏皓:中国企业如何应对奥运赛场外的"品宣战"</contenttitle><content></content></doc>用以下代码读取数据:
import codecsimport refrom tqdm import tqdmfile_path=r"D:\pythonworkspace\NLP_project\news_tensite_xml.dat" #原始的语料信息save_path=r"D:\pythonworkspace\NLP_project\SougouNews_dataset.txt" #处理后只有文章内容的语料seg_save_path=r"D:\pythonworkspace\NLP_project\SougouNews_daraset_Seg.txt" #文章内容分析后的语料#read fileprint("read news dataset:",file_path)with open(file_path, encoding='gb18030') as f:news_data = f.read().encode('gbk', 'ignore').decode('gbk')#print(news_data)读取完之后,就要进行下一步的工作了。
数据清洗,就是在语料中找到我们感兴趣的东西,把不感兴趣的、视为噪音的内容清洗删除,包括对于原始文本提取标题、摘要、正文等信息,对于爬取的网页内容,去除广告、标签、HTML、JS 等代码和注释等。
常见的数据清洗方式有:人工去重、对齐、删除和标注等,或者规则提取内容、正则表达式匹配、根据词性和命名实体提取、编写脚本或者代码批处理等。
在这个例子中,我们所说的语料清洗,指的就是只获取content标签之间的内容:
可以看到上面有两个函数:stringQ2B和stringpartQ2B这两个函数是处理文本内容的,具体的我还没有看,等回头看了再重新写个专题补上:
def is_Qnumber(uchar):"""判断一个unicode是否是全角数字"""if uchar >= u'\uff10' and uchar <= u'\uff19':return Trueelse:return Falsedef is_Qalphabet(uchar):"""判断一个unicode是否是全角英文字母"""if (uchar >= u'\uff21' and uchar <= u'\uff3a') or (uchar >= u'\uff41' and uchar <= u'\uff5a'):return Trueelse:return Falsedef Q2B(uchar):"""单个字符 全角转半角"""inside_code = ord(uchar)if inside_code == 0x3000:inside_code = 0x0020else:inside_code -= 0xfee0if inside_code < 0x0020 or inside_code > 0x7e: #转完之后不是半角字符返回原来的字符return ucharreturn 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])分词可以直接用python中的jieba库:
with codecs.open(seg_save_path, 'w', encoding='utf8') as fw:for content in tqdm(news_content):content = re.sub(r'<content>|</content>|\s', '', content)# content = stringQ2B(content) # 全部全角转半角item = stringpartQ2B(item) # 只有数字字母全角转半角if content != "":# 这里分词调用的是jieba 也可以使用其它分词工具content_seg = jieba.cut(content.strip())fw.write(" ".join(content_seg) + "\n")词性标注和去停用词还没有动手去实践,所以在这里先不写。
这里有一个详细讲解各种预处理的博客:https://blog.csdn.net/qq_35273499/article/details/79098689
做完语料预处理之后,接下来需要考虑如何把分词之后的字和词语表示成计算机能够计算的类型。显然,如果要计算我们至少需要把中文分词的字符串转换成数字,确切的说应该是数学中的向量。有两种常用的表示模型分别是词袋模型和词向量。
即不考虑词语原本在句子中的顺序,直接将每一个词语或者符号统一放置在一个集合(如 list),然后按照计数的方式对出现的次数进行统计。统计词频这只是最基本的方式,TF-IDF 是词袋模型的一个经典用法。
词向量是将字、词语转换成向量矩阵的计算模型。目前为止最常用的词表示方法是 One-hot,这种方法把每个词表示为一个很长的向量。这个向量的维度是词表大小,其中绝大多数元素为 0,只有一个维度的值为 1,这个维度就代表了当前的词。
还有 Google 团队的 Word2Vec,其主要包含两个模型:跳字模型(Skip-Gram)和连续词袋模型(Continuous Bag of Words,简称 CBOW)。
以及两种高效训练的方法:负采样(Negative Sampling)和层序 Softmax(Hierarchical Softmax)。值得一提的是,Word2Vec 词向量可以较好地表达不同词之间的相似和类比关系。除此之外,还有一些词向量的表示方式,如 Doc2Vec、WordRank 和 FastText 等。
这个后面肯定是还要再学习的,只不过在今天,也学习了一点,就是说在对语料进行预处理之后,我们就可以构建词向量了,今天用的是word2vec模型,直接用gensim库中的word2vec函数就可以实现:
首先定义词向量模型的训练函数:
然后加载词向量模型,其实我一直对词向量模型都不太理解,但是今天实践了之后,我觉得和神经网络中的什么vgg,resnet其实都差不多,只不过是说我们训练的vgg和resnet之后,有一个权重保存为.h5文件了,模型本身是没有变的,而词向量模型就类似于神经网络模型中的权重文件,个人理解.
def load_word2vec_model(w2v_path){# load word2vecmodel = word2vec.KeyedVectors.load_word2vec_format(w2v_path, binary=True)return model} dataset_path=r"D:\pythonworkspace\NLP_project\SougouNews_daraset_Seg.txt"save_model_path =r"D:\pythonworkspace\NLP_project\word2vec_model.bin"train_word2vec(dataset_path, save_model_path, size=100, window=5, binary=True)当用word2vec训练完语料库的词向量之后,就可以用它来做一些事情了:
(1)找出某一词向量最相近的集合
(2)查看两个词向量的相近程度
(3)找出一组集合中不同的类别
结果:
美丽 和 漂亮 的相似度为 0.6385814与北京最相近的3个字的词石家庄 0.636853039264679北京市 0.5878795385360718哈尔滨 0.5805991888046265北京站 0.5749763250350952五棵松 0.5512964129447937和 新华社 与相关的词有:中新社 0.7977388501167297新华网 0.6743009686470032中新网 0.6310275793075562胡续 0.6224453449249268中国日报 0.6152859330177307北京 上海 人民 石家庄上述中不同类的名词 人民