在训练随机森林分类器的过程中,我一直试图在scikit-learn中使用加权样本.当我直接将样本权重传递给分类器时它很有效,例如 RandomForestClassifier().fit(X,y,sample_weight=weights)
,但是当我尝试网格搜索以找到分类器的更好的超参数时,我碰到了一堵墙:
要在使用grid参数时传递权重,用法是:
grid_search = GridSearchCV(RandomForestClassifier(), params, n_jobs=-1,
fit_params={"sample_weight"=weights})
Run Code Online (Sandbox Code Playgroud)
问题是交叉验证器不知道样本权重,因此不会将它们与实际数据一起重新采样,因此调用grid_search.fit(X,y)
失败:交叉验证器创建X和y,sub_X和sub_y的子集,最终调用分类器classifier.fit(sub_X, sub_y, sample_weight=weights)
但现在权重尚未重新采样,因此抛出异常.
目前我已经通过在训练分类器之前对高重量样本进行过度采样来解决这个问题,但这是一个临时的解决方法.有关如何进行的任何建议?
我跟踪了一个 java 进程,该进程触发了大量内核时间来查看正在使用的系统调用,并且惊讶地看到它gettimeofday()
并clock_gettime()
占主导地位(我怀疑这是由于日志记录),考虑到以下man vdso
状态,这很奇怪:
使用strace (1)跟踪系统调用时,vDSO 导出的符号(系统调用)不会出现在跟踪输出中。
这些系统调用是怎么发生的?有没有办法避免它们?
该机器在 EC2 上运行 Ubuntu 16.04.1。
为方便起见,我用 C ( testgtod.c
)创建了一个最小的测试程序:
#include <stdlib.h>
#include <sys/time.h>
void main(void)
{
struct timeval tv;
for(int i = 0; i < 1000; i++) {
/* glibc wrapped, shouldn't actually syscall */
gettimeofday(&tv, NULL);
}
}
Run Code Online (Sandbox Code Playgroud)
然后我在strace下编译并运行程序: gcc testgtod.c -o testgtod && sudo strace ./testgtod
输出包括对 gettimeofday() 的一千次调用,尽管我有预料。
我测试过的东西以确保我看不到东西:
确保二进制文件是一个 64 位精灵使用 file
ldd ./testgtod
确保 vDSO 处于活动状态:
linux-vdso.so.1 => (0x00007ffcee25d000) …