First-party
Below is the complete skill definition this hub loads when the skill is triggered — what the agent sees as its instructions, verbatim and unabridged.
# IMI Segmentation Engine
This skill teaches the AI to build, evaluate, and activate consumer segmentations the way
IMI's senior strategists do — with methodological rigour, commercial sizing, and activation
strategies that make segments actionable, not academic.
---
## IMI's Segmentation Philosophy
**A segment that can't be found, sized, and activated is useless.**
Many segmentations die in a PowerPoint. IMI's approach ensures every segment passes the
"so what?" test:
1. **Identifiable** — Can we define who is in this segment from observable data?
2. **Sizeable** — Is the segment large enough to justify investment?
3. **Accessible** — Can we reach this segment through media, channels, or touchpoints?
4. **Differentiable** — Does this segment behave differently enough to warrant distinct strategy?
5. **Actionable** — Can the client DO something different for this segment?
If a segment fails any of these five tests, it is not a useful segment.
---
## Segmentation Types
### 1. Attitudinal Segmentation
Groups consumers by what they think, believe, and value.
- **Variables:** Brand perceptions, category attitudes, lifestyle values, need states
- **Best for:** Messaging strategy, positioning, brand architecture
- **IMI tools:** Custom survey batteries, Pulse™ passion point profiles
### 2. Behavioural Segmentation
Groups consumers by what they actually do.
- **Variables:** Purchase frequency, channel usage, brand switching, spend level
- **Best for:** CRM strategy, loyalty programmes, promotional targeting
- **IMI tools:** Transaction data, panel data, survey-reported behaviour
### 3. Needs-Based Segmentation
Groups consumers by what they need from the category.
- **Variables:** Occasion, need state, functional/emotional drivers
- **Best for:** Product development, portfolio strategy, innovation
- **IMI tools:** MaxDiff, conjoint, occasion diaries
### 4. Demographic/Life-Stage Segmentation
Groups consumers by who they are.
- **Variables:** Age, income, life stage, household composition, location
- **Best for:** Media planning, distribution strategy, initial audience sizing
- **IMI tools:** Census data, panel data, survey demographics
**IMI's recommendation:** Always combine at least two types. Demographics alone are too
blunt; attitudes alone are too hard to target. The best segmentations layer behavioural
and attitudinal data on a demographic foundation.
---
## The Segmentation Process
### Step 1: Variable Selection
Choose the right input variables for clustering:
```python
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
def prepare_segmentation_variables(df, variable_cols, weight_col='resp_weight'):
"""
Prepare variables for clustering: handle missing data, standardise, check variance.
"""
# Check variance — drop near-zero-variance variables
variances = df[variable_cols].var()
low_var = variances[variances < 0.1].index.tolist()
if low_var:
print(f"Dropping low-variance variables: {low_var}")
variable_cols = [v for v in variable_cols if v not in low_var]
# Check correlations — flag highly correlated pairs (r > 0.85)
corr_matrix = df[variable_cols].corr()
high_corr_pairs = []
for i in range(len(variable_cols)):
for j in range(i+1, len(variable_cols)):
if abs(corr_matrix.iloc[i, j]) > 0.85:
high_corr_pairs.append(
(variable_cols[i], variable_cols[j],
round(corr_matrix.iloc[i, j], 3))
)
if high_corr_pairs:
print(f"Warning: highly correlated pairs: {high_corr_pairs}")
print("Consider removing one from each pair or using PCA")
# Standardise
scaler = StandardScaler()
scaled = scaler.fit_transform(df[variable_cols].fillna(df[variable_cols].median()))
return pd.DataFrame(scaled, columns=variable_cols, index=df.index), scaler
```
### Step 2: Clustering
IMI typically uses k-means or latent class analysis. The choice depends on data type:
```python
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score, calinski_harabasz_score
def find_optimal_segments(scaled_df, min_k=3, max_k=8, random_state=42):
"""
Test multiple k values and evaluate segment solutions.
"""
results = []
for k in range(min_k, max_k + 1):
kmeans = KMeans(n_clusters=k, random_state=random_state, n_init=20)
labels = kmeans.fit_predict(scaled_df)
sil = silhouette_score(scaled_df, labels)
ch = calinski_harabasz_score(scaled_df, labels)
# Segment sizes
sizes = pd.Series(labels).value_counts(normalize=True).sort_index()
min_size = sizes.min()
max_size = sizes.max()
results.append({
'k': k,
'silhouette': round(sil, 3),
'calinski_harabasz': round(ch, 1),
'min_segment_pct': round(min_size * 100, 1),
'max_segment_pct': round(max_size * 100, 1),
'size_ratio': round(max_size / min_size, 1)
})
return pd.DataFrame(results)
```
**IMI's solution selection criteria:**
1. **Statistical quality:** Silhouette score > 0.25 (higher is better)
2. **Minimum segment size:** No segment smaller than 10% of the sample
3. **Discrimination:** Segments must differ on key variables (not just marginally)
4. **Interpretability:** A strategist must be able to name and describe each segment
5. **Commercial utility:** Client must be able to act differently for each segment
### Step 3: Profiling
Once segments are assigned, profile each segment across all available dimensions:
```sql
SELECT
segment_id,
segment_name,
-- Demographics
ROUND(AVG(CASE WHEN age_band = '18-24' THEN 1.0 ELSE 0.0 END) * 100, 1) AS pct_18_24,
ROUND(AVG(CASE WHEN age_band = '25-34' THEN 1.0 ELSE 0.0 END) * 100, 1) AS pct_25_34,
ROUND(AVG(CASE WHEN gender = 'F' THEN 1.0 ELSE 0.0 END) * 100, 1) AS pct_female,
-- Category behaviour
ROUND(AVG(purchase_frequency), 1) AS avg_purchase_freq,
ROUND(AVG(avg_spend_per_occasion), 2) AS avg_spend,
-- Brand metrics
ROUND(AVG(CASE WHEN brand_consideration >= 4 THEN 1.0 ELSE 0.0 END) * 100, 1) AS brand_consideration_t2b,
-- Segment size
COUNT(*) AS unweighted_n,
SUM(resp_weight) AS weighted_n
FROM segmented_respondents
GROUP BY segment_id, segment_name
ORDER BY segment_id;
```
### Step 4: Sizing and Prioritisation
**Segment Priority Score:**
| Factor | Weight | Description |
|---|---|---|
| Segment size | 25% | Weighted population size |
| Category value | 30% | Spend per capita × frequency |
| Brand opportunity | 25% | Gap between current brand share and potential |
| Accessibility | 20% | How easily can the brand reach this segment? |
```python
def prioritise_segments(segment_profiles):
"""
Score and rank segments by commercial priority.
"""
# Normalise each factor to 0-1 scale
for col in ['size_pct', 'value_per_capita', 'brand_opportunity', 'accessibility']:
segment_profiles[f'{col}_norm'] = (
(segment_profiles[col] - segment_profiles[col].min()) /
(segment_profiles[col].max() - segment_profiles[col].min())
)
# Weighted score
segment_profiles['priority_score'] = (
0.25 * segment_profiles['size_pct_norm'] +
0.30 * segment_profiles['value_per_capita_norm'] +
0.25 * segment_profiles['brand_opportunity_norm'] +
0.20 * segment_profiles['accessibility_norm']
)
return segment_profiles.sort_values('priority_score', ascending=False)
```
### Step 5: Activation Strategy
For each priority segment, define:
```
1. TARGETING: How will media/sales/CRM identify this segment?
- Media proxy variables (demographics, interests, channels)
- CRM indicators (purchase patterns, engagement signals)
- Lookalike modelling inputs
2. MESSAGING: What should the brand say to this segment?
- Key need states to address
- Emotional vs. functional messaging balance
- Tone of voice adjustments
3. CHANNEL: Where does this segment engage?
- Media consumption profile
- Retail channel preferences
- Digital touchpoints
4. OFFER: What should the brand offer this segment?
- Product/variant emphasis
- Price/promotion sensitivity
- Bundle or cross-sell opportunities
```
---
## Special Segmentation: Newcomers Analysis
IMI's Newcomers framework identifies consumers who are new to a category — recent entrants
who are forming brand preferences and habits.
**Why Newcomers matter:**
- They have no established brand loyalty — they are up for grabs
- Their early experiences disproportionately shape long-term behaviour
- Winning a Newcomer is worth more than retaining an existing buyer (lifetime value)
**Identifying Newcomers:**
```sql
SELECT
r.respondent_id,
r.demographics,
cu.first_purchase_date,
cu.category_tenure_months,
cu.brands_tried,
cu.current_primary_brand
FROM respondents r
JOIN category_usage cu ON r.respondent_id = cu.respondent_id
WHERE cu.category_tenure_months <= 12 -- Newcomer = entered category within 12 months
AND cu.category_id = :category_id;
```
**Newcomer profiling questions:**
1. What triggered their category entry? (Life event, recommendation, advertising)
2. What brands did they consider first?
3. What drove their first choice?
4. How loyal are they to that first choice already?
5. What would make them switch?
---
## Special Segmentation: Gen Z Profiling
Gen Z (born 1997-2012) requires specific segmentation considerations:
1. **Attitudinal variables matter more.** Gen Z is internally diverse — demographics within
Gen Z are less predictive than attitudes and values.
2. **Digital behaviour is a segmentation input.** Platform usage, content consumption, and
creator affiliations are valid clustering variables for Gen Z.
3. **Values are non-negotiable.** Sustainability, inclusivity, and authenticity are baseline
expectations, not differentiators, for Gen Z segments.
4. **Volatility is structural.** Gen Z segments may shift over 6-12 months as cultural
trends move. Build in re-validation cycles.
---
## Output Templates
### Template: Segmentation Summary
```markdown
## Audience Segmentation: [Category/Brand]
**Method:** [K-means / Latent Class / Hybrid]
**Variables:** [list]
**Solution:** [N] segments | **Base:** n=[total]
### Segment Overview
| Segment | Name | Size (%) | Value Index | Priority |
|---|---|---|---|---|
| 1 | [Descriptive name] | X% | XXX | HIGH/MED/LOW |
| 2 | ... | | | |
### Segment Profiles
#### Segment 1: [Name]
**Who they are:** [demographic sketch]
**What they value:** [attitudinal profile]
**How they behave:** [behavioural profile]
**Brand relationship:** [current brand usage/consideration]
**How to reach them:** [media/channel profile]
**What to say:** [messaging direction]
### Prioritisation
| Segment | Size | Value | Opportunity | Accessibility | Score |
|---|---|---|---|---|---|
### Essential Insight
[One sentence: which segment represents the biggest growth opportunity and why]
### Recommended Next Steps
1. [Specific IMI capability for activation]
```
---
## Common Pitfalls
1. **Too many segments.** More than 6-7 segments are unmanageable. If the stats say 9 is
optimal but the client can only execute against 4, the answer is 4-5 segments.
2. **Segments defined by what they are, not what to do.** "Health-conscious moms" is a
description, not a strategy. Every segment needs a clear activation path.
3. **Ignoring segment stability.** If segments shift dramatically when you re-run with a
different random seed, the solution is unstable. Test robustness.
4. **Academic segmentation.** A segmentation that explains 60% of variance but can't be
targeted in media is useless. Prioritise actionability over statistical elegance.
5. **Forgetting to size.** The most interesting segment might be 3% of the market. Always
size segments before building strategy around them.
---
## Cross-Skill References
- For passion point profiling of segments → `imi-pulse-intelligence`
- For brand health within segments → `imi-brand-strategy`
- For SQL queries over segmentation data → `imi-rag-sql-intelligence`
- For Say/Do gap within specific segments → `imi-say-do-gap`
- For writing up segmentation deliverables → `imi-client-deliverable`
---
*Built for IMI International's Local AI — grounded in decades of consumer segmentation
across 200+ client partners and 45 countries.*
*Purpose: Insight. Method: Rigour. Outcome: Profit.*
## AXE MCP Server Integration
Every skill in the AXE Skills Hub runs with access to the **AXE MCP Server** — giving it the full fleet intelligence toolkit automatically. No setup required; tools are available in any AXE-powered session.
### Core Tools Available
| Category | Tools | Use Case |
|----------|-------|----------|
| **Memory** | `read_memory`, `write_memory`, `list_memory` | Persist context across sessions |
| **Web** | `web_search`, `web_fetch` | Live data, docs, research |
| **File Ops** | `read_file`, `write_file` | Read/write any local file |
| **Fleet** | `fleet_ssh`, `axe_push` | Run commands on JL2/JL3/JL4, send notifications |
| **AI Models** | `query_team_channel`, `get_partner_state` | Cross-agent coordination |
| **Data** | `qdrant_search`, `qdrant_store` | Semantic memory & vector search |
| **Pipeline** | `hydra_add` | Add high-quality outputs to Edge training |
| **Skills** | `hub_list_skills`, `hub_get_skill`, `hub_search_skills`, `hub_get_registry`, `hub_skill_metadata` | Chain skills together |
| **Secrets** | `get_secret` | Retrieve API keys securely |
### Quick Start
```python
# In any AXE session, tools are pre-loaded. Example chaining:
# 1. Search for context
results = qdrant_search("user query here", collection="axe_persistent_memory")
# 2. Fetch live data if needed
content = web_fetch("https://docs.example.com/api")
# 3. Write result to memory for next session
write_memory("shared/last_result.md", output)
# 4. Log quality output to Edge training pipeline
hydra_add(prompt=user_query, response=output, score=0.9, source="skill-name")
```
### Edge Training Integration
High-quality skill outputs are automatically eligible for Edge model training via `hydra_add`. When a response scores ≥0.85 in evals, pipe it to the Hydra pipeline to compound Edge's knowledge. This is how skills make Edge smarter over time.
```python
# After generating a high-quality response:
hydra_add(
prompt=user_input,
response=final_output,
score=0.9, # eval score
source="skill-name" # tracks provenance
)
```This skill teaches the AI to build, evaluate, and activate consumer segmentations the way
IMI's senior strategists do — with methodological rigour, commercial sizing, and activation
strategies that make segments actionable, not academic.
A segment that can't be found, sized, and activated is useless.
Many segmentations die in a PowerPoint. IMI's approach ensures every segment passes the
"so what?" test:
If a segment fails any of these five tests, it is not a useful segment.
Groups consumers by what they think, believe, and value.
Groups consumers by what they actually do.
Groups consumers by what they need from the category.
Groups consumers by who they are.
IMI's recommendation: Always combine at least two types. Demographics alone are too
blunt; attitudes alone are too hard to target. The best segmentations layer behavioural
and attitudinal data on a demographic foundation.
Choose the right input variables for clustering:
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
def prepare_segmentation_variables(df, variable_cols, weight_col='resp_weight'):
"""
Prepare variables for clustering: handle missing data, standardise, check variance.
"""
# Check variance — drop near-zero-variance variables
variances = df[variable_cols].var()
low_var = variances[variances < 0.1].index.tolist()
if low_var:
print(f"Dropping low-variance variables: {low_var}")
variable_cols = [v for v in variable_cols if v not in low_var]
# Check correlations — flag highly correlated pairs (r > 0.85)
corr_matrix = df[variable_cols].corr()
high_corr_pairs = []
for i in range(len(variable_cols)):
for j in range(i+1, len(variable_cols)):
if abs(corr_matrix.iloc[i, j]) > 0.85:
high_corr_pairs.append(
(variable_cols[i], variable_cols[j],
round(corr_matrix.iloc[i, j], 3))
)
if high_corr_pairs:
print(f"Warning: highly correlated pairs: {high_corr_pairs}")
print("Consider removing one from each pair or using PCA")
# Standardise
scaler = StandardScaler()
scaled = scaler.fit_transform(df[variable_cols].fillna(df[variable_cols].median()))
return pd.DataFrame(scaled, columns=variable_cols, index=df.index), scaler
IMI typically uses k-means or latent class analysis. The choice depends on data type:
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score, calinski_harabasz_score
def find_optimal_segments(scaled_df, min_k=3, max_k=8, random_state=42):
"""
Test multiple k values and evaluate segment solutions.
"""
results = []
for k in range(min_k, max_k + 1):
kmeans = KMeans(n_clusters=k, random_state=random_state, n_init=20)
labels = kmeans.fit_predict(scaled_df)
sil = silhouette_score(scaled_df, labels)
ch = calinski_harabasz_score(scaled_df, labels)
# Segment sizes
sizes = pd.Series(labels).value_counts(normalize=True).sort_index()
min_size = sizes.min()
max_size = sizes.max()
results.append({
'k': k,
'silhouette': round(sil, 3),
'calinski_harabasz': round(ch, 1),
'min_segment_pct': round(min_size * 100, 1),
'max_segment_pct': round(max_size * 100, 1),
'size_ratio': round(max_size / min_size, 1)
})
return pd.DataFrame(results)
IMI's solution selection criteria:
Once segments are assigned, profile each segment across all available dimensions:
SELECT
segment_id,
segment_name,
-- Demographics
ROUND(AVG(CASE WHEN age_band = '18-24' THEN 1.0 ELSE 0.0 END) * 100, 1) AS pct_18_24,
ROUND(AVG(CASE WHEN age_band = '25-34' THEN 1.0 ELSE 0.0 END) * 100, 1) AS pct_25_34,
ROUND(AVG(CASE WHEN gender = 'F' THEN 1.0 ELSE 0.0 END) * 100, 1) AS pct_female,
-- Category behaviour
ROUND(AVG(purchase_frequency), 1) AS avg_purchase_freq,
ROUND(AVG(avg_spend_per_occasion), 2) AS avg_spend,
-- Brand metrics
ROUND(AVG(CASE WHEN brand_consideration >= 4 THEN 1.0 ELSE 0.0 END) * 100, 1) AS brand_consideration_t2b,
-- Segment size
COUNT(*) AS unweighted_n,
SUM(resp_weight) AS weighted_n
FROM segmented_respondents
GROUP BY segment_id, segment_name
ORDER BY segment_id;
Segment Priority Score:
| Factor | Weight | Description |
|---|---|---|
| Segment size | 25% | Weighted population size |
| Category value | 30% | Spend per capita × frequency |
| Brand opportunity | 25% | Gap between current brand share and potential |
| Accessibility | 20% | How easily can the brand reach this segment? |
def prioritise_segments(segment_profiles):
"""
Score and rank segments by commercial priority.
"""
# Normalise each factor to 0-1 scale
for col in ['size_pct', 'value_per_capita', 'brand_opportunity', 'accessibility']:
segment_profiles[f'{col}_norm'] = (
(segment_profiles[col] - segment_profiles[col].min()) /
(segment_profiles[col].max() - segment_profiles[col].min())
)
# Weighted score
segment_profiles['priority_score'] = (
0.25 * segment_profiles['size_pct_norm'] +
0.30 * segment_profiles['value_per_capita_norm'] +
0.25 * segment_profiles['brand_opportunity_norm'] +
0.20 * segment_profiles['accessibility_norm']
)
return segment_profiles.sort_values('priority_score', ascending=False)
For each priority segment, define:
1. TARGETING: How will media/sales/CRM identify this segment?
- Media proxy variables (demographics, interests, channels)
- CRM indicators (purchase patterns, engagement signals)
- Lookalike modelling inputs
2. MESSAGING: What should the brand say to this segment?
- Key need states to address
- Emotional vs. functional messaging balance
- Tone of voice adjustments
3. CHANNEL: Where does this segment engage?
- Media consumption profile
- Retail channel preferences
- Digital touchpoints
4. OFFER: What should the brand offer this segment?
- Product/variant emphasis
- Price/promotion sensitivity
- Bundle or cross-sell opportunities
IMI's Newcomers framework identifies consumers who are new to a category — recent entrants
who are forming brand preferences and habits.
Why Newcomers matter:
Identifying Newcomers:
SELECT
r.respondent_id,
r.demographics,
cu.first_purchase_date,
cu.category_tenure_months,
cu.brands_tried,
cu.current_primary_brand
FROM respondents r
JOIN category_usage cu ON r.respondent_id = cu.respondent_id
WHERE cu.category_tenure_months <= 12 -- Newcomer = entered category within 12 months
AND cu.category_id = :category_id;
Newcomer profiling questions:
Gen Z (born 1997-2012) requires specific segmentation considerations:
Gen Z are less predictive than attitudes and values.
creator affiliations are valid clustering variables for Gen Z.
expectations, not differentiators, for Gen Z segments.
trends move. Build in re-validation cycles.
## Audience Segmentation: [Category/Brand]
**Method:** [K-means / Latent Class / Hybrid]
**Variables:** [list]
**Solution:** [N] segments | **Base:** n=[total]
### Segment Overview
| Segment | Name | Size (%) | Value Index | Priority |
|---|---|---|---|---|
| 1 | [Descriptive name] | X% | XXX | HIGH/MED/LOW |
| 2 | ... | | | |
### Segment Profiles
#### Segment 1: [Name]
**Who they are:** [demographic sketch]
**What they value:** [attitudinal profile]
**How they behave:** [behavioural profile]
**Brand relationship:** [current brand usage/consideration]
**How to reach them:** [media/channel profile]
**What to say:** [messaging direction]
### Prioritisation
| Segment | Size | Value | Opportunity | Accessibility | Score |
|---|---|---|---|---|---|
### Essential Insight
[One sentence: which segment represents the biggest growth opportunity and why]
### Recommended Next Steps
1. [Specific IMI capability for activation]
optimal but the client can only execute against 4, the answer is 4-5 segments.
description, not a strategy. Every segment needs a clear activation path.
different random seed, the solution is unstable. Test robustness.
targeted in media is useless. Prioritise actionability over statistical elegance.
size segments before building strategy around them.
imi-pulse-intelligenceimi-brand-strategyimi-rag-sql-intelligenceimi-say-do-gapimi-client-deliverable*Built for IMI International's Local AI — grounded in decades of consumer segmentation
across 200+ client partners and 45 countries.*
*Purpose: Insight. Method: Rigour. Outcome: Profit.*
Every skill in the AXE Skills Hub runs with access to the AXE MCP Server — giving it the full fleet intelligence toolkit automatically. No setup required; tools are available in any AXE-powered session.
| Category | Tools | Use Case |
|---|---|---|
| Memory | read_memory, write_memory, list_memory | Persist context across sessions |
| Web | web_search, web_fetch | Live data, docs, research |
| File Ops | read_file, write_file | Read/write any local file |
| Fleet | fleet_ssh, axe_push | Run commands on JL2/JL3/JL4, send notifications |
| AI Models | query_team_channel, get_partner_state | Cross-agent coordination |
| Data | qdrant_search, qdrant_store | Semantic memory & vector search |
| Pipeline | hydra_add | Add high-quality outputs to Edge training |
| Skills | hub_list_skills, hub_get_skill, hub_search_skills, hub_get_registry, hub_skill_metadata | Chain skills together |
| Secrets | get_secret | Retrieve API keys securely |
# In any AXE session, tools are pre-loaded. Example chaining:
# 1. Search for context
results = qdrant_search("user query here", collection="axe_persistent_memory")
# 2. Fetch live data if needed
content = web_fetch("https://docs.example.com/api")
# 3. Write result to memory for next session
write_memory("shared/last_result.md", output)
# 4. Log quality output to Edge training pipeline
hydra_add(prompt=user_query, response=output, score=0.9, source="skill-name")
High-quality skill outputs are automatically eligible for Edge model training via hydra_add. When a response scores ≥0.85 in evals, pipe it to the Hydra pipeline to compound Edge's knowledge. This is how skills make Edge smarter over time.
# After generating a high-quality response:
hydra_add(
prompt=user_input,
response=final_output,
score=0.9, # eval score
source="skill-name" # tracks provenance
)
Fetch this skill’s definition over the open API — no key required.
curl -s /v1/skills/imi-segmentation-engine