• 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]:
     
     DateLocationMinTempMaxTempRainfallEvaporationSunshineWindGustDirWindGustSpeedWindDir9am...Humidity3pmPressure9amPressure3pmCloud9amCloud3pmTemp9amTemp3pmRainTodayRISK_MMRainTomorrow
    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/saccuracyf1precisionrecall
    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

  • 相关阅读:
    [C/C++] 指针数组和数组指针
    [计算机网络] DNS劫持和DNS污染
    [计算机网络-数据链路层] CSMA、CSMA/CA、CSMA/CD详解
    [BinaryTree] 二叉树常考知识点
    NODE-windows 下安装nodejs及其配置环境
    MATLAB/Excel-如何将Excel数据导入MATLAB中
    Excel-怎样实现行列转置
    一篇文章学懂Shell脚本
    SQL-MySQL使用教程-对MySQL的初步尝试
    资源贴-在线编译环境推荐
  • 原文地址:https://www.cnblogs.com/dingdangsunny/p/12864393.html
Copyright © 2020-2023  润新知