Bối cảnh: Tôi có một khung dữ liệu trong đó tất cả các giá trị phân loại đã được lập chỉ mục bằng cách sử dụng StringIndexer.Áp dụng IndexToString cho các tính năng vectơ trong Spark
val categoricalColumns = df.schema.collect { case StructField(name, StringType, nullable, meta) => name }
val categoryIndexers = categoricalColumns.map {
col => new StringIndexer().setInputCol(col).setOutputCol(s"${col}Indexed")
}
Sau đó, tôi đã sử dụng VectorAssembler để vector hóa tất cả các cột tính năng (bao gồm các cột danh mục được lập chỉ mục).
val assembler = new VectorAssembler()
.setInputCols(dfIndexed.columns.diff(List("label") ++ categoricalColumns))
.setOutputCol("features")
Sau khi áp dụng trình phân loại và một vài bước bổ sung, tôi kết thúc với khung dữ liệu có nhãn, tính năng và dự đoán. Tôi muốn mở rộng tính năng vector của mình để tách các cột để chuyển đổi các giá trị được lập chỉ mục trở lại dạng Chuỗi ban đầu của chúng.
val categoryConverters = categoricalColumns.zip(categoryIndexers).map {
colAndIndexer => new IndexToString().setInputCol(s"${colAndIndexer._1}Indexed").setOutputCol(colAndIndexer._1).setLabels(colAndIndexer._2.fit(df).labels)
}
Câu hỏi: Có đơn giản cách để làm điều này, hoặc là cách tiếp cận tốt nhất để bằng cách nào đó gắn cột dự đoán vào khung dữ liệu thử nghiệm?
Những gì tôi đã cố gắng:
val featureSlicers = categoricalColumns.map {
col => new VectorSlicer().setInputCol("features").setOutputCol(s"${col}Indexed").setNames(Array(s"${col}Indexed"))
}
Áp dụng điều này mang lại cho tôi các cột mà tôi muốn, nhưng họ đang có phong độ Vector (vì nó có nghĩa là để làm) và không gõ đúp.
Edit: Các đầu ra mong muốn là khung ban đầu dữ liệu (ví dụ: tính năng phân loại như String không index) với một cột bổ sung cho thấy nhãn dự đoán (mà trong trường hợp của tôi là 0 hoặc 1).
Ví dụ, nói đầu ra của phân loại của tôi trông như thế này:
+-----+---------+----------+
|label| features|prediction|
+-----+---------+----------+
| 1.0|[0.0,3.0]| 1.0|
+-----+---------+----------+
Bằng cách áp dụng VectorSlicer trên mỗi tính năng tôi sẽ nhận được:
+-----+---------+----------+-------------+-------------+
|label| features|prediction|statusIndexed|artistIndexed|
+-----+---------+----------+-------------+-------------+
| 1.0|[0.0,3.0]| 1.0| [0.0]| [3.0]|
+-----+---------+----------+-------------+-------------+
Mà là tuyệt vời, nhưng tôi cần:
+-----+---------+----------+-------------+-------------+
|label| features|prediction|statusIndexed|artistIndexed|
+-----+---------+----------+-------------+-------------+
| 1.0|[0.0,3.0]| 1.0| 0.0 | 3.0 |
+-----+---------+----------+-------------+-------------+
Để sau đó có thể sử dụng IndexToString và chuyển đổi thành:
+-----+---------+----------+-------------+-------------+
|label| features|prediction| status | artist |
+-----+---------+----------+-------------+-------------+
| 1.0|[0.0,3.0]| 1.0| good | Pink Floyd |
+-----+---------+----------+-------------+-------------+
hoặc thậm chí:
+-----+----------+-------------+-------------+
|label|prediction| status | artist |
+-----+----------+-------------+-------------+
| 1.0| 1.0| good | Pink Floyd |
+-----+----------+-------------+-------------+
Tôi có một vấn đề tương tự. Tôi có một tập dữ liệu của hàng ngàn hoặc cột và một số trong số đó là phân loại vì vậy tôi phải "chia" chúng thành nhiều cột hơn bằng cách sử dụng một 'StringIndexer' và' OneHotEncoder'. Vấn đề xảy ra khi tôi cố gắng nhận ra những gì đại diện cho mọi tính năng của vector kết hợp. –
Có lý do nào để bỏ dữ liệu đầu vào ở nơi đầu tiên không? – zero323
Có. Sơ đồ phân loại mong đợi một khung dữ liệu có cột "nhãn" và "tính năng". Trường hợp cột tính năng là một Vector không thể có chuỗi. Để rõ ràng, tôi vẫn có khung dữ liệu gốc với tất cả dữ liệu đầu vào. – gstvolvr