Exploratory Data Analysis (EDA): A Step-by-Step Guide
Exploratory Data Analysis, or EDA for short, is a crucial step in any data science project. EDA is the process of exploring and analyzing a dataset to understand its main characteristics, uncover patterns and relationships, develop hypotheses, and inform modeling decisions down the line. Proper EDA provides direction for how to manipulate and leverage the data to extract meaningful insights that can drive decision making.
EDA is particularly critical in AI and machine learning projects, where the quality and nuances of the data can have a huge impact on model performance. In fact, a survey by Anaconda found that data scientists spend up to 40% of their time on data preparation and EDA tasks. Investing this time upfront can pay huge dividends in terms of more robust and accurate models.
In this step-by-step guide, we‘ll walk through the key steps of the EDA process:
- Understanding the data
- Checking data quality
- Univariate analysis
- Bivariate and multivariate analysis
- Dimensionality reduction and clustering
- Summary and insights
We‘ll apply each step to an example dataset to see the techniques in action. By the end, you‘ll have a solid grasp of EDA and a framework you can apply to any AI/ML project. Let‘s dive in!
Step 1: Understand the Data
The first step is to load the data and understand the variables you‘re working with. Start by reading the data into a pandas DataFrame:
import pandas as pd
df = pd.read_csv(‘data.csv‘)
Then get a high-level view of the data:
print(df.shape)
print(df.columns)
df.head()
df.info()
df.describe()
This will show you the number of rows and columns, the name of each column, the first few rows, the data types and non-null counts, and summary statistics for numerical columns.
Already you can start to spot things like:
- The dimensions of the dataset
- The features and what they represent
- Potential data quality issues like missing values or outliers
- The range and distribution of numerical variables
For example, suppose we are working with the famous Titanic dataset. We might see output like:
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 891 non-null int64
1 Survived 891 non-null int64
2 Pclass 891 non-null int64
3 Name 891 non-null object
4 Sex 891 non-null object
5 Age 714 non-null float64
6 SibSp 891 non-null int64
7 Parch 891 non-null int64
8 Ticket 891 non-null object
9 Fare 891 non-null float64
10 Cabin 204 non-null object
11 Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
Here we can see the dataset has 891 rows and 12 columns, with a mix of numerical and categorical features. The Age and Cabin columns have missing values we‘ll need to deal with. Already we can start forming hypotheses about which features might be most predictive of survival.
Take your time in this step to really wrap your head around the dataset. Refer to the data dictionary and documentation if available. Forming a solid understanding of the data upfront will pay dividends throughout the rest of the EDA process.
Step 2: Check Data Quality
Real-world data is messy. A study by Merrill Corp found that data scientists spend 60% of their time cleaning and organizing data. Before you start analyzing, it‘s critical to clean the data and check for quality issues. Some common problems to check for:
Missing values
df.isnull().sum()
Duplicate rows
df.duplicated().sum()
Outliers
df.boxplot()
Inconsistent values
df[‘column‘].value_counts()
Unexpected data types
df.dtypes
For the Titanic data, we might find:
- 177 missing values for
Age - 687 missing values for
Cabin - 2 missing values for
Embarked - No duplicate rows
- A few outliers in
Fare
Address any issues you find through techniques like filling missing values, removing duplicates and outliers, or converting data types. Consider whether the issues are systemic (operating on entire columns) or isolated (single rows).
Document any alterations you make to the data and the rationale behind them. The goal is to ensure the data is accurate and reliable before progressing with analysis.
Step 3: Univariate Analysis
With confidence in data quality, we can start to examine individual variables in isolation. This is known as univariate analysis.
For numerical variables, you want to understand the central tendency, spread, and distribution. Useful commands include:
df[‘column‘].describe()
df[‘column‘].hist()
df.boxplot(column=‘column‘)
While for categorical variables, you want to examine the distinct values and their frequencies:
df[‘column‘].value_counts()
df[‘column‘].value_counts(normalize=True)
df[‘column‘].value_counts().plot(kind=‘bar‘)
Visualization is key to identifying interesting patterns. Histograms and box plots work well for numerical variables, while bar plots are ideal for categorical variables.
For the Titanic data, we might find:
- A right-skewed distribution for
Age, with a mean of 29.7 and median of 28 - Three distinct classes for
Pclass, with 3rd class the most frequent - Two categories for
Sex, with 65% male and 35% female - A multimodal distribution for
Fare, suggesting potential clusters
These insights can inform feature engineering decisions, like binning Age or one-hot encoding Pclass. Univariate analysis gives us a baseline understanding to build on in the next step.
Step 4: Bivariate and Multivariate Analysis
The real power of EDA comes from analyzing the relationships between variables. That‘s where we often uncover the most interesting and actionable insights.
For two numerical variables, start with a simple scatter plot:
import matplotlib.pyplot as plt
plt.scatter(df[‘column1‘], df[‘column2‘])
This shows the correlation between the variables. You can enhance it by adding a trend line:
from scipy.stats import linregress
slope, intercept, r_value, p_value, std_err = linregress(df[‘column1‘], df[‘column2‘])
plt.plot(df[‘column1‘], intercept + slope*df[‘column1‘], color=‘red‘)
For a categorical and numerical variable, box plots are effective:
df.boxplot(column=‘numerical_column‘, by=‘categorical_column‘)
This allows you to compare the distribution of the numerical variable across each category.
When you have two categorical variables, contingency tables are the way to go:
pd.crosstab(df[‘column1‘], df[‘column2‘])
This shows the frequency of each combination of categories. Chi-squared tests can gauge the statistical significance of relationships between categorical variables.
In the Titanic data, we might discover:
- Gender had a significant impact on survival rate, with 74% of females surviving vs only 19% of males
- Ticket class also correlated with survival, with 63% of 1st class passengers surviving vs 24% of 3rd class
- Age was negatively correlated with survival, with younger passengers more likely to survive
Multivariate techniques can uncover more complex relationships. Creating a heatmap of the correlation matrix is a quick way to gauge relationships between all numerical variables:
import seaborn as sns
corr = df.corr()
sns.heatmap(corr, cmap=‘coolwarm‘, annot=True, fmt=".2f")
For mixed numerical and categorical data, techniques like parallel coordinates plots can be effective:
from pandas.plotting import parallel_coordinates
parallel_coordinates(df, ‘target_column‘)
In AI/ML projects, identifying strong relationships between features and the target has major implications for feature engineering and model selection. Correlated features may need to be combined or removed to avoid multicollinearity. Interactions between features can be modeled through polynomial features or tree-based methods. Domain knowledge can suggest promising feature combinations to engineer.
Step 5: Dimensionality Reduction and Clustering
High-dimensional datasets with many features can be challenging to visualize and model. That‘s where dimensionality reduction techniques like PCA and t-SNE come in, allowing us to compress the data into a lower-dimensional space while preserving the essential structure.
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
components = pca.fit_transform(df)
plt.scatter(components[:,0], components[:,1])
PCA can also help identify the most informative features and recognize noise. Clustering algorithms like K-means can group similar observations and reveal patterns:
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=3)
clusters = kmeans.fit_predict(df)
plt.scatter(df[:,0], df[:,1], c=clusters)
Dimensionality reduction and clustering are powerful tools for uncovering hidden structures in the data that can inform feature engineering and model selection.
Applied to the Titanic dataset, we might find that the data can be effectively compressed to two principal components: one capturing overall "status" (correlated with Pclass, Fare, and Cabin) and another related to family structure (SibSp, Parch). Clustering might reveal two main passenger types: solo travelers and families.
Step 6: Summary and Insights
The final step is to take a step back and summarize what you‘ve learned about the data through your analysis. Review the key insights and takeaways from each step.
For the Titanic dataset, our EDA might conclude:
- Gender, Pclass, and Age were the key predictors of survival
- Missingness in Age and Cabin needs to be addressed, potentially through imputation
- Fare and Pclass are highly correlated and may need to be combined into a "status" feature
- Data can be compressed to two main dimensions related to wealth and family
- Interactions between Gender and Pclass should be considered in modeling
Capture these summary points in a written report or slide deck to reference throughout the rest of the project. Distill the insights into action items and next steps to guide future work.
EDA Best Practices
We‘ve covered a lot of ground in this guide to EDA! As we wrap up, here are a few best practices to keep in mind:
- Always understand your variables before doing any analysis
- Check data quality rigorously and document any transformations
- Visualize as much as possible to uncover patterns
- Don‘t forget to analyze relationships, not just individual variables
- Let the data guide your insights, but use domain knowledge to pose questions
- Summarize key takeaways and use them to inform the rest of the project
The Future of EDA
As data becomes more complex and high-dimensional, manual EDA becomes more challenging and time-consuming. Luckily, AI itself is helping to automate and streamline the EDA process.
Automated EDA tools like AWS SageMaker Clarify and Google Cloud‘s Facets can quickly generate summary statistics and visualizations with just a few lines of code. This frees up data scientists to focus on higher-level analysis and insights.
Looking ahead, we can expect to see even more AI-powered EDA, with advanced techniques like:
- Neural networks for outlier and anomaly detection
- Deep learning for feature extraction and dimensionality reduction
- Reinforcement learning for optimal data summarization
- Natural language processing for data documentation and metadata
- Augmented analytics for natural language question answering
By leveraging AI to supercharge EDA, data scientists can uncover insights faster and more effectively than ever before.
Conclusion
EDA is a powerful and essential skill for every data scientist, especially those working in AI and machine learning. Through a deliberate and systematic process of data exploration and visualization, we can uncover valuable insights to inform modeling and drive decision making.
The key steps we covered – understanding the data, checking data quality, univariate analysis, bivariate and multivariate analysis, dimensionality reduction, and summary – provide a repeatable framework you can apply to any data science project.
As we‘ve seen, EDA is both an art and a science. It requires a keen eye for patterns, a knack for visualization, and a solid grasp of statistics. But with practice and the right tools, anyone can become an EDA expert.
So get out there and start exploring your data – the insights are waiting to be discovered!