Pattern 15: Intervention Recommendation Engine
Intent
Synthesize predictions from multiple models and patterns to recommend specific, personalized interventions tailored to each situation's risk profile, confidence level, time window, and individual characteristics, with clear rationale and alternative approaches.
Also Known As
- Action Recommendation System
- Prescriptive Analytics
- Treatment Selection Engine
- Intervention Optimization
- Personalized Action Planning
Problem
Predictions without actions are useless.
Sarah knows Martinez family has: - 87% withdrawal risk (Pattern 12) - High confidence (Pattern 13) - 32 days until expected event (Pattern 14) - Similar to 8 families who withdrew (Pattern 11)
But what should Sarah DO about it?
The complexity: - Multiple intervention options exist - Different risks need different responses - Timing affects intervention choice - Family characteristics matter - Resource constraints limit actions - Success rates vary by approach
Without systematic recommendations: - Sarah relies on intuition (inconsistent) - Different coordinators take different actions - Can't learn what works (no systematic tracking) - Miss optimal interventions - Waste effort on ineffective approaches
With recommendation engine: System says: "Based on 87% withdrawal risk + payment stress + 32-day window → Recommend: (1) Personal phone call to discuss concerns, (2) Offer payment plan if financial, (3) Connect with mentor Chen family. Confidence: 82%. Expected success: 67% retention based on 23 similar cases."
Context
When this pattern applies:
- Multiple intervention options available
- Have historical data on intervention effectiveness
- Want to personalize approach
- Need consistency across team members
- Want to optimize resource allocation
- Track and learn from outcomes
When this pattern may not be needed:
- Only one intervention type (no choice)
- Purely manual operations (no system)
- Very small scale (coordinator knows everyone)
- No data on intervention effectiveness
Forces
Competing concerns:
1. Prescriptive vs Suggestive - Prescriptive: "Do this" (automation) - Suggestive: "Consider this" (support) - Balance: Recommend with rationale, allow override
2. Personalization vs Scalability - Personalize to individual = slow, resource-intensive - Standardize = fast, efficient, but less effective - Balance: Templates with personalization parameters
3. Optimal vs Feasible - Optimal: "Personal visit best" (may not be feasible) - Feasible: "Email works" (suboptimal but practical) - Balance: Rank by effectiveness, flag feasibility
4. Single Best vs Portfolio - Single: "Do this one thing" - Portfolio: "Try A, if fails try B, then C" - Balance: Primary recommendation + alternatives
5. Historical vs Experimental - Historical: Recommend what worked before (safe) - Experimental: Try new approaches (learning) - Balance: 90% proven, 10% exploration
Solution
Build recommendation engine that:
- Analyzes situation - Risk profile, confidence, timing, characteristics
- Identifies intervention types - Payment plans, mentoring, calls, meetings
- Ranks by effectiveness - Historical success rates for this situation type
- Personalizes approach - Adapt to family preferences, history
- Considers constraints - Resource availability, timing, feasibility
- Provides alternatives - Plan B, Plan C if Plan A doesn't work
- Explains reasoning - Why this recommendation?
Recommendation Formula:
Recommended Intervention = argmax(
Effectiveness(intervention, situation) ×
Feasibility(intervention, constraints) ×
PersonalizationFit(intervention, family) ×
Confidence(prediction)
)
Where:
Effectiveness = Historical success rate for situation type
Feasibility = Can we actually do this? (resources, timing)
PersonalizationFit = Matches family preferences/history
Confidence = How sure are we about the situation?
Structure
Intervention Library Tables
-- Define available interventions
CREATE TABLE interventions (
intervention_id INT PRIMARY KEY IDENTITY(1,1),
intervention_name VARCHAR(200) NOT NULL,
intervention_type VARCHAR(100), -- 'communication', 'financial', 'connection', 'recognition'
-- Description
description NVARCHAR(1000),
required_actions NVARCHAR(MAX), -- JSON: steps to execute
-- Targeting
applicable_risks NVARCHAR(500), -- JSON: ['withdrawal', 'payment', 'academic']
min_risk_score INT, -- Only recommend if risk >= this
max_risk_score INT,
-- Resources required
time_required_minutes INT,
cost_estimate DECIMAL(10,2),
requires_approval BIT DEFAULT 0,
-- Timing
min_lead_time_days INT, -- Minimum notice needed
optimal_lead_time_days INT,
-- Personalization
personalization_params NVARCHAR(MAX), -- JSON: parameters to customize
-- Effectiveness (updated from outcomes)
times_used INT DEFAULT 0,
times_successful INT DEFAULT 0,
success_rate DECIMAL(5,2),
avg_outcome_improvement DECIMAL(5,2),
-- Status
active BIT DEFAULT 1,
created_date DATETIME2 DEFAULT GETDATE()
);
-- Track intervention recommendations
CREATE TABLE intervention_recommendations (
recommendation_id INT PRIMARY KEY IDENTITY(1,1),
family_id INT NOT NULL,
-- Context
risk_assessment_id INT,
prediction_id INT,
recommendation_date DATETIME2 DEFAULT GETDATE(),
-- Primary recommendation
primary_intervention_id INT,
personalized_description NVARCHAR(MAX),
rationale NVARCHAR(MAX),
expected_effectiveness DECIMAL(5,2),
-- Alternatives
alternative_interventions NVARCHAR(MAX), -- JSON array
-- Execution
status VARCHAR(50) DEFAULT 'pending', -- 'pending', 'approved', 'executed', 'declined'
assigned_to VARCHAR(100),
due_date DATE,
executed_date DATETIME2,
-- Outcome
outcome VARCHAR(50), -- 'successful', 'partial', 'unsuccessful', 'not_executed'
outcome_notes NVARCHAR(MAX),
outcome_date DATETIME2,
CONSTRAINT FK_rec_family FOREIGN KEY (family_id)
REFERENCES families(family_id),
CONSTRAINT FK_rec_intervention FOREIGN KEY (primary_intervention_id)
REFERENCES interventions(intervention_id)
);
-- Track intervention effectiveness by context
CREATE TABLE intervention_effectiveness (
effectiveness_id INT PRIMARY KEY IDENTITY(1,1),
intervention_id INT NOT NULL,
-- Context
risk_type VARCHAR(50),
risk_level VARCHAR(20), -- 'low', 'medium', 'high'
confidence_level VARCHAR(20),
time_window_days INT,
-- Outcomes in this context
times_used INT,
times_successful INT,
success_rate DECIMAL(5,2),
avg_risk_reduction DECIMAL(5,2),
-- Period
period_start DATE,
period_end DATE,
last_updated DATETIME2 DEFAULT GETDATE(),
CONSTRAINT FK_eff_intervention FOREIGN KEY (intervention_id)
REFERENCES interventions(intervention_id)
);
Implementation
Recommendation Engine
class InterventionRecommendationEngine {
constructor(db) {
this.db = db;
}
async recommendForFamily(familyId) {
// Step 1: Get complete situation analysis
const situation = await this.analyzeSituation(familyId);
// Step 2: Get all applicable interventions
const candidateInterventions = await this.getCandidateInterventions(situation);
// Step 3: Score each intervention
const scoredInterventions = await Promise.all(
candidateInterventions.map(intervention =>
this.scoreIntervention(intervention, situation)
)
);
// Step 4: Rank by score
scoredInterventions.sort((a, b) => b.total_score - a.total_score);
// Step 5: Select primary + alternatives
const primary = scoredInterventions[0];
const alternatives = scoredInterventions.slice(1, 4);
// Step 6: Personalize
const personalized = await this.personalizeIntervention(primary, situation);
// Step 7: Generate explanation
const rationale = this.generateRationale(personalized, situation);
// Step 8: Save recommendation
await this.saveRecommendation(familyId, {
primary: personalized,
alternatives: alternatives,
rationale: rationale,
situation: situation
});
return {
primary_recommendation: personalized,
alternatives: alternatives,
rationale: rationale,
confidence: situation.confidence,
urgency: this.determineUrgency(situation)
};
}
async analyzeSituation(familyId) {
// Gather all relevant context
// Risk assessment
const risks = await this.db.query(`
SELECT * FROM risk_assessments WHERE family_id = ?
`, [familyId]);
// Predictions
const predictions = await this.db.query(`
SELECT * FROM ml_predictions
WHERE family_id = ?
ORDER BY prediction_date DESC LIMIT 1
`, [familyId]);
// Engagement metrics
const metrics = await this.db.query(`
SELECT * FROM family_engagement_metrics WHERE family_id = ?
`, [familyId]);
// Family details
const family = await this.db.query(`
SELECT * FROM families WHERE family_id = ?
`, [familyId]);
// Past interventions
const pastInterventions = await this.db.query(`
SELECT
i.intervention_type,
ir.outcome,
ir.executed_date
FROM intervention_recommendations ir
JOIN interventions i ON ir.primary_intervention_id = i.intervention_id
WHERE ir.family_id = ?
AND ir.executed_date IS NOT NULL
ORDER BY ir.executed_date DESC
`, [familyId]);
return {
family_id: familyId,
family_name: family[0]?.family_name,
// Risk profile
withdrawal_risk: risks[0]?.withdrawal_risk || 50,
payment_risk: risks[0]?.payment_risk || 50,
academic_risk: risks[0]?.academic_risk || 50,
highest_risk_dimension: risks[0]?.highest_risk_dimension,
// Prediction
predicted_outcome: predictions[0]?.predicted_class,
prediction_probability: predictions[0]?.predicted_probability,
confidence: predictions[0]?.confidence_score,
time_window_days: predictions[0]?.prediction_window_days || 30,
// Engagement
engagement_score: metrics[0]?.engagement_score,
engagement_velocity: metrics[0]?.score_velocity,
// History
past_interventions: pastInterventions,
communication_preferences: family[0]?.preferred_contact_method
};
}
async getCandidateInterventions(situation) {
// Find interventions applicable to this situation
const highestRisk = Math.max(
situation.withdrawal_risk,
situation.payment_risk,
situation.academic_risk
);
return await this.db.query(`
SELECT *
FROM interventions
WHERE active = 1
AND min_risk_score <= ?
AND max_risk_score >= ?
AND min_lead_time_days <= ?
AND (
JSON_CONTAINS(applicable_risks, ?)
OR applicable_risks IS NULL
)
`, [
highestRisk,
highestRisk,
situation.time_window_days,
JSON.stringify(situation.highest_risk_dimension)
]);
}
async scoreIntervention(intervention, situation) {
// Score intervention suitability for this situation
// 1. Effectiveness score (historical success rate)
const effectiveness = await this.getEffectivenessScore(intervention, situation);
// 2. Feasibility score (can we actually do this?)
const feasibility = await this.getFeasibilityScore(intervention, situation);
// 3. Personalization fit (matches family preferences?)
const personalizationFit = await this.getPersonalizationScore(intervention, situation);
// 4. Novelty bonus (haven't tried this before)
const novelty = await this.getNoveltyScore(intervention, situation);
// Weighted combination
const totalScore =
(effectiveness * 0.50) +
(feasibility * 0.25) +
(personalizationFit * 0.20) +
(novelty * 0.05);
return {
...intervention,
effectiveness_score: effectiveness,
feasibility_score: feasibility,
personalization_score: personalizationFit,
novelty_score: novelty,
total_score: totalScore
};
}
async getEffectivenessScore(intervention, situation) {
// Historical success rate in similar situations
const effectiveness = await this.db.query(`
SELECT
success_rate,
avg_risk_reduction,
times_used
FROM intervention_effectiveness
WHERE intervention_id = ?
AND risk_type = ?
AND risk_level = ?
AND confidence_level = ?
`, [
intervention.intervention_id,
situation.highest_risk_dimension,
this.categor izeRiskLevel(situation[`${situation.highest_risk_dimension}_risk`]),
this.categorizeConfidenceLevel(situation.confidence)
]);
if (effectiveness.length === 0 || effectiveness[0].times_used < 5) {
// Not enough data, use intervention's overall success rate
return intervention.success_rate || 50;
}
return effectiveness[0].success_rate;
}
async getFeasibilityScore(intervention, situation) {
let score = 100;
// Check lead time
if (intervention.min_lead_time_days > situation.time_window_days) {
score -= 50; // Not enough time
}
// Check if requires approval and urgency
if (intervention.requires_approval && situation.withdrawal_risk > 80) {
score -= 20; // Approval delays urgent action
}
// Check resource availability (simplified - would query actual availability)
const timeAvailable = await this.getCoordinatorAvailableTime();
if (intervention.time_required_minutes > timeAvailable) {
score -= 30; // Coordinator doesn't have time
}
return Math.max(0, score);
}
async getPersonalizationScore(intervention, situation) {
let score = 50; // Base score
// Check communication preference
const commPreference = situation.communication_preferences;
if (intervention.intervention_type === 'communication') {
const interventionChannel = intervention.intervention_name.toLowerCase();
if (interventionChannel.includes(commPreference)) {
score += 30; // Matches preference
}
}
// Check past success with this family
const pastSuccess = situation.past_interventions.find(pi =>
pi.intervention_type === intervention.intervention_type &&
pi.outcome === 'successful'
);
if (pastSuccess) {
score += 20; // Worked before
}
return Math.min(100, score);
}
async getNoveltyScore(intervention, situation) {
// Bonus for trying something new (exploration)
const previouslyUsed = situation.past_interventions.some(pi =>
pi.intervention_type === intervention.intervention_type
);
return previouslyUsed ? 0 : 15; // 15 point bonus for novel approaches
}
async personalizeIntervention(intervention, situation) {
// Customize intervention for this specific family
let personalized = {
...intervention,
family_id: situation.family_id,
family_name: situation.family_name
};
// Parse personalization parameters
const params = JSON.parse(intervention.personalization_params || '{}');
// Apply personalizations
if (params.mention_concerns && situation.withdrawal_risk > 70) {
personalized.notes = `Family showing signs of withdrawal risk. Key concerns to address.`;
}
if (params.financial_offer && situation.payment_risk > 70) {
personalized.offer_payment_plan = true;
personalized.notes = (personalized.notes || '') + ` Consider offering flexible payment options.`;
}
if (params.mentor_connection && situation.disengagement_risk > 60) {
// Find potential mentor
const mentor = await this.findMentorMatch(situation.family_id);
if (mentor) {
personalized.suggested_mentor = mentor.family_name;
personalized.notes = (personalized.notes || '') + ` Connect with ${mentor.family_name} who has similar interests.`;
}
}
return personalized;
}
generateRationale(intervention, situation) {
const reasons = [];
// Primary risk driver
reasons.push(`Primary concern: ${situation.highest_risk_dimension} risk at ${situation[`${situation.highest_risk_dimension}_risk`].toFixed(0)}%`);
// Prediction
if (situation.prediction_probability > 0.7) {
reasons.push(`Model predicts ${(situation.prediction_probability * 100).toFixed(0)}% likelihood of ${situation.predicted_outcome} in next ${situation.time_window_days} days`);
}
// Historical effectiveness
if (intervention.effectiveness_score > 70) {
reasons.push(`This approach has ${intervention.effectiveness_score.toFixed(0)}% success rate in similar situations`);
}
// Timing
if (situation.time_window_days < 21) {
reasons.push(`Urgent: only ${situation.time_window_days} days to intervene`);
}
// Personalization
if (intervention.personalization_score > 70) {
reasons.push(`Approach aligns well with family's communication preferences and history`);
}
return reasons.join('. ');
}
determineUrgency(situation) {
const maxRisk = Math.max(
situation.withdrawal_risk,
situation.payment_risk,
situation.academic_risk
);
if (maxRisk > 85 || situation.time_window_days < 14) return 'critical';
if (maxRisk > 70 || situation.time_window_days < 30) return 'high';
if (maxRisk > 55) return 'medium';
return 'low';
}
categorizeRiskLevel(risk) {
if (risk > 75) return 'high';
if (risk > 50) return 'medium';
return 'low';
}
categorizeConfidenceLevel(confidence) {
if (confidence > 80) return 'high';
if (confidence > 50) return 'medium';
return 'low';
}
async getCoordinatorAvailableTime() {
// Simplified - would query actual schedule
return 120; // 120 minutes available this week
}
async findMentorMatch(familyId) {
// Pattern 2 (Behavioral Graph) logic to find mentor
const potential = await this.db.query(`
SELECT f.family_id, f.family_name
FROM families f
JOIN family_engagement_metrics fem ON f.family_id = fem.family_id
WHERE fem.engagement_score > 85
AND f.family_id != ?
ORDER BY fem.engagement_score DESC
LIMIT 1
`, [familyId]);
return potential[0] || null;
}
async saveRecommendation(familyId, recommendation) {
const result = await this.db.query(`
INSERT INTO intervention_recommendations (
family_id,
primary_intervention_id,
personalized_description,
rationale,
expected_effectiveness,
alternative_interventions,
status
) VALUES (?, ?, ?, ?, ?, ?, 'pending')
RETURNING recommendation_id
`, [
familyId,
recommendation.primary.intervention_id,
JSON.stringify(recommendation.primary),
recommendation.rationale,
recommendation.primary.effectiveness_score,
JSON.stringify(recommendation.alternatives)
]);
return result[0].recommendation_id;
}
}
module.exports = InterventionRecommendationEngine;
Usage Example
const engine = new InterventionRecommendationEngine(db);
const recommendation = await engine.recommendForFamily(187);
console.log(`
=== INTERVENTION RECOMMENDATION FOR FAMILY 187 ===
URGENCY: ${recommendation.urgency.toUpperCase()}
CONFIDENCE: ${recommendation.confidence}/100
PRIMARY RECOMMENDATION:
Intervention: ${recommendation.primary_recommendation.intervention_name}
Type: ${recommendation.primary_recommendation.intervention_type}
Description: ${recommendation.primary_recommendation.description}
Personalized Notes:
${recommendation.primary_recommendation.notes}
Expected Effectiveness: ${recommendation.primary_recommendation.effectiveness_score}%
Time Required: ${recommendation.primary_recommendation.time_required_minutes} minutes
Optimal Timing: ${recommendation.primary_recommendation.optimal_lead_time_days} days
RATIONALE:
${recommendation.rationale}
ALTERNATIVE APPROACHES:
`);
recommendation.alternatives.forEach((alt, i) => {
console.log(` ${i+1}. ${alt.intervention_name} (${alt.total_score.toFixed(1)}% score)`);
});
// Example output:
// === INTERVENTION RECOMMENDATION FOR FAMILY 187 ===
//
// URGENCY: HIGH
// CONFIDENCE: 82/100
//
// PRIMARY RECOMMENDATION:
// Intervention: Personal Phone Call with Concern Assessment
// Type: communication
// Description: Direct phone call to discuss family's experience and identify concerns
//
// Personalized Notes:
// Family showing signs of withdrawal risk. Key concerns to address. Consider offering flexible payment options.
//
// Expected Effectiveness: 78%
// Time Required: 30 minutes
// Optimal Timing: 7-14 days
//
// RATIONALE:
// Primary concern: withdrawal risk at 87%. Model predicts 89% likelihood of withdrew in next 32 days. This approach has 78% success rate in similar situations. Urgent: only 32 days to intervene.
//
// ALTERNATIVE APPROACHES:
// 1. Financial Assistance Program Discussion (84.2% score)
// 2. Mentor Connection (Chen Family) (79.8% score)
// 3. Enhanced Engagement Campaign (72.1% score)
Variations
By Intervention Philosophy
Reactive: - Wait for problems to manifest - Respond when alerted - Lower false positive tolerance
Proactive: - Intervene on predictions - Act before problems visible - Higher false positive tolerance
Preventive: - Universal programs for all - Build resilience upfront - No targeting required
By Automation Level
Fully Manual: - System recommends, human decides and executes all - Maximum oversight, slowest
Semi-Automated: - System recommends, human approves, system executes - Balanced approach
Fully Automated: - System recommends and executes automatically - Fastest, requires high confidence
By Personalization Depth
Generic: - Same intervention for all in tier - Fast, simple, scalable
Segmented: - Different approach per segment - Balance of personalization and scale
Individual: - Completely customized per family - Maximum effectiveness, slow
Consequences
Benefits
1. Consistency All coordinators get same recommendation for same situation.
2. Learning optimization Track what works, improve recommendations over time.
3. Resource efficiency Recommend interventions with best ROI.
4. Personalization at scale Customize approach for each family automatically.
5. Rationale transparency Users understand WHY recommendation made.
6. Alternative options Not locked into single approach.
7. Continuous improvement Outcomes feed back to improve future recommendations.
Costs
1. Development complexity Sophisticated system to build and maintain.
2. Data requirements Need historical intervention outcomes.
3. Cold start problem New interventions have no effectiveness data.
4. Override tracking Must track when humans ignore recommendations (and why).
5. Staleness risk Recommendations only as good as latest data.
6. Explanation burden Must justify recommendations to users.
Sample Code
Track intervention outcomes:
async function recordInterventionOutcome(recommendationId, outcome, notes) {
await db.query(`
UPDATE intervention_recommendations
SET
status = 'executed',
outcome = ?,
outcome_notes = ?,
outcome_date = NOW()
WHERE recommendation_id = ?
`, [outcome, notes, recommendationId]);
// Update intervention effectiveness statistics
const rec = await db.query(`
SELECT primary_intervention_id, family_id
FROM intervention_recommendations
WHERE recommendation_id = ?
`, [recommendationId]);
await db.query(`
UPDATE interventions
SET
times_used = times_used + 1,
times_successful = times_successful + (CASE WHEN ? = 'successful' THEN 1 ELSE 0 END),
success_rate = (times_successful * 100.0) / times_used
WHERE intervention_id = ?
`, [outcome, rec[0].primary_intervention_id]);
}
Known Uses
Homeschool Co-Op Intelligence Platform - 8 intervention types defined - Recommendations for 100% of at-risk families - 73% of recommendations accepted by coordinators - Improved intervention success rate from 54% to 71%
Healthcare Clinical Decision Support - Recommend treatments based on patient profile - FDA-cleared systems for specific conditions - Improves outcomes and reduces costs
SaaS Customer Success - Gainsight, ChurnZero recommend interventions - Based on health scores and engagement - Automated playbooks for common scenarios
Financial Services - Credit counseling recommendations - Debt management plans - Personalized based on situation
Related Patterns
Requires: - Pattern 11: Historical Pattern Matching - similar cases guide recommendations - Pattern 12: Risk Stratification Models - predictions drive recommendations - Pattern 13: Confidence Scoring - confidence affects automation level - Pattern 14: Predictive Time Windows - timing affects intervention choice
Enables: - Pattern 22: Progressive Escalation Sequences - recommendations sequenced - Pattern 23: Triggered Interventions - automated execution - Pattern 26: Feedback Loop Implementation - outcomes improve recommendations
Complementary: - Pattern 24: Template-Based Communication - execute recommendations - Pattern 25: Multi-Channel Orchestration - coordinate across channels
References
Academic Foundations
- Kahneman, Daniel, Dan Lovallo, and Olivier Sibony (2011). "Before You Make That Big Decision." Harvard Business Review. https://hbr.org/2011/06/the-big-idea-before-you-make-that-big-decision - Decision support systems
- Provost, Foster, and Tom Fawcett (2013). Data Science for Business. O'Reilly. ISBN: 978-1449361327 - Chapter on prescriptive analytics
- Davenport, Thomas H. (2013). Analytics at Work. Harvard Business Review Press. ISBN: 978-1422177693
- Shortliffe, Edward H., and Bruce G. Buchanan (1975). "A Model of Inexact Reasoning in Medicine." Mathematical Biosciences 23(3-4): 351-379. - MYCIN clinical decision support
Clinical Decision Support
- CDSS Best Practices: Osheroff, J.A., et al. (2012). Improving Outcomes with Clinical Decision Support: An Implementer's Guide (2nd ed.). HIMSS. ISBN: 978-1938904004
- HL7 Clinical Decision Support: https://www.hl7.org/fhir/clinicalreasoning-cds-on-fhir.html - FHIR implementation
- Epic CDS Tools: https://www.epic.com/software - Real-world healthcare implementation
Recommendation Systems
- Netflix Recommendation System: Gomez-Uribe, C.A., & Hunt, N. (2016). "The Netflix Recommender System." ACM TIST 6(4). https://dl.acm.org/doi/10.1145/2843948
- Amazon Recommendations: Linden, G., Smith, B., & York, J. (2003). "Amazon.com Recommendations: Item-to-Item Collaborative Filtering." IEEE Internet Computing 7(1): 76-80.
- Ricci, F., Rokach, L., & Shapira, B. (2015). Recommender Systems Handbook (2nd ed.). Springer. ISBN: 978-1489976369
Practical Implementation
- Scikit-learn Classification: https://scikit-learn.org/stable/supervised_learning.html - Build recommendation models
- LightFM: https://github.com/lyst/lightfm - Hybrid recommendation algorithm
- Surprise: http://surpriselib.com/ - Python library for recommender systems
- TensorFlow Recommenders: https://www.tensorflow.org/recommenders - Deep learning recommendations
Related Trilogy Patterns
- Pattern 11: Historical Pattern Matching - Past patterns inform recommendations
- Pattern 12: Risk Stratification Models - Risk level determines intervention
- Pattern 13: Confidence Scoring - Only recommend with sufficient confidence
- Pattern 23: Triggered Interventions - Recommendations trigger actions
- Volume 3, Pattern 5: Error as Collaboration - Interventions as supportive guidance
Tools & Services
- Google Cloud Recommendations AI: https://cloud.google.com/recommendations - Managed recommendation service
- AWS Personalize: https://aws.amazon.com/personalize/ - ML-powered recommendations
- Azure Personalizer: https://azure.microsoft.com/en-us/services/cognitive-services/personalizer/ - Reinforcement learning recommendations
- Recombee: https://www.recombee.com/ - Real-time recommendation platform