{ "cells": [ { "attachments": {}, "cell_type": "markdown", "id": "82a8f73f-c2f7-4e3a-87b7-47ae6fa896bf", "metadata": { "tags": [] }, "source": [ "## Data Wrangler Data Prep Widget - Example Notebook" ] }, { "attachments": {}, "cell_type": "markdown", "id": "a092b5af", "metadata": {}, "source": [ "---\n", "\n", "This notebook's CI test result for us-west-2 is as follows. CI test results in other regions can be found at the end of the notebook. \n", "\n", "![This us-west-2 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://h75twx4l60.execute-api.us-west-2.amazonaws.com/sagemaker-nb/us-west-2/aws_sagemaker_studio|sagemaker_data_prep_assistant|data_prep_widget.ipynb)\n", "\n", "---" ] }, { "attachments": {}, "cell_type": "markdown", "id": "6c07e63e-ef85-49db-8870-f357da0fc6df", "metadata": {}, "source": [ "The [Data Wrangler data prep widget](https://aws.amazon.com/blogs/machine-learning/interactive-data-prep-widget-for-notebooks-powered-by-amazon-sagemaker-data-wrangler/) automatically generates key visualizations on top of a Pandas data frame to understand data distribution, detect data quality issues, and surface data insights such as outliers for each feature. It helps interact with the data and discover insights that may go unnoticed with ad hoc querying. It also recommends transformations to remediate, enables you to apply data transformations on the UI and automatically generate code in the notebook cells." ] }, { "attachments": {}, "cell_type": "markdown", "id": "cb9b75d9-4b6f-47c3-913d-7312696d63f4", "metadata": {}, "source": [ "By `import sagemaker_datawrangler` we are enabling the interactive data preparation assistant widget for Pandas dataframe in Amazon SageMaker Studio Notebooks " ] }, { "cell_type": "code", "execution_count": null, "id": "2ac38f47-8006-4e6a-b3b6-65739db9c600", "metadata": { "tags": [] }, "outputs": [], "source": [ "import pandas as pd\n", "import boto3\n", "import io\n", "import sagemaker_datawrangler" ] }, { "attachments": {}, "cell_type": "markdown", "id": "45797202-2108-4d26-b326-e607dc797ad0", "metadata": { "tags": [] }, "source": [ "For our use case, we use modified version of the [Titanic dataset](https://www.openml.org/search?type=data&sort=runs&id=40945&status=active), a popular dataset in the ML community so you can get started with SageMaker Data Wrangler quickly. The original [dataset](https://www.openml.org/search?type=data&sort=runs&id=40945&status=active) was obtained from [OpenML](https://www.openml.org/), and modified to add synthetic data quality issues by Amazon for this demo. You can download the modified version of dataset from public S3 path `s3://sagemaker-example-files-prod-{region}/datasets/tabular/dirty-titanic/titanic-dirty-4.csv`\n", "\n", "Read the dataset with `pandas`" ] }, { "cell_type": "code", "execution_count": null, "id": "e91c4aad-2c75-45d7-9d0f-13ad0cc0d7f4", "metadata": { "tags": [] }, "outputs": [], "source": [ "s3 = boto3.client(\"s3\")\n", "obj = s3.get_object(\n", " Bucket=f\"sagemaker-example-files-prod-{boto3.session.Session().region_name}\",\n", " Key=\"datasets/tabular/dirty-titanic/titanic-dirty-4.csv\",\n", ")\n", "df = pd.read_csv(io.BytesIO(obj[\"Body\"].read()))" ] }, { "attachments": {}, "cell_type": "markdown", "id": "2fc1843c-596a-4707-8bfc-06c4be7785c7", "metadata": {}, "source": [ "After the data is loaded in the Pandas data frame, you can view the data by just using `df` or `display(df)`. Along with listing the row, the data prep widget produces insights, visualizations, and advice on data quality. You don’t need to write any additional code to generate feature and target insights, distribution information, or rendering data quality checks. You can choose the data frame table’s header to view the statistical summary showing the data quality warnings, if any." ] }, { "cell_type": "code", "execution_count": null, "id": "35d220fd-96d0-44dd-b59c-2f6332b41437", "metadata": { "tags": [] }, "outputs": [], "source": [ "df" ] }, { "attachments": {}, "cell_type": "markdown", "id": "235aafb0-c94d-47ce-92fc-60f6ac678d59", "metadata": {}, "source": [ "" ] }, { "attachments": {}, "cell_type": "markdown", "id": "696b0b27-67e6-4933-9264-b1da7978ba2f", "metadata": {}, "source": [ "Each column shows a bar chart or histogram based on the data type. By default, the widget samples up to 10,000 observations for generating meaningful insights. It also provides the option to run the insight analysis on the entire dataset.\n" ] }, { "attachments": {}, "cell_type": "markdown", "id": "f11153a6-1f49-41c6-a765-896dfd7b451f", "metadata": {}, "source": [ "For categorical data, the widget generates the bar chart with all the categories. In the following screenshot, for example, the column \"sex\" identifies the categories on the data. You can hover over the bar (male in this case) to see the details of these categories, like the total number of rows with the value male and its distribution in the total visualized dataset (64.07% in this example). It also highlights the total percentage of missing values in a different color for categorical data. For quantitative data like the \"ticket\" column, it shows distribution along with the percentage of invalid values." ] }, { "attachments": {}, "cell_type": "markdown", "id": "ad8a6c10-f3b1-43bb-a8d7-c3ea2b77e4c7", "metadata": { "tags": [] }, "source": [ "\n", " \n" ] }, { "attachments": {}, "cell_type": "markdown", "id": "cc9f64fc-2cb3-46c0-aa24-dbb536c87033", "metadata": {}, "source": [ "The Insights tab provides details with descriptions for each column. This section lists aggregated statistics, such as mode, number of uniques, ratios and counts for missing/invalid values, etc., as well as visualize data distribution with help of a histogram or a bar chart. In the following screenshots, you can check out the data insights and distribution information displayed with easily understandable visualizations generated for the selected column \"survived\"" ] }, { "attachments": {}, "cell_type": "markdown", "id": "dcad537f-d27f-421a-823e-025be0c7d1ed", "metadata": {}, "source": [ " " ] }, { "attachments": {}, "cell_type": "markdown", "id": "bce3c589-dc0c-4ec9-8a3b-5498308d7f9a", "metadata": {}, "source": [ "The studio data prep widget highlights identified data quality issues with the warning sign in the header. Widget can identify the whole spectrum of data quality issues from basics (missing values, constant column, etc.) to more ML specific (target leakage, low predictive score features, etc.). Widget highlights the cells causing the data quality issue and reorganize the rows to put the problematic cells at the top. To remedy the data quality issue widget provides several transformers, applicable on a click of a button.\n", "\n", "To explore the data quality section, choose the column header, and in the side panel, choose the Data quality tab. You should see the following in your Studio environment." ] }, { "attachments": {}, "cell_type": "markdown", "id": "6e0af1a7-25ef-4a5a-812c-d53b56b85793", "metadata": {}, "source": [ "![alt text](images/survived-dataquality.png \"Data Issue Warnings\")" ] }, { "attachments": {}, "cell_type": "markdown", "id": "671616c7-82e2-4d11-bc51-ed03ae65a3aa", "metadata": {}, "source": [ "Let’s look at the different options available on the Data quality tab. For this example, we choose the age column, which is detected as a quantitative column based on the data. As we can see in the following screenshot, this widget suggests different type of transformations that you could apply, including the most common actions, such as Replace with new value, Drop missing, Replace with median, or Replace with mean. You can choose any of those for your dataset based on the use case (the ML problem you’re trying to solve). It also gives you the Drop column option if you want to remove the feature altogether." ] }, { "attachments": {}, "cell_type": "markdown", "id": "850a0bfd-cda6-4189-9927-2c10a4b819dc", "metadata": {}, "source": [ "![alt text](images/dataqualityoptions.png \"Set as a Target Column\")" ] }, { "attachments": {}, "cell_type": "markdown", "id": "970454df-1082-4089-84aa-9ac224f0db78", "metadata": {}, "source": [ "When you choose Apply and export code, the transform is applied to the deep copy of the data frame. After the transform is applied successfully, the data table is refreshed with the insights and visualizations. The transform code is generated after the existing cell in the notebook. You can run this exported code later on to apply the transformation on your datasets, and extend it as per your needs. You can customize the transformation by directly modifying the generated code. If we apply the Drop missing option in the Age column, the following transformation code is applied to the dataset, and code is also generated in a cell below the widget:" ] }, { "cell_type": "code", "execution_count": null, "id": "31d3c92e-ed95-4df5-86fa-166df8f6dd65", "metadata": {}, "outputs": [], "source": [ "# Pandas code generated by sagemaker_datawrangler\n", "output_df = df.copy(deep=True)\n", "\n", "# Code to Drop missing for column: age to resolve warning: Missing values\n", "output_df = output_df[output_df[\"age\"].notnull()]" ] }, { "attachments": {}, "cell_type": "markdown", "id": "80cfc0c7-c8b8-4240-bbea-7d839c539944", "metadata": {}, "source": [ "The following is generated code for example of a code snippet for Replace with new value:" ] }, { "cell_type": "code", "execution_count": null, "id": "cca125c2-e06b-4852-bfb0-3bf7ffbdf4fb", "metadata": {}, "outputs": [], "source": [ "# Pandas code generated by sagemaker_datawrangler\n", "output_df = df.copy(deep=True)\n", "\n", "\n", "# Code to Replace with new value for column: age to resolve warning: Missing values\n", "generic_value = 0\n", "output_df[\"age\"] = output_df[\"age\"].fillna(generic_value)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "949f0ea3-0686-4bed-b938-fbb1f4fe7503", "metadata": {}, "source": [ "The following is another example of a code snippet for Replace with median:" ] }, { "cell_type": "code", "execution_count": null, "id": "4871e9df-539f-4e22-8406-6c8b699fd377", "metadata": {}, "outputs": [], "source": [ "# Pandas code generated by sagemaker_datawrangler\n", "output_df = df.copy(deep=True)\n", "\n", "# Code to Replace with median for column: age to resolve warning: Missing values\n", "output_df[\"age\"] = output_df[\"age\"].fillna(output_df[\"age\"].median(skipna=True))" ] }, { "attachments": {}, "cell_type": "markdown", "id": "3479bd85-4933-459a-8444-cd5a6816d532", "metadata": {}, "source": [ "You can view the results of the applied transform directly on the table. The widget automatically generates Pandas or PySpark code in the Notebook on a new cell. " ] }, { "attachments": {}, "cell_type": "markdown", "id": "bf5da385-8980-41bf-b3ed-af8a95c2ea1d", "metadata": {}, "source": [ "Now let’s look at the data prep widget’s target insight capability. Assume you want to use the survived feature to predict if a passenger will survive. Choose the survived column header. In the side panel, choose Select as target column. The ideal data distribution for the survived feature should have only two classes: yes (1) or no (0), which helps classify the Titanic crash survival chances. However, due to data inconsistencies in the chosen target column, the survived feature has 0, 1, ?, unknown, and yes." ] }, { "attachments": {}, "cell_type": "markdown", "id": "c8ee1657-4585-449d-b68e-09017412d7dd", "metadata": {}, "source": [ "The data prep widget lists the target column insights with recommendations and sample explanations to solve the issues with the target column data quality. It also automatically highlights the anomalous data in the column." ] }, { "attachments": {}, "cell_type": "markdown", "id": "28de8131-e03e-4be2-ae88-dd67b681ab05", "metadata": { "tags": [] }, "source": [ "![alt text](images/dataquality.png \"Apply and export code\")" ] }, { "attachments": {}, "cell_type": "markdown", "id": "91a88f0f-69c7-4394-8818-a68ba873790f", "metadata": {}, "source": [ "We choose the recommended transform Drop rare target values, because there are fewer observations for the rare target values." ] }, { "cell_type": "code", "execution_count": null, "id": "7ed8446a-a851-4b21-a24d-2da3e6d93051", "metadata": {}, "outputs": [], "source": [ "# Pandas code generated by sagemaker_datawrangler\n", "output_df = df.copy(deep=True)\n", "\n", "# Code to Drop rare target values for column: survived to resolve warning: Too few instances per class\n", "rare_target_labels_to_drop = [\"?\", \"unknown\", \"yes\"]\n", "output_df = output_df[~output_df[\"survived\"].isin(rare_target_labels_to_drop)]" ] }, { "attachments": {}, "cell_type": "markdown", "id": "41cb54e0-2099-40cb-85c4-6b0c3b6be441", "metadata": {}, "source": [ "If you want to see a standard [pandas](https://pandas.pydata.org/) visualization in the notebook, you can choose View the Pandas table and toggle between the widget and the Pandas representation, as shown in the following screenshot." ] }, { "cell_type": "code", "execution_count": null, "id": "b1398e47-c7b2-4c1a-a735-fbb2a4c16055", "metadata": { "tags": [] }, "outputs": [], "source": [ "df" ] }, { "attachments": {}, "cell_type": "markdown", "id": "e4ec4e34-ae87-4ff5-8c54-2a5b87d494cc", "metadata": {}, "source": [ " " ] }, { "attachments": {}, "cell_type": "markdown", "id": "12fe8025", "metadata": {}, "source": [ "## Notebook CI Test Results\n", "\n", "This notebook was tested in multiple regions. The test results are as follows, except for us-west-2 which is shown at the top of the notebook.\n", "\n", "![This us-east-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://h75twx4l60.execute-api.us-west-2.amazonaws.com/sagemaker-nb/us-east-1/aws_sagemaker_studio|sagemaker_data_prep_assistant|data_prep_widget.ipynb)\n", "\n", "![This us-east-2 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://h75twx4l60.execute-api.us-west-2.amazonaws.com/sagemaker-nb/us-east-2/aws_sagemaker_studio|sagemaker_data_prep_assistant|data_prep_widget.ipynb)\n", "\n", "![This us-west-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://h75twx4l60.execute-api.us-west-2.amazonaws.com/sagemaker-nb/us-west-1/aws_sagemaker_studio|sagemaker_data_prep_assistant|data_prep_widget.ipynb)\n", "\n", "![This ca-central-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://h75twx4l60.execute-api.us-west-2.amazonaws.com/sagemaker-nb/ca-central-1/aws_sagemaker_studio|sagemaker_data_prep_assistant|data_prep_widget.ipynb)\n", "\n", "![This sa-east-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://h75twx4l60.execute-api.us-west-2.amazonaws.com/sagemaker-nb/sa-east-1/aws_sagemaker_studio|sagemaker_data_prep_assistant|data_prep_widget.ipynb)\n", "\n", "![This eu-west-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://h75twx4l60.execute-api.us-west-2.amazonaws.com/sagemaker-nb/eu-west-1/aws_sagemaker_studio|sagemaker_data_prep_assistant|data_prep_widget.ipynb)\n", "\n", "![This eu-west-2 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://h75twx4l60.execute-api.us-west-2.amazonaws.com/sagemaker-nb/eu-west-2/aws_sagemaker_studio|sagemaker_data_prep_assistant|data_prep_widget.ipynb)\n", "\n", "![This eu-west-3 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://h75twx4l60.execute-api.us-west-2.amazonaws.com/sagemaker-nb/eu-west-3/aws_sagemaker_studio|sagemaker_data_prep_assistant|data_prep_widget.ipynb)\n", "\n", "![This eu-central-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://h75twx4l60.execute-api.us-west-2.amazonaws.com/sagemaker-nb/eu-central-1/aws_sagemaker_studio|sagemaker_data_prep_assistant|data_prep_widget.ipynb)\n", "\n", "![This eu-north-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://h75twx4l60.execute-api.us-west-2.amazonaws.com/sagemaker-nb/eu-north-1/aws_sagemaker_studio|sagemaker_data_prep_assistant|data_prep_widget.ipynb)\n", "\n", "![This ap-southeast-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://h75twx4l60.execute-api.us-west-2.amazonaws.com/sagemaker-nb/ap-southeast-1/aws_sagemaker_studio|sagemaker_data_prep_assistant|data_prep_widget.ipynb)\n", "\n", "![This ap-southeast-2 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://h75twx4l60.execute-api.us-west-2.amazonaws.com/sagemaker-nb/ap-southeast-2/aws_sagemaker_studio|sagemaker_data_prep_assistant|data_prep_widget.ipynb)\n", "\n", "![This ap-northeast-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://h75twx4l60.execute-api.us-west-2.amazonaws.com/sagemaker-nb/ap-northeast-1/aws_sagemaker_studio|sagemaker_data_prep_assistant|data_prep_widget.ipynb)\n", "\n", "![This ap-northeast-2 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://h75twx4l60.execute-api.us-west-2.amazonaws.com/sagemaker-nb/ap-northeast-2/aws_sagemaker_studio|sagemaker_data_prep_assistant|data_prep_widget.ipynb)\n", "\n", "![This ap-south-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://h75twx4l60.execute-api.us-west-2.amazonaws.com/sagemaker-nb/ap-south-1/aws_sagemaker_studio|sagemaker_data_prep_assistant|data_prep_widget.ipynb)\n" ] } ], "metadata": { "instance_type": "ml.t3.medium", "kernelspec": { "display_name": "Python 3 (Data Science 3.0)", "language": "python", "name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:us-east-1:081325390199:image/sagemaker-data-science-310-v1" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.6" } }, "nbformat": 4, "nbformat_minor": 5 }