python下读sougou中文语料文件

下载的sougou中文语料文件是xml格式的,有1.5G,需要在python下进行正文的提取及中文分词工作。


1. 首先,进行正文的提取,有几个需要注意的细节。


a. 检测文件的中文编码

在python下安装chardet包,使用chardet检查中文格式. 注意读文件时使用的是'rb'.

b. 读取原始数据

在获取了中文编码格式后,使用codecs包,注意参数errors="ignore"的使用,否则会出现以下类似错误:

UnicodeDecodeError: 'gb2312' codec can't decode byte 0xfd in position 440: illegal multibyte sequence


c. 在处理大的文件时,for循环里不要做类似以下的操作,否则速度非常慢。

text_str  = '';

for item in a:

  b = item.replace('<content>','');

  text_str = text_str + (b.replace('</content>',''));

读大文件,linecache.getlines也可以用于加速文件操作。



d. 在写入文件时,特意增加了'\n',这样方便后续的“按行读文件”操作。

   (增加换行符后的文本,在notepad++里的显示如下图,因为有个分行和行号,看起来很方便。)

   


完整的代码如下:

import chardet
import codecs
import re

def detect_file_encoding(file_path):
    ''' 返回文件的编码 '''
    f = open(file_path, 'rb')
    data = f.read()
    predict =  chardet.detect(data)
    f.close()
    return predict['encoding']

if __name__ == '__main__':
    # detect file encode type 
    file_path = r'D:\Work\NLP\Dataset\new\sogou\news_tensite_xml.dat';
    print( detect_file_encoding(file_path) )
    
    # read file
    f2 = codecs.open(file_path, encoding='GB2312', errors="ignore")
    content2 = f2.read();
    f2.close()

    # write to text file
    f = codecs.open(r'D:\Work\NLP\Dataset\new\sogou\output\news_tensite_xml.txt', 'w',encoding='utf8');

    # exact the text between <content> and  </content>
    a = re.findall('<content>.*</content>', content2)
    print("Length of list: %d" % len(a));
    i = 0;
    for item in a:
      b = item.replace('<content>','');
      b = b.replace('</content>','');
      f.write(str(b)+'\n');
      i = i+1;
      if i%1000 == 0:
        print("index: %d / %d" % (i,len(a)));
    
    f.close();



2. 使用jieba进行中文分词工作,完整代码如下。

这里需要注意的是,输入给jiebad的是每行字符串,而不是整个文件作为字符串(太大了)。

import jieba
import codecs
import datetime

inp = r'D:\Work\NLP\Dataset\new\sogou\tmp\news_tensite_xml.txt';
outp = r'D:\Work\NLP\Dataset\new\sogou\output\news_tensite_xml_segment.txt';

finput = codecs.open(inp, encoding='utf8', errors="ignore")
foutput = codecs.open(outp, 'w',encoding='utf8');
space = " ";

i = 0;
start = datetime.datetime.now()
for line in finput: 
  i = i+1;
  if i%1000 == 0:
    print(i);
  line_seg = jieba.cut(line) 
  foutput.write(space.join(line_seg));

end = datetime.datetime.now()
print (end-start)    

  
finput.close() 
foutput.close() 


附加: 使用以上分词的结果进行word2vec训练,代码如下。

# -*- coding: utf-8 -*- 
# train_word2vec_model.py用于训练模型 
import logging 
import os.path 
import sys 
import multiprocessing 
from gensim.models import Word2Vec 
from gensim.models.word2vec import LineSentence 
import datetime

if __name__=='__main__': 
  program = os.path.basename(sys.argv[0]) 
  logger = logging.getLogger(program) 
  logging.basicConfig(format='%(asctime)s: %(levelname)s: %(message)s') 
  logging.root.setLevel(level=logging.INFO) 
  logging.info("running %s" % ' '.join(sys.argv)) 


  #inp = r'D:\Work\NLP\Dataset\new\sogou\output\news_tensite_xml.smarty_segment.txt';
  #outp = r'D:\Work\NLP\Dataset\new\sogou\output\news_tensite_xml.smarty_corpus.mode';
  #outp2 = r'D:\Work\NLP\Dataset\new\sogou\output\news_tensite_xml.smarty_corpus.vector';
  inp = r'D:\Work\NLP\Dataset\new\sogou\output\news_tensite_xml_segment.txt';
  outp = r'D:\Work\NLP\Dataset\new\sogou\output\news_tensite_xml_corpus.mode';
  outp2 = r'D:\Work\NLP\Dataset\new\sogou\output\news_tensite_xml_corpus.vector';
  
  start = datetime.datetime.now()
  model = Word2Vec(LineSentence(inp),size=400,window=5,min_count=5)
  model.save(outp) 
  model.wv.save_word2vec_format(outp2,binary=False)
  
  end = datetime.datetime.now()
  print (end-start)  

附加: 训练完后测试word2vec,代码如下。

import gensim

model = gensim.models.Word2Vec.load(r'D:\Work\NLP\Dataset\new\sogou\output\news_tensite_xml_corpus.mode')

result = model.most_similar(u'喜欢')
for word in result:
   print( word[0],word[1] )

得到的结果如下:







猜你喜欢

转载自blog.csdn.net/sunfoot001/article/details/75795664