ML 模型无法正确预测
Posted
技术标签:
【中文标题】ML 模型无法正确预测【英文标题】:ML Model not predicting properly 【发布时间】:2019-04-20 14:21:54 【问题描述】:我正在尝试使用 SMR、Logistic 回归等各种技术创建 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作为参考
我该怎么办?
【问题讨论】:
看起来你得到的预测可以被解释为有效...... 假设“效率”意味着错误率,那么这对这个数据来说似乎相当不错。 @MatthieuBrucher,请原谅我,但我不太明白你的意思。 @GordonLinoff,我希望有更多像数据点这样的钟形输出。 请提供您正在使用的数据集的链接 【参考方案1】:根据经验,我们通常遵循以下约定:
-
对于少量功能,请使用
Logistic Regression
。
对于很多功能但不是很多数据,请使用SVM
。
如需大量功能和大量数据,请使用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%!!。
为什么会这样?
如果你想让一个人通过 T 恤颜色识别/分类另一个人,你不能说:嘿,如果它是红色的,那就意味着他是 John,如果是红色,那就是 Peter,如果是红色,那就是 Aisling!他会说“真的,有什么区别”?!!。
这正是您的数据集中的内容!
简单地说,运行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% 令人印象深刻!
换句话说,你没有信息特征,导致每个类模型缺乏唯一性!
怎么办? 我相信您不允许删除某些类,因此您仅有的两个解决方案是:
要么接受这个非常有效的结果。
或添加更多信息功能。
更新
如果您提供了相同的数据集但具有更多特征(即完整的特征集),现在的情况就不同了。
我建议您执行以下操作:
预处理您的数据集(即通过估算缺失值或删除包含缺失值的行以及将日期转换为某些唯一值来准备数据集 (example) ...等) .
检查哪些特性对Orders
类最重要,您可以通过使用Forests of Trees
来评估特性的重要性来实现这一点。 Here 是一个完整而简单的示例,说明如何在 Scikit-Learn
中执行此操作。
创建一个新版本的数据集,但这次将Orders
保留为Y
响应,并将上述功能保留为X
变量。
按照我在上面的实现中向您展示的相同GrdiSearchCV
和StratifiedKFold
过程。
提示
正如 Vivek Kumar 在下面的评论中提到的,stratify
参数已添加到 Scikit-learn
更新到 train_test_split 函数中。
它通过传递类似数组的基本事实来工作,所以你不需要我在上面的函数stratifiedSplit(X, Y)
中的解决方法。
【讨论】:
嗨@Yahya,非常感谢您的解释。这是数据集的另一个链接。你建议我在这种情况下应该怎么做:docs.google.com/spreadsheets/d/… 非常感谢!!我更改了模型,现在通过步骤,我在预测花费的金额方面达到了 80% 的准确率。 @SarvagyaGupta 很高兴我能帮上忙 :)train_test_split
也有一个分层参数以及test_size
。这里有特殊需要使用自定义stratifiedSplit
方法吗?
@VivekKumar 是的,你是对的,我知道这一点,它已添加到 Scikit-learn
更新中。但是,当我使用它时它抛出了一个异常,我忘记了它是什么但是当我检查时我没有时间修复它,因为我的主要关注点是找到原因而不是如何实现。我会将其添加到答案中作为提示。以上是关于ML 模型无法正确预测的主要内容,如果未能解决你的问题,请参考以下文章
ML.NET Cookbook:(10)如何使用模型做出一个预测?