How to clean data in Python for machine learning?

Contents

This post was made public as part of the Data Science Blogathon

Introduction

Python is an easy-to-learn programming language, making it the preferred choice for data science beginners, data analysis and machine learning. It also has a large online student community and excellent data-centric libraries..

With so much data that is generated, it is essential that the data we use for data science applications such as machine learning and predictive modeling is clean. But, What do we understand by clean data? And what messes up the data in the first place?

Dirty data just means bad data. Duplication of records, Incomplete or outdated data and incorrect analysis can mess up the data. This data must be cleaned. Data cleansing (or data cleaning) refers to the procedure of “clean up” this dirty data, identifying errors in the data and then rectifying them.

Data cleansing is an important step in a machine learning project, and we'll cover some basic data cleansing techniques (and Python) in this post.

Data cleaning in Python

We will learn more about data cleansing in Python with the help of a sample data set. We will use the Russian housing data set and Kaggle.

We will start by importing the must-have libraries.

# import libraries
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline

Download the data and then read it in a Pandas DataFrame using the read_csv function () and specifying the file path. Subsequently, use shape attribute to check number of rows and columns in dataset. The code for this is as follows:

df = pd.read_csv('housing_data.csv')
df.shape

The data set has 30 471 rows and 292 columns.

Now we will separate the numeric columns from the categorical columns.

# select numerical columns
df_numeric = df.select_dtypes(include=[np.number])
numeric_cols = df_numeric.columns.values
# select non-numeric columns
df_non_numeric = df.select_dtypes(exclude=[np.number])
non_numeric_cols = df_non_numeric.columns.values

Now we are done with the preliminary steps. Now we can move on to cleaning the data. We will start by identifying columns that contain missing values ​​and try to correct them.

Missing values

We will start by calculating the percentage of missing values ​​in each column and then storing this information in a DataFrame.

# % of values missing in each column
values_list = list()
cols_list = list()
for col in df.columns:
    pct_missing = np.mean(df[col].isnull())*100
    cols_list.append(col)
    values_list.append(pct_missing)
pct_missing_df = pd.DataFrame()
pct_missing_df['col'] = cols_list
pct_missing_df['pct_missing'] = values_list

The DataFrame pct_missing_df now contains the percentage of missing values ​​in each column along with the column names.

We can also create an image from this information for a better understanding using the following code:

pct_missing_df.loc[pct_missing_df.pct_missing > 0].plot(kind='bar', figsize=(12,8))
plt.show()

The result after executing the above line of code should look like this:

missing data clear data

It is clear that some columns are missing very few values, while other columns are missing a substantial percentage of values. Now we will fix these missing values.

There are several ways we can correct these missing values. Some of them are”

Fall observations

One way could be to discard those observations that contain some null value for any of the columns. This will work when the percentage of missing values ​​in each column is much lower. We will eliminate the observations that contain nulls in those columns that have less than 0,5% null. These columns would be metro_min_walk, metro_km_walk, railroad_station_walk_km, railroad_station_walk_min e ID_railroad_station_walk.

less_missing_values_cols_list = list(pct_missing_df.loc[(pct_missing_df.pct_missing < 0.5) & (pct_missing_df.pct_missing > 0), 'col'].values)
df.dropna(subset=less_missing_values_cols_list, inplace=True)

This will reduce the number of records in our dataset to 30,446 records.

Delete columns (functions)

Another way to address missing values ​​in a dataset would be to delete those columns or features that have a significant percentage of missing values.. These columns do not contain much information and can be completely erased from the dataset. In our case, let's eliminate all those columns that are missing more than 40% of values. These columns would be build_year, state, hospital_beds_raion, cafe_sum_500_min_price_avg, cafe_sum_500_max_price_avg y cafe_avg_price_500.

# dropping columns with more than 40% null values
_40_pct_missing_cols_list = list(pct_missing_df.loc[pct_missing_df.pct_missing > 40, 'col'].values)
df.drop(columns=_40_pct_missing_cols_list, inplace=True)

The number of features in our dataset is now 286.

Impute missing values

Data is still missing in our dataset. Now we will impute the missing values ​​in each numeric column with the median value of that column.

df_numeric = df.select_dtypes(include=[np.number])
numeric_cols = df_numeric.columns.values
for col in numeric_cols:
    missing = df[col].isnull()
    num_missing = np.sum(missing)
    if num_missing > 0:  # impute values only for columns that have missing values
        med = df[col].median() #impute with the median
        df[col] = df[col].fillna(with)

Missing values ​​in numeric columns are now fixed. In the case of categorical columns, we will replace the missing values ​​with the fashion values ​​of that column.

df_non_numeric = df.select_dtypes(exclude=[np.number])
non_numeric_cols = df_non_numeric.columns.values
for col in non_numeric_cols:
    missing = df[col].isnull()
    num_missing = np.sum(missing)
    if num_missing > 0:  # impute values only for columns that have missing values
        mod = df[col].describe()['top'] # impute with the most frequently occuring value
        df[col] = df[col].fillna(mod)

All missing values ​​in our dataset have already been dealt with. We can verify this by running the following code:

df.isnull().sum().sum()

If the output is zero, means now there are no missing values ​​left in our dataset.

Furthermore we can replace the missing values ​​with a particular value (What -9999 the 'missing') which will indicate the fact that the data was missing in this place. This can be a substitute for the imputation of lost value.

Atypical values

An outlier is an unusual observation that deviates from most of the data. Outliers can significantly affect the performance of a machine learning model. Therefore, identifying outliers and addressing them is essential.

Let's take the column ‘life_sq’ as an example. We will first use the describe method () to look at the descriptive statistics and see if we can collect information from it.

df.life_sq.describe()

The output will look like this:

count    30446.000000
mean        33.482658
std         46.538609
min          0.000000
25%         22.000000
50%         30.000000
75%         38.000000
max       7478.000000
Name: life_sq, dtype: float64

Of departure, it is clear that something is not correct. The maximum value appears to be abnormally large compared to the mean and median values. Let's make a box plot of this data to get a better idea.

df.life_sq.plot(kind='box', figsize=(12, 8))
plt.show()

The output will look like this:

clean box plot data

From the box plot it is clear that the observation for the maximum value (7478) is an outlier in this data. Descriptive statistics, the box plots y los diagramas de dispersión nos ayudan a identificar valores atípicos en los datos.

We can deal with outliers like we did with missing values. We can delete the observations that we think are outliers, or we can replace outliers with suitable values, or we can do some kind of transformation on the data (as logarithm or exponential). In our case, let's delete the record where the value of ‘life_sq’ it is 7478.

# removing the outlier value in life_sq column
df = df.loc[df.life_sq < 7478]

Duplicate records

Sometimes, data can contain duplicate values. It is essential to clear duplicate records from your dataset before proceeding with any machine learning project. In our data, since the ID column is a unique identifier, we will eliminate duplicate records considering all but the ID column.

# dropping duplicates by considering all columns other than ID
cols_other_than_id = list(df.columns)[1:]
df.drop_duplicates(subset=cols_other_than_id, inplace=True)

This will help us to erase duplicate records. When using the shape method, you can verify that the duplicate records have truly been removed. The number of observations is now 30,434.

Fixing the data type

Often, in the data set, values ​​are not stored in correct data type. This can create a roadblock in later stages and we may not get the desired result or get errors during execution.. A common data type error is dates. Dates are often parsed as objects in Python. There is a separate data type for dates in Pandas, called DateTime.

We will first check the data type of the timestamp column in our data.

df.timestamp.dtype

This returns the data type 'object'. Now we know that the timestamp is not stored correctly. To fix this problem, convert timestamp column to DateTime format.

# converting timestamp to datetime format
df['timestamp'] = pd.to_datetime(df.timestamp, format="%Y-%m-%d")

Now we have the timestamp in the correct format. Similarly, there can be columns where integers are stored as objects. It is essential to identify these characteristics and correct the data type before proceeding with machine learning.. Lucky for us, we don't have any such problems in our dataset.

EndNote

In this post, We discussed some basic ways that we can clean data in Python before starting our machine learning project. We need to identify and erase the missing values, identify and address outliers, clear duplicate records and correct the data type of all columns in our dataset before continuing with our AA task.

The author of this post is Vishesh Arora. You can connect with me at LinkedIn.

The media shown in this post about sign language accreditation is not the property of DataPeaker and is used at the author's discretion.

Subscribe to our Newsletter

We will not send you SPAM mail. We hate it as much as you.

Datapeaker