Модель ML не предсказывает должным образом - PullRequest
0 голосов
/ 17 ноября 2018

Я пытаюсь создать модель ML (регрессию), используя различные методы, такие как SMR, логистическая регрессия и другие.При всех методах я не могу получить эффективность более 35%.Вот что я делаю:

X_data = [X_data_distance]
X_data = np.vstack(X_data).astype(np.float64)
X_data = X_data.T
y_data = X_data_orders
#print(X_data.shape)
#print(y_data.shape)
#(10000, 1)
#(10000,)
X_train, X_test, y_train, y_test = train_test_split(X_data, y_data, test_size=0.33, random_state=42)
svr_rbf = SVC(kernel= 'rbf', C= 1.0)
svr_rbf.fit(X_train, y_train)
plt.plot(X_data_distance, svr_rbf.predict(X_data), color= 'red', label= 'RBF model')

Для графика я получаю следующее: enter image description here

Я пробовал различные настройки параметров, меняяпараметр C, gamma даже пробовал разные ядра, но ничего не меняет точность.Даже попробовал SVR, логистическая регрессия вместо SVC, но ничего не помогает.Я пробовал различное масштабирование для обучающих входных данных, таких как StandardScalar() и scale().

Я использовал этот в качестве справочного

Что мне делать?

1 Ответ

0 голосов
/ 18 ноября 2018

Как правило, мы обычно придерживаемся этого соглашения:

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

Поскольку ваш набор данных составляет 10K, было бы лучше использовать Logistic Regression, потому что SVM будет длиться вечно!.


Тем не менее, поскольку ваш набор данных содержит много классов, существует вероятность дисбаланса классов в вашей реализации. Поэтому я попытался обойти эту проблему, используя StratifiedKFold вместо train_test_split, что не гарантирует сбалансированные классы в разбиениях.

Более того, я использовал GridSearchCV с StratifiedKFold , чтобы выполнить перекрестную проверку для настройки параметров и опробовать все различные оптимизаторы !

Итак, полная реализация выглядит следующим образом:

import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
from sklearn.model_selection import GridSearchCV, StratifiedKFold, StratifiedShuffleSplit
import numpy as np


def getDataset(path, x_attr, y_attr):
    """
    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
    :return: tuple, (X, Y)
    """
    df = pd.read_csv(path)
    X = X = np.array(df[x_attr]).reshape(len(df), len(x_attr))
    Y = np.array(df[y_attr])
    return X, Y

def stratifiedSplit(X, Y):
    sss = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=0)
    train_index, test_index = next(sss.split(X, Y))
    X_train, X_test = X[train_index], X[test_index]
    Y_train, Y_test = Y[train_index], Y[test_index]
    return X_train, X_test, Y_train, Y_test


def run(X_data, Y_data):
    X_train, X_test, Y_train, Y_test = stratifiedSplit(X_data, Y_data)
    param_grid = {'C': [0.01, 0.1, 1, 10, 100, 1000], 'penalty': ['l1', 'l2'],
                  'solver':['newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga']}
    model = LogisticRegression(random_state=0)
    clf = GridSearchCV(model, param_grid, cv=StratifiedKFold(n_splits=10))
    clf.fit(X_train, Y_train)
    print(accuracy_score(Y_train, clf.best_estimator_.predict(X_train)))
    print(accuracy_score(Y_test, clf.best_estimator_.predict(X_test)))


X_data, Y_data = getDataset("data - Sheet1.csv", ['distance'], 'orders')

run(X_data, Y_data)

Несмотря на все попытки со всеми различными алгоритмами, точность не превышает 36% !!.


Почему это?

Если вы хотите, чтобы человек узнал / классифицировал другого человека по цвету его футболки, вы не можете сказать: эй, если он красный, это означает, что он Джон, а если красный, то это Питер, а если красный, то это Эйслинг !! Он сказал бы: «В самом деле, в чем разница?».

И это именно то, что находится в вашем наборе данных!

Просто запустите print(len(np.unique(X_data))) и print(len(np.unique(Y_data))), и вы обнаружите, что цифры такие странные, в двух словах:

Number of Cases: 10000 !!
Number of Classes: 118 !!
Number of Unique Inputs (i.e. Features): 66 !!

Все классы делятся чертовски много информации, которая делает впечатляющим даже с точностью до 36%!

Другими словами, у вас нет информативных функций, которые приводят к отсутствию уникальности каждой модели класса!


Что делать? Я считаю, что вам не разрешено удалять некоторые классы, поэтому у вас есть только два решения:

  1. Либо жить с этим очень действительным результатом.

  2. Или добавить более информативную функцию (и).


Обновление

Если вы предоставили тот же набор данных, но с дополнительными функциями (т. Е. Полным набором функций), ситуация теперь другая.

Я рекомендую вам сделать следующее:

  1. Предварительно обработайте ваш набор данных (т.е. подготовьте его, вменяя пропущенные значения или удаляя строки, содержащие пропущенные значения, и конвертируя даты в некоторые уникальные значения ( пример ) .. Т.д.).

  2. Проверьте, какие функции наиболее важны для классов Orders. Вы можете достичь этого с помощью Forests of Trees для оценки важности функций. Здесь - полный и простой пример того, как это сделать в Scikit-Learn.

  3. Создайте новую версию набора данных, но на этот раз удерживайте Orders в качестве ответа Y, а найденные выше функции в качестве X переменных.

  4. Выполните ту же процедуру GrdiSearchCV и StratifiedKFold, которую я показал вам в приведенной выше реализации.


Подсказка

Как упомянуто Вивеком Кумаром в комментарии ниже, параметр stratify был добавлен в Scikit-learn обновлении функции train_test_split .

Он работает, передавая основанную на массиве основную истину, поэтому вам не нужен мой обходной путь в функции stratifiedSplit(X, Y) выше.

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