<jupyter_start><jupyter_text>Build RAI pipeline**Requirements** - In order to benefit from this tutorial, you will need:- A basic understanding of Machine Learning- An Azure account with an active subscription - [Create an account for free](https://azure.microsoft.com/free/?WT.mc_id=A261C142F)- An Azure ML workspace with computer cluster - [Configure workspace](../../configuration.ipynb)- A python environment- Installed Azure Machine Learning Python SDK v2 - [install instructions](../../../README.md) - check the getting started section**Learning Objectives** - By the end of this tutorial, you should be able to:- Connect to your AML workspace from the Python SDK- Create `Pipeline` using component defined by yaml**Motivations** - This notebook demos how to build complex RAI sample pipeline.    1. Connect to Azure Machine Learning WorkspaceThe [workspace](https://docs.microsoft.com/en-us/azure/machine-learning/concept-workspace) is the top-level resource for Azure Machine Learning, providing a centralized place to work with all the artifacts you create when you use Azure Machine Learning. In this section we will connect to the workspace in which the job will be run. 1.1 Import the required libraries<jupyter_code># import required libraries
from azure.identity import DefaultAzureCredential, InteractiveBrowserCredential

from azure.ai.ml import MLClient, Input, Output, load_component
from azure.ai.ml.dsl import pipeline<jupyter_output><empty_output><jupyter_text>1.2 Configure credentialWe are using `DefaultAzureCredential` to get access to workspace. `DefaultAzureCredential` should be capable of handling most Azure SDK authentication scenarios. Reference for more available credentials if it does not work for you: [configure credential example](../../configuration.ipynb), [azure-identity reference doc](https://docs.microsoft.com/en-us/python/api/azure-identity/azure.identity?view=azure-python).<jupyter_code>try:
    credential = DefaultAzureCredential()
    # Check if given credential can get token successfully.
    credential.get_token("https://management.azure.com/.default")
except Exception as ex:
    # Fall back to InteractiveBrowserCredential in case DefaultAzureCredential not work
    credential = InteractiveBrowserCredential()<jupyter_output><empty_output><jupyter_text>1.3 Get a handle to the workspaceWe use config file to connect to a workspace. The Azure ML workspace should be configured with computer cluster. [Check this notebook for configure a workspace](../../configuration.ipynb)<jupyter_code># Get a handle to workspace
ml_client = MLClient.from_config(credential=credential)

# Retrieve an already attached Azure Machine Learning Compute.
cluster_name = "cpu-cluster"
print(ml_client.compute.get(cluster_name))<jupyter_output><empty_output><jupyter_text>1.4 Retrieve or create RAI environment<jupyter_code>rai_cli_example_path = (
    "../../../../cli/jobs/pipelines-with-components/rai_pipeline_adult_analyse"
)

environment_name = "AML-RAI-Environment"
try:
    ml_client.environments.get(name=environment_name, version="1")
except Exception:
    print(f"Cannot find environment {environment_name} in workspace, creating it")
    from azure.ai.ml.entities import Environment

    environment = Environment(
        image="mcr.microsoft.com/azureml/openmpi3.1.2-ubuntu18.04:20220303.v1",
        conda_file=f"{rai_cli_example_path}/environment/conda_envs/python-aml-rai.yaml",
        name=environment_name,
        version="1",
        description="AML RAI environment",
    )
    ml_client.environments.create_or_update(environment)<jupyter_output><empty_output><jupyter_text>1.5 Retrieve or create RAI input data<jupyter_code>input_train_data = "adult_train_pq"
input_test_data = "adult_test_pq"

try:
    ml_client.data.get(name=input_train_data, version="1")
except Exception:
    print(f"Cannot find data {input_train_data} in workspace, register it now")
    from azure.ai.ml.entities import Data
    from azure.ai.ml.constants import AssetTypes

    train_data = Data(
        path=f"{rai_cli_example_path}/data/adult_train.parquet",
        type=AssetTypes.URI_FILE,
        description="RAI sample train data",
        name=input_train_data,
        version="1",
    )

    ml_client.data.create_or_update(train_data)

try:
    ml_client.data.get(name=input_test_data, version="1")
except Exception:
    print(f"Cannot find data {input_test_data} in workspace, register it now")
    from azure.ai.ml.entities import Data
    from azure.ai.ml.constants import AssetTypes

    test_data = Data(
        path=f"{rai_cli_example_path}/data/adult_test.parquet",
        type=AssetTypes.URI_FILE,
        description="RAI sample test data",
        name=input_test_data,
        version="1",
    )

    ml_client.data.create_or_update(test_data)<jupyter_output><empty_output><jupyter_text>2. Define command component via YAMLBelow is example to define command component using YAML.<jupyter_code>rai_components_path = f"{rai_cli_example_path}/components"

train_log_reg_component = load_component(
    path=f"{rai_components_path}/component_train_logreg.yaml"
)
register_model_component = load_component(
    path=f"{rai_components_path}/component_register_model.yaml"
)
rai_constructor_component = load_component(
    path=f"{rai_components_path}/component_rai_insights.yaml"
)
rai_explanation_component = load_component(
    path=f"{rai_components_path}/component_explain.yaml"
)
rai_causal_component = load_component(
    path=f"{rai_components_path}/component_causal.yaml"
)
rai_counterfactual_component = load_component(
    path=f"{rai_components_path}/component_counterfactual.yaml"
)
rai_erroranalysis_component = load_component(
    path=f"{rai_components_path}/component_error_analysis.yaml"
)
rai_gather_component = load_component(
    path=f"{rai_components_path}/component_gather_rai_insights.yaml"
)<jupyter_output><empty_output><jupyter_text>3. Sample pipeline job 3.1 Build pipeline<jupyter_code>@pipeline(
    compute="cpu-cluster",
    experiment_name=f"test_classification_pipeline_from_python",
)
def rai_classification_pipeline(
    target_column_name,
    train_data,
    test_data,
):
    """Submission of classification pipeline from Python."""
    train_job = train_log_reg_component(
        target_column_name=target_column_name, training_data=train_data
    )

    register_job = register_model_component(
        model_input_path=train_job.outputs.model_output,
        model_base_name="test_classification_pipeline_from_python",
        model_name_suffix=-1,
    )

    create_rai_job = rai_constructor_component(
        title="Run built from Python",
        task_type="classification",
        model_info_path=register_job.outputs.model_info_output_path,
        train_dataset=train_data,
        test_dataset=test_data,
        target_column_name=target_column_name,
        categorical_column_names='["Race", "Sex", "Workclass", "Marital Status", "Country", "Occupation"]',
        maximum_rows_for_test_dataset=5000,
        classes="[]",
    )

    explain_job = rai_explanation_component(
        comment="Insert text here",
        rai_insights_dashboard=create_rai_job.outputs.rai_insights_dashboard,
    )

    causal_job = rai_causal_component(
        rai_insights_dashboard=create_rai_job.outputs.rai_insights_dashboard,
        treatment_features='["Age", "Sex"]',
        heterogeneity_features='["Marital Status"]',
        nuisance_model="linear",
        heterogeneity_model="linear",
        alpha=0.05,
        upper_bound_on_cat_expansion=50,
        treatment_cost="0",
        min_tree_leaf_samples=2,
        max_tree_depth=2,
        skip_cat_limit_checks=False,
        categories="auto",
        n_jobs=1,
        verbose=1,
        random_state="None",
    )

    counterfactual_job = rai_counterfactual_component(
        rai_insights_dashboard=create_rai_job.outputs.rai_insights_dashboard,
        total_cfs=10,
        desired_class="opposite",
        method="random",
        desired_range="[]",
        permitted_range="{}",
        features_to_vary="all",
        feature_importance=True,
    )

    erroranalysis_job = rai_erroranalysis_component(
        rai_insights_dashboard=create_rai_job.outputs.rai_insights_dashboard,
        filter_features='["Race", "Sex"]',
        max_depth=3,
        num_leaves=31,
        min_child_samples=20,
    )

    rai_gather_job = rai_gather_component(
        constructor=create_rai_job.outputs.rai_insights_dashboard,
        insight_1=explain_job.outputs.explanation,
        insight_2=causal_job.outputs.causal,
        insight_3=counterfactual_job.outputs.counterfactual,
        insight_4=erroranalysis_job.outputs.error_analysis,
    )

    rai_gather_job.outputs.dashboard.mode = "upload"
    rai_gather_job.outputs.ux_json.mode = "upload"

    return {
        "dashboard": rai_gather_job.outputs.dashboard,
        "ux_json": rai_gather_job.outputs.ux_json,
    }


pipeline_job = rai_classification_pipeline(
    target_column_name="income",
    train_data=Input(path=f"{input_train_data}:1", mode="download", type="uri_file"),
    test_data=Input(path=f"{input_test_data}:1", mode="download", type="uri_file"),
)

# Enbale downloading outputs
import uuid
from azure.ai.ml import Output

rand_path = str(uuid.uuid4())
pipeline_job.outputs.dashboard = Output(
    path=f"azureml://datastores/workspaceblobstore/paths/{rand_path}/dashboard/",
    mode="upload",
    type="uri_folder",
)
pipeline_job.outputs.ux_json = Output(
    path=f"azureml://datastores/workspaceblobstore/paths/{rand_path}/ux_json/",
    mode="upload",
    type="uri_folder",
)

pipeline_job.settings.force_rerun = True<jupyter_output><empty_output><jupyter_text>3.2 Submit pipeline job<jupyter_code># submit job to workspace
pipeline_job = ml_client.jobs.create_or_update(
    pipeline_job, experiment_name="pipeline_samples"
)
pipeline_job
# Wait until the job completes
ml_client.jobs.stream(pipeline_job.name)<jupyter_output><empty_output><jupyter_text>3.3 Download the outputs<jupyter_code># ml_client.jobs.download(pipeline_job.name, download_path="local/path/to/store/outputs", output_name="dashboard")
# ml_client.jobs.download(pipeline_job.name, download_path="local/path/to/store/outputs", output_name="ux_json")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09816487037576464, 'fraction_numerical': 0.007476454024662588, 'mean_word_length': 4.773542600896861, 'pattern_counts': {'":': 2, '<': 37, '<?xml version=': 0, '>': 37, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '405368', 'license': 'MIT', 'n_tokens_mistral': 3227, 'n_tokens_neox': 3207, 'n_words': 598, 'path': 'sdk/jobs/pipelines/2f_rai_pipeline_sample/rai_pipeline_sample.ipynb', 'repo_name': 'jplummer01/azureml-examples', 'size': '10299'}