Это действительно не тот путь.Основываясь на сообщении об ошибке, ReviewText
явно является блоком неструктурированного текста.
Если вы передадите его непосредственно в ml_kmeans
, он будет рассматриваться как категориальная переменная, пропущенная через StringIndexer
(именно здесь происходит сбой - если вас интересуют подробности, вы можете проверить, spark.ml StringIndexer выбрасывает 'Unseen label' в fit () , но на практике это вряд ли уместно здесь),Тогда результат соберется в вектор длины, равный 1.
Как вы можете себе представить, это не очень полезная модель.
В общем случае вы должны как минимум (этого может не быть и, скорее всего, будет недостаточно для достижения хороших результатов на практике):
- Токенизация необработанного текста.
- Кодирование токенов.
Spark ML предоставляет небольшой набор базовых преобразователей текста, включая, но не ограничиваясь, Tokenizer
, StopWordsRemover
, NGram
, TF-IDF и дополнительные, более продвинутые инструменты предоставляются сторонними библиотеками (прежде всего NLP John Snow Labs), а также Pipeline
API , который можно использовать для их составления в многократно используемые модули .Я настоятельно рекомендую вам прочитать официальную документацию по каждому из этих инструментов, прежде чем продолжить.
Возвращаясь к вашей проблеме, вы можете начать с чего-то вроде этого
pipeline <- ml_pipeline(
# Tokenize the input
ft_tokenizer(sc, input_col = "ReviewText", output_col = "raw_tokens"),
# Remove stopwords - https://en.wikipedia.org/wiki/Stop_words
ft_stop_words_remover(sc, input_col = "raw_tokens", output_col = "tokens"),
# Apply TF-IDF - https://en.wikipedia.org/wiki/Tf-idf
ft_hashing_tf(sc, input_col = "tokens", output_col = "tfs"),
ft_idf(sc, input_col = "tfs", output_col = "features"),
ml_kmeans(sc, features_col = "features", init_mode = "random")
)
model <- ml_fit(pipeline, reviewsTbl_training)
и настроить его так, чтобы оно подходиловаш конкретный сценарий.