Как последовательно соединить модели ML / модели конвейера? - PullRequest
3 голосов
/ 01 ноября 2019


Предпосылка:
Я работал над этим набором данных ML, и я обнаружил, что мой буст ADA и SVM очень хороши, когда дело доходит до обнаружения TP. Матрица смешения для обеих моделей одинакова, как показано ниже.
Вот изображение:
SVM Confusion Matrix

Из 10 обученных моделей, 2 из которых являются ADAи SVM. Остальные 8, некоторые имеют более низкую точность, а другие - на ~ + -2%

ОСНОВНОЙ ВОПРОС:

Как связать / конвейерную обработку таким образом, чтобы все мои тестовые случаи обрабатывались следующим образом?

  1. Пропустить все случаи через SVM и ADA. Если SVM или ADA имеют достоверность 80% +, возвращают результат
  2. В противном случае, если SVM или ADA не имеют высокой достоверности, оставьте только те тестовые случаи, которые будут оценены другими 8 моделями для окончательного решения

Потенциальное решение:
Моя потенциальная попытка заключалась в использовании двух классификаторов для голосования. Один классификатор только с 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.

  • Точность моих моделей на индивидуальном уровне считается хорошей? Модели предсказывают вероятность развития сердечно-сосудистых заболеваний. Точность ниже:
    All the models

Извините за длинный пост и спасибо за ваш вклад и предложения. Я новичок в ML, поэтому буду признателен за любые указатели.

1 Ответ

1 голос
/ 03 ноября 2019

Это простая реализация, которая, мы надеемся, решит вашу главную проблему объединения нескольких оценок:

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, вы можете сделать что-то подобное, чтобы записать ее производительность во время тренировки, и добавить еще несколько if с функцией predict:

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

Примечаниечто вы не должны использовать простую точность для такой задачи.

...