ML 模型无法正确预测

ML Model not predicting properly

我正在尝试使用 SMR、逻辑回归等各种技术创建 ML 模型(回归)。使用所有技术,我无法获得超过 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')

对于情节,我得到以下信息:

我尝试了各种参数调优,改变参数C,gamma甚至尝试了不同的内核,但没有改变精度。甚至尝试过 SVR、Logistic 回归而不是 SVC,但没有任何帮助。我尝试了不同的缩放比例来训练输入数据,例如 StandardScalar()scale().

我用了this作为参考

我该怎么办?

根据经验,我们通常遵循以下约定:

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

因为你的数据集是 10K 个案例,所以最好使用 Logistic Regression 因为 SVM 将永远完成!.


然而,由于您的数据集包含很多个classes,所以有可能class 你的实施不平衡。因此,我试图通过使用 StratifiedKFold 而不是 train_test_split 来解决这个问题,这不能保证拆分中的平衡 classes。

此外,我使用 GridSearchCVStratifiedKFold 执行交叉验证,以便 调整 参数并尝试所有不同的 优化器!

所以完整的实现如下:

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%!!.


这是为什么?

如果你想通过 T 恤的颜色使一个人 recognize/classify 成为另一个人,你不能说:嘿,红色表示他是 John,红色表示他是 Peter,但如果红色表示他是 Aisling !!他会说"really, what the hack is the difference"?!!

这正是您数据集中的内容!

简单地说,运行 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 !!

所有 class 都 共享 大量信息,甚至高达 36% 的准确率都令人印象深刻!

换句话说,你没有信息特征,导致每个class模型缺乏独特性!


怎么办? 我相信你不能删除一些 classes,所以你只有两个解决方案:

  1. 要么接受这个非常有效的结果。

  2. 或添加更多信息功能。


更新

如果您提供了相同的数据集但具有更多特征(即完整的特征集),那么现在的情况就不同了。

我建议您执行以下操作:

  1. 预处理您的数据集(即通过输入缺失值或删除包含缺失值的行,并将日期转换为一些唯一值来准备数据集() ...等等).

  2. 检查哪些特征对Orders类最重要,您可以通过使用Forests of Trees来评估特征的重要性来实现。 Here 是如何在 Scikit-Learn.

  3. 中执行此操作的完整而简单的示例
  4. 创建一个新版本的数据集,但这次将 Orders 作为 Y 响应,将上面找到的特征作为 X 变量。

  5. 按照我在上面的实施中向您展示的相同 GrdiSearchCVStratifiedKFold 过程进行操作。


提示

正如 Vivek Kumar 在下面的评论中提到的,stratify 参数已在 Scikit-learn 更新中添加到 train_test_split 函数。

它通过传递类似数组的基本事实来工作,所以你不需要我在上面的函数 stratifiedSplit(X, Y) 中的解决方法。