【文本摘要项目】1-数据预处理与词向量训练

背景

    本系列以百度大脑某次比赛内容作为学习任务,记录下完成任务过程中设计的知识点以及涉及的相关技术。之所以选择该任务(比赛已经结束),是因为该任务中设计文本摘要多轮对话等,在自然语言处理中较为核心的问题,因此假装自己在处理该任务,并学习记录下处理该任务设计的知识点。
    该任务主题为汽车大师问答摘要与推理。要求使用汽车大师提供的11万条 技师与用户的多轮对话与诊断建议报告。具体任务描述参见原始网站内容,附链接:原始任务详情描述
    本文为处理该任务时面临的第一个问题:文本处理、文本表示(词向量)等内容,特此记录过程的主要技术点,目的是方便后续类似任务时查阅。

核心内容

    第一篇内容较为简单,从搭建环境到具体做了哪些内容,以及中间的一些技巧,主要包含两个方面:文本预处理和文本表示,其中文本表示采用gensim训练词向量;文本处理包括:数据清洗、文本分词(句)、过滤、去停用词等内容。先简单实现,后面继续深入整理优化,例如处理oov(out of vocabulary)等问题。

文本预处理

1. 原始数据处理

    对原始数据处理包括去除重复、去除nan等内容,整个过程中利用pandas对数据进行处理。样例如下:

# 0. 数据读取
dataframe = pd.read_csv(csv_file_path)

# 1. 空值、重复值处理
dataframe.dropna(subset['Report'], inplace=True)
dataframe.fillna('', inplace=True)
dataframe.drop_duplicates(keep='first', inplace=True)
2. 针对每条数据的预处理

    针对每条数据的处理,里面用了一个小技巧:并发处理dataframe。由于原始dataframe较大,因此考虑将其分解若干个(cpu个数)小块,每一块并行进行预处理,最后将每个核处理的结果进行拼接,得到最终的处理结果。

# 2. 句子处理
dataframe = multi_process_csv(dataframe, func=sentences_proc)
def multi_process_csv(dataframe, func):    

    # 数据切分    
    data_split = np.array_split(dataframe, cpu_cores)    

    # 并发处理    
    with Pool(processes=cpu_cores) as pool:        
        dataframe = pd.concat(pool.map(func, data_split))    
    
    pool.close()    
    pool.join()    

    return dataframe

    这里面一个比较巧妙的点在于数据划分,将原始数据划分为若干个dataframe后,又能利用dataframe的并行处理效果,双重省时。其中func为文本预处理函数。接下来考虑编写func中所做的事情。

def sentences_proc(dataframe):
    col_list = ['Brand', 'Model', 'Question', 'Dialogue',  'Report']
    
    for col in col_list:    
        if col in dataframe.columns:        
            dataframe[col] = dataframe[col].apply(sentence_proc, )
            
    return dataframe
def sentence_proc(sentence):    
    # 将原对话拆分为若干个句子    
    sent_generator = sentence.split('|')    
    
    # 每个句子分别进行分处理    
    # 1. 去除非中文符号    
    sent_generator = (clean_sent(sent) for sent in sent_generator)    
    # 2. 分词处理    
    sent_generator = (seg_words(sent) for sent in sent_generator)    

    # 重新组合成处理后的句子    
    return ' '.join(sent_generator)

    注意,这里有一个点:generator 部分,本来这儿应该用列表推导式[ ],但是,用( )会得到一个生成器,速度更快。中间涉及两个函数对句子处理的函数,样例如下:

def clean_sent(sent):    
    """      
    :param sent: strings      
    :return: 去除非中文字符      
    """   
    sent = re.sub(r'[^\u4e00-\u9fa5]', '', sent)   
    return sent
def seg_words(sent):    
    # 分词    
    word_generator = jieba.cut(sent)   
    # 过滤条件1    
    word_generator = (word for word in word_generator if word and word not in remove_words)    
    # 过滤条件2    
    word_generator = (word for word in word_generator if word and word not in stop_words)
    
    return ' '.join(word_generator)

    至此,数据预处理部分基本完成,将处理后的文本保存并构建词向量训练所需要的格式。

词向量训练

def train_word2vec(file_path=config.merged_seg_path):    
    # 训练词向量    
    model = Word2Vec(        
            LineSentence(source=file_path),
            vector_size=config.embedding_dim,        
            sg=1,        
            workers=cpu_cores,        
            window=5,        
            min_count=5,        
            epochs=config.word2vec_train_epochs,)    
       
       return model

    这中间有一个有一个点:LinSentence可接收两种参数来训练,一个是file对象,一个str对象。

总结

  • dataframe切分,然后利用每个cup并行对csv文件进行处理,这个点比较新颖。
  • ( )比列表推到式更快。
  • 词向量训练的参数可接受file对象。

完整代码

text summary

posted @ 2021-05-28 20:19  温良Miner  阅读(556)  评论(0编辑  收藏  举报
分享到: