将 scikit-learn 详细日志写入外部文件

Posted

技术标签:

【中文标题】将 scikit-learn 详细日志写入外部文件【英文标题】:Writing scikit-learn verbose log into an external file 【发布时间】:2017-05-21 08:08:21 【问题描述】:

我正在尝试使用GridSearchCV 优化 SVR 模型,但由于过度拟合而面临问题,为了克服这个问题,我尝试减少迭代次数,而不是将其留到收敛。要比较这两个模型,我需要两种情况的迭代次数。

我尝试通过verbose = 1 执行此操作,但它在 jupyter notebook 中不起作用。我需要访问迭代次数并将其保存为变量以绘制优化结果。将详细日志写入外部文件可以解决问题,但我无法做到。

我从上一个问题中得到了一些信息 Knowing the number of iterations needed for convergence in SVR scikit-learn 但还是没能解决问题

这是我的代码示例:

model_1=SVR(kernel='rbf',C=316,epsilon=0, gamma=0.003162,max_iter=2500,verbose=1)
model_1.fit(tr_sets[:,:2],tr_sets[:,2])

【问题讨论】:

【参考方案1】:

考虑到 Christian 在他的回答中所说的,如果 scikit-learn 的日志记录是由 print() 完成的,要将其保存到外部文件中,您应该将 sys.stdout 重定向到您希望的文件,然后任何print() 输出都将打印到文件而不是控制台。

要将sys.stdout 重定向到文件,请执行以下操作:

import sys

sys.stdout=open("external_file.txt","w")
print ("this is a log message")

sys.stdout.close()

现在,如果您打开 external_file.txt,您将在文件中看到“这是一条日志消息”文本

别忘了在脚本结束时关闭文件! (sys.stdout.close())

【讨论】:

这就是问题所在,日志不是由print() 命令完成的。但是无论如何谢谢你:) 有没有人弄清楚它是如何工作的?更改 stdout 不会捕获 GridSearchCV 的日志记录到文件。 根据这个answer,sklearn使用joblib的“日志”,如果详细级别高于50,它将向sys.stdout发送消息。因此您可以将sys.stdout设置为打开的文件,并在GridSearchCV 中使用verbose=51【参考方案2】:

如果我正确理解 scikit 中的日志记录,他们根本没有使用 python 日志记录基础设施,而是直接使用 print(),这使得捕获它非常困难,特别是与 jupyter notebooks 结合使用,这对捕获标准流。

啊哈找到了,它内部使用了joblibs详细打印基础设施,这有我提到的问题。

https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/cross_validation.py

我过去曾使用过这个技巧来使用 normall 日志记录工具来制作 joblib:https://github.com/joblib/joblib/issues/190 但我不知道如何在 scikit learn 中进行这种猴子修补工作

【讨论】:

这意味着它太复杂了,谢谢

以上是关于将 scikit-learn 详细日志写入外部文件的主要内容,如果未能解决你的问题,请参考以下文章

Python 日志记录与写入文件

Python + logging输出到屏幕,将log日志写入到文件

Oracle 触发器将所有插入/更新写入文件

Log4j - 如何在没有其他详细信息的情况下仅将我的消息日志写入文件

使用 .NET 应用程序从外部主机将数据写入 GCP BigTable

日志文件写入失败(permission denied)