sklearn分類算法性能比較


 

In [1]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#用來划分訓練集和測試集
from sklearn.model_selection import train_test_split
#用來為各種算法計時
import time
 

接下來讀取數據,並對數據進行觀察。

In [2]:
data = pd.read_csv("weatherAUS.csv")
data.head()
Out[2]:
 
  Date Location MinTemp MaxTemp Rainfall Evaporation Sunshine WindGustDir WindGustSpeed WindDir9am ... Humidity3pm Pressure9am Pressure3pm Cloud9am Cloud3pm Temp9am Temp3pm RainToday RISK_MM RainTomorrow
0 2008-12-01 Albury 13.4 22.9 0.6 NaN NaN W 44.0 W ... 22.0 1007.7 1007.1 8.0 NaN 16.9 21.8 No 0.0 No
1 2008-12-02 Albury 7.4 25.1 0.0 NaN NaN WNW 44.0 NNW ... 25.0 1010.6 1007.8 NaN NaN 17.2 24.3 No 0.0 No
2 2008-12-03 Albury 12.9 25.7 0.0 NaN NaN WSW 46.0 W ... 30.0 1007.6 1008.7 NaN 2.0 21.0 23.2 No 0.0 No
3 2008-12-04 Albury 9.2 28.0 0.0 NaN NaN NE 24.0 SE ... 16.0 1017.6 1012.8 NaN NaN 18.1 26.5 No 1.0 No
4 2008-12-05 Albury 17.5 32.3 1.0 NaN NaN W 41.0 ENE ... 33.0 1010.8 1006.0 7.0 8.0 17.8 29.7 No 0.2 No

5 rows × 24 columns

 

該數據集包含來自澳大利亞多個氣象站的每日天氣觀測。 目標變量RainTomorrow的意思是:第二天下雨了嗎?“是”或“否”。 下面我們將通過對目標RainTomorrow訓練一個二元分類模型來預測明天是否會下雨。 在訓練二元分類模型時,應該排除RISK_MM。不排除它將泄露模型的答案並降低其可預測性。

In [3]:
#去除RISK_MM變量
del data['RISK_MM']
#觀察數據維度
data.shape
Out[3]:
(142193, 23)
 

可以發現,在上面的數據框有不少的缺失值(NaN),對這些缺失值的處理會在很大程度上影響模型的准確性。

In [4]:
#查看各列缺失值情況
naVariable = pd.isna(data).sum()/data.shape[0]
plt.hist(x = naVariable,
         bins = 10,
         color = 'steelblue',
         edgecolor = 'black'
         )
Out[4]:
(array([14.,  3.,  2.,  0.,  0.,  0.,  0.,  1.,  2.,  1.]),
 array([0.        , 0.04769292, 0.09538585, 0.14307877, 0.1907717 ,
        0.23846462, 0.28615755, 0.33385047, 0.3815434 , 0.42923632,
        0.47692924]),
 <a list of 10 Patch objects>)
 
 

可以看到,很多變量缺失值占15%以內,部分變量缺失值占35%以上。 所以簡單起見,我們的處理方法是先去除缺失值占比35%以上的變量(刪除列),再從剩下的數據中去除含有缺失值的觀測(刪除行)。

In [5]:
#刪除缺失35%以上的列
data.drop(list(naVariable[naVariable>0.35].index), axis=1, inplace=True)
#刪除帶有缺失值的行
data.dropna(axis=0, how='any', inplace=True)
data.shape
Out[5]:
(112925, 19)
 

可以看到,與上面的(142193, 23)相比,處理后的數據並沒有損失很多,我們將在此基礎上繼續進行分析。

In [6]:
#查看變量類型
data.dtypes
Out[6]:
Date              object
Location          object
MinTemp          float64
MaxTemp          float64
Rainfall         float64
WindGustDir       object
WindGustSpeed    float64
WindDir9am        object
WindDir3pm        object
WindSpeed9am     float64
WindSpeed3pm     float64
Humidity9am      float64
Humidity3pm      float64
Pressure9am      float64
Pressure3pm      float64
Temp9am          float64
Temp3pm          float64
RainToday         object
RainTomorrow      object
dtype: object
 

可以看到,部分變量為字符串,我們需要將其轉換為對應的數值,相當於分類(因子)變量。 下面,我們划分自變量與因變量並完成這一轉換工作。

In [7]:
#自變量
X = data.iloc[:,0:(data.shape[1])-1]
#處理日期型數據
X['Date']= pd.to_datetime(X['Date'])
#提取年月日
X['year']=X['Date'].dt.year
X['month']=X['Date'].dt.month
X['day']=X['Date'].dt.day
del X['Date']
#轉換為分類變量
for nominal in list(X.dtypes[X.dtypes==object].index):
    class_mapping = {label:idx for idx,label in enumerate(set(X[nominal]))}
    X[nominal] = X[nominal].map(class_mapping)
X = X.apply(lambda x: (x - np.min(x)) / (np.max(x) - np.min(x)))
#因變量
y = data['RainTomorrow']
y = pd.get_dummies(y, prefix='Rain').iloc[:,1]
 

為對各種算法模型的表現進行評估,我們按照0.8:0.2的比例划分訓練集和測試集。

In [8]:
#划分訓練集和測試集
train_X, test_X, train_y, test_y = train_test_split(X,
                                                   y,
                                                   test_size = 0.2,
                                                   random_state = 0)

     

In [9]:
results = pd.DataFrame()
time_consumption = []
 

首先是線性回歸模型,由於回歸模型的輸出結果是連續型變量,所以我們將大於0.5的值標記為1,小於0.5的值標記為0。

In [10]:
start = time.time()
from sklearn.linear_model import LinearRegression
regression_m = LinearRegression()
regression_m.fit(train_X, train_y)
results['regression_r'] = (regression_m.predict(test_X)>0.5).astype("int")
end = time.time()
time_consumption.append(end - start)
 

神經網絡模型,隱含層維度(5, 3),事實上這一參數明顯會影響到模型預測結果。

In [11]:
from sklearn.neural_network import MLPClassifier
start = time.time()
neural_m = MLPClassifier(alpha=1e-5, hidden_layer_sizes=(5, 3))
neural_m.fit(train_X, train_y)
results['neural_m_r'] = neural_m.predict(test_X)
end = time.time()
time_consumption.append(end - start)
 

KNN模型,n_neighbors參數為鄰居個數,這里選取為3。

In [12]:
from sklearn import neighbors
start = time.time()
knn_m = neighbors.KNeighborsClassifier(n_neighbors=3)
knn_m.fit(train_X, train_y)
results['knn_m_r'] = knn_m.predict(test_X)
end = time.time()
time_consumption.append(end - start)
 

決策樹模型

In [13]:
from sklearn.tree import DecisionTreeClassifier
start = time.time()
tree_m = DecisionTreeClassifier()
tree_m.fit(train_X,train_y)
results['tree_r'] = tree_m.predict(test_X)
end = time.time()
time_consumption.append(end - start)
 

隨機森林模型

In [14]:
from sklearn.ensemble import RandomForestClassifier
start = time.time()
forest_m = RandomForestClassifier()
forest_m.fit(train_X,train_y)
results['forest_r'] = forest_m.predict(test_X)
end = time.time()
time_consumption.append(end - start)
 

支持向量機

In [15]:
from sklearn.svm import LinearSVC
start = time.time()
SVC_m = LinearSVC()
SVC_m.fit(train_X, train_y)
results['SVC_r'] = SVC_m.predict(test_X)
end = time.time()
time_consumption.append(end - start)
 

計算各種模型的評價指標,包括精確率(precision)、召回率(recall)、准確率(准確率)以及F1分數(F1_Score)。 最后將運行所用時間添加進去。

In [16]:
evaluations = pd.DataFrame()
from sklearn.metrics import *
for i in range(0, results.shape[1]):
    evaluation = {"precision": precision_score(test_y, results.iloc[:,i]), 
                  "recall": recall_score(test_y, results.iloc[:,i]), 
                  "accuracy": accuracy_score(test_y, results.iloc[:,i]), 
                  "f1": f1_score(test_y, results.iloc[:,i])}
    evaluations = evaluations.append(evaluation, ignore_index=True)
evaluations.rename(index=dict(zip(range(0, evaluations.shape[0]), 
                                  list(results.columns))),inplace=True)

evaluations.insert(0, 'time/s', time_consumption)
 

查看評價指標。

In [17]:
evaluations
Out[17]:
 
  time/s accuracy f1 precision recall
regression_r 0.181857 0.846358 0.556379 0.753724 0.440932
neural_m_r 40.708138 0.849989 0.588335 0.734750 0.490578
knn_m_r 28.071440 0.816294 0.509864 0.611331 0.437285
tree_r 1.523269 0.787337 0.533825 0.512295 0.557244
forest_r 2.394298 0.844941 0.566584 0.727822 0.463830
SVC_r 5.248482 0.847288 0.577173 0.730602 0.477001
 

通過上表可以看出,神經網絡模型和KNN模型所用的時間較長,執行速度較慢。其他算法速度均較快。 從預測結果來說,各個模型相差不大,神經網絡模型和支持向量機模型效果較好,KNN和決策樹模型效果較差。 因此,如果對程序的執行速度有嚴格要求,選擇線性回歸模型是明智的做法;如果綜合考慮,個人認為支持向量機是適合於該數據集的最佳模型。

 

當然,以上粗略的比較並不能說明算法本身的優劣,各種評價指標與數據集有很大關聯。 另外,上面大多使用的是各種模型默認的參數配置,相信通過調節各種參數,能夠提高模型的預測性能。

數據:

鏈接:https://pan.baidu.com/s/1RWw93h-gLSAKr-TzyGBrwQ
提取碼:dy5v

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM