Repository: JuliaAI/MLJBase.jl (julia)

Issue:
target_scitype for SupervisedPipelines
Hello everyone,

I think we could add a `target_scitype` directive for SupervisedPipelines.

```julia

LinearRegressor = @load LinearRegressor pkg=MLJLinearModels verbosity = 0
pipe = (X -> coerce(X, :age=>Continuous)) |> ContinuousEncoder() |> LinearRegressor()
target_scitype(pipe)
```

will result in Unknown.

The following should work and happy to try and make the change if your concern is somewhere else:

```julia

target_scitype(p::SupervisedPipeline) = target_scitype(supervised_component(p))
```

Pull request description:
To solve https://github.com/JuliaAI/MLJBase.jl/issues/710

Patch:
diff --git a/src/composition/models/pipelines.jl b/src/composition/models/pipelines.jl
index 41cae336..8379da7e 100644
--- a/src/composition/models/pipelines.jl
+++ b/src/composition/models/pipelines.jl
@@ -613,3 +613,5 @@ function iteration_parameter(pipe::SupervisedPipeline)
     name =  supervised_component_name(pipe)
     MLJBase.prepend(name, iteration_parameter(model))
 end
+
+target_scitype(p::SupervisedPipeline) = target_scitype(supervised_component(p))
\ No newline at end of file


Test patch:
diff --git a/test/composition/models/pipelines.jl b/test/composition/models/pipelines.jl
index defe883f..28355387 100644
--- a/test/composition/models/pipelines.jl
+++ b/test/composition/models/pipelines.jl
@@ -358,6 +358,9 @@ end
     MLJBase.tree(mach.fitresult.predict).arg1.model.features == [:x3, ]
     @test predict(mach, X) ≈ hand_built
 
+    # Check target_scitype of a supervised pipeline is the same as the supervised component
+    @test target_scitype(p) == target_scitype(KNNRegressor())
+
     # test cache is set correctly internally:
     @test all(fitted_params(mach).machines) do m
         MLJBase._cache_status(m)  == " caches data"
@@ -408,6 +411,9 @@ end
     fit!(mach, verbosity=0)
     @test predict(mach, X) == fill('f', 7)
 
+    # Check target_scitype of a supervised pipeline is the same as the supervised component
+    @test target_scitype(p) == target_scitype(ConstantClassifier())
+    
     # test pipelines with weights:
     w = map(y) do η
         η == 'm' ? 100 : 1
@@ -436,6 +442,9 @@ MLJBase.transform(transf::MyTransformer3, verbosity, X) =
                    MyTransformer3(:age))
     mach = fit!(machine(p99, X), verbosity=0)
     @test transform(mach, X) == float.(X.age)
+
+    # Check target_scitype of an unsupervised pipeline is Unknown
+    @test target_scitype(p99) == Unknown
 end
 
 @testset "integration 5" begin
@@ -473,6 +482,8 @@ end
     y = transform(mach, x)
     x̂ = inverse_transform(mach, y)
     @test isapprox(x, x̂)
+    # Check target_scitype of an unsupervised pipeline is Unknown
+    @test target_scitype(p) == Unknown
 end
 
 # A dummy clustering model: