1. 程式人生 > >NLP文字解析資料預處理的方法

NLP文字解析資料預處理的方法

假設我們現在有一個文字的多標籤的分類任務。其資料集的格式為w9410 w305 w1893 w307 w3259 w4480 w1718 w5700 w18973 w346 w11 w855 w1038 w12475 w146978 w11 w1076 w25 w7512 w45368 w1718 w4668 w6 w11061 w111 c866 c28 c423 c1869 c1331 c431 c17 c204 c4 c274 c56 c1841 c1770 c3266 c17 c350 c4 c370 c116 c406 c734 c28 c423 c768 c769 c485 c11 c506 c734 c184 __label__807273409165680991 __label__8175048003539471998。可以看到這條資料有兩個標籤。其餘的用字元表示(經過脫敏處理),所以我們需要自己來建立word_vocabulary。

具體如下:

                import codecs
                from collections import Counter 
                #1.load raw data 
		file_object = codecs.open(training_data_path,mode='r',encoding='utf-8')
		lines = file_object.readlines()
		#2.loop each line ,put to counter 
		c_inputs = Counter()
		c_labels = Counter()
		for line in lines:
			raw_list = line.strip().split("__label__")
			input_list = raw_list[0].strip().split(" ")
			print (input_list)
			input_list = [x.strip().replace(" ","") for x in input_list if x!=" "]
			print(input_list)
			label_list = [l.strip().replace(" ","") for l in raw_list[1:] if l!=" "]
			print(label_list)
			c_inputs.update(input_list)
			print(c_inputs)
			c_labels.update(label_list)
			print(c_labels)
		#3 return most frequency words 
		vocab_list = c_inputs.most_common(vocab_size)
		print(vocab_list)
		label_list = c_labels.most_common()
		print(label_list)
		#4 put those words to dict 
		for i ,tuplee in enumerate(vocab_list):
			word,_= tuplee
			vocabulary_word2index[word] = i+2
			vocabulary_index2word[i+2] = word
		for i,tuplee in enumerate(label_list):
			label,_ = tuplee
			label = str(label)
			vocabulary_label2index[label] = i 
			vocabulary_index2label[i] = label
		#save to file system if vocabulary of words not exists .
		if not os.path.exists(cache_path):
			with open(cache_path,'ab') as data_f:
				pickle.dump(vocabulary_word2index,vocabulary_index2word,vocabulary_label2index,vocabulary_index2label)
	return vocabulary_word2index,vocabulary_index2word,vocabulary_label2index,vocabulary_index2label

1。之所以使用codecs.open()方法是因為此方法讀入資料時可以直接解碼。

2. 定義Counter()

c_inputs = Counter()  c_inputs.update(input_list)

其返回的是類似如下的格式:Counter({'c734': 2, 'w1718': 2, 'c28': 2, 'c4': 2, 'c17': 2, 'w11': 2, 'c423': 2, 'w3259': 1, 'w6': 1, 'w9410': 1, 'w18973': 1, 'c506': 1, 'c768': 1, 'c11': 1, 'w305': 1, 'c204': 1, 'c406': 1, 'c1869': 1, 'c485': 1, 'w1076': 1, 'w4668': 1, 'w146978': 1, 'w25': 1, 'c370': 1, 'c1841': 1, 'c1770': 1, 'w346': 1, 'c3266': 1, 'w111': 1, 'c274': 1, 'w45368': 1, 'w1893': 1, 'c1331': 1, 'w307': 1, 'w855': 1, 'c769': 1, 'w11061': 1, 'c350': 1, 'c116': 1, 'w7512': 1, 'c431': 1, 'w4480': 1, 'c56': 1, 'w1038': 1, 'w12475': 1, 'c866': 1, 'w5700': 1, 'c184': 1})

是一個字典,後面使其每個詞出現的頻率,從多到少排序。這個方法的好處,是直接就給出了,不需要我們自己寫程式碼,來計數,排序。

3.c_inputs = Counter()  c_inputs.most_common([n])

most_common()方法是:從多到少返回一個有前n多的元素的列表。如果沒有n,則返回所有的元素。

4.把詞彙列表、標籤列表各轉化為一個字典。

for i ,tuplee in enumerate(vocab_list):

用的enumerate()方法

總結:這樣,我們就把資料提取為word2index的字典形式,然後再把資料data轉化為index的形式,以使計算機能夠處理。

5。將data、label轉為index的形式便於計算機處理

x = [vocabulary_word2index.get(x,UNK_ID) for x in input_list]

通過get方法在字典中找到每個詞的下標,如果該詞沒有在詞彙表中出現,則用UNK_ID作為該詞返回的下標

label_list = [vocabulary_label2index[label] for label in label_list]

得到標籤所對應的下標。

6。y = transform_multilabel_as_multihot(label_list,label_size)

這部分的作用是 將標籤對應的下標進一步變形轉為multihot的形式,就是label_size的長度中,出現過的label其所對應的位置記為1,其餘的為0。轉為0 1 的形式。

7。X = pad_sequences(X, maxlen=sentence_len, value=0.)  # padding to max length

該方法的作用將每個序列都通過填充pad轉為長度為max length的序列,便於處理。其填充的pad字元對應的下標用0表示。

8. 將訓練資料集劃分為驗證集和訓練集兩部分

        num_examples = len(lines)
	trainging_number = int(training_portion*num_examples)
	train = (X[0:trainging_number],Y[0:trainging_number])
	valid_number = min(1000,num_examples-trainging_number)
	test = (X[trainging_number+1:trainging_number+valid_number+1],Y[trainging_number+1:trainging_number+valid_number+1])
	return train,test
最終返回了訓練集與驗證集。其X為每個詞對應的index的形式,是數字。label為每個標籤對應的下標的位置為1,其餘為0。