Как комбинировать функции с выводом разных измерений с помощью обучения Scikit

Я использую scikit-learn с Pipeline и FeatureUnion для извлечения функций из разных входов. Каждый образец (экземпляр) в моем наборе данных относится к документам различной длины. Моя цель - вычислить верхний tfidf для каждого документа независимо, но я продолжаю получать это сообщение об ошибке:

ValueError: blocks [0,:] имеет несовместимые размеры строк. Получил блоки [0,1].shape[0] == 1, ожидается 2000.

2000 - размер обучающих данных. Это основной код:

book_summary= Pipeline([
   ('selector', ItemSelector(key='book')),
   ('tfidf', TfidfVectorizer(analyzer='word', ngram_range(1,3), min_df=1, lowercase=True, stop_words=my_stopword_list, sublinear_tf=True))
])

book_contents= Pipeline([('selector3', book_content_count())]) 

ppl = Pipeline([
    ('feats', FeatureUnion([
         ('book_summary', book_summary),
         ('book_contents', book_contents)])),
    ('clf', SVC(kernel='linear', class_weight='balanced') ) # classifier with cross fold 5
]) 

Я написал два класса для обработки каждой функции конвейера. Моя проблема с конвейером book_contents, который в основном работает с каждым образцом и возвращает матрицу TFidf для каждой книги независимо.

class book_content_count(): 
  def count_contents2(self, bookid):
        book = open('C:/TheCorpus/'+str(int(bookid))+'_book.csv', 'r')       
        book_data = pd.read_csv(book, header=0, delimiter=',', encoding='latin1',error_bad_lines=False,dtype=str)
                      corpus=(str([user_data['text']]).strip('[]')) 
        return corpus

    def transform(self, data_dict, y=None):
        data_dict['bookid'] #from here take the name 
        text=data_dict['bookid'].apply(self.count_contents2)
        vec_pipe= Pipeline([('vec', TfidfVectorizer(min_df = 1,lowercase = False, ngram_range = (1,1), use_idf = True, stop_words='english'))])
        Xtr = vec_pipe.fit_transform(text)
        return Xtr

    def fit(self, x, y=None):
        return self

Образец данных (пример):

title                         Summary                          bookid
The beauty and the beast      is a traditional fairy tale...    10
ocean at the end of the lane  is a 2013 novel by British        11

Тогда каждый идентификатор будет ссылаться на текстовый файл с фактическим содержанием этих книг

я пытался toarray а также reshape функции, но без удачи. Любая идея, как решить эту проблему. Спасибо

0 ответов

Вы можете использовать Neuraxle FeatureUnion с настраиваемым объединителем, который вам нужно будет написать самостоятельно. Объединитель - это класс, переданный в FeatureUnion Neuraxle для объединения результатов, как вы ожидали.

1. Импортируйте классы Neuraxle.

from neuraxle.base import NonFittableMixin, BaseStep
from neuraxle.pipeline import Pipeline
from neuraxle.steps.sklearn import SKLearnWrapper
from neuraxle.union import FeatureUnion

2. Определите свой собственный класс, унаследовав его от BaseStep:

class BookContentCount(BaseStep): 

    def transform(self, data_dict, y=None):
        transformed = do_things(...)  # be sure to use SKLearnWrapper if you wrap sklearn items.
        return transformed

    def fit(self, x, y=None):
        return self

3. Создайте участника объединения, чтобы присоединиться к результатам объединения объектов так, как вы хотите:

class CustomJoiner(NonFittableMixin, BaseStep):
    def __init__(self):
        BaseStep.__init__(self)
        NonFittableMixin.__init__(self)

    # def fit: is inherited from `NonFittableMixin` and simply returns self.

    def transform(self, data_inputs):
        # TODO: insert your own concatenation method here.
        result = np.concatenate(data_inputs, axis=-1)
        return result

4. Наконец, создайте конвейер, передав объединителя в FeatureUnion:

book_summary= Pipeline([
    ItemSelector(key='book'),
    TfidfVectorizer(analyzer='word', ngram_range(1,3), min_df=1, lowercase=True, stop_words=my_stopword_list, sublinear_tf=True)
])

p = Pipeline([
    FeatureUnion([
        book_summary,
        BookContentCount()
    ], 
        joiner=CustomJoiner()
    ),
    SVC(kernel='linear', class_weight='balanced')
]) 

Примечание: если вы хотите, чтобы ваш конвейер Neuraxle снова стал конвейером scikit-learn, вы можете сделать p = p.tosklearn().

Чтобы узнать больше о Neuraxle: https://github.com/Neuraxio/Neuraxle

Еще примеры из документации: https://www.neuraxle.org/stable/examples/index.html

Другие вопросы по тегам