【问题标题】:Python for loop only appending last result to list/DataFrame (example with iris dataset)Python for 循环仅将最后一个结果附加到列表/数据帧(以 iris 数据集为例)
【发布时间】:2020-03-24 00:29:46
【问题描述】:

我希望将每个使用的模型的结果附加到列表data,但是函数calc 只附加最后一个模型的结果。我确信这是我在这里想念的非常简单的东西!

    from sklearn import datasets
    from sklearn.linear_model import LogisticRegression
    from sklearn.tree import DecisionTreeClassifier
    from sklearn.naive_bayes import BernoulliNB
    from sklearn.model_selection import train_test_split

    import sklearn.metrics as metrics
    import matplotlib.pyplot as plt

    classifiers =[LogisticRegression(solver='liblinear', penalty='l2', C=200),
              LogisticRegression(penalty='l2', C=1),
              DecisionTreeClassifier(),
              BernoulliNB()]

    class_names = ['Logistic Regression', 'Logistic Regression'
                    'Regularized','CART', 'Naive Bayes (Bernoulli)']

# import some data to play with
    iris = datasets.load_iris()
    Xdata = iris.data[:, :2]  # we only take the first two features
    ydata = iris.target

    def calc (classifier_names, classifier_models, Xdata, ydata):

        X_train, X_test, y_train, y_test = \
    train_test_split(Xdata, ydata,test_size = 0.50, stratify=ydata,
                  random_state = 42)

        X_scaler = StandardScaler()
        X_train = X_scaler.fit_transform(X_train)
        X_test = X_scaler.transform(X_test)

        data=[]
        for name, clf in zip(classifier_names, classifier_models):

                clf.fit(X_train, y_train)
                score = clf.score(X_test, y_test)
                y_pred = clf.predict(X_test)
                ROC_AUC =  plot_ROC_AUC(clf, X_test, y_test)
                Accuracy = metrics.accuracy_score(y_test, y_pred)
                Brier_Score = metrics.brier_score_loss(y_test, y_pred)
                data.append((ROC_AUC, 
                         Accuracy, 
                         Brier_Score))
                cols = ['ROC_AUC', 'Accuracy', 'Brier_Score']
                result = pd.DataFrame(data, columns = cols, index=classifier_names)

                return result

    output = calc(class_names, classifiers, Xdata, ydata)  

output
                                 ROC_AUC  Accuracy  Brier_Score
Logistic Regression              0.925517  0.855072     0.144928
Logistic Regression Regularized  0.925517  0.855072     0.144928
CART                             0.925517  0.855072     0.144928
Naive Bayes (Bernoulli)          0.925517  0.855072     0.144928    
#want this to change here


#function within the calc function

    def plot_ROC_AUC(fit_model, X_test, y_test):

         probs=fit_model.predict_proba(X_test)
         preds = probs[:,1]
         fpr, tpr, threshold = metrics.roc_curve(y_test, preds)
         roc_auc = metrics.auc(fpr, tpr)

         #plot ROC
         plt.title('Receiver Operating Characteristic')
         plt.plot(fpr, tpr, 'b', label = 'AUC = %0.2f' % roc_auc)
         plt.legend(loc = 'lower right')
         plt.plot([0, 1], [0, 1],'r--')
         plt.xlim([0, 1])
         plt.ylim([0, 1])
         plt.ylabel('True Positive Rate')
         plt.xlabel('False Positive Rate')
         plt.show()

         return roc_auc

【问题讨论】:

  • 您是否尝试过使用append 函数? output.append(calc())
  • 是的,这行不通

标签: python for-loop scikit-learn append


【解决方案1】:

我不确定您尝试的具体内容,但我在这里看到了一个问题

 def calc (classifier_names, classifier_models, X, y):

        X_train, X_test, y_train, y_test = \
    train_test_split(Xdata, ydata,test_size = 0.50, stratify=ydata,
                  random_state = 42)

        X_scaler = StandardScaler()
        X_train = X_scaler.fit_transform(X_train)
        X_test = X_scaler.transform(X_test)

        data=[]
        for name, clf in zip(classifier_names, classifier_models):

                clf.fit(X_train, y_train)
                score = clf.score(X_test, y_test)
                y_pred = clf.predict(X_test)
                ROC_AUC =  plot_ROC_AUC(clf, X_test, y_test)
                Accuracy = metrics.accuracy_score(y_test, y_pred)
                Brier_Score = metrics.brier_score_loss(y_test, y_pred)
                data.append((ROC_AUC, 
                         Accuracy, 
                         Brier_Score))
                cols = ['ROC_AUC', 'Accuracy', 'Brier_Score']
                result = pd.DataFrame(data, columns = cols, index=classifier_names)

                return result

或简化:

 def func(something, darkside):
     for i in range(some_int):
         return some_other_func(i)

这个循环只会执行一步,因为return 语句会跳出函数。

我认为你应该尝试做的是在一些 DataFrame 中聚合 for 循环的结果,然后返回聚合。在这一点上,我可以说这是一个缩进问题,但看起来更高,我看到你在每个循环上也覆盖了 result,所以我会从那里开始

也许将循环移到函数之外?而是这样做:

def func(something, darkside):
    return some_expression_of(something,darkside)

for name, clf, in zip(classifer_names, classifier_models:
    func(name,clf)

【讨论】:

    猜你喜欢
    • 2019-05-15
    • 2019-07-08
    • 2021-04-26
    • 2020-04-25
    • 2016-01-31
    • 2016-12-17
    • 2016-10-13
    • 2021-12-13
    • 1970-01-01
    相关资源
    最近更新 更多