Как комбинировать функции с выводом разных измерений с помощью обучения 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