改善神经网络与SVC的性能

时间:2018-11-22 11:45:02

标签: python machine-learning scikit-learn neural-network svm

我正在训练一个具有100个要素,64个标签和150K观测值(训练+测试)的分类模型。数据比较嘈杂,并且已经过预处理。 使用SVC,我达到了很好的结果,足以满足要求。 分数是97.8%

SVC模型提供了7700个支持向量,因此实时预测的过程要求很大。

我想知道NN是否可以执行类似的操作。我测试了1层和2层的几种配置,但最好的结果是1层。通过我的实验,我得到了94.8%的具有300个神经元的隐藏层,不足以满足要求。

代码中包含数据集(70MB) 我的i7 8750H,16GB微星笔记本电脑可容纳约60英尺。

哪种层结构可以改善实验效果?

import numpy as np
import pandas as pd
import time
from sklearn.svm import SVC
from sklearn.neural_network import MLPClassifier

local = 'data.csv'
url='https://www.dropbox.com/s/dccj9leppapy9pv/data.csv?dl=1'
print('Loading dataset')
X = pd.read_csv(url).values[:,1:]
train =  X[ X[:,-1] == 1][:,:-1]
test =   X[ X[:,-1] == 0][:,:-1]
X_train, y_train = train[:,:-1], train[:,-1]
X_test,  y_test  = test[:,:-1],  test[:,-1]

now = time.time()
model = SVC(C=2500, gamma=10, kernel='rbf',verbose=True)
model.fit(X_train, y_train)
print('elapsed time:', time.time()-now)
score = model.score(X_test,y_test)
print('SVC score:', score)
print(len(model.support_vectors_) ,'support vectors')

now = time.time()
model = MLPClassifier(hidden_layer_sizes=(300,), activation='logistic',solver='adam',verbose=True,tol=1e-10,learning_rate_init=0.1,learning_rate='adaptive')
model.fit(X_train, y_train)
print('elapsed time:', time.time()-now)
score = model.score(X_test,y_test)
print('NN score:', score)

1 个答案:

答案 0 :(得分:1)

问题是您误问了您的问题,但我明白了您的问题是什么

基本上,您有一个很大的数据集,具有高维度,具有以下事实:

Number of cases: 150K
Number of Classes: 64
Number of Features: 99

NB 您具有99功能(不是100)不包括“响应/类别”列!

目标:

找到在CPU负载,内存负载和时间方面提供最高准确度和最佳性能的最佳算法!

尝试过的事情

SVM算法虽然给出了出色的精度结果,但是却花了很多时间才能完成。

问题:

应该{​​{1}} 特别调整哪些参数,以获得比使用hidden_layer_sizes中的94.8已经hidden_layer_sizes=(300,)的参数更好的精度。 ?


答案

在您的问题中,应回答许多隐式子问题。实际上,您需要对数据集进行完整的数据分析,才能做出一个明智的决定。所以这不是一个简单直接的案例。不过,让我将问题分解为子问题,然后尝试解决它们:

首先:

正如我在previous answer中所提到的,根据惯例选择分类算法有一个经验法则:

  1. 要使用少量功能,请使用Neural Network
  2. 要使用很多功能而不需要大量数据,请使用Logistic Regression
  3. 要获取许多功能和大量数据,请使用SVM

有了Neural Network个观测值和150K个功能,99将永远花光!因此,我们只剩下SVMLogistic Regression

根据上述经验法则,Neural Network是一个更好的候选者,确实它为您提供了Neural Network的准确度分数,这是一个很好的结果,但是,您实际上需要 > 得分(> 97%)!。

其次:

对于94.8%,选择隐藏层的大小没有经验法则,但是有一些准则;来自Jeff Heaton的 Java神经网络简介(第二版)

隐藏层数:

  • 0 仅能表示线性可分离函数或决策。

  • 1 可以近似任何包含连续映射的函数 从一个有限的空间到另一个有限的空间。

  • 2 可以代表任意精度的任意决策边界 具有合理的激活功能,可以近似任何平滑 映射到任何准确性

另一方面,根据经验,在隐藏层中使用过多的神经元会导致拟合不足,而在隐藏层中使用过多的神经元可能会导致拟合过度:

  • 隐藏神经元的数量应该在输入层的大小和输出层的大小之间。

  • 隐藏神经元的数量应为输入层大小的2/3加上输出层大小的大小。

  • 隐藏神经元的数量应小于输入层大小的两倍。

但是问题是:如果我们尝试上述建议会花费多少时间?!

在这里您需要使用GridSearchCV,最终会比Artificial Neural Network本身花费更多的时间!


因此,正如您所看到的,在准确性和性能之间需要权衡。您不能同时为特定数据集声明 杰出 和良好的 实时 性能,因为它既庞大又大部分都是零!


该怎么办?

您有以下选择:

1。要么继续使用当前的SVMSVM实施方案,以实现 高精度 ,但 时间表现

2。或使用Gaussian Naive Bayes可以提供 出色的性能 (因为它基本上是用于在线分类的!),但 最差的准确度< / em> ,如下所示:

ANN

结果

import time
import pandas as pd
from sklearn.naive_bayes import GaussianNB
from sklearn.model_selection import StratifiedShuffleSplit
import numpy as np

def getDataset(path, x_attr, y_attr, mapping=None):
    """
    Extract dataset from CSV file
    :param path: location of csv file
    :param x_attr: list of Features Names
    :param y_attr: Y header name in CSV file
    :param mapping: dictionary of the classes integers
    :return: tuple, (X, Y)
    """
    df = pd.read_csv(path)
    if mapping is not None:
        df.replace(mapping, inplace=True)
    X = np.array(df[x_attr]).reshape(len(df), len(x_attr))
    Y = np.array(df[y_attr])
    return X, Y

def run(X_data, Y_data):
    sss = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=0)
    train_index, test_index = next(sss.split(X_data, Y_data))
    X_train, X_test = X_data[train_index], X_data[test_index]
    Y_train, Y_test = Y_data[train_index], Y_data[test_index]
    clf = GaussianNB()
    print("Start Modeling...")
    now = time.time()
    clf.fit(X_train, Y_train)
    print('Elapsed Time:', time.time() - now)
    print("Finished Modeling...")
    print(clf.score(X_test, Y_test))

X, Y = getDataset("data.csv", [str(x) for x in range(1,98)] + ["99"], "98")
run(X, Y)

3。或者介于两者之间并将您的精度期望值最小化,然后可以使用Start Modeling... Elapsed Time: 0.12834382057189941 Finished Modeling... 0.6888808876959838 来达到中等性能,如下所示:

Logistic Regression

结果

import time
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import StratifiedShuffleSplit
import numpy as np

def getDataset(path, x_attr, y_attr, mapping=None):
    """
    Extract dataset from CSV file
    :param path: location of csv file
    :param x_attr: list of Features Names
    :param y_attr: Y header name in CSV file
    :param mapping: dictionary of the classes integers
    :return: tuple, (X, Y)
    """
    df = pd.read_csv(path)
    if mapping is not None:
        df.replace(mapping, inplace=True)
    X = np.array(df[x_attr]).reshape(len(df), len(x_attr))
    Y = np.array(df[y_attr])
    return X, Y

def run(X_data, Y_data):
    sss = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=0)
    train_index, test_index = next(sss.split(X_data, Y_data))
    X_train, X_test = X_data[train_index], X_data[test_index]
    Y_train, Y_test = Y_data[train_index], Y_data[test_index]
    clf = LogisticRegression(random_state=0, C=10)
    print("Start Modeling...")
    now = time.time()
    clf.fit(X_train, Y_train)
    print('Elapsed Time:', time.time() - now)
    print("Finished Modeling...")
    print(clf.score(X_test, Y_test))

X, Y = getDataset("data.csv", [str(x) for x in range(1,98)] + ["99"], "98")
run(X, Y)

4。或者,您最后可以做的是检查哪些功能对类最重要,您可以通过使用Start Modeling... Elapsed Time: 80.22028756141663 Finished Modeling... 0.9141762953749468 来评估功能的重要性来实现。 Here是一个完整而简单的示例,说明如何在Forests of Trees中执行此操作,然后创建数据集的新版本,但这一次仅包含最重要的功能。还建议通过删除最包含零输入的行/观测来获得当前数据集的子样本!