Вместо apply, как векторизовать для доступа к методам класса, когда классы хранятся внутри фрейма данных pandas?

#python #pandas #class #methods

#python #pandas #класс #методы

Вопрос:

У меня есть следующий код.

 import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import f1_score, roc_auc_score, recall_score, precision_score
from sklearn import datasets
import warnings
warnings.filterwarnings('ignore')

cancer = datasets.load_breast_cancer()
df = pd.DataFrame(cancer.data, columns=cancer.feature_names)
df['target'] = cancer.target
target = df['target']
X_train, X_test, y_train, y_test = train_test_split(df.drop(columns='target', axis=1), target, test_size=0.4, random_state=13, stratify=target)


d = {
    'model_names': ['RF', 'LR'],
    'models': [RandomForestClassifier(), LogisticRegression()]
}

df = pd.DataFrame(d)

scoring_metrics = {
            'precision': precision_score,
            'recall': recall_score,
            'f1': f1_score,
            'roc_auc': roc_auc_score
        }

def calc_score(col, metric):
        return round(metric(y_test, col.fit(X_train, y_train).predict(X_test)), 4)

# would like to replace the following step and vectorize the process
for metric_name, metric_func in scoring_metrics.items():
            df[metric_name] = df['models'].apply(calc_score, metric=metric_func)
  

Я хотел бы знать, возможно ли изменить for loop и apply и векторизовать его. Я надеялся на что-то подобное.

 scorer_from_scoring_metrics_dict(y_test, df['models'].fit(X_train, y_train).predict(X_test))
  

должен дать мне pandas series метрику, используемую для оценки для каждой модели.

В идеале я хочу, чтобы для каждой модели в столбце dataframe были найдены разные оценки из scoring_metrics dict и добавлены в качестве нового столбца.


Когда я делаю

 df['models'].fit(X_train, y_train).predict(X_test)
  

Я получаю сообщение об ошибке

 AttributeError                            Traceback (most recent call last)
<ipython-input-47-acb17f05fec7> in <module>
----> 1 df['models'].fit(X_train, y_train).predict(X_test)

~Anaconda3libsite-packagespandascoregeneric.py in __getattr__(self, name)
   4374             if self._info_axis._can_hold_identifiers_and_holds_name(name):
   4375                 return self[name]
-> 4376             return object.__getattribute__(self, name)
   4377 
   4378     def __setattr__(self, name, value):

AttributeError: 'Series' object has no attribute 'fit'
  

Комментарии:

1. В двух словах, нет, вы не можете «векторизовать» вызовы функций подобным образом. Однако вы можете использовать некоторую параллельную обработку или многопоточность

2. @RafaelC Спасибо за информацию. Я этого не знал.

3. @RafaelC пожалуйста, добавьте свой комментарий в качестве ответа, если хотите. Я могу пометить это правильно. Также добавьте, почему именно это так не работает.