【问题标题】:Improve performace of Neural Netkork vs SVC提高神经网络与 SVM 的性能
【发布时间】:2019-04-25 02:22:03
【问题描述】:

我正在训练一个具有 100 个特征、64 个标签和 150K 观察值的分类模型(训练+测试)。数据有噪声并且已经过预处理。 使用 SVC,我得到了很好的结果,足以满足要求。 得分为 97.8%

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

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

代码中包含数据集(70MB) 我的 i7 8750H、16GB msi 笔记本电脑大约 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 上进行测试?我通常会使用sklearn.preprocessing.train_test_split 来随机拆分我的 X 和 y。
  • 测试列车先前已拆分,因此为方便起见,从标记为 1s 和 0s 的最后一列中选择

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


【解决方案1】:

问题是你的问题措辞错误,但我知道你的问题是什么:

基本上,您有一个非常大的高维度数据集,其中包含以下事实:

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

注意您有 99 特征(不是 100 个)不包括响应/类列!

目标:

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

已经尝试过的:

SVM 算法给出了非常好的准确结果,但它花了很多时间来完成。

问题:

应该调整哪些参数尤其是hidden_layer_sizes 以获得比您已经在Neural Network 中使用hidden_layer_sizes=(300,) 获得的94.8 更好的精度?


回答

在您的问题中,有许多隐含的子问题需要回答。实际上,您需要对数据集进行完整的数据分析才能做出正确的决定;所以这不是一个简单直接的案例。尽管如此,让我将问题分解为子问题并尝试解决它们:

首先:

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

  1. 对于少量功能,请使用Logistic Regression
  2. 对于很多功能但不是很多数据,请使用SVM
  3. 对于很多功能和大量数据,请使用Neural Network

有了150K 观察和99 功能,SVM 将永远完成!这样我们就剩下Logistic RegressionNeural Network

根据上述经验法则,Neural Network 是一个更好的候选者,它确实给了你94.8% 准确度得分,这是一个很好的结果,但是,你需要真正优秀 em> 得分 (>97%)!。

其次:

对于Artificial Neural Network,选择隐藏层的大小没有经验法则,而是有一些指导原则; Jeff Heaton 的 Java 神经网络简介(第二版)

隐藏层数:

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

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

  • 2 可以将任意决策边界表示为任意精度 具有合理的激活函数,可以逼近任何平滑 映射到任何精度

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

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

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

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

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

这里你需要使用GridSearchCV,你最终会比SVM本身花费更多的时间!!!


如您所见,在准确性和性能之间需要权衡取舍。您不能同时声称您的特定数据集具有出色和良好的实时性能,因为它庞大且大部分都是零!!


怎么办?

您有以下选择:

1. 使用您当前的 SVMANN 实现以实现高精度最差的实时性能 em>

2.或者使用Gaussian Naive Bayes,它提供出色的性能(因为它基本上是用于在线分类!)但准确度最差如下:

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)

结果

Start Modeling...
Elapsed Time: 0.12834382057189941
Finished Modeling...
0.6888808876959838

3. 或者介于两者之间并将您的准确度期望最小化,然后您可以使用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)

结果

Start Modeling...
Elapsed Time: 80.22028756141663
Finished Modeling...
0.9141762953749468

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

【讨论】:

  • 非常感谢叶海亚。很多东西要学!在您的广泛回应中。刚刚用 RandomForest 进行了测试,准确率达到了 98.1%……我需要继续努力,因为模型到磁盘需要 2GB。
  • @Guido 很高兴我能帮忙:)。只是让您知道我没有考虑随机森林,因为我知道它对 RAM 和 CPU 的负载很大。但我很高兴你能做到:)
猜你喜欢
  • 2021-06-18
  • 2019-12-02
  • 2012-02-16
  • 2016-08-02
  • 2018-01-10
  • 2017-09-06
  • 2017-08-05
相关资源
最近更新 更多