導(dǎo)語(yǔ)
現(xiàn)在問(wèn)答機(jī)器人真是火的不要不要的,大致分為兩類:普適多場(chǎng)景的和單一專業(yè)場(chǎng)景的問(wèn)答機(jī)器人。由于資源有限财著,不知死活的筆者只做了單一場(chǎng)景的分類器,如對(duì)海量數(shù)據(jù)撑碴、多場(chǎng)景的問(wèn)答機(jī)器人感興趣的話可以參考QA問(wèn)答系統(tǒng)中的深度學(xué)習(xí)技術(shù)實(shí)現(xiàn)撑教,對(duì)于該網(wǎng)站在NLP方面的貢獻(xiàn)簡(jiǎn)直不能更感激(請(qǐng)?jiān)试S獻(xiàn)上我的膝蓋)!
1. 問(wèn)答語(yǔ)料庫(kù)
由于僅面向業(yè)務(wù)灰羽,場(chǎng)景單一驮履,所以訓(xùn)練集語(yǔ)料庫(kù)只包含20類鱼辙,共400多條問(wèn)題廉嚼,每類問(wèn)題對(duì)應(yīng)一個(gè)回答。
2. 訓(xùn)練詞向量
不知死活的筆者決定興師動(dòng)眾的選擇word2vec將訓(xùn)練集語(yǔ)料轉(zhuǎn)化為詞向量作為模型的輸入倒戏。關(guān)于word2vec的原理及其C語(yǔ)言的詞向量訓(xùn)練方法怠噪,請(qǐng)參考word2vec詞向量訓(xùn)練及中文文本相似度計(jì)算以及該博文內(nèi)的鏈接。筆者根據(jù)【python gensim使用】word2vec詞向量處理中文語(yǔ)料用Python訓(xùn)練的中文詞向量模型杜跷。(英文的詞向量訓(xùn)練可以參考
利用Gensim訓(xùn)練關(guān)于英文維基百科的Word2Vec模型(Training Word2Vec Model on English Wikipedia by Gensim))
2.1 中文語(yǔ)料庫(kù)
可以參考Windows下使用Word2vec繼續(xù)詞向量訓(xùn)練中提到的語(yǔ)料庫(kù)傍念,不知死活的筆者選擇從搜狗實(shí)驗(yàn)室下載了全網(wǎng)新聞?wù)Z料,不得不說(shuō)葛闷,搜狗實(shí)驗(yàn)室是非常具有貢獻(xiàn)力的憋槐!完整版1.02G,解壓后2.22G淑趾,共378個(gè)文件阳仔,HTML格式,你值得擁有扣泊!
2.2 分詞合并
首先是分詞近范,可供選擇的工具有很多:Jieba、ANSJ延蟹、NLPIR评矩、LTP等等,在此筆者選擇Jieba進(jìn)行分詞:
import jieba
def readLines(filename):
# read txt or csv file
fp = open(filename, 'r')
lines = []
for line in fp.readlines():
line = line.strip()
line = line.decode("utf-8")
lines.append(line)
fp.close()
return lines
def parseSent(sentence):
# use Jieba to parse sentences
seg_list = jieba.cut(sentence)
output = ' '.join(list(seg_list)) # use space to join them
return output
然后將所有文檔合并阱飘,并寫(xiě)入corpus.csv中:
import re
import codecs
import os
# only content is valid
pattern = "<content>(.*?)</content>"
csvfile = codecs.open("corpus.csv", 'w', 'utf-8')
fileDir = os.listdir("./corpus/")
for file in fileDir:
with open("./corpus/%s" % file, "r") as txtfile:
for line in txtfile:
m = re.match(pattern, line)
if m:
segSent = parseSent(m.group(1))
csvfile.write("%s" % segSent)
特別mark以下斥杜,codecs這個(gè)包在調(diào)整編碼方面的貢獻(xiàn)真的不要太大,尤其是常常對(duì)于中文編碼無(wú)力的不知死活的筆者來(lái)說(shuō)沥匈,簡(jiǎn)直是神器蔗喂!
對(duì)于中文的編碼處理:utf-8 --> unicode --> utf-8
2.3 訓(xùn)練word2vec模型
在此,筆者使用gensim的word2vec進(jìn)行詞向量的訓(xùn)練:
from gensim.models import word2vec
import logging
logging.basicConfig(format = '%(asctime)s : %(levelname)s : %(message)s', level = logging.INFO)
sentences = word2vec.Text8Corpus("corpus.csv") # 加載語(yǔ)料
model = word2vec.Word2Vec(sentences, size = 400) # 訓(xùn)練skip-gram模型
# 保存模型咐熙,以便重用
model.save("corpus.model")
# 對(duì)應(yīng)的加載方式
# model = word2vec.Word2Vec.load("corpus.model")
# 以一種C語(yǔ)言可以解析的形式存儲(chǔ)詞向量
model.save_word2vec_format("corpus.model.bin", binary = True)
# 對(duì)應(yīng)的加載方式
# model = word2vec.Word2Vec.load_word2vec_format("corpus.model.bin", binary=True)
關(guān)于調(diào)參弱恒,可自行參考gensim文檔。
2.4 獲得詞向量
接下來(lái)就是使用上述獲得的model將訓(xùn)練集的中文語(yǔ)料轉(zhuǎn)化為詞向量:
def getWordVecs(wordList):
vecs = []
for word in wordList:
word = word.replace('\n', '')
try:
# only use the first 500 dimensions as input dimension
vecs.append(model[word])
except KeyError:
continue
# vecs = np.concatenate(vecs)
return np.array(vecs, dtype = 'float')
3. 構(gòu)建模型
3.1 Naive Bayes
效果良好棋恼,效率高返弹!
from sklearn.naive_bayes import MultinominalNB
MNB = MultinominalNB(alpha = 0.000607)
3.2 Random Forest
效果良好锈玉,效率一般。
from sklearn.ensemble import RandomForestClassifier
RFC = RandomForestClassifier(min_samples_leaf = 3, n_estimators = 100)
3.3 RBM + Logistic Regression
效果很好义起,效率很低……由于這個(gè)模型只需要訓(xùn)練一次拉背,所以效率關(guān)系不大(抱歉我隨便亂用模型,實(shí)際上這模型本身來(lái)源于sklearn上的實(shí)例……原本著使用效果至上的原則默终,然而至于為何這樣搭配……)
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.neural_network import BernoulliRBM
rbm.learning_rate = 0.07
rbm.n_iter = 50
# more components tend to give better prediction performance, but larger fitting time
rbm.n_components = 800
rbm.batch_size = 10
logistic.C = 10000.0
rbm = BernoulliRBM(random_state = 0, verbose = True)
logistic = LogisticRegression()
clf = Pipeline(steps = [('rbm', rbm), ('logistic', logistic)])
總的來(lái)說(shuō)椅棺,神經(jīng)網(wǎng)絡(luò)(例如MLP)對(duì)這類文本分類問(wèn)題效果普遍不錯(cuò),至于傳統(tǒng)機(jī)器學(xué)習(xí)算法齐蔽,樸素貝葉斯也有不俗的表現(xiàn)两疚。
4. 其他
這次學(xué)習(xí)到sklearn
中一個(gè)非常有用的功能sklearn.externals.joblib
,可用于導(dǎo)出訓(xùn)練好的模型含滴,這對(duì)于training cost非常高的模型來(lái)說(shuō)實(shí)在是非常好用坝詹场!
from sklearn.externals import joblib
# save classifier
joblib.dump(clf, "Classifier.pkl")
# load classifier
clf = joblib.load("Classifier.pkl")
其次就是sklearn
中的sklearn.pipeline.Pipeline
谈况,將多個(gè)模型結(jié)合在一起勺美,通過(guò)Pipeline的方式進(jìn)行訓(xùn)練,真的是非常方便氨稀赡茸!
from sklearn.pipeline import Pipeline
clf = Pipeline(steps = [clf1, clf2])