问题描述
我需要制作一个基于三个列表/数组 java.io.IOException: There appears to be a gap in the edit log. We expected txid 90247527115,but got txid 90247903412.
、y_true
和 y_pred
计算分数的评分器。问题是网格搜索中的评分器为训练集和验证集计算了一个分数,我不知道如何区分它。这就是我尝试做的(完整示例):
sample_value
并且错误是 import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import gridsearchcv
from sklearn.metrics import make_scorer
def RF_metric(y_true,y_pred,sample_value):
dict_temp = {'y_pred': list(y_pred),'y_true': list(y_true),'sample_value': sample_value}
df_temp = pd.DataFrame(dict_temp)
df_temp['daily_score'] = df_temp[['y_pred','y_true','sample_value']].apply(
lambda row: row[2] if row[0] == row[1] else -row[2],axis=1)
df_temp['cum_score'] = df_temp['daily_score'].cumsum()
final_score = df_temp['cum_score'].to_list()[-1]
return final_score
param_dict = {'n_estimators': [100,150,200],'max_depth': [5,10,15],}
dates = pd.date_range(start='2020-01-01',end='2020-10-01')
df = pd.DataFrame({'Date': dates,'A':np.random.rand(len(dates)),'B':np.random.rand(len(dates)),'label':np.random.choice([0,1],len(dates)),'sample_value':np.random.rand(len(dates))})
train_start = pd.to_datetime('2020-01-01')
train_end = pd.to_datetime('2020-06-01')
val_start = train_end
val_end = pd.to_datetime('2020-07-01')
df_train = df[(train_start <= df['Date']) & (df['Date'] < train_end)]
df_val = df[(val_start <= df['Date']) & (df['Date'] < val_end)]
cv_list = [(list(df_train.index),list(df_val.index))]
X = df[['A','B']].values
Y = df[['label']].values.ravel()
clf = RandomForestClassifier()
scoring = make_scorer(RF_metric,sample_value = df_val['sample_value'].to_list())
gs = gridsearchcv(clf,param_dict,cv=cv_list,scoring=scoring,n_jobs=4)
gs.fit(X,Y)
解决方法
由于升级您的版本有帮助,问题似乎是 return_train_score
过去默认为 True
,因此您的 scoring
确实通过了训练集,但验证的 sample_value
}}。
一种解决方案(这会有所帮助,例如,如果您仍然想要训练分数,或者想要切换到 kfold 交叉验证)是不使用便利函数 make_scorer
。它只返回一个带有签名 (estimator,X,y)
的可调用对象,其中“分数”越大越好。您可以编写自己的此类可调用对象,然后您可以访问所有 X
(包括 sample_value
列!),而不仅仅是估算器的预测。