我們一般解決機器學習問題的步驟如下:
1.拿到數據集,對數據集進行清洗。數據集清洗一般包括以下幾個方面:重復值處理,缺失值處理,字符型數值處理(因為sklearn機器學習算法只能識別數值型的數據),特征提取(這就需要我們弄清楚每個特征的意義,選取對結果影響較大的特征),數據集切分,劃分訓練集和測試集。
2.建立模型。我們的機器學習問題分為兩類,分類(Classifier)和回歸(Regression),我們根據我們的目標來選擇合適的算法,像邏輯回歸,線性回歸,樸素貝葉斯,支持向量機等。
3.模型評估,對模型的預測結果做一個評估。通常我們選用的評估標準有精度(Accuracy),Recall值,Fpr,F1-score,Roc_Auc值等等。
4.模型優化,如果模型的各項評價指標比較低,那么我們可以從以下幾個方面去優化我們的模型:1.再次整理數據集,2.優化特征選擇,3.優化模型參數
交叉驗證是評估機器學習算法非常重要的手段,那我們要怎么理解交叉驗證這種方法呢?
在機器學習中數據對我們而言是非常寶貴的,如果用整個數據來訓練模型,再用這個模型去預測已有的數據,那么預測的效果一定非常的好,因為模型已經學習過了該數據。那么這個預測效果來講是沒有多大參考價值的,因為我們需要模型預測未知數據的效果要好。
所以我們首先要做的就是對數據集進行劃分,將其劃分為訓練集和測試集,用訓練集來建立模型,用測試集來評估模型。
如圖所示,我們將這個數據集按照7:3的比例劃分為訓練集和測試集,這個比例可以自己指定。
當然這種數據集劃分還是稍微有一點缺點,如果訓練集數據比較復雜,而測試集數據比較簡單,那么模型的表現效果會非常的好。如果訓練集數據比較簡單,而測試集數據比較負責,那么模型的表現效果會非常的差。所以這樣得到的模型結果存在極大的不準確性,為了使得我們訓練出來的模型能準確的反應其真實效果,我們引入了交叉驗證。
我們用下面這張圖來說明交叉驗證到底是怎么回事?
1.我們將訓練集(trainning set)分為三份,當然我們也可以分為五份,十份甚至更多,這個可以自己指定,我們就以三份為例。
2.我們選擇其中兩份作為訓練集,另外一份作為驗證集,這樣就產生了三種情況。1和2預測3,1和3預測2,2和3預測1,那么我們最終的結果就是三個模型的平均值,均值更能代表我們模型的準確性。這是一個邊訓練邊測試的過程,能使我們更好的把握模型的準確性。
下面我們用代碼來實現我們的上述過程,我們使用sklearn庫封裝好的數據集iris數據集。我們先使用sklearn.model_selection.train_test_split函數對數據集進行切分。
from sklearn import datasets
from sklearn.model_selection import train_test_split,cross_val_score
from sklearn.linear_model import LogisticRegression
iris = datasets.load_iris()
X = iris.data
y = iris.target
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3,random_state=0)
#train_test_split函數有四個返回值;test_size是切分的比例,可以自己指定;random_state是指定隨機的種子。
Lr = LogisticRegression()
Lr.fit(X_train,y_train)
Lr.score(X_test,y_test)
0.8888888888888888#邏輯回歸模型的精度為0.89
接下來我們使用sklearn.model_selection.cross_val_score函數對模型做一個交叉驗證。
from sklearn import datasets
from sklearn.model_selection import train_test_split,cross_val_score
from sklearn.linear_model import LogisticRegression
iris = datasets.load_iris()
X = iris.data
y = iris.target
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3,random_state=0)
Lr = LogisticRegression()
scores = cross_val_score(Lr,X_train,y_train,cv=5)
print(scores)
[0.90909091 1. 0.95238095 0.9047619 0.94736842]
print(scores.mean())
0.9427204374572795
由上述結果可以看出,我們做了交叉驗證以后,模型的精度為0.94,這個結果高于之前的0.88,且更能代表模型的準確性。cross_val_score需要傳入四個參數(模型,特征數據,標簽數據,cv交叉驗證的次數,也就是我們上圖所畫出的將數據分為幾份,同時也有幾個返回值)。
接下來我們再說一個交叉驗證中常用的KFold函數,它也是一個數據集劃分函數,它的返回值是訓練集和測試集的索引值。舉一個例子:
import numpy as np
from sklearn.model_selection import KFold
data = np.arange(72).reshape(12,6)
kf = KFold(n_splits = 4,shuffle = False)
for train_index,test_index in kf.split(data):
print('train_index:%s' % train_index,'test_index:%s' % test_index)
train_index:[ 3 4 5 6 7 8 9 10 11] test_index:[0 1 2]
train_index:[ 0 1 2 6 7 8 9 10 11] test_index:[3 4 5]
train_index:[ 0 1 2 3 4 5 9 10 11] test_index:[6 7 8]
train_index:[0 1 2 3 4 5 6 7 8] test_index:[ 9 10 11]
KFold函數將我們12個樣本的索引值分成了4組(n_splits = 4),取三組索引作為訓練集索引,一組作為測試集索引。kf.split為經常使用的屬性,對需要處理的數據集進行劃分,同時該值也可以傳入cv參數,cv=kf.split(data)。
機器學習算法的預測結果也存在著偶然性,所以為了獲得更準確的結果,我們通過交叉驗證,得到多個結果,取其平均值,這個均值更能代表我們模型的準確性。