如何利用機器學習甄別淘寶優質店鋪

資料團學社發表於2019-01-07

本文約2400字,閱讀需要7分鐘

關鍵詞:Python sklearn 決策樹 KNN 邏輯迴歸 SVM

本文講述了使用python分別構建決策樹、KNN、邏輯迴歸、SVM、神經網路共五種不同的模型甄別淘寶優質店鋪的過程。


目錄

  • 背景知識介紹

  • 資料和工具準備

  • 模型介紹、程式碼示範和結果比較

  • 調參方法

  • 模型進階:隨機森林


 背景知識介紹 

在經歷數年雙十一血拼,雙十二剁手之後,作為一名優秀的資料分析師,我覺得我需要研究一下如何精準的定位優質店鋪,看穿套路,理性消費。

今天的資料來自於阿里雲天池。

這是一份包含2000家店鋪的評分,等級,評論等資訊和數年交易記錄的資料。

資料維度可以檢視明細:

如何利用機器學習甄別淘寶優質店鋪

透過這份資料,我們可以構建一套選店模型,為即將到來的各種大小節日做準備。這個過程我們將使用sklearn包來完成。

我們要做的事情,就是構建模型根據店鋪的訪問、購買資訊等資料,來評測該店鋪是否為優質店鋪。一部分資料將用來作為訓練集,另一部分資料會用來測試已經訓練好模型的精確度。我們這裡將重點關注模型的擬合情況,對每個模型進行調參比較,選出最適合的那一個~

欠擬合指模型沒有很好地捕捉到資料特徵,不能夠很好地擬合資料:

如何利用機器學習甄別淘寶優質店鋪

過擬合通俗一點地說就是模型把資料學習的太徹底,以至於把噪聲資料的特徵也學習到了,這樣就會導致在後期測試的時候不能夠很好地識別資料,即不能正確的分類,模型泛化能力太差:

如何利用機器學習甄別淘寶優質店鋪

 資料和工具準備 

一組資料到手,清理整合等預處理工作是繞不開的。我們可以得到了一份適合建模使用的樣本資料:

如何利用機器學習甄別淘寶優質店鋪

 *具體處理過程可以在文末獲取

準備好資料以後,文末匯入所需的包、填充資料空值,再拆分提取訓練集測試集資料,並將資料進行標準化,為後續的模型構建做足準備~

訓練集(Training Set):幫助我們訓練模型,簡單的說就是透過訓練集的資料讓我們確定擬合曲線的引數。 

驗證集(Validation Set):用來做模型選擇(model selection),即做模型的最終最佳化及確定的,用來輔助我們的模型的構建,可選; 

測試集(Test Set): 用來測試已經訓練好的模型的精確度。。 

實際應用中,一般只將資料集分成兩類,即訓練集Training set 和測試集Test set.

既然資料都準備好了,那就開始我的表演~對於每個模型,我都會給出模型介紹程式碼簡單的調參過程檢視模型結果的混淆矩陣

*考慮這份資料比較粗糙,我們僅使用0分店鋪和4分店鋪的資料。

 不同模型的構建及其效果 

模型一:決策樹

#決策樹
max_depth_l = [2,3,4,5,6,7,8,9,10]
for max_depth in max_depth_l:
    dt_model = DecisionTreeClassifier(max_depth=max_depth)
    dt_model.fit(x_train_scaled,y_train)
    train_accuracy = dt_model.score(x_train_scaled,y_train)
    test_accuracy = dt_model.score(x_test_scaled,y_test)
    print('max depth',max_depth)
    print('訓練集上的準確率:{:2f}%'.format(train_accuracy*100))
    print('測試集上的準確率:{:2f}%'.format(test_accuracy*100))

決策樹是一個類似於人們決策過程的樹結構,從根節點開始,每個分枝代表一個新的決策事件,會生成兩個或多個分枝,每個葉子代表一個最終判定所屬的類別。

決策樹,需要調節的主要引數是樹的深度。深度越淺,容易造成欠擬合;而深度越深,則會過擬合。我們建立一個列表,羅列不同的深度,建立模型進行嘗試,最終選擇在測試集上表現最好的模型。

我們看到,隨著深度的增加,模型在訓練集上的準確率越來越高,而在測試集上的效果則越來越差,這是過擬合的表現,而在深度為5的時候,測試集的準確率為73.39,達到最高值,所以這組模型為決策樹的最佳模型。

如何利用機器學習甄別淘寶優質店鋪

 

繪製混淆矩陣檢視模型效果:

dt_model = DecisionTreeClassifier(max_depth=5)
dt_model.fit(x_train_scaled,y_train)
predictions = dt_model.predict(x_test_scaled)
test_accuracy = dt_model.score(x_test_scaled,y_test)
print(classification_report(y_test,predictions))
print('決策樹的準確率:{:2f}%'.format(test_accuracy*100))

cnf_matrix = confusion_matrix(y_test,predictions)
plot_confusion_matrix(cnf_matrix, classes=[0,1],
                      title='Confusion matrix')

 

如何利用機器學習甄別淘寶優質店鋪

*橫座標是預測值,即“模型認為該店鋪為差評/優質店鋪”,縱座標代表真實值,即“該店鋪為差評/優質店鋪”。0為差評,1為優質

模型在預測優質店鋪上容易誤殺,把優質店鋪預測為差評店鋪,錯誤達到43個,不過店鋪茫茫多,錯過這個還有下個,本著寧可錯殺,不能放過的原則,模型還是可以的。

 模型二:KNN 

k_values = range(3,13)
for k_value in k_values:
    knn_model = KNeighborsClassifier(n_neighbors=k_value)
    knn_model.fit(x_train_scaled,y_train)
    train_accuracy = knn_model.score(x_train_scaled,y_train)
    test_accuracy = knn_model.score(x_test_scaled,y_test)   
    print('k value:',k_value)
    print('訓練集上的準確率:{:2f}%'.format(train_accuracy*100))
    print('測試集上的準確率:{:2f}%'.format(test_accuracy*100))

K最近鄰(k-Nearest Neighbor,KNN)分類演算法是最簡單的機器學習演算法。 KNN演算法的指導思想是“近朱者赤,近墨者黑”——由你的鄰居來推斷出你的類別。

KNN同樣需要調節超引數,我們需要選取不同的鄰近點個數,除錯模型達到最優狀態。

如何利用機器學習甄別淘寶優質店鋪

引數n_neighbors達到10的時候,效果最棒

knn_model = KNeighborsClassifier(n_neighbors=10)
knn_model.fit(x_train_scaled,y_train)
predictions = knn_model.predict(x_test_scaled)
print(classification_report(y_test,predictions))
accuracy = knn_model.score(x_test_scaled,y_test)
print('KNN預測準確率:{:2f}%'.format(accuracy*100))
cnf_matrix = confusion_matrix(y_test,predictions)
plot_confusion_matrix(cnf_matrix, classes=[0,1],
                      title='Confusion matrix')


如何利用機器學習甄別淘寶優質店鋪

*橫座標是預測值,即“模型認為該店鋪為差評/優質店鋪”,縱座標代表真實值,即“該店鋪為差評/優質店鋪”。0為差評,1為優質

模型在判斷差評店鋪方面效果比決策樹更好,但錯殺優質店鋪的數量也達到51,好像多了一點。

 模型三:邏輯迴歸 

c_list = [0.01,0.1,1,1e1,1e2,1e3,1e4]
for c in c_list:
    lg_model = LogisticRegression(C=c)
    lg_model.fit(x_train_scaled,y_train)
    train_accuracy = lg_model.score(x_train_scaled,y_train)
    test_accuracy = lg_model.score(x_test_scaled,y_test)   
    print('C value:',c)
    print('訓練集上的準確率:{:2f}%'.format(train_accuracy*100))
    print('測試集上的準確率:{:2f}%'.format(test_accuracy*100))

迴歸分析是一種預測建模技術的方法,研究因變數(目標)和自變數(預測器)之前的關係。邏輯迴歸是一種廣泛應用於分類問題的迴歸方法。

邏輯迴歸是一種廣義線性迴歸,原理是線上性迴歸的結果外套用sigmoid函式,

如何利用機器學習甄別淘寶優質店鋪

把輸出結果壓縮在0-1之間,如果結果>0.5,也就意味著機率大於一半,我們把它判定為1,反之為-1,從而起到分類的作用。

Sklearn的邏輯迴歸中,預設加入正則化超引數用於防止過擬合。可調節的引數是C,C越小、抵抗過擬合的力度越大;C越大則效果越小,我們也需要根據實際情況調節。

*引數中1e1,1e2……為科學計數法,表示10,100……以此類推

如何利用機器學習甄別淘寶優質店鋪

我們看到C在100的時候,效果就已經達到最優,而C越小模型的擬合程度越差,所以並不是任何情況,都需要使用過擬合調節。

lg_model = LogisticRegression(C=100)
lg_model.fit(x_train_scaled,y_train)
predictions = lg_model.predict(x_test_scaled)
print(classification_report(y_test,predictions))
accuracy = lg_model.score(x_test_scaled,y_test)
print('邏輯迴歸預測準確率:{:2f}%'.format(accuracy*100))
cnf_matrix = confusion_matrix(y_test,predictions)
plot_confusion_matrix(cnf_matrix, classes=[0,1],
                      title='Confusion matrix')


如何利用機器學習甄別淘寶優質店鋪

*橫座標是預測值,即“模型認為該店鋪為差評/優質店鋪”,縱座標代表真實值,即“該店鋪為差評/優質店鋪”。0為差評,1為優質

預測準確率約為70.39%,效果相較於前兩個模型要差一點。錯殺還是51,也不少~

 模型四:支援向量機 

c_list = [1,1e1,1e2,1e3,1e4,1e5,1e6]
for c in c_list:
    svm_model = SVC(C=c)
    svm_model.fit(x_train_scaled,y_train)
    train_accuracy = svm_model.score(x_train_scaled,y_train)
    test_accuracy = svm_model.score(x_test_scaled,y_test)   
    print('C value:',c)
    print('訓練集上的準確率:{:2f}%'.format(train_accuracy*100))
    print('測試集上的準確率:{:2f}%'.format(test_accuracy*100))

什麼是SVM:支援向量機就是使用一條直線(二維)或超平面(多維)將資料分成兩類,同時保證離超平面最近的點與超平面的間隔儘可能小。就像下圖那樣。

如何利用機器學習甄別淘寶優質店鋪

C為懲罰項,同樣是為了防止過擬合。不同的C值可以有不同的結果:

如何利用機器學習甄別淘寶優質店鋪

svm_model = SVC(C=1e6)
svm_model.fit(x_train_scaled,y_train)
predictions = svm_model.predict(x_test_scaled)
print(classification_report(y_test,predictions))
accuracy = svm_model.score(x_test_scaled,y_test)
print('支援向量機預測準確率:{:2f}%'.format(accuracy*100))
cnf_matrix = confusion_matrix(y_test,predictions)
plot_confusion_matrix(cnf_matrix, classes=[0,1],
                      title='Confusion matrix')


如何利用機器學習甄別淘寶優質店鋪

預測準確率為75.11%,是目前為止效果最好的模型了~

 模型五:神經網路 

mlp =MLPClassifier(hidden_layer_sizes=(100,50),max_iter=1000,activation='relu')
mlp.fit(x_train_scaled,y_train)
train_accuracy = mlp.score(x_train_scaled,y_train)
test_accuracy = mlp.score(x_test_scaled,y_test)   
print('訓練集上的準確率:{:2f}%'.format(train_accuracy*100))
print('測試集上的準確率:{:2f}%'.format(test_accuracy*100))
predictions = mlp.predict(x_test_scaled)
cnf_matrix = confusion_matrix(y_test,predictions)
plot_confusion_matrix(cnf_matrix, classes=[0,1],
                      title='Confusion matrix')

*這個原理比較複雜,文末提供了參考資料供大家閱讀~

使用sklearn中BP神經網路的包,建立神經網路模型進行預測,我們可以調節的超引數有神經網路隱藏層的層數,啟用函式等。


如何利用機器學習甄別淘寶優質店鋪

預測準確率為71.67%,結果一般般吧~

我們用了這麼多模型,我相信有同學一定會問,每個模型都有一種甚至數種超引數需要調節,那麼哪種排列組合是最佳組合呢?

呵呵~~~這個問題難度有點高哦!如果我說每次都是蒙的,你會信嗎?

 如何調節超引數 

對於模型的超引數調節,並沒有固定的套路,通常需要經過數輪嘗試和以往的經驗才能找到最正確的那個。當然,每次手動調節也確實是一件挺麻煩的事,所以,這裡分享一個一勞永逸的方法——網格搜尋,交叉驗證

原理很簡單,我們把測試集再分成數份作為驗證集。比如分成10份,我們叫10折,然後選取一組引數,分別在每個折上進行執行,得到10個結果,求出平均結果作為這一組最後的結果,最後得到最優結果的那一組引數。

好!下面我們來看下具體程式碼實現過程。

首先建立一個字典,字典裡包含我們需要比較的模型,和每個模型中引數的選取範圍。

model_dict = {
              'Decision Tree':(DecisionTreeClassifier(),
                               {'max_depth':[2,3,4,5,6,7,8,9,10],}
                              ),

              'KNN':(KNeighborsClassifier(),
                     {'n_neighbors':list(range(1,21)),
                      'p':[1,2],}
                              ),

              'Logistic Regression':(LogisticRegression(),
                                     {'C':[1,1e1,1e2,1e3,1e4,1e5,1e6],}
                              ),

              'SVM':(SVC(),
                     {'C':[1,1e1,1e2,1e3,1e4,1e5,1e6],}
                              ),

              'MLP':(MLPClassifier(),
                     {'hidden_layer_sizes':[(100,50),(100,30),(100,50,30),(100,100)],
                      'max_iter':[200,500,1000,5000,10000],
                      'activation':['relu','logistic','tanh']
                         }
                              ),
             }

然後我們使用GridSearchCV,遍歷引數,並排列組合,然後再進行交叉驗證,選取最佳引數組合。我們採用5折對訓練集進行劃分:

for model_name,(model,model_params) in model_dict.items():
    clf = GridSearchCV(estimator=model,param_grid=model_params,cv=5)
    clf.fit(x_train_scaled,y_train)
    best_model = clf.best_estimator_

    acc = best_model.score(x_test_scaled,y_test)
    print('{}模型預測準確率:{:2f}%'.format(model_name,acc*100))
    print('{}模型最佳引數:{}'.format(model_name,clf.best_params_))


如何利用機器學習甄別淘寶優質店鋪

因為經過了驗證集進一步的驗證,最後的結果有所變化,神經網路模型的結果為最優結果,並且這裡羅列了每個模型的最佳引數組合。

我們使用了5種模型,並透過反覆調節,正確率達到了74.3%,顯然,這並不是一個十分滿意的結果。那麼是否還有其他更強大的模型,可以再進一步提升呢?

 更強大的模型:隨機森林 

既然任何的一種模型都達不到要求,那麼我們就用許多模型,把他們組合在一起,這叫強強聯手。對於這類把許多模型組合在一起,成為一個整體的模型我們稱之為整合模型

下面,我使用一種整合模型——隨機森林來進一步探索資料。主要原理是構建多棵決策樹,每棵決策樹都會有一個結果,最後透過投票機制,選出最終結果。

from sklearn.ensemble import RandomForestClassifier
tree_param_grid = {'n_estimators':[10,20,30,50,80],
                   'min_samples_split':[2,8,10,20,30,50,60,70,80],
                   'min_samples_leaf':[2,5,10,20,30,50],
                   'random_state':[2]
                  }
grid = GridSearchCV(RandomForestClassifier(),param_grid=tree_param_grid,cv=5)
grid.fit(x_train_scaled,y_train)
best_model = grid.best_estimator_
acc1 = best_model.score(x_train_scaled,y_train)
acc2 = best_model.score(x_test_scaled,y_test)
print('隨機森林模型訓練準確率:{:2f}%'.format(acc1*100))
print('隨機森林模型預測準確率:{:2f}%'.format(acc2*100))
print('隨機森林模型最佳引數:{}'.format(grid.best_params_))

同樣採用交叉驗證來調節引數。特別注意的是random_state引數,一定要限定一下隨機數種子,否則每次執行模型,採用的是不同的隨機數,呈現的結果不同,就無法對比了。

隨機森林模型訓練準確率:76.559140%
隨機森林模型預測準確率:78.111588%
隨機森林模型最佳引數:{'min_samples_leaf': 2, 'min_samples_split': 70, 'n_estimators': 50, 'random_state': 2}

從結果上看,有了比較明顯的提升,在預測集上達到了78.11%的準確率,對比前面的模型有了較大的提升~

整合模型有很多種,每一種都嘗試下,最終的準確率應該可以達到80%。但是,相比起模型,資料更為重要。受限於資料量,資料精度和資料維度,模型離願望中的90%準確性還有很大的距離。如果有更大的樣本,比如2W條資料,更精細的分類,比如score精確到小數點後一位4.0,4.1,4.2……和更多的欄位,比如成交金額,成交數量,店鋪年份等等,那麼模型一定會更精確。畢竟模型不是魔法,我們討論的也只是科學而不是玄學。

最後的最後,要甄別優質店鋪還真是不容易~學好知識才是最重要的!

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31558017/viewspace-2374667/,如需轉載,請註明出處,否則將追究法律責任。

相關文章