Улучшение производительности Neural Netkork vs SVC - PullRequest
0 голосов
/ 22 ноября 2018

Я тренирую модель для классификации с 100 функциями, 64 метками и 150K наблюдений (поезд + тест).Данные зашумлены и уже предварительно обработаны.Используя SVC, я достигаю довольно хороших результатов, достаточно для требований.Оценка составляет 97,8%

Модель SVC обеспечивает 7700 векторов поддержки, поэтому требования к процессу для прогнозирования в реальном времени велики.

Мне интересно, может ли NN выполнить аналогичное.Я протестировал несколько конфигураций с 1 и 2 слоями, но лучший результат для 1 слоя.В моих экспериментах я получил 94,8% со скрытым слоем с 300 нейронами, что недостаточно для требований.

Включен набор данных в коде (70 МБ).

Какая структура слоев могла бы улучшить этот эксперимент?.

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 голосов
/ 22 ноября 2018

Дело в том, что вы неправильно сформулировали свой вопрос, но я понял, в чем ваша проблема:

В основном у вас очень большой набор данных с большими размерами со следующими фактами:

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

NB У вас есть 99 функций (не 100) , исключая столбец ответов / классов!

Цель:

Найти лучшийалгоритм, который дает высочайшую точность и лучшую производительность в отношении нагрузки на процессор, загрузки памяти и времени!

Что было опробовано:

SVM Алгоритм, который дал превосходныйточность результата, но он занял чертовски много времени, чтобы закончить.

Вопрос:

Какие параметры должны быть настроены особенно hidden_layer_sizesчтобы достичь большей точности, чем тот, который вы уже получили 94.8, используя hidden_layer_sizes=(300,) в Neural Network?


Ответ

В вашем вопросе есть много скрытых подвопросов, которыеследует ответить.На самом деле вам нужно выполнить полный анализ данных в вашем наборе данных, чтобы в итоге принять правильное решение;так что это не простой прямой случай.Тем не менее, позвольте мне разбить проблему на подзадачи и попытаться решить их:

Во-первых:

Как я уже упоминал в предыдущем ответе Существует практическое правило выбора алгоритма классификации в соответствии с соглашением следующим образом:

  1. Для небольшого числа функций, используйте Logistic Regression.
  2. Для многих функций, но немного данных, перейдите с SVM.
  3. Для множества функций и большого количества данных, перейдите с Neural Network.

с 150K наблюдениями и 99 Особенности, SVM займет целую вечность!Таким образом, у нас остаются Logistic Regression и Neural Network.

В соответствии с вышеупомянутым эмпирическим правилом, Neural Network является лучшим кандидатом, и на самом деле он дал вам 94.8% показатель точности, который является отличнымрезультат, однако, вам требуется буквально выдающийся оценка (> 97%)!.

Во-вторых:

Для Artificial Neural Network, эмпирического правила выбора размера скрытых слоев не существует, но есть некоторые рекомендации;от Введение в нейронные сети для Java (второе издание) Джеффа Хитона :

Количество скрытых слоев:

  • 0 способен только представлять линейные отделимые функции или решения.

  • 1 может аппроксимировать любую функцию, которая содержит непрерывное отображение из одного конечного пространства в другое.

  • 2 может представлять произвольную границу решения с произвольной точностью с помощью рациональных функций активации и может приближать любое гладкое отображение к любой точности .

С другой стороны, использование слишком небольшого количества нейронов в скрытых слоях приведет к недостаточному подгонке, тогда как использование слишком большого количества нейронов в скрытых слоях может привести к переобучению, как правило:

  • Количество скрытых нейронов должно быть между размером входного слоя и размером выходного слоя.

  • Количество скрытыхнейроны должны быть в 2/3 размера входного слоя плюс размер выходного слоя.

  • Количество скрытых нейронов должно быть менее чем в два раза больше размера входного слоя.

Но вопрос в следующем: Сколько времени это будет стоить, если мы попробуем вышеупомянутые предложения?!

Здесь вам нужно использовать GridSearchCV и вы в конечном итоге будете тратить больше времени, чем SVM само по себе !!!


Итак, как вы можете видеть, существует компромисс между точностью и производительностью.Вы не можете требовать выдающегося и хорошего реального времени производительности в то же время для вашего конкретного набора данных, потому что он огромный и в основном заполнен нулями!!


Что делать?

У вас есть следующие варианты:

1. Либо придерживайтесь текущей реализации SVM или ANN, чтобы достичь высокой точности , но худшей производительности в реальном времени !

2. Или идите с гауссовым наивным байесовским , который дает выдающуюся производительность (потому что это в основном для онлайн-классификации!), Но наихудшая точность следующим образом:

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 для оценки важности функций. Здесь представляет собой полный и простой пример того, как сделать это в Scikit-Learn, а затем создать новую версию набора данных, но на этот раз включает только самые важные функции.Также рекомендуется создать подвыборку текущего набора данных, удалив строки / наблюдения, которые чаще всего содержат ввод нулей!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...