正文之前的BB時(shí)間
因?yàn)閭€(gè)人實(shí)驗(yàn)需要,要對(duì)Cornell Movie Dialogs Corpus進(jìn)行一些預(yù)處理研叫,記錄一下處理過程孩哑,以后其他類似的數(shù)據(jù)處理可以借鑒老玛。
我的實(shí)驗(yàn)是實(shí)現(xiàn)一個(gè)主題驅(qū)動(dòng)的自動(dòng)聊天機(jī)器人媒峡,Cornell Movie Dialogs Corpus是一個(gè)從電影數(shù)據(jù)中生成的電影對(duì)白語料庫瘟栖,包含大概600部電影對(duì)白,并且語料中含有電影名谅阿、角色慢宗、IMDB評(píng)分等許多信息。但我的實(shí)驗(yàn)中只需要里面的純對(duì)話信息奔穿,將每個(gè)對(duì)話處理成前面幾句是對(duì)話上下文context、最后一句是對(duì)話回復(fù)response敏晤,并需要替換其中的低頻詞贱田,將其保存為tfrecord。
語料庫中原始文件包含:
- movie_titles_metadata.txt 包含每部電影標(biāo)題信息
- movie_characters_metadata.txt 包含每部電影角色信息
- movie_lines.txt 每個(gè)表達(dá)(utterance)的實(shí)際文本
- movie_conversations.txt 對(duì)話的結(jié)構(gòu)嘴脾,用語句ID表示
- raw_script_urls.txt 原始來源的url
*具體介紹可見文章http://blog.csdn.net/zdcs/article/details/53465855
我已經(jīng)用numpy和pandas在jupyter中將上面的文件處理成 convLine.csv 和 lineIndex.csv 兩個(gè)文件男摧,兩個(gè)文件格式如下:
convLine.csv 對(duì)話文件,每個(gè)對(duì)話語句line用ID表示:
L1,L2,L3 || L4,L5,L6,L7,L8 || L9,L10,L11 ...
lineIndex.csv 語句文件译打,每個(gè)語句lineID對(duì)應(yīng)的真正的句子:
L1,hello! || L2, how are you? || L3, fine,thank you. ...
(||表示換行)
下面對(duì)這兩個(gè)文件進(jìn)行處理耗拓,正文開始~~
這里是正文
處理數(shù)據(jù)集的過程有兩輪遍歷。
第一輪遍歷完成文件對(duì)齊奏司、分割seq2seq數(shù)據(jù)集乔询、獲得數(shù)據(jù)集大小和詞匯表;
第二輪遍歷得到忽略詞韵洋、獲得topic訓(xùn)練數(shù)據(jù)集以及寫入tfrecord竿刁。
第一輪遍歷
利用lineIndex.csv 文件建立字典黄锤。
meta_lineIndex_path = os.path.join(config.data_root, 'lineIndex.csv')
convline_dict = {}
with open(meta_lineIndex_path, newline='')as f:
lineIndex_reader = csv.reader(f)
for row in lineIndex_reader:
convline_dict[row[0]] = row[1]
由于數(shù)據(jù)集中有的的對(duì)話比較長、輪數(shù)較多食拜,因此進(jìn)行了采樣鸵熟,將輪次長的對(duì)話拆分成幾個(gè)輪次短的對(duì)話,分割次數(shù)視長度而定负甸。這里需要注意同一個(gè)對(duì)話拆分開后流强,分割數(shù)據(jù)集時(shí)應(yīng)該分到一起。
采樣過程示意:
對(duì)話數(shù)據(jù)
L1, L2, L3, L4, L5, L6, L7, L8
[---對(duì)話1---]
[--------對(duì)話2-------]
[--------------對(duì)話3---------------]
new_max_turn = min(len(row)-1,max_turn)
assert min_turn <= new_max_turn, "context最小輪數(shù)大于最大輪數(shù)"
sampling_count_range = list(map(int, sampling_range.split(',')))
sample_count_tag = bisect.bisect_left(sampling_count_range, new_max_turn)//獲得采樣次數(shù)
context_list = list()
response = list()
while sample_count_tag != 0:
context = list()
context_truns=new_max_turn
if sample_count_tag > 1:
while True:
alternative_context_truns=random.randint(
min_turn,
new_max_turn
)
if alternative_context_truns!=context_truns://防止重復(fù)采樣
context_truns=alternative_context_truns
break
# 處理context
for turn in row[:context_truns]:
word_list = word_tokenize(convline_dict[turn])
context.extend(list(word_list) + [end_of_turn_symbol])
context_list.append(context)
# 處理response
word_list = word_tokenize(convline_dict[row[context_truns]])
response.append(list(word_list) + [end_of_turn_symbol])
#注意多次采樣的context和response分開
sample_count_tag = sample_count_tag-1
采樣后得到了對(duì)話的context和response數(shù)據(jù)呻待,將其分割成訓(xùn)練集打月、測(cè)試集和驗(yàn)證集,更新詞匯表带污。
第二輪遍歷
將數(shù)據(jù)集中的詞表word_list轉(zhuǎn)換為idx_list僵控,并添加忽略詞symbol。
seq2seq_context = token_manager.translate_word_list_to_idx_list(context_word_list, False)
seq2seq_response = token_manager.translate_word_list_to_idx_list([go_symbol] + response_word_list, False)
topic_context = token_manager.translate_word_list_to_idx_list(context_word_list, True)
topic_response = token_manager.translate_word_list_to_idx_list(response_word_list, True)
寫入topic訓(xùn)練數(shù)據(jù)集以及生成tfrecord文件鱼冀。
完成报破!
正文之后再BB兩句
整個(gè)數(shù)據(jù)集處理過程還是比較簡單的,用到的技巧也不多千绪,以后再有其他實(shí)驗(yàn)也算有經(jīng)驗(yàn)了充易。
就是一開始采樣完分割數(shù)據(jù)集時(shí),沒有注意對(duì)同一個(gè)對(duì)話多次采樣獲得多個(gè)對(duì)話應(yīng)該分割到同一個(gè)數(shù)據(jù)集中荸型,差點(diǎn)造成實(shí)驗(yàn)造假盹靴。(|3」∠)。瑞妇。稿静。還好小H童靴幫我發(fā)現(xiàn)了~以后還是要多多注意!