Emoloyee Attrition Analysis

Explored workforce data using Python, SQL, and Tableau to identify the factors most closely associated with employee attrition and retention.

Tools Used: Python • Jupyter Notebooks • SQL • SQLite • Pandas • Tableau

Overview

I chose employee attrition data to identify patterns that may explain why employees leave a company. Python and SQL were used to clean and analyze the data to uncover the factors most closely associated with attrition. The findings were then presented in an interactive Tableau dashboard to communicate the results clearly.

Dataset

The dataset contains employee demographic, compensation, and workplace information used to analyze employee attrition. Factors such as overtime, monthly income, job satisfaction, and department were examined to identify patterns and determine whether they were associated with higher attrition rates.

Analysis Focus

Employee attrition, workforce trends, and retention factors

Source

Kaggle

Records

1,470

Features

Age, Department, Job Role, Monthly Income, Job Satisfaction, Overtime, Years at Company, Education, and Attrition

Format

CSV

Tools

Python • Jupyter Notebooks • SQL • SQLite • Tableau

Attrition Data

Why This Dataset?

I chose the employee attrition dataset because it included a variety of workplace, demographic, and compensation factors that could be compared against employee turnover. This made it well suited for exploring how factors such as overtime, job satisfaction, department, and monthly income may be associated with higher attrition rates while practicing data cleaning, SQL analysis, and dashboard development.

Data Preparation

The data was prepared using Python to ensure that formatting was consistent throughout the dataset. This allowed Python functions and SQL queries to execute without errors while helping ensure that the returned data was accurate.

Data Quality Assessment

Data Quality Check Findings Action Taken
Column Names Names were reviewed for consistency and readability. Standardized column names where needed for easier Python and SQL analysis.
Missing Values No significant missing values were found in the fields used for analysis. Retained the dataset without removing records.
Data Types Numeric and categorical fields were reviewed to ensure they matched the expected data types. Verified and corrected data types where necessary.
Text Formatting Categorical values such as Department, Job Role, Overtime, and Attrition were checked for consistency. Removed extra whitespace and standardized formatting.
Database Preparation The cleaned dataset needed to be queried using SQL. Exported the prepared dataset into a SQLite database for further analysis.

Cleaning Decisions

  • Reviewed Column Names
  • Checked Data Types
  • Looked for Missing Values
  • Standardized Formatting
  • Cleaned Text Fields where needed
  • Exported the cleaned Dataset to SQLite
  • Analysis

    Python Analysis

    Python and Jupyter Notebook were used to inspect the dataset’s columns, rows, data types, and formatting. Inconsistent formatting was corrected and standardized so the data could be analyzed reliably and SQL queries could execute without errors. This preparation ensured that the workforce analysis was based on consistent and accurate data.

    Loading the Dataset

    
                            import pandas as pd
    
                            df = pd.read_csv("WA_Fn-UseC_-HR-Employee-Attrition.csv")
    
                            print(df.shape)
                            df.head()
                        

    The full Employee Attrition dataset was loaded into a Pandas DataFrame so its structure, records, and fields could be reviewed before cleaning and analysis.

    
                            df.info()
                            print(df.dtypes)
                            print(df.isnull().sum())
                        

    The dataset was inspected to review column names, data types, and missing values before any cleaning or analysis began.

    
                            numeric_columns = [
                                "Age",
                                "MonthlyIncome",
                                "YearsAtCompany",
                                "JobSatisfaction"
                            ]
    
                            for column in numeric_columns:
                                df[column] = pd.to_numeric(
                                    df[column],
                                    errors="coerce"
                                )
                        

    Numeric fields were standardized to ensure consistent formatting and reliable analysis.

    
                            df['Attrition'].value_counts(normalize=True) * 100
                        

    Python was used to summarize employee attrition across key categories, providing an initial understanding of workforce trends before creating the dashboard.

    Exporting to SQLite

    
                            import sqlite3
    
                            with sqlite3.connect(...) as conn:
                                df.to_sql(
                                    "employee_attrition",
                                    conn,
                                    if_exists="replace",
                                    index=False
                                )
                        

    The prepared DataFrame was exported into a SQLite database, allowing the cleaned data to be validated and analyzed using SQL.

    SQL Analysis

    Once the data was standardized in Python, the cleaned dataset was exported into a SQLite database for further analysis. SQL was then used to examine employee attrition by department, overtime, job satisfaction, and monthly income to identify the factors most closely associated with employee turnover.

    
                            WITH department_attrition AS (
                                SELECT
                                    Department,
                                    COUNT(*) AS total_employees,
                                    SUM(CASE WHEN Attrition = 'Yes' THEN 1 ELSE 0 END) AS employees_left,
                                    ROUND(
                                        100.0 * SUM(CASE WHEN Attrition = 'Yes' THEN 1 ELSE 0 END)
                                        / NULLIF(COUNT(*), 0),
                                        2
                                    ) AS attrition_rate
                                FROM employee_attrition
                                GROUP BY Department
                            ),
                            ranked_departments AS (
                                SELECT
                                    *,
                                    RANK() OVER (
                                        ORDER BY attrition_rate DESC
                                    ) AS attrition_rank
                                FROM department_attrition
                            )
                            SELECT *
                            FROM ranked_departments
                            ORDER BY attrition_rank;
                        

    This query uses common table expressions (CTEs) and a window function to calculate and rank each department by employee attrition rate. The results make it easy to compare departments and identify which areas of the organization experienced the highest employee turnover.

    
                            WITH employee_risk AS (
                                SELECT
                                    EmployeeNumber,
                                    Department,
                                    JobRole,
                                    OverTime,
                                    JobSatisfaction,
                                    YearsAtCompany,
                                    MonthlyIncome,
                                    Attrition,
                                    CASE
                                        WHEN OverTime = 'Yes'
                                            AND JobSatisfaction <= 2
                                            AND YearsAtCompany <= 3
                                            THEN 'High Risk'
                                        WHEN OverTime = 'Yes'
                                            OR JobSatisfaction <= 2
                                            THEN 'Moderate Risk'
                                        ELSE 'Lower Risk'
                                    END AS risk_group
                                FROM employee_attrition
                            )
                            SELECT
                                risk_group,
                                COUNT(*) AS employee_count,
                                SUM(CASE WHEN Attrition = 'Yes' THEN 1 ELSE 0 END) AS employees_left,
                                ROUND(
                                    100.0 * SUM(CASE WHEN Attrition = 'Yes' THEN 1 ELSE 0 END)
                                    / NULLIF(COUNT(*), 0),
                                    2
                                ) AS attrition_rate
                            FROM employee_risk
                            GROUP BY risk_group
                            ORDER BY attrition_rate DESC;
                        

    This query uses a common table expression (CTE) and conditional logic to group employees into attrition risk categories based on overtime, job satisfaction, and years at the company. It then compares attrition rates across each risk group to identify which combination of factors is most strongly associated with employee turnover.

    Dashboard

    Tableau was used to create a dashboard that summarizes the key findings. Each chart in the dashboard examines how job satisfaction, overtime, monthly income, and department are associated with employee attrition, making the results easier to understand and compare.

    Dashboard Design

    The dashboard consist of 4 vertical bar charts, each focusing on a different business question.

    Attrition by Overtime

    This vertical bar chart compares employee attrition rates based on overtime status. Employees who worked overtime had an attrition rate of approximately 30%, compared with around 10% for employees who did not work overtime.

    Attrition by Job Satisfaction

    This vertical bar chart compares employee attrition rates across different levels of job satisfaction. Employees with very low job satisfaction experienced attrition rates between approximately 20% and 30%, while employees with very high job satisfaction had attrition rates just above 10%.

    Attrition by Department

    This vertical bar chart compares employee attrition rates across departments. Sales experienced the highest attrition rate at just over 20%, followed by Human Resources at just under 20%, while Research & Development had the lowest attrition rate.

    Average Income by Attrition

    This vertical bar chart compares the average monthly income of employees who stayed with those who left the company. Employees who remained earned an average monthly income of nearly $7,000, while employees who left earned less than $5,000 on average, suggesting a relationship between lower income and higher attrition.

    Key Insights

  • Employees who worked overtime experienced significantly higher attrition rates, with turnover around 30% compared to approximately 10% for employees who did not work overtime.
  • Lower job satisfaction was associated with higher employee attrition, while employees reporting higher job satisfaction were more likely to remain with the company.
  • The Sales department experienced the highest attrition rate, suggesting turnover patterns varied across different areas of the organization.
  • Employees who left the company earned a lower average monthly income than those who remained, indicating that compensation may be associated with employee retention.
  • Employee attrition appeared to be influenced by multiple workplace factors, highlighting the importance of considering job satisfaction, workload, department, and compensation together rather than in isolation.
  • Challenges

    One of the primary challenges was comparing multiple workplace factors to determine which were most strongly associated with employee attrition. Rather than relying on a single metric, the analysis required examining overtime, job satisfaction, department, and monthly income together to better understand employee turnover.

    Another challenge was organizing the data into a format that supported reliable SQL analysis. Consistent formatting and standardized data types were necessary to ensure that Python functions, SQL queries, and Tableau visualizations produced accurate and consistent results.

    Finally, creating more advanced SQL queries required combining common table expressions (CTEs), window functions, and conditional logic to analyze employee groups and identify meaningful patterns in attrition.

    Lessons Learned

    This project reinforced the importance of preparing data before beginning any analysis. Ensuring that data types, formatting, and values were consistent helped produce reliable Python analyses, SQL queries, and Tableau visualizations.

    I also learned that employee attrition is influenced by multiple workplace factors rather than a single variable. Examining overtime, job satisfaction, department, and monthly income together provided a more complete understanding of employee turnover than looking at any one factor individually.

    Finally, this project strengthened my SQL skills by applying common table expressions (CTEs), window functions, and conditional logic to answer more complex business questions. It also reinforced the value of combining Python, SQL, and Tableau into a complete analytics workflow.

    Project Resources

    Interested in exploring the project further? View the source code or interact with the dashboard below.