如何顺序链接 ML 模型/管道模型?
Posted
技术标签:
【中文标题】如何顺序链接 ML 模型/管道模型?【英文标题】:How to chain ML models/pipeline models sequentially? 【发布时间】:2020-02-28 02:23:06 【问题描述】:前提: 我一直在研究这个 ML 数据集,我发现我的 ADA 提升和 SVM 在检测方面非常出色TP。两种模型的混淆矩阵如下所示。 这是图像:
在我训练的 10 个模型中,有 2 个是 ADA 和 SVM。其他 8 个,一些精度较低,另一些精度高 ~+-2%
主要问题:
我如何链接/流水线以便我的所有测试用例都按以下方式处理?
-
通过 SVM 和 ADA 传递所有案例。如果 SVM 或 ADA 的置信度超过 80%,则返回结果
否则,如果 SVM 或 ADA 的置信度不高,则仅让其他 8 个模型评估那些测试用例以做出最终决定
可能的解决方案: 我的潜在尝试涉及使用 2 个投票分类器。一个分类器只有 ADA 和 SVM,第二个分类器有其他 8 个模型。但我不知道如何做这项工作 这是我的方法的代码:
from sklearn.ensemble import VotingClassifier
ensemble1=VotingClassifier(estimators=[
('SVM',model[5]),
('ADA',model[7]),
], voting='hard').fit(X_train,Y_train)
print('The accuracy for ensembled model is:',ensemble1.score(X_test, Y_test))
#I was trying to make ensemble 1 the "first pass" if it was more than 80% confident in it's decision, return the result
#ELSE, ensemble 2 jumps in to make a decision
ensemble2=VotingClassifier(estimators=[
('LR',model[0]),
('DT',model[1]),
('RFC',model[2]),
('KNN',model[3]),
('GBB',model[4]),
('MLP',model[6]),
('EXT',model[8]),
('XG',model[9])
], voting='hard').fit(X_train,Y_train)
#I don't know how to make these two models work together though.
额外问题: 这些问题是为了帮助我解决一些额外的问题,而不是主要问题:
我正在努力做的事情值得吗?
只有真阳性和假阳性的混淆矩阵是否正常?或者这是否表明训练不正确?如上图 5 所示。
我的模型在个人层面上的准确性是否被认为是好的?这些模型正在预测患心脏病的可能性。准确度如下:
很抱歉发了这么长的帖子,感谢您的所有意见和建议。我是 ML 新手,所以我很感激任何指点。
【问题讨论】:
“我正在努力做的事情值得吗?”和“这些被认为是好的吗?”对于 SO 来说不是合适的问题,这是关于具体的编码问题。您的第二个项目符号甚至不包含问题,并且错误消息非常清楚且可以自我解释,代码有什么问题。 嗯,这些问题更像是一种奖励……您不必回答它们,但如果您有时间回答它们,那就太好了。这个问题的主要目的是弄清楚你是否可以将算法链接在一起。就代码而言,我想我不应该显示错误,但我试图显示我正在走的路线。我会再次编辑问题。 不好 - 现在你已经清楚地将它们标记为“额外问题”(但在第二个项目符号中仍然没有问题),但你完全不清楚你 主要问题是! 您似乎已经意识到VotingClassifier
不提供任何类型的 sequential 操作,因此您尝试做的绝对不是链/管道.
感谢@desertnaut 我进行了更正。希望很清楚,我现在要求的是什么。如果投票分类器不起作用,有人可以给我一个粗略的例子或向我指出如何使其工作的资源吗?
【参考方案1】:
这是一个简单的实现,有望解决链接多个估算器的主要问题:
class ChainEstimator(BaseEstimator,ClassifierMixin):
def __init__(self,est1,est2):
self.est1 = est1
self.est2 = est2
def fit(self,X,y):
self.est1.fit(X,y)
self.est2.fit(X,y)
return self
def predict(self,X):
ans = np.zeros((len(X),)) - 1
probs = self.est1.predict_proba(X) #averaging confidence of Ada & SVC
conf_samples = np.any(probs>=.8,axis=1) #samples with >80% confidence
ans[conf_samples] = np.argmax(probs[conf_samples,:],axis=1) #Predicted Classes of confident samples
if conf_samples.sum()<len(X): #Use est2 for non-confident samples
ans[~conf_samples] = self.est2.predict(X[~conf_samples])
return ans
你可以这样称呼:
est1 = VotingClassifier(estimators=[('ada',AdaBoostClassifier()),('svm',SVC(probability=True))],voting='soft')
est2 = VotingClassifier(estimators=[('dt',DecisionTreeClassifier()),('knn',KNeighborsClassifier())])
clf = ChainEstimator(est1,est2).fit(X_train,Y_train)
ans = clf.predict(X_test)
现在,如果您想基于est1
的性能进行链接,您可以执行以下操作来记录其在训练期间的性能,并在predict
函数上添加更多if
s:
def fit(self,X,y):
self.est1.fit(X,y)
self.est1_perf = cross_val_score(self.est1,X,y,cv=4,scoring='f1_macro')
self.est2.fit(X,y)
self.est2_perf = cross_val_score(self.est2,X,y,cv=4,scoring='f1_macro')
return self
请注意,您不应该对此类问题使用简单的准确性。
【讨论】:
非常感谢您为我提供了潜在的解决方案以及 cmets。你说的“你不应该对这样的问题使用简单的准确性”是什么意思?另外,你之前提到我的 SVM 和 ADA 可能有问题,因为它们都有相同的混淆矩阵,你知道为什么吗? 当我使用def fit(self,X,y): self.est1.fit(X,y) self.est1_perf = cross_val_score(self.est1,X,y,cv=4,scoring='f1_macro') self.est2.fit(X,y) self.est2_perf = cross_val_score(self.est2,X,y,cv=4,scoring='f1_macro') return self
时,我收到以下错误3次:/usr/local/lib/python3.6/dist-packages/sklearn/metrics/classification.py:1437: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples. 'precision', 'predicted', average, warn_for)
因为您的数据集似乎不平衡,并且在这种情况下,准确性可能会严重误导。 f1 是一个更好的选择。问题不在于它们具有相同的混淆度量,问题是您的矩阵不包含真负数。所以回答你的第二个额外问题是:不,它不正常
abt 第二个错误,它发生在具有混淆矩阵的模型(如模型 5 和模型 7)上,即预测没有标签属于 neg 类。尝试结合imbalance learning 技术来解决这个问题以上是关于如何顺序链接 ML 模型/管道模型?的主要内容,如果未能解决你的问题,请参考以下文章