Session 07: Power BI for Insurance Analytics
Learning Objectives
- Understand when to use Power BI versus Python for insurance data visualization and build a decision framework for tool selection
- Import the cleaned insurance dataset into Power BI Desktop and establish correct table relationships
- Write DAX measures for the seven essential insurance KPIs — Total Premium, Total Claims, Loss Ratio, Expense Ratio, Combined Ratio, Claim Settlement Ratio, and YoY Growth
- Build a 3-page interactive insurance dashboard covering Claims Overview, Policy Analytics, and Customer Segmentation with slicers, drill-throughs, and KPI cards
- Apply dashboard design principles to create a clean, interpretable, boardroom-ready dashboard that passes the 5-second test
1. Power BI vs. Python Visualization
Power BI and Python are complementary tools for insurance data visualization. Each has strengths and weaknesses, and knowing which to use for which task is a mark of a mature insurance analytics professional. The answer is rarely "always use X" — it depends on the audience, the complexity of the analysis, and the need for interactivity vs. reproducibility.
| Dimension | Power BI | Python (Matplotlib/Seaborn) |
|---|---|---|
| Best for | Interactive dashboards, self-service analytics, business user consumption, recurrent reporting | Custom visualizations, statistical charting, production of publication figures, ad-hoc analysis |
| Interactivity | Native — slicers, filters, cross-filtering, drill-through, tooltips, bookmarks | Requires additional libraries (Plotly, Bokeh, Dash) or manual HTML/JS integration |
| Reproducibility | Manual steps required — can be version-controlled (.pbip) but scripted ETL separate | Fully reproducible — a Jupyter notebook with well-ordered cells produces the same output every time |
| Statistical charting | Basic statistical visuals — box plots, funnel charts, decomposition trees. Advanced (violin, pairplot, heatmap) requires custom visuals. | Full statistical charting — Seaborn, built-in statistical transformations, distribution fitting |
| Sharing & governance | Enterprise-grade — Power BI Service, row-level security, scheduled refresh, mobile apps | Requires separate distribution — PDF, HTML, Dash app, or integration into an application |
| Learning curve | Moderate — DAX is the most challenging part, drag-and-drop for basic visuals | Steep — requires programming fundamentals, but consistent API across libraries |
1.1 The Decision Framework
Use this simple three-question framework when deciding between Power BI and Python:
- Does the audience need interactivity? (slicers, drill-down, cross-filtering) → If yes, use Power BI. If a static chart is sufficient, Python may be faster.
- Is this a recurring dashboard or a one-off analysis? → If recurring (monthly board report, weekly claims monitoring), invest in Power BI. If one-off (a single chart for a paper or presentation), use Python.
- Does the analysis require statistical transformations? (smoothing, clustering, regression residuals, distribution fitting) → If yes, Python. If the analysis is aggregations and comparisons, Power BI.
The best insurance analytics teams use both — Power BI for the interactive dashboards that business teams consume daily, and Python for the ad-hoc analysis and model development that feeds into those dashboards.
2. Power BI Interface & Data Loading
This section assumes you have Power BI Desktop installed (free download from Microsoft), and you have the cleaned dataset (`insurance_cleaned.csv`) from Session 05.
2.1 Initial Setup and Data Import
Step 1 — Open Power BI Desktop: You will see a blank canvas with three tabs at the bottom: Report (where you build visuals), Data (where you view tables), and Model (where you manage relationships).
Step 2 — Import the CSV: Click "Get Data" → "Text/CSV" → navigate to `insurance_cleaned.csv` → Click "Load" (not "Transform Data" yet — we will use Power Query for transformations in a moment).
Step 3 — Check the imported data: Go to the "Data" tab (the table icon on the left). You should see all columns from the CSV. Click on columns to verify data types — dates should show as Date, numbers as Decimal Number or Whole Number, and text as Text.
Step 4 — Open Power Query Editor for data transformations: "Home" tab → "Transform Data" → "Transform Data" (opens Power Query Editor). Perform these checks:
- Verify that `claim_date`, `settlement_date`, `start_date`, `end_date` are of type Date (not Text)
- If any date column was imported as Text: click the column header, go to "Transform" → "Date" → select the correct format
- Check that `premium`, `claim_amount`, `sum_assured` are Decimal Number (not Whole Number — premiums need decimals)
- If needed: Use "Replace Values" to clean any stray characters
Step 5 — Review the Model: Go to the "Model" tab (the bar chart icon on the left sidebar). If you imported a single table, you will see only one entity. For this dashboard, a single flat table is sufficient — we flattened the schema in Session 05.
2.2 Creating a Date Table
A date table is essential for time-based DAX calculations. Power BI works best when you have a separate date table linked to your data:
Option A — Create in Power Query: In Power Query Editor, right-click in the Queries pane → "New Blank Query" → Advanced Editor → paste:
let
StartDate = #date(2020, 1, 1),
EndDate = #date(2026, 12, 31),
NumberOfDays = Duration.Days(EndDate - StartDate),
DateList = List.Dates(StartDate, NumberOfDays, #duration(1, 0, 0, 0)),
TableFromList = Table.FromList(DateList, Splitter.SplitByNothing()),
RenamedColumns = Table.RenameColumns(TableFromList,{{"Column1", "Date"}}),
ChangedType = Table.TransformColumnTypes(RenamedColumns,{{"Date", type date}}),
AddedYear = Table.AddColumn(ChangedType, "Year", each Date.Year([Date]), Int64.Type),
AddedMonth = Table.AddColumn(AddedYear, "Month", each Date.Month([Date]), Int64.Type),
AddedMonthName = Table.AddColumn(AddedMonth, "MonthName", each Date.MonthName([Date]), type text),
AddedQuarter = Table.AddColumn(AddedMonthName, "Quarter", each Date.QuarterOfYear([Date]), Int64.Type),
AddedYearMonth = Table.AddColumn(AddedQuarter, "YearMonth", each Date.ToText([Date], "yyyy-MM"), type text)
in
AddedYearMonth
Then, create the relationship: In the Model view, connect the Date table's `Date` column to your fact table's `claim_date` column. This allows you to use time-intelligence functions in DAX.
3. DAX Measures for Insurance KPIs
DAX (Data Analysis Expressions) is the formula language of Power BI. Unlike Excel formulas that operate on individual cells, DAX measures operate on context — they automatically recalculate based on the filters, slicers, and cross-filtering applied by the user. This is what makes Power BI interactive.
3.1 Foundational Measures
Create these measures in the "Modeling" tab → "New Measure":
-- Total Premium (sum of all premium values in the current filter context)
Total Premium = SUM('insurance_cleaned'[premium])
-- Total Claims Amount
Total Claims = SUM('insurance_cleaned'[claim_amount])
-- Claim Count (using COUNTROWS instead of COUNT — more reliable with column filters)
Claim Count = COUNTROWS('insurance_cleaned')
-- Policy Count (distinct count, since one policy may have multiple claims)
Policy Count = DISTINCTCOUNT('insurance_cleaned'[policy_id])
-- Average Claim Size
Avg Claim Size = DIVIDE([Total Claims], [Claim Count])
3.2 Insurance-Specific Measures
-- Loss Ratio: Claims / Premium
Loss Ratio = DIVIDE([Total Claims], [Total Premium], 0)
-- Format: Home tab → Percentage, 2 decimal places
-- Loss Ratio (as percentage expressed as number 0-100 for gauge charts)
Loss Ratio % = DIVIDE([Total Claims], [Total Premium], 0) * 100
-- Claim Settlement Ratio: Settled / (Settled + Rejected)
-- First, define measures for each status
Settled Claims = CALCULATE([Claim Count], 'insurance_cleaned'[status] = "Settled")
Rejected Claims = CALCULATE([Claim Count], 'insurance_cleaned'[status] = "Rejected")
Pending Claims = CALCULATE([Claim Count], 'insurance_cleaned'[status] = "Pending")
Claim Settlement Ratio = DIVIDE([Settled Claims], [Settled Claims] + [Rejected Claims], 0)
-- Average Days to Settle
Avg Days to Settle = AVERAGE('insurance_cleaned'[days_to_settle])
-- Fraud Rate
Fraud Count = CALCULATE([Claim Count], 'insurance_cleaned'[fraud_flag] = 1)
Fraud Rate = DIVIDE([Fraud Count], [Claim Count], 0)
3.3 Time Intelligence Measures
-- Total Premium Previous Year (requires date table and relationship)
Premium PY = CALCULATE([Total Premium], SAMEPERIODLASTYEAR('DateTable'[Date]))
-- Premium Year-over-Year Growth
Premium YoY % = DIVIDE([Total Premium] - [Premium PY], [Premium PY], 0)
-- Claims Year-to-Date
Claims YTD = TOTALYTD([Total Claims], 'DateTable'[Date])
-- Claims Previous Month
Claims PM = CALCULATE([Total Claims], PREVIOUSMONTH('DateTable'[Date]))
-- Rolling 12-Month Claims Average
Claims Rolling 12M = AVERAGEX(
DATESINPERIOD('DateTable'[Date], LASTDATE('DateTable'[Date]), -12, MONTH),
[Total Claims]
)
3.4 Conditional / Categorical Measures
-- Loss Ratio by Product Type (this is implied by context — DAX is automatic)
-- Severity Bucket: classify claims for visual grouping
Claim Severity Bucket = SWITCH(
TRUE(),
'insurance_cleaned'[claim_amount] <= 25000, "Low (≤₹25K)",
'insurance_cleaned'[claim_amount] <= 100000, "Medium (₹25K-₹1L)",
'insurance_cleaned'[claim_amount] <= 500000, "High (₹1L-₹5L)",
"Catastrophic (>₹5L)"
)
-- Premium per Policy (average premium per distinct policy)
Premium per Policy = DIVIDE([Total Premium], [Policy Count], 0)
-- Loss Ratio Trend Indicator
Loss Ratio Trend = IF(
[Loss Ratio] > 0.75,
"High — Investigate",
IF([Loss Ratio] > 0.60, "Moderate — Monitor", "Healthy")
)
4. Building Visuals in Power BI
With measures defined, the next step is to build the visual elements. Power BI provides a rich set of visual types. For insurance dashboards, five visual types cover 90% of needs.
4.1 The Five Essential Visual Types for Insurance
| Visual | Insurance Use | Configuration Notes |
|---|---|---|
| Card / Multi-row Card | Display a single KPI value prominently — Total Premium, Loss Ratio, Claim Count | Add a title (turn off auto-display of column name), format as currency or percentage, set high-contrast background, enable "Category Label" for context |
| KPI Visual | Show KPI with trend indicator and goal — Loss Ratio vs. 75% target, Premium YoY growth | Use "Value" = KPI, "Trend Axis" = Date, "Target" = goal value or measure. The trend mini-sparkline is the key feature. |
| Line & Clustered Column Chart | Dual-axis: premium (column) + loss ratio (line), claims count (column) + settlement ratio (line) | Enable "Show secondary axis" for the line measure. Use consistent colors (monochrome for columns, a contrasting color for the line). |
| Stacked Column / Bar | Claims by status (paid vs. pending vs. rejected) by month, Premium by channel by product | Use "100% Stacked" when proportions matter more than absolute values. Use regular Stacked when volume matters. |
| Matrix Table | Detailed data view — claims by product by month with drill-down, policy details | Enable stepped layout, conditional formatting on values (loss ratio > 75% → red), row subtotals, column subtotals |
5. Page 1 — Claims Overview Dashboard
The Claims Overview page answers the question: "What is happening with our claims?" This is the page that the Head of Claims, the Chief Operating Officer, and the Underwriting team will look at daily. It focuses on five things: volume, speed, cost, settlement rate, and fraud.
5.1 Page Layout
┌─────────────────────────────────────────────────────────────────────┐
│ CLAIMS OVERVIEW [Slicers: Year ▼] [Product ▼] [Status ▼] │
├──────────────────┬──────────────────┬──────────────────┬─────────────┤
│ Total Claims │ Avg Claim Size │ Avg Days to │ Claim │
│ ₹X,XX,XX,XXX │ ₹XX,XXX │ Settle XX days │ Settlement │
│ vs PY: +X.X% │ vs PY: +X.X% │ vs PY: -X days │ Ratio X.X% │
├──────────────────┼──────────────────┴──────────────────┴─────────────┤
│ Monthly Claims Trend (Line + Column combo) │
│ [Column: claim count by month] [Line: rolling 3-month avg] │
│ X-axis: Month-Year, Y1: Claim Count, Y2: Avg Claim Size │
├─────────────────────┬──────────────────────┬────────────────────────┤
│ Claims by Type (Bar)│ Claims by Status │ Claims by Product │
│ [X: claim_type] │ (Donut/Pie) │ (100% Stacked Bar) │
│ [Y: claim count] │ [Settled : Pending │ [X: product] │
│ │ : Rejected] │ [Y: % of total] │
├─────────────────────┴──────────────────────┴────────────────────────┤
│ Claims Detail Table — last 100 claims (matrix/table) │
│ [Claim ID, Customer, Type, Amount, Status, Days Open, Fraud Flag] │
│ Conditional formatting: Red for >90 days, Fraud flag highlighted │
└─────────────────────────────────────────────────────────────────────┘
5.2 Building the Page Step-by-Step
Step 1 — Add slicers: Add a "Year" slicer using the Date table's Year column. Set it to "List" or "Dropdown" style. Add a "Policy Type" slicer using the policy_type column. Set to "Tile" or "Dropdown" style. Add a "Status" slicer using status column. These three slicers will filter everything on the page.
Step 2 — Add KPI cards: Create 4 KPI visual elements at the top:
- Card 1: Total Claims (formatted as ₹ Crores with 2 decimal places)
- Card 2: Avg Claim Size (formatted as ₹ with no decimals)
- Card 3: Avg Days to Settle (formatted as whole number, add a goal of 15)
- Card 4: Claim Settlement Ratio (formatted as %, add a goal of 95%)
For each card, enable the "Category Label" to show the measure name. Set background color to a dark card with white text for visual separation from the chart area.
Step 3 — Monthly claims trend chart: Add a "Line and Stacked Column" chart. Column values: Claim Count (Y-axis). Line values: Avg Claim Size (Secondary Y-axis). X-axis: Date table's YearMonth or Date field. Add a "rolling average" if you created a measure for it. Format the line in a contrasting color (red or orange against blue columns). Remove the chart title and add it as a text box above: "Claims Volume and Average Size Over Time."
Step 4 — Claims by type bar chart: Add a clustered bar chart. Axis: claim_type (from insurance_cleaned). Value: Claim Count. Sort descending by value. Enable data labels. Apply consistent color to match the dashboard theme.
Step 5 — Claims by status donut: Add a donut chart. Legend: status. Value: Claim Count. Add data labels showing percentage and count. The donut should immediately answer: what proportion of claims are settled vs. pending vs. rejected?
Step 6 — Claims by product stacked bar: Add a 100% stacked bar chart. Axis: policy_type. Value: Claim Count. Legend: status. This shows the proportion of settled/pending/rejected claims for each product type, allowing the claims manager to see if one product is generating more pending or rejected cases.
Step 7 — Claims detail table: Add a table visual showing: claim_id, customer_id, policy_type, claim_amount, claim_date, days_to_settle, status, fraud_flag. Apply conditional formatting to days_to_settle (red background if > 90 days). Apply conditional formatting to fraud_flag (yellow background if 1). This table gives the operational team a working list of claims to manage.
Step 8 — Arrange and align: Use Power BI's format tools to align all visuals evenly. A 16:9 page ratio works well. Set the page background to a dark or light color that matches your chosen theme. Ensure all visuals have the same border styling for a professional, cohesive appearance.
6. Page 2 — Policy Analytics Dashboard
The Policy Analytics page answers the question: "What is happening with our portfolio?" This is the page for the Head of Products, the Chief Marketing Officer, and the Distribution team.
6.1 Page Layout
┌─────────────────────────────────────────────────────────────────────┐
│ POLICY ANALYTICS [Slicers: Year ▼] [Product ▼] [Channel ▼] │
├──────────────────┬──────────────────┬──────────────────┬─────────────┤
│ Total Premium │ Policy Count │ Avg Premium │ Loss Ratio │
│ ₹X,XX,XX,XXX │ XX,XXX │ ₹XX,XXX │ XX.X% │
│ vs PY: +X.X% │ vs PY: +X.X% │ vs PY: +X.X% │ vs PY: ±X% │
├──────────────────┴──────────────────┴──────────────────┴─────────────┤
│ Premium & Loss Ratio Trend (Line and Stacked Column — Dual Axis) │
│ [Column: Total Premium by month] [Line: Loss Ratio trend] │
│ [Reference line on Loss Ratio at 75%] │
├──────────────────────────┬──────────────────────────────────────────┤
│ Premium by Product │ Premium by Channel & Product │
│ (Horizontal Bar) │ (Stacked Bar, Channel axis, Legend=Prod)│
│ [Sorted descending, │ [Data labels for total per channel] │
│ data labels in ₹Cr] │ │
├──────────────────────────┴──────────────────────────────────────────┤
│ │ │
│ Policy Portfolio Matrix — Premium vs. Loss Ratio by Product │
│ (Scatter chart: X=Premium, Y=Loss Ratio, Legend=Product, │
│ Size=Policy Count) │
│ Quadrant lines at median premium and 75% loss ratio │
│ 4 quadrants: High Premium/Low LR (⭐) | High Premium/High LR (⚠) │
│ Low Premium/Low LR (✓) | Low Premium/High LR (✗) │
└─────────────────────────────────────────────────────────────────────┘
6.2 Building the Page Step-by-Step
Step 1 — Top slicers: Add slicers for Year, Policy Type, and Channel. Use dropdown style for compact layout. These slicers control all visuals on the page.
Step 2 — KPI cards: Total Premium, Policy Count, Avg Premium per Policy, and Loss Ratio. Use the KPI visual type where possible to include the trend indicator (up arrow/down arrow) and goal comparison. Format the Loss Ratio card with conditional formatting on the value — green if below 60%, amber if 60–75%, red if above 75%.
Step 3 — Dual-axis trend chart: Line and stacked column chart. Column values: Total Premium. Line values: Loss Ratio %. Secondary axis for Loss Ratio. Add a reference line on the secondary axis at 75% (use "Analytics" pane → "Line" → Constant Line). This single chart answers the most important portfolio question: "are we growing profitably?"
Step 4 — Premium by product: Horizontal bar chart. Axis: policy_type. Value: Total Premium. Sort descending. Format data labels in ₹ Crores. This chart shows which products are driving premium volume.
Step 5 — Premium by channel and product: Stacked bar chart. Axis: channel. Value: Total Premium. Legend: policy_type. 100% stacking can be used if the focus is on channel composition by product. Regular stacking if channel volume comparison matters.
Step 6 — Premium vs. Loss Ratio scatter: Scatter chart. Values: policy_type (in Legend). X-Axis: Total Premium. Y-Axis: Loss Ratio %. Size: Policy Count. Add constant lines at the median of X and at 75% on Y. The four resulting quadrants show at a glance which products are: high-volume with healthy loss ratios (quadrant to protect), high-volume with concerning loss ratios (quadrant to investigate), low-volume healthy, and low-volume concerning.
7. Page 3 — Customer Segmentation & Demographics
The Customer Segmentation page answers the question: "Who are our policyholders and how do they behave?" This page helps the marketing team target campaigns, the underwriting team understand risk profiles, and the product team design products for specific segments.
7.1 Page Layout
┌─────────────────────────────────────────────────────────────────────┐
│ CUSTOMER INSIGHTS [Slicers: Age Group ▼] [Location ▼] [Product ▼] │
├──────────────────┬──────────────────┬──────────────────┬─────────────┤
│ Total Customers │ Avg Age │ Avg Credit Score │ Top Location│
│ XX,XXX │ XX years │ XXX │ XXXX │
├──────────────────┴──────────────────┴──────────────────┴─────────────┤
│ Customer Age Distribution (Histogram) │
│ X-axis: Age Group [18-25, 26-35, 36-45, 46-55, 56-65, 65+] │
│ Y-axis: Customer Count │
│ Color: Claims Frequency overlay (line on secondary axis) │
├──────────────────────────┬──────────────────────────────────────────┤
│ Top Locations by Premium │ Customer Risk Profile │
│ (Map chart if available,│ (Waterfall or decomposition tree: │
│ else horizontal bar) │ Risk score = Credit Score + Age + │
│ │ Claim History composite) │
├──────────────────────────┴──────────────────────────────────────────┤
│ Customer Table — Top 100 by Premium with drill-through │
│ [Name, Policy, Premium, Claims Count, Total Claims, Fraud Flag] │
│ Conditional formatting on fraud flag. Row selection drills through │
│ to customer detail page. │
└─────────────────────────────────────────────────────────────────────┘
7.2 Building the Page Step-by-Step
Step 1 — Create Age Group column: In Power Query or as a calculated column in DAX:
Age Group = SWITCH(
TRUE(),
'insurance_cleaned'[age] < 25, "18-25",
'insurance_cleaned'[age] < 35, "26-35",
'insurance_cleaned'[age] < 45, "36-45",
'insurance_cleaned'[age] < 55, "46-55",
'insurance_cleaned'[age] < 65, "56-65",
"65+"
)
Step 2 — Top KPI cards: Total Customers, Average Age, Average Credit Score, Top Location. The "Top Location" measure requires:
Top Location = TOPN(
1,
VALUES('insurance_cleaned'[location]),
[Policy Count]
)
-- Then use this in a card visual
Step 3 — Customer age histogram: Create a clustered column chart with Age Group as the axis and distinct Customer Count as the value. Add a measure for "Claim Frequency by Age Group" as a line on the secondary axis:
Claims per Customer by Age Group = DIVIDE(
[Claim Count],
DISTINCTCOUNT('insurance_cleaned'[customer_id])
)
This dual-axis chart reveals the critical relationship: does claim frequency increase with age? (It should — older policyholders generally file more claims in health and motor lines.)
Step 4 — Top locations: If you have geographic data, create a filled map (choropleth) or ArcGIS map visual. For a simpler approach, use a horizontal bar chart with location as axis and Total Premium as value, sorted descending. Limit to top 10 locations.
Step 5 — Risk profile decomposition: Use a "Decomposition Tree" visual (available in Power BI). Place: "Risk Score" (calculated as a composite of credit_score, age, and claim_history) as the value. Breakdown by: product_type, location, age_group, channel. This allows the user to click into any segment and see what drives its risk profile.
If Decomposition Tree is not available, use a Matrix with conditional formatting on Loss Ratio by Segment.
Step 6 — Customer drill-through table: Create a table with customer_id, policy_type, age, location, premium, claim_count, total_claim_amount, fraud_flag. Enable conditional formatting: yellow background for fraud_flag = 1. Right-click on a row → "Drill through" option (requires setting up a drill-through page). This allows the user to click on any customer and see their full details on a separate page.
8. Dashboard Design Principles
A dashboard that is technically correct but poorly designed will not be used. The following principles are distilled from observing which insurance dashboards actually drive decisions — and which ones sit unused.
8.1 The Five-Second Test
A stakeholder should be able to look at your dashboard and answer the most important question within five seconds. For the Claims Overview page: "Are claims trending better or worse than last month?" For the Policy Analytics page: "Is our premium growth profitable?" If the answer is not visible within 5 seconds, the dashboard needs to be redesigned. The most important number must be the biggest thing on the page, ideally in the top-left position where the eye naturally goes first.
8.2 The Three-Page Rule
An insurance analytics dashboard should have exactly three pages — one for claims, one for policies, one for customers. More pages mean the user never goes past page 2. Fewer pages mean the content is insufficient. Within each page, limit yourself to 6–8 visuals. More than 8 visuals produces visual fatigue; fewer than 4 generally fails to tell a complete story.
8.3 The Consistent Color Rule
Use a consistent color scheme and assign meaning to colors. For insurance dashboards, establish these conventions: Green = good, healthy, improving (low loss ratio, fast settlement, high retention). Amber = monitor, moderate, borderline. Red = concerning, requires action (high loss ratio, long settlement, high fraud). Blue = neutral, informational (volumes, counts, premiums).
Apply these colors consistently across all three pages. A red loss ratio on Page 1 and a red KPI on Page 2 should convey the same level of urgency. Never use red for a neutral measure — overuse of red creates alarm fatigue and the stakeholders will stop taking it seriously.
8.4 The Filter Consistency Rule
When a user selects "Motor" in the Product Type slicer on Page 1, they expect the same filter to apply when they navigate to Page 2 and Page 3. Power BI calls this "synchronizing slicers across pages." Use the "View" → "Sync Slicers" feature to ensure consistent filtering. Nothing frustrates a dashboard user more than having to re-select the same filter on every page.
8.5 The "Why" Annotation Rule
For every chart that shows a significant trend, add a text box or annotation explaining why the trend occurred. A chart showing "Loss Ratio increased from 68% to 82% in June" is incomplete. The annotation "Monsoon claims surge — motor accident frequency up 35%" turns data into insight. In a static report, these annotations are written by the analyst. In a Power BI dashboard, you can use "Text Box" elements pinned in specific locations to provide permanent context for the most common interpretations.
8.6 Publishing and Sharing
Once your dashboard is built, you have three sharing options:
- Power BI Service (cloud): Publish to the Power BI service (requires a Pro license for shared consumption). Schedule daily data refresh. Create a mobile-optimised view for executives.
- Power BI Report Server (on-premises): For insurers with regulatory restrictions on cloud data. Requires Power BI Premium licenses. Slower feature release cycle than cloud.
- Export to PDF/PPT: For stakeholders who do not have Power BI access. Export each page as a high-resolution image or use the "Export to PowerPoint" feature. Create a "print-friendly" version of each page (white background, lighter shading, consistent page breaks).
Hands-On Project: Build a 3-Page Insurance Dashboard in Power BI
Build a complete 3-page insurance analytics dashboard in Power BI Desktop using the cleaned `insurance_cleaned.csv` dataset from Session 05. Follow the layouts and specifications from Sections 5, 6, and 7. The goal is not just to place visuals — it is to create a dashboard that a Head of Claims, Head of Products, and Head of Marketing would use daily to monitor their business.
Steps
- Data preparation: Import the cleaned CSV. Create and mark a Date table. Establish correct relationships in the Model view.
- DAX measures: Create ALL the measures from Section 3 at minimum. Add any additional measures you find useful as you build.
- Page 1 — Claims Overview: Build exactly as specified in Section 5. Minimum: 4 KPI cards, 1 dual-axis trend chart, 2 category charts, 1 detail table, 3 slicers. All slicers must control all visuals on the page.
- Page 2 — Policy Analytics: Build exactly as specified in Section 6. Minimum: 4 KPI cards (use KPI visual type with trend), 1 dual-axis trend chart, 1 horizontal bar, 1 stacked bar, 1 scatter plot. Constant lines on scatter at median premium and 75% loss ratio.
- Page 3 — Customer Segmentation: Build as specified in Section 7. Minimum: 4 KPI cards, 1 age histogram with dual-axis, 1 location bar, 1 decomposition tree or matrix, 1 drill-through table. Set up drill-through to a "Customer Detail" page (4th page, not shown in nav).
- Design: Apply consistent colors, synchronize slicers across all 3 pages, add annotations to at least 2 charts explaining trends, apply conditional formatting to at least 2 tables (settlement time overdue, fraud flagged).
- Test and export: Test with at least 3 filter combinations. Export each page as a PNG at 150 DPI for inclusion in a management report. Write a 1-page executive summary interpreting the key insights from the dashboard.
View Solution / Walkthrough
Solution Architecture Checklist
Before submission, verify your dashboard against this checklist:
| Check | Page 1 — Claims | Page 2 — Policies | Page 3 — Customers |
|---|---|---|---|
| KPI cards (4 per page) | ☐ | ☐ | ☐ |
| Dual-axis trend chart | ☐ Claims + Avg Size | ☐ Premium + Loss Ratio | ☐ Age Histogram + Freq |
| Category comparison chart | ☐ Claims by Type | ☐ Premium by Product | ☐ Top Locations |
| Second comparison chart | ☐ Claims by Status | ☐ Premium by Channel | ☐ Risk Profile |
| Detail table | ☐ Claims Detail | ☐ — | ☐ Customer Table |
| Slicers (sync'd across pages) | ☐ Year, Product, Status | ☐ Year, Product, Channel | ☐ Age Group, Location, Product |
| Conditional formatting | ☐ Days > 90 red | ☐ Loss Ratio > 75% red | ☐ Fraud flag = 1 yellow |
| Drill-through configured | ☐ N/A | ☐ N/A | ☐ Customer Detail page |
| Annotations (min 2 total) | ☐ | ☐ | ☐ |
Executive Summary (Sample)
Claims Overview: The portfolio processed ₹X crore in total claims across YYYY claims during the period. The average claim size is trending upward at Z% year-over-year, indicating claims inflation that warrants pricing review for motor and health lines. The claim settlement ratio of A% is above the regulatory target of B%, and average settlement time of C days has improved by D days YoY — reflecting the recent claims automation initiative in the motor line. However, E% of claims remain pending beyond 30 days, concentrated in property insurance, where surveyor availability remains the bottleneck.
Policy Analytics: Premium grew F% year-over-year to ₹G crore, driven primarily by the motor and health lines. The combined ratio stands at H%, broadly stable compared to last year, with the underlying loss ratio of I% partially offset by an expense ratio of J%. The scatter analysis reveals that the motor and health portfolios are in the "high-premium, healthy-loss-ratio" quadrant, while the property portfolio shows elevated loss ratios that require underwriting tightening. The channel mix is shifting — digital direct now accounts for K% of new business, up from L% last year, reflecting the success of the app-based customer acquisition strategy.
Customer Insights: The portfolio serves M customers with an average age of N and an average credit score of O. The age-claim frequency analysis confirms the expected pattern: claim frequency increases significantly for policyholders over 55, particularly in health insurance, driving a higher loss ratio for this segment. Region P accounts for the largest share of premium, but also shows a loss ratio above the portfolio average, suggesting the need for region-specific pricing. The top Q% of customers by premium contribute R% of total premium but only S% of total claims — a retention priority segment.
Key Takeaways
Power BI excels at interactive dashboards for recurring business consumption; Python excels at custom statistical visualizations for ad-hoc analysis. Use each tool where it is strongest, and connect them where they complement each other.
A proper Date table is non-negotiable for insurance time intelligence in Power BI. Without it, time-based DAX functions cannot work correctly and time-series analysis will be unreliable.
DAX measures are context-dependent by design. Always test measures under at least 3 different filter combinations to ensure they behave correctly — especially time-intelligence measures.
The 3-page dashboard template — Claims Overview, Policy Analytics, Customer Segmentation — covers the complete insurance business. The scatter plot (premium vs. loss ratio) is the single most strategic visual for portfolio management.
A technically correct dashboard that fails the "5-second test" will not be used. Design principles — consistent colors, synchronous slicers, business-focused titles, trend annotations — determine whether a dashboard drives decisions or sits untouched.
Test Your Understanding
1. A recurring monthly dashboard for the Head of Claims that requires interactive filters for product type, region, and time period should be built in:
2. In Power BI, what is the purpose of marking a table as a Date Table?
3. The following DAX measure calculates the loss ratio correctly:
Loss Ratio = DIVIDE(
SUM('insurance_cleaned'[claim_amount]),
SUM('insurance_cleaned'[premium]),
0
)
The third parameter (0) in the DIVIDE function specifies:
4. The "5-second test" for a Power BI dashboard states that:
5. In the Premium vs. Loss Ratio scatter chart, a product that appears in the top-left quadrant (high premium, low loss ratio) is best described as: