免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Query意圖分析:記一次完整的機器學習過程(scikit learn library學習筆記) | 我愛機器學習
userphoto

2015.11.16

關注

所謂學習問題,是指觀察由n個樣本組成的集合,并根據(jù)這些數(shù)據(jù)來預測未知數(shù)據(jù)的性質。

學習任務(一個二分類問題):

區(qū)分一個普通的互聯(lián)網(wǎng)檢索Query是否具有某個垂直領域的意圖。假設現(xiàn)在有一個O2O領域的垂直搜索引擎,專門為用戶提供團購、優(yōu)惠券的檢索;同時存在一個通用的搜索引擎,比如百度,通用搜索引擎希望能夠識別出一個Query是否具有O2O檢索意圖,如果有則調用O2O垂直搜索引擎,獲取結果作為通用搜索引擎的結果補充。

我們的目的是學習出一個分類器(classifier),分類器可以理解為一個函數(shù),其輸入為一個Query,輸出為0(表示該Query不具有o2o意圖)或1(表示該Query具有o2o意圖)。

特征提取

要完成這樣一個學習任務,首先我們必須找出決定一個Query是否具有O2O意圖的影響因素,這些影響因素稱之為特征(feature)。特征的好壞很大程度上決定了分類器的效果。在機器學習領域我們都知道特征比模型(學習算法)更重要。(順便說一下,工業(yè)界的人都是這么認為的,學術界的人可能不以為然,他們整天搗鼓算法,發(fā)出來的文章大部分都沒法在實際中應用。)舉個例子,如果我們的特征選得很好,可能我們用簡單的規(guī)則就能判斷出最終的結果,甚至不需要模型。比如,要判斷一個人是男還是女(人類當然很好判斷,一看就知道,這里我們假設由計算機來完成這個任務,計算機有很多傳感器(攝像頭、體重器等等)可以采集到各種數(shù)據(jù)),我們可以找到很多特征:身高、體重、皮膚顏色、頭發(fā)長度等等。因為根據(jù)統(tǒng)計我們知道男人一般比女人重,比女人高,皮膚比女人黑,頭發(fā)比女人短;所以這些特征都有一定的區(qū)分度,但是總有反例存在。我們用最好的算法可能準確率也達不到100%。假設計算機還能夠讀取人的身份證號碼,那么我們可能獲得一個更強的特征:身份證號碼的倒數(shù)第二位是否是偶數(shù)。根據(jù)身份證編碼規(guī)則,我們知道男性的身份證號碼的倒數(shù)第二位是奇數(shù),女生是偶數(shù)。因此,有了這個特征其他的特征都不需要了,而且我們的分類器也很簡單,不需要復雜的算法。

言歸正傳,對于O2O Query意圖識別這一學習任務,我們可以用的特征可能有:Query在垂直引擎里能夠檢索到的結果數(shù)量、Query在垂直引擎里能夠檢索到的結果的類目困惑度(perplexity)(檢索結果的類目越集中說明其意圖越強)、Query能否預測到特征的O2O商品類目、Query是否包含O2O產品詞或品牌詞、Query在垂直引擎的歷史展現(xiàn)次數(shù)(PV)和點擊率(ctr)、Query在垂直引擎的檢索結果相關性等等。

特征表示

特征表示是對特征提取結果的再加工,目的是增強特征的表示能力,防止模型(分類器)過于復雜和學習困難。比如對連續(xù)的特征值進行離散化,就是一種常用的方法。這里我們以“Query在垂直引擎里能夠檢索到的結果數(shù)量”這一特征為例,簡要介紹一下特征值分段的過程。首先,分析一下這一維特征的分布情況,我們對這一維特征值的最小值、最大值、平均值、方差、中位數(shù)、三分位數(shù)、四分位數(shù)、某些特定值(比如零值)所占比例等等都要有一個大致的了解。獲取這些值,python編程語言的numpy模塊有很多現(xiàn)成的函數(shù)可以調用。最好的辦法就是可視化,借助python的matplotlib工具我們可以很容易地劃出數(shù)據(jù)分布的直方圖,從而判斷出我們應該對特征值劃多少個區(qū)間,每個區(qū)間的范圍是怎樣的。比如說我們要對“結果數(shù)量”這一維特征值除了“0”以為的其他值均勻地分為10個區(qū)間,即每個區(qū)間內的樣本數(shù)大致相同。“0”是一個特殊的值,因此我們想把它分到一個單獨的區(qū)間,這樣我們一共有11個區(qū)間。python代碼實現(xiàn)如下:

import numpy as npdef bin(bins):    assert isinstance(bins, (list, tuple))    def scatter(x):        if x == 0: return 0        for i in range(len(bins)):            if x <= bins[i]: return i + 1        return len(bins)    return np.frompyfunc(scatter, 1, 1)data = np.loadtxt("D:\query_features.xls", dtype='int')# descreteo2o_result_num = data[:,0]o2o_has_result = o2o_result_num[o2o_result_num > 0]bins = [ np.percentile(o2o_has_result, x) for x in range(10, 101, 10) ]data[:,0] = bin(bins)(o2o_result_num)

我們首先獲取每個區(qū)間的起止范圍,即分別算法特征向量的10個百分位數(shù),并依此為基礎算出新的特征值(通過bin函數(shù),一個numpy的universal function)。

訓練數(shù)據(jù)

這里我們通過有監(jiān)督學習的方法來擬合分類器模型。所謂有監(jiān)督學習是指通過提供一批帶有標注(學習的目標)的數(shù)據(jù)(稱之為訓練樣本),學習器通過分析數(shù)據(jù)的規(guī)律嘗試擬合出這些數(shù)據(jù)和學習目標間的函數(shù),使得定義在訓練集上的總體誤差盡可能的小,從而利用學得的函數(shù)來預測未知數(shù)據(jù)的學習方法。注意這不是一個嚴格的定義,而是我根據(jù)自己的理解簡化出來的。

一批帶有標注的訓練數(shù)據(jù)從何而來,一般而言都需要人工標注。我們從搜索引擎的日志里隨機采集一批Query,并且保證這批Query能夠覆蓋到每維特征的每個取值(從這里也可以看出為什么要做特征分區(qū)間或離散化了,因為如不這樣做我們就不能保證能夠覆蓋到每維特征的每個取值)。然后,通過人肉的方法給這邊Query打上是否具有O2O意圖的標簽。數(shù)據(jù)標注是一個痛苦而漫長的過程,需要具有一定領域知識的人來干這樣的活。標注質量的好壞很有可能會影響到學習到的模型(這里指分類器)在未知Query上判別效果的好壞。即正確的老師更可能教出正確的學生,反之,錯誤的老師教壞學生的可能性越大。在我自己標注數(shù)據(jù)的過程中,發(fā)現(xiàn)有一些Query的O2O意圖比較模棱兩可,導致我后來回頭看的時候總覺得自己標得不對,反反復復修改了好幾次。

選擇模型

在我們的問題中,模型就是要學習的分類器。有監(jiān)督學習的分類器有很多,比如決策樹、隨機森林、邏輯回歸、梯度提升、SVM等等。如何為我們的分類問題選擇合適的機器學習算法呢?當然,如果我們真正關心準確率,那么最佳方法是測試各種不同的算法(同時還要確保對每個算法測試不同參數(shù)),然后通過交叉驗證選擇最好的一個。但是,如果你只是為你的問題尋找一個“足夠好”的算法,或者一個起點,也是有一些還不錯的一般準則的,比如如果訓練集很小,那么高偏差/低方差分類器(如樸素貝葉斯分類器)要優(yōu)于低偏差/高方差分類器(如k近鄰分類器),因為后者容易過擬合。然而,隨著訓練集的增大,低偏差/高方差分類器將開始勝出(它們具有較低的漸近誤差),因為高偏差分類器不足以提供準確的模型。

這里我們重點介紹一次完整的機器學習全過程,所以不花大篇幅在模型選擇的問題上,推薦大家讀一些這篇文章:《如何選擇機器學習分類器?》。

通過交叉驗證擬合模型

機器學習會學習數(shù)據(jù)集的某些屬性,并運用于新數(shù)據(jù)。這就是為什么習慣上會把數(shù)據(jù)分為兩個集合,由此來評價算法的優(yōu)劣。這兩個集合,一個叫做訓練集(train data),我們從中獲得數(shù)據(jù)的性質;一個叫做測試集(test data),我們在此測試這些性質,即模型的準確率。將一個算法作用于一個原始數(shù)據(jù),我們不可能只做出隨機的劃分一次train和test data,然后得到一個準確率,就作為衡量這個算法好壞的標準。因為這樣存在偶然性。我們必須好多次的隨機的劃分train data和test data,分別在其上面算出各自的準確率。這樣就有一組準確率數(shù)據(jù),根據(jù)這一組數(shù)據(jù),就可以較好的準確的衡量算法的好壞。交叉驗證就是一種在數(shù)據(jù)量有限的情況下的非常好evaluate performance的方法。

 1 from sklearn import cross_validation 2 from sklearn import tree 3 from sklearn import ensemble 4 from sklearn import linear_model 5 from sklearn import svm 6  7 lr = linear_model.LogisticRegression() 8 lr_scores = cross_validation.cross_val_score(lr, train_data, train_target, cv=5) 9 print("logistic regression accuracy:")10 print(lr_scores)11 12 clf = tree.DecisionTreeClassifier(criterion='entropy', max_depth=8, min_samples_split=5)13 clf_scores = cross_validation.cross_val_score(clf, train_data, train_target, cv=5)14 print("decision tree accuracy:")15 print(clf_scores)16 17 rfc = ensemble.RandomForestClassifier(criterion='entropy', n_estimators=3, max_features=0.5, min_samples_split=5)18 rfc_scores = cross_validation.cross_val_score(rfc, train_data, train_target, cv=5)19 print("random forest accuracy:")20 print(rfc_scores)21 22 etc = ensemble.ExtraTreesClassifier(criterion='entropy', n_estimators=3, max_features=0.6, min_samples_split=5)23 etc_scores = cross_validation.cross_val_score(etc, train_data, train_target, cv=5)24 print("extra trees accuracy:")25 print(etc_scores)26 27 gbc = ensemble.GradientBoostingClassifier()28 gbc_scores = cross_validation.cross_val_score(gbc, train_data, train_target, cv=5)29 print("gradient boosting accuracy:")30 print(gbc_scores)31 32 svc = svm.SVC()33 svc_scores = cross_validation.cross_val_score(svc, train_data, train_target, cv=5)34 print("svm classifier accuracy:")35 print(svc_scores)

上面的代碼我們嘗試同交叉驗證的方法對比五種不同模型的準確率,結果如下:

 1 logistic regression accuracy: 2 [ 0.76953125  0.83921569  0.85433071  0.81102362  0.83858268] 3 decision tree accuracy: 4 [ 0.73828125  0.8         0.77559055  0.71653543  0.83464567] 5 random forest accuracy: 6 [ 0.75        0.76862745  0.76377953  0.77165354  0.80314961] 7 extra trees accuracy: 8 [ 0.734375    0.78039216  0.7992126   0.76377953  0.79527559] 9 gradient boosting accuracy:10 [ 0.7578125   0.81960784  0.83464567  0.80708661  0.84251969]11 svm classifier accuracy:12 [ 0.703125    0.78431373  0.77952756  0.77952756  0.80708661]

在O2O意圖識別這個學習問題上,邏輯回歸分類器具有最好的準確率,其次是梯度提升分類器;決策樹和隨機森林在我們的測試結果中并沒有體現(xiàn)出明顯的差異,可能是我們的特殊數(shù)量太少并且樣本數(shù)也較少的原因;另外大名典典的SVM的表現(xiàn)卻比較讓人失望??傮w而言,準確率只有82%左右,分析其原因,一方面我們實現(xiàn)的特征數(shù)量較少;另一方面暫時未能實現(xiàn)區(qū)分能力強的特征。后續(xù)會對此持續(xù)優(yōu)化。

由于邏輯回歸分類器具有最好的性能,我們決定用全部是可能訓練數(shù)據(jù)來擬合之。

lr = lr.fit(train_data, train_target)

模型數(shù)據(jù)持久化

學到的模型要能夠在將來利用起來,就必須把模型保存下來,以便下次使用。同時,數(shù)據(jù)離散化或數(shù)據(jù)分區(qū)的范圍數(shù)據(jù)也要保存下來,在預測的時候同樣也需要對特征進行區(qū)間劃分。python提供了pickle模塊用來序列號對象,并保存到硬盤上。同時,scikit-learn庫也提供了更加高效的模型持久化模塊,可以直接使用。

1 from sklearn.externals import joblib2 joblib.dump(lr, 'D:\lr.model')3 import pickle4 bin_file = open(r'D:\result_bin.data', 'wb')5 pickle.dump(bins, bin_file)6 bin_file.close()

分類器的使用

現(xiàn)在大功告成了,我們需要做的就是用學習到的分類器來判斷一個新的Query到底是否具有O2O意圖。因為我們分類器的輸入是Query的特征向量,而不是Query本身,因此我們需要實現(xiàn)提取好Query的特征。假設我們已經(jīng)離線算好了每個Query的特征,現(xiàn)在使用的時候只需要將其加載進內場即可。分類器使用的過程首先是從硬盤讀取模型數(shù)據(jù)和Query特征,然后調用模型對Query進行預測,輸出結果。

 1 # load result bin data and model 2 bin_file = open(r'D:\result_bin.data', 'rb') 3 bins = pickle.load(bin_file) 4 bin_file.close() 5  6 lr = joblib.load('D:\lr.model') 7  8 # load data 9 query = np.genfromtxt(r'D:\o2o_query_rec\all_query', dtype='U2', comments=None, converters={0: lambda x: str(x, 'utf-8')})10 feature = np.loadtxt(r'D:\o2o_query_rec\all_features', dtype='int', delimiter='\001')11 12 # descrite13 feature[:,0] = bin(bins)(feature[:,0])14 feature[:,1] = ufunc_segment(feature[:,1])15 16 # predict17 result = lr.predict(feature)18 19 # save result20 #np.savetxt(r'D:\o2o_query_rec\classify_result.txt', np.c_[query, result], fmt=u"%s", delimiter="\t")21 result_file = open(r'D:\o2o_query_rec\classify_result.txt', 'w')22 i = 023 for q in query:24     result_file.write('%s\t%d\n' % (q, result[i]))25     i += 126 result_file.close()

需要注意的是我們Query的編碼是UTF-8,load的時候需要做相應的轉換。另外,在python 3.3版本,numpy的savetxt函數(shù)并不能正確保持UTF-8格式的中文Query(第20行注釋掉的代碼輸出的Query都變成了bytes格式的),如果小伙伴們有更好的辦法能夠解決這個問題,請告訴我,謝謝!

 

原文:zero_learner

本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
貝葉斯,一個神奇的算法模型??!
python機器學習基礎線性回歸與嶺回歸算法詳解
機器學習實戰(zhàn) | SKLearn最全應用指南
使用sklearn自帶的貝葉斯分類器進行文本分類和參數(shù)調優(yōu)
Python那些事——極簡Python帶你探索分類與回歸的奧秘
從決策樹到隨機森林:樹型算法的原理與實現(xiàn)
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服