A RandomForestClassifier
экземпляр ожидает следующие данные в качестве меток:
y: в виде массива, shape = [n_samples] или [n_samples, n_outputs] Целевые значения (метки классов в классификации, действительные числа в регрессии).
Но transformer.fit_transform(df.category)
возвращает разреженную матрицу типа '<class 'numpy.float64'>
, что не ожидается.
Если вы пытаетесь классифицировать некоторые данные вограничивая количество категорий, например, «хороший товар», «поврежденный товар», ... и т. д., вы можете кодировать эти данные не пословно, а как метки через кодировщик этикеток:
(о предсказании каждого слова с помощью нескольких меток см. ниже)
transformer = TfidfVectorizer(lowercase=True, stop_words=stop, max_features=500)
X = transformer.fit_transform(df.Text)
le = LabelEncoder()
y = le.fit_transform(df.category)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
model = RandomForestClassifier()
model.fit(X_train, y_train)
le.inverse_transform(model.predict(X_test))
Out:
array(['good product', 'good product'], dtype=object)
- (или около того) - это самое простое решение.
Если вы планируете провести некоторую многослойную классификацию, есть две проблемы:
- Будет много меток, в зависимости от количества отдельных слов в строке
df.category
- разреженная матрица - это то, что вы можете преобразовать в numpy.array, но это стоит памяти, и матрица содержит плавающие значения, так как это значения tf-idf, но
RandomForestClassifier
будет отлично работать с целочисленными метками:
Итак,
y.toarray()
array([[0. , 0.77722116, 0.62922751, 0. ],
[0.84292635, 0. , 0.53802897, 0. ],
[0. , 0. , 0. , 1. ],
[0. , 0.77722116, 0.62922751, 0. ]])
- хорошо, он конвертируется в некоторый целочисленный массив {0, 1}
, но его проще использовать MultiLabelBinarizer
(обратите внимание, что применяется split
в каждую строку, чтобы получить слово, а не символьную бинаризацию):
transformer = TfidfVectorizer(lowercase=True, stop_words=stop, max_features=500)
X = transformer.fit_transform(df.Text)
mlb = MultiLabelBinarizer()
y = mlb.fit_transform(df.category.map(lambda x: x.split()))
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
model = RandomForestClassifier()
model.fit(X_train, y_train)
В этом случае y
:
y
Out:
array([[0, 1, 1, 0],
[1, 0, 1, 0],
[0, 0, 0, 1],
[0, 1, 1, 0]])
И он может предсказать слова:
mlb.inverse_transform(model.predict(X_test))
Out:
[('good', 'product'), ('good', 'product')]
Установка TfidfTransformer опасна
Не по теме, но: здесь вы переустановили векторизатор:
X = transformer.fit_transform(df.Text)
print(transformer.vocabulary_)
y = transformer.fit_transform(df.category)
print(transformer.vocabulary_)
Out:
{'its': 3, 'good': 1, 'product': 6, 'damaged': 0, 'sttate': 7, 'is': 2, 'unknown': 8, 'one': 5, 'more': 4}
{'good': 1, 'product': 2, 'damaged': 0, 'unknown': 3}
- это может привести к ошибкам, если выпозже попробую использовать преобразователь, чтобы сделать некоторые с данными Text
.Лучше создать два трансформатора и использовать их отдельно.