ValueError: Неизвестный тип метки: «unknown» в RandomForestClassifier - PullRequest
0 голосов
/ 09 февраля 2019

Я пытаюсь обучить набор данных с помощью RandomForestClassifier

transformer = TfidfVectorizer(lowercase=True, stop_words=stop, max_features=500)
X = transformer.fit_transform(df.Text)
y = transformer.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)

мой набор данных будет выглядеть как

Review(text format)    Category(text format)
Its good product       good product
Its damaged product    damaged product

Я получаю ошибку, что

raise ValueError("Unknown label type: %r" % y_type)
ValueError: Unknown label type: 'unknown'

Может кто-нибудьпредложить какое-либо решение, чтобы решить это?

1 Ответ

0 голосов
/ 09 февраля 2019

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)

- (или около того) - это самое простое решение.

Если вы планируете провести некоторую многослойную классификацию, есть две проблемы:

  1. Будет много меток, в зависимости от количества отдельных слов в строке df.category
  2. разреженная матрица - это то, что вы можете преобразовать в 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.Лучше создать два трансформатора и использовать их отдельно.

...