Пользовательский класс вызывает ошибку при попытке вызвать fit_transform - PullRequest
0 голосов
/ 06 мая 2019

Я создал пользовательские классы, которые хотят использовать с конвейерами scikit-learn и Feature-Unions.

Каждый класс принимает в качестве входных данных фрейм данных с 2 столбцами: 0, 1

Каждая строка в первом столбце является массивом пустых чисел, а каждая строка во второй строке является числом.

Учитывая эти два входа, я создал статическую функцию, которая вычисляет для каждой строки значений кадра данных 40.

Так что, если исходный кадр данных имеетформа 100 x 2, вывод должен быть 100 x 40.

Я использовал модули BaseEstimator и TransformerMixin для простой обработки методов fit_transform.

Когда я вызываю метод fit_transform, я получаю следующую ошибку:

ValueError: Форма переданных значений (288, 40), индексы подразумевают (288, 2)

class MelFrequencyCepstralCoefficientsCalculator(BaseEstimator, TransformerMixin):
    """outputs Mel-frequency cepstral coefficients"""

    def __init__(self):
        """

        """

    @staticmethod
    def calculate_coef(file_array: np.array,
                       sample_rate):
        """

        :param file_array:
        :param sample_rate:
        :return:
        """
        # mfcc: Mel-frequency cepstral coefficients to each row

        # this output is an array of shape (40, )
        mfccs = np.mean(librosa.feature.mfcc(y=file_array,
                                             sr=sample_rate,
                                             n_mfcc=40).T, axis=0)
        return mfccs

    def transform(self, X, y=None) -> np.array:
        print('Calculating Mel-frequency cepstral coefficients')

        res = X.progress_apply(lambda row: self.calculate_coef(row[0], row[1]), axis=1).values

        print('Output shape: {}'.format(res.shape))

        return res

    def fit(self, X, y=None):
        """Returns `self` unless something different happens in train and test"""
        return self

mfccs = MelFrequencyCepstralCoefficientsCalculator()

x_val = mfccs.fit_transform(x_val_raw)

Разве я не могу иметь собственный класс, который создает более одного объекта в конвейере sklearn?

PS: progress_appy допустим.Я использую модуль tqdm, который расширяет apply , чтобы иметь индикатор выполнения для каждого вычисления

Обходной путь, который намного медленнее, но работает, следующий:

    def transform(self, X: pd.DataFrame, y=None) -> np.array:
    """

    :param X:
    :param y:
    :return:
    """
    print('Calculating Mel-frequency cepstral coefficients')

    # res = X.apply(lambda row: self.calculate_coef(row[0], row[1]), axis=1)

    features = np.empty((0, 40))

    rows = X.iterrows()

    for row in tqdm(rows):
        ext_features = self.calculate_coef(row[1][0], row[1][1])
        features = np.vstack([features, ext_features])

    print('Output shape: {}'.format(features.shape))

    return features
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...