本文所涉及到的所有資料和代碼見,github
感謝霍姆格雷特的博文,額,我還是比較這種風格的,好的,現在讓我們來訓練自己的詞向量吧。
1、環境配置
- 環境:win10 + python3.6
- 所需工具包:gensim(word2vec)、jieba(中文分詞)
- 以上工具包均用pip install安裝
2、語料庫說明
哎呀,他用的《誅仙》,我就用《斗羅大陸》,文件見GitHub,也可以換成自己喜歡的文檔(如有侵權,請聯繫作者刪除)
3、實驗步驟
3.1、文件編碼轉換
因爲文件*“douluo.txt”*原始編碼爲GBK
,整個項目編碼爲UTF-8,需統一格式。否則直接讀取文本將得到亂碼。
在項目中新建一個文件gbk2utf8.py
進行編碼轉換,將編碼轉爲UTF-8,存至一個新文件
def gbk2utf8():
file_out = open('data/douluo_utf8.txt', 'w', encoding="utf-8") # 輸出文件路徑
with open('data/douluo.txt', 'r', encoding="GB18030") as file_object:
for line in file_object:
line = line.strip()
file_out.write(line + "\n")
file_out.close()
print("end")
所做工作就是解碼原始文件,逐句讀取,去除空白,在用uft-8編碼,寫入新的文件‘douluo_uft8.txt’。處理後,一下子舒服了好多。
3.2、 中文分詞
分詞用的工具是結巴分詞,將分詞結果寫入到新的文件“douluo_cut_word.txt”
。爲了更高的分詞準確率,本文使用了停用詞表 stop_words.txt
與用戶字典表 user_dict.txt
,均在github中可以下載。
在項目中新建seg_words.py
文件,並填入以下內容
import jieba
def seg_words():
# 定義一些常量值,多次調用的文件路徑放在這裏,容易修改
origin_file = "data/douluo_utf8.txt" # 初代文件
stop_words_file = "data/stop_words.txt" # 停用詞路徑
user_dict_file = "data/user_dict.txt" # 用戶自定義詞典路徑
stop_words = list()
# 加載停用詞
with open(stop_words_file, 'r', encoding="utf8") as stop_words_file_object:
contents = stop_words_file_object.readlines()
for line in contents:
line = line.strip()
stop_words.append(line)
# 加載用戶字典
jieba.load_userdict(user_dict_file)
target_file = open("data/douluo_cut_word.txt", 'w', encoding="utf-8")
with open(origin_file, 'r', encoding="utf-8") as origin_file_object:
contents = origin_file_object.readlines()
for line in contents:
line = line.strip()
out_str = ''
word_list = jieba.cut(line, cut_all=False)
for word in word_list:
if word not in stop_words:
if word != "\t":
out_str += word
out_str += ' '
target_file.write(out_str.rstrip() + "\n")
target_file.close()
print("end")
分詞後的結果如下,效果還可以,如果需要更好的效果,需要自己調整。
3.3、模型訓練
新建文件train_model.py
,調用gensim庫進行word2vec模型的訓練
import logging
import os
import sys
import multiprocessing
from gensim.models import Word2Vec
from gensim.models.word2vec import PathLineSentences
def train_model():
# 日誌信息輸出
program = os.path.basename(sys.argv[0])
logger = logging.getLogger(program)
logging.basicConfig(format='%(asctime)s: %(levelname)s: %(message)s')
logging.root.setLevel(level=logging.INFO)
logger.info("running %s" % ' '.join(sys.argv))
# input爲輸入語料, outp1爲輸出模型, outp2位vector格式的模型
input_dir = 'data/douluo_cut_word.txt'
outp1 = 'model/douluo.model'
outp2 = 'model/douluo.vector'
# 訓練模型
# 輸入語料目錄:PathLineSentences(input_dir)
# embedding size:256 共現窗口大小:10 去除出現次數5以下的詞,多線程運行,迭代10次
model = Word2Vec(PathLineSentences(input_dir),
size=256, window=10, min_count=5,
workers=multiprocessing.cpu_count(), iter=10)
model.save(outp1) # 存儲二進制模型文件
model.wv.save_word2vec_format(outp2, binary=False) # 存儲類似於數組的模型文件
3.4、模型測試
新建test.py
文件
import warnings
import gensim
if __name__ == '__main__':
warnings.filterwarnings(action='ignore', category=UserWarning,module='gensim')
model = gensim.models.Word2Vec.load("model/douluo.model")
word = '寧榮榮'
result = model.similar_by_word(word)
print("跟 "+word+" 最相近的詞:")
for i in result:
print(i)
最終的結果如下:
3.5、項目目錄
項目可以不一個個執行,可直接執行main.py
4、擴展知識
1,高級優化技巧入門
- 包含大數據分詞,提高效率等
- 如何讀入一個目錄的訓練語料
- 通過numpy調用模型