Tensorflow的TextCNN在搜狗新聞數據的文本分類
開發環境:
- python環境:python3
- 編譯器:pycharm
- 文本編輯器:Notepad++
- 開發框架:Tensorflow
- 系統環境:Windows10
數據集準備和處理:
本文用到的數據集來自搜狗實驗室提供的新聞數據,涵蓋了國內,國際,體育,社會,娛樂等 18 個頻道的新聞數據,不過數據集的質量不是特別高,存在大量的分類不清晰、文不對題數據。限於單機的性能我只下載了精簡版的一個月數據,大約 347M。用Notepad打開可以看到文本的樣式如下:
是xml格式,基於中文的GB2313編碼,每一個<doc>
與</doc>
之間是一篇單獨的新聞,包含 URL、文檔編號、標題和正文,其中新聞的分類類別在 URL 的子域名中,如 sports 代表體育,house 代表房產等等,所以本文只需要拿到 URL 和 content 之間的內容就行,接下來就要進行對數據的清理,提取出我們需要的數據(URL中的categories和content)。
下載下來的原始數據分為 128 個 TXT 文件,每個文件中包含有不同類別的新聞數據,我要做的是遍歷每個文件,然後把相同類別的新聞提取出來並寫入新的文件中。讀取中文 txt 文檔亂碼是個比較麻煩的問題,要弄清其編碼的格式才能保證讀出來的不是亂碼,否則沒法對數據進行後續分類操作(但即便這樣,我讀出來還是有很多亂碼,看來python對中文編碼的支持還是存在一些問題),這裏用到了一個叫做chatdet的python庫,通過這個庫可以查看我們文檔的編碼格式是什麽樣的,先可以寫一個測試代碼測試該txt數據的編碼格式,代碼如下:
import os import chardet cur_dir= os.getcwd() list_dirs = os.listdir(‘data‘) for file in list_dirs: file_path = os.path.join(‘data‘,file) f = open(file_path, ‘rb‘) f_read = f.read() f_charInfo = chardet.detect(f_read) print(f_charInfo)
可以看出,該庫對文本的編碼預測是GB2312(當置信度大於90%時我覺得是可信的)。知道了編碼後,我們就可以提出 URL 和 content,需要用正則表達式把子域名拿出來,最後得到 15 個按類別分好的文件,除去一些亂碼較多的文件,最終留下了 11 個類別,留下的類別如下:
數據處理代碼:
#!/user/bin/python # -*- coding: utf-8 -*- import os import re def _read_file(txt_file): # 讀取txt文件 return open(txt_file,"rb").read().decode("GB2312","ignore") def extract_class_content(doc): # 提取分類和內容 url = doc.split(‘<url>‘)[1].split(‘</url>‘)[0] content = doc.split(‘<content>‘)[1].split(‘</content>‘)[0] category = re.findall(r"http://(.*?).sohu.com/",url) return category[0],content def file_writer(category,content): dir_name = ‘category_datas‘ # os.path.join(path, name) 連接目錄和文件名 path = os.path.join(dir_name,category) f = open(path,‘a‘,encoding=‘utf-8‘) f.write(category + ‘\t‘ + content + ‘\n‘) f.close() def category_data(txt_file): # 將每個文件中不同類別的新聞分別存儲 f = _read_file(txt_file) docs_xmls = f.split(‘<doc>\n‘) for doc in docs_xmls: if doc: category,content = extract_class_content(doc) file_writer(category,content) if __name__ == ‘__main__‘: # os.listdir() 指定所有目錄下所有的文件和目錄名 for file in os.listdir(‘data‘): file_path = os.path.join(‘data‘,file) category_data(file_path)
然後,看看各個類別下數據量的分布,發現體育、商業、新聞的數量較多,文化類的比較少,數據分布不太平衡,但這並不影響,因為我們並不會用到全部的數據,而是從每個類別中抽取一部分來訓練模型。
參考文章:
1.解決python讀取txt文件亂碼問題
Tensorflow的TextCNN在搜狗新聞數據的文本分類