【发布时间】:2014-12-31 15:35:27
【问题描述】:
我正在尝试为我正在进行的项目生成一些“哪个引擎效果最好”的数据。我的一般想法是做一些非常简单的事情,选择一个引擎,进行交叉验证,生成所有交叉验证结果的列表,其中最大的是“最好的”。所有测试均在同一组教学数据上完成。这是我的想法的一个sn-p。然后我会将它放入一个循环中,而不是将 simple_clf 设置为 svm.SVC() 有一个引擎循环并为每个引擎执行其余代码。基础数据位于 featurevecs 中,而 scorenums 包含一个相应的分数值,0 到 9,特定基础数据项应该生成该分数值。
X_train, X_test, y_train, y_test = train_test_split(
featurevecs, scorenums, test_size = 0.333, random_state = 0 )
# this would be in a loop of engine types but I'm just making sure basic code works
simple_clf = svm.SVC()
simple_clf = grid_search.GridSearchCV( simple_clf, CLFPARAMS, cv = 3 )
simple_clf.fit( X_train, y_train )
kf = cross_validation.KFold( len( X_train ), k = 5 )
scores = cross_validation.cross_val_score( simple_clf, X_test,
y_test, cv = kf )
print scores.mean(), scores.std() / 2
# loop would end here
我的问题是分数无法用于我应该提供的“最佳”方面。分数可以提供 .mean() 和 .std() 供我打印。但我不仅希望引擎返回完全匹配的结果,还希望得到“接近”匹配。就我而言,关闭意味着数字分数在预期分数的 1 以内。也就是说,如果预期得分为 3,则 2、3 或 4 都将被视为匹配和良好的结果。
我查看了文档,似乎最新的 scikit-learn 最前沿版本在度量包中增加了一个允许将自定义分数函数传递给网格搜索的功能,但我不确定这是否足够我需要什么。因为我还需要能够将它传递给 cross_val_score 函数,而不仅仅是 grid_search,不是吗?不管它不是一个选项,我都被锁定在我必须使用的 scikit-learn 版本中。
我还注意到在最新的前沿版本中对 cross_val_predict 的引用似乎正是我所需要的,但我再次被锁定在我使用的版本中。
当 cross_validation 的“好”定义不是它使用的完全匹配默认值时,在前沿之前做了什么?肯定是做了什么。我只需要指出正确的方向。
由于公司 IT 政策,我被困在 scikit-learn 的 0.11 版本,只能使用经过批准的软件,而不久前批准的版本是我唯一的选择。
这是我更改的内容,使用有用的提示查看 0.11 文档中的 cross_val_score 并发现它可以获得自定义分数函数,并且只要它与参数匹配,我就可以编写自己的函数。这是我现在拥有的代码。这会做我正在寻找的,即生成的结果不仅基于精确匹配,而且还基于“关闭”,其中关闭定义为 1 以内。
# KLUDGE way of changing testing from match to close
SCORE_COUNT = 0
SCORE_CROSSOVER_COUNT = 0
def my_custom_score_function( y_true, y_pred ):
# KLUDGE way of changing testing from match to close
global SCORE_COUNT, SCORE_CROSSOVER_COUNT
if( SCORE_COUNT < SCORE_CROSSOVER_COUNT ):
close_applies = False
else:
close_applies = True
SCORE_COUNT += 1
print( close_applies, SCORE_CROSSOVER_COUNT, SCORE_COUNT )
deltas = np.abs( y_true - y_pred )
good = 0
for delta in deltas:
if( delta == 0 ):
good += 1
elif( close_applies and ( delta == 1 ) ):
good += 1
answer = float( good ) / float( len( y_true ) )
return answer
主程序中的代码 sn-p:
fold_count = 5
# KLUDGE way of changing testing from match to close
# set global variables for custom scorer function
global SCORE_COUNT, SCORE_CROSSOVER_COUNT
SCORE_COUNT = 0
SCORE_CROSSOVER_COUNT = fold_count
# do a simple cross validation
simple_clf = svm.SVC()
simple_clf = grid_search.GridSearchCV( simple_clf, CLFPARAMS, cv = 3 )
simple_clf.fit( X_train, y_train )
print( '{0} '.format( test_type ), end = "" )
kf = cross_validation.KFold( len( X_train ), k = fold_count )
scores = cross_validation.cross_val_score( simple_clf, X_train, y_train,
cv = kf,
score_func = my_custom_score_function )
print( 'Accuracy (+/- 0) {1:0.4f} (+/- {2:0.4f}) '.format( scores, scores.mean(),
scores.std() / 2 ),
end = "" )
scores = cross_validation.cross_val_score( simple_clf, X_train, y_train,
cv = kf,
score_func = my_custom_score_function )
print( 'Accuracy (+/- 1) {1:0.4f} (+/- {2:0.4f}) '.format( scores, scores.mean(),
scores.std() / 2 ),
end = "" )
print( "" )
【问题讨论】:
-
自定义记分器在当前发布的 0.15.2 版本中。
-
不幸的是,我被困在 0.11,离 0.15.2 还很远。其次,自定义记分器只能从 metric 包提供的选项中获得,也就是说,您必须使用其中一个记分器。它们都提供了比我需要的简单预测更多的方法 +/- 1 == 预期是很好的定义。直到 0.16 才可以编写自己的 score 函数。除非我错过了如何通过参数使度量包评分器之一按我的意愿工作。
-
你为什么卡在旧版本上?您可以在本地安装一个新的。另外,你可以在 0.11 中使用自己的 score 函数,只是界面不同。顺便说一句,也许您有兴趣研究 skll 项目。
标签: python scikit-learn