【文本摘要项目】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
对象。