如何为我的项目找到正确的回归模型

数据挖掘 scikit-学习 回归 优化
2022-03-08 10:17:26

我尝试了几件事来找到具有最佳参数的最佳回归模型,但我不能超过 40% 的正确预测。

所以我在一个 excel 文件中有 67741 行。清理后的数据是这样的(只有 4 列,够吗?):

行

和这样的目标行: 在此处输入图像描述

我将尝试解释我的过程。

我去了这个网站https://scikit-learn.org/stable/tutorial/machine_learning_map/index.html从这张图中,应该适合我的数据的模型是 Lasso 和 ElasticNet,我用这段代码得到了非常糟糕的分数:

classifiers = [
ElasticNetCV(cv=5, random_state=0,max_iter=40000), # i added the max_iter cause i got a warning saying that i should increase it
linear_model.Lasso(alpha=0.1,max_iter=40000)] # i added the max_iter cause i got a warning saying that i should increase it

X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.33, random_state=42)

for clf, param in zip(classifiers, param_grid):
    name = clf.__class__.__name_
    clf.fit(X_train, y_train)
    print("=" * len(name))
    print("{}".format(name))

    print(clf.score(X_test, y_test))

成绩:

============
ElasticNetCV
0.002404878871672067
=====
Lasso
0.0066801704903023396

然后我尝试了其他几个模型,我终于得到了一些东西:

BaggingRegressor(base_estimator=DecisionTreeRegressor(),
              max_features=0.5, max_samples=0.5)

分数 :

================
BaggingRegressor
0.3460147571634854

所以我使用了 GridSearch 然后交叉验证分数来获得最好的参数,但是每次我启动它时,我都会得到一个不同的结果:

BaggingRegressor(base_estimator=DecisionTreeRegressor(), bootstrap=True, 
bootstrap_features=False,
              max_features=0.2, max_samples=0.7, n_estimators=10,
              n_jobs=None, oob_score=False, random_state=None, verbose=0,
              warm_start=False)

我是这样用的:

param_grid = [{'max_samples': [0.1, 0.2, 0.5, 0.7, 1],
           'max_features': [0.1, 0.2, 0.5, 0.7, 1],
           'n_estimators': [5,10,15,20,25]}

def grid_search(clf, param_grid):
    grid_search = GridSearchCV(clf, param_grid, cv=5)
    grid_search.fit(X, y)
    print(grid_search.best_estimator_)
    print("=" * len(name))
    print(grid_search.best_params_)
    print("=" * len(name))
    print(grid_search.best_score_)

和这样的交叉验证:scores = cross_val_score(clf, X, y, cv=10)

抱歉,如果它有点长,有 67000 行我不能得到超过 30% 的正确预测?有什么问题 ?

谢谢

2个回答

此答案基于有关问题评论中提供的数据的其他信息:

[...]所以它是关于交付第一个和第二个是对应于城市的ID,第三个是日期,最后一个是对应于正在变化的卡车的ID(我对其进行了排序,这就是为什么它在第一个中相同3 列)。目标 Y 是延迟。

如果您只是以未格式化的方式将时间列添加到回归中,则方法将无法很好地消化信息。想想你的问题。由于交通状况(时间或星期几),交货可能会延迟。我建议您对时间进行编码,例如以一天中的某个小时、一周中的某天、一年中的一周(左右)进行编码,并将所有这些(可能是一次性编码的)变量/特征添加到您的模型中(连同其余特征)。您可以使用正则化(例如套索)来“缩小”不必要的特征。这应该给你一个合适的。

本质上,您需要真正确保从“日期”列中获得尽可能多的信息。在 Python 中,您可以通过预定义的函数对日期进行编码,例如

import datetime
Todays date datetime.datetime.today()
Day of week datetime.datetime.today().weekday()
Week of year datetime.datetime.today().isocalendar()[1]

在此处查找如何应用套索的示例

这与其说是寻找最佳回归模型和参数的问题,不如说是特征工程的问题。您尝试使用 3 个 id 列和 1 个 date 列进行回归。唯一有点度量标准的列是日期列,我不希望它包含足够的信息来进行可靠的回归。另外,我假设您有很多卡车开往许多城市,这意味着在虚拟编码之后,您将拥有大量虚拟变量。

特征工程

特征工程是一个非常广泛的主题,一篇 SE-post 无法涵盖。但是,这里有两个简单的经验法则:

  • 聚合具有许多类别并使用不同方式聚合它们的分类列(例如按地区聚合城市,但也按大小聚合它们,等等)。
  • 不要将 id-columns 视为特征,而应将其视为 id。使用它们来连接其他数据集。例如,从卡车 ID 中,您可能可以获得有关卡车(型号、类型……)和驾驶员(经验……)的更多信息。此外,从 city-id,您可以获得大量信息(城市之间的距离、城市的大小/人口、天气等)。

以下是一些关于附加功能的简单建议:

  • 月份和工作日(也可能是季节)
  • 一天中的几类时间(下午晚上,...)
  • 如果有很多城市,请删除 city-id 列并按地区、大小或任何对您有意义的方式聚合它。
  • 此外,如果有许多卡车,请删除卡车 ID 列并将其汇总(例如,按卡车类型交付类型司机工作年限或您可以获得的任何数据)。
  • 当前城市与卡车之前所在城市之间的估计道路距离
  • 目的地城市/始发城市的路网规模
  • 各个时间和地点的天气(下雨下雪晴天,...)
  • 卡车最后一次交货的延误

这些只是一些建议。使用对您有意义的任何功能,并使用您能找到的任何附加数据。也许,在您的新数据集上运行决策树并检查特征重要性。这将使您了解哪些功能最有希望用于进一步的特征工程。

寻找最佳模型

完成特征工程后,您可以考虑寻找最佳模型。对于这种数据量,我建议使用 ElasticNet 和 Lasso,但我肯定会尝试使用决策树、随机森林和 xgboost。另外,考虑将目标变量分成几个类别并进行分类而不是回归。这也可能适合您的用例。