Inspiration

Postpartum mood disorders affect roughly 1 in 5 new mothers, yet the people closest to them, their partners, are often left without guidance on what to look for or how to help. Most maternal health tools focus on the mother alone, but recovery doesn't happen in isolation. We asked ourselves: what if we could turn partners from worried bystanders into informed, confident caregivers?

We have seen how early intervention transforms outcomes and how often it's delayed simply because the support system didn't know what to watch for. Beside Her was born from that gap.

What it does

Beside Her is a postpartum mental health support platform with two user roles:

  • Mothers complete daily check-ins rating their mood, anxiety, energy, and sleep on simple scales, with optional written notes. The web app integrates VitalLens for contactless vital sign capture (heart rate and blood pressure) via the device camera. A mobile version (React Native / Expo Go) is also in development to eventually support the Presage SmartSpectra SDK for expanded biometric monitoring including HRV and breathing rate (integration still in progress).

  • Partners receive a personalized dashboard powered by ML analysis, showing trend visualizations, escalation levels, and AI-generated daily guidance with concrete action items (2-minute, 15-minute, and 60-minute suggestions). When escalation reaches critical levels, a crisis resource card surfaces automatically.

The system links mothers and partners through a unique partner code, so data flows securely between accounts.

How we built it

Architecture

The application is a Flask backend connected to a Supabase PostgreSQL database, with an HTML/CSS/JavaScript frontend using Chart.js for visualizations. For the mobile version, we converted to React Native (Expo) with native Android modules to integrate the Presage SmartSpectra SDK.

ML Pipeline — ml_analysis.py

Our custom ML analysis module runs seven analytical techniques on the mother's check-in data:

  1. Weighted Severity Scoring - Computes a composite 0–10 risk index. Given average check-in values for mood ($\bar{m}$), anxiety ($\bar{a}$), energy ($\bar{e}$), and sleep ($\bar{s}$), the base score is:

$$\text{base} = (5 - \bar{m}) \times 1.2 + \bar{a} \times 0.8 + (5 - \bar{e}) \times 0.5 + (5 - \bar{s}) \times 0.3$$

Mood and anxiety are weighted highest as primary PPD indicators per the Edinburgh Postnatal Depression Scale (EPDS). The score is then normalized to a 0–10 scale:

$$S = \frac{\text{base}}{\text{max_possible}} \times 10, \quad \text{where } \text{max_possible} = (4 \times 1.2) + (5 \times 0.8) + (4 \times 0.5) + (4 \times 0.3) = 12.0$$

Trend and anomaly penalties are then added: $+1.0$ if mood is worsening, $+0.5$ if anxiety is worsening, and $+0.3$ per anomaly day detected. The final score is capped at 10.

  1. Trend Detection - Fits scikit-learn LinearRegression on mood, anxiety, and energy over time, using actual date distances (not sequential indices) so time gaps are respected. For each feature, the model computes a per-day slope $\beta$, and classifies the trend:

$$\beta < -0.01 \implies \text{worsening}, \quad |\beta| \leq 0.01 \implies \text{stable}, \quad \beta > 0.01 \implies \text{improving}$$

This only runs when 7+ check-ins are available (gated by the confidence system). If mood is classified as worsening, a declining_mood_flag is raised and fed into the severity score.

  1. Anomaly Detection - Applies z-score analysis on mood scores, comparing each day to the mother's personal baseline:

$$z_i = \frac{m_i - \bar{m}}{\sigma_m}$$

Days where $z_i \leq -2.0$ (i.e., mood is 2+ standard deviations below her personal mean) are flagged as anomaly days. The system also performs masking detection - if mood z-scores look normal ($z > -1.0$) but vitals from VitalLens show elevated heart rate ($> 100$ bpm) or low HRV ($< 30$ ms), a masking flag is raised, catching cases where a mother may be underreporting distress.

  1. KMeans Clustering - Groups days into 3 natural clusters based on a composite score of $(m_i - a_i)$ (mood minus anxiety) per day. Cluster centers are sorted and labeled as good, moderate, or hard days. The dominant cluster determines a weekly summary (e.g., "This was predominantly a Hard week"). Requires 7+ entries.

  2. Rule-Based Safety Flags - Deterministic clinical rules based on PPD diagnostic criteria, requiring no ML. Flags include: persistent_low_mood (3+ consecutive days with mood $\leq 2$), high_anxiety (3+ days with anxiety $\geq 4$), sleep_disruption (3+ days with sleep $\leq 2$), high_risk_combination (mood avg $\leq 2.5$ AND anxiety avg $\geq 3.5$ simultaneously), and silence_alert (last check-in more than 2 days ago). A crisis language detector scans notes for keywords like "hopeless" or "can't go on" and triggers an immediate crisis override to escalation level red.

  3. Postpartum Phase Detection - Calculates weeks since birth and adjusts all interpretations accordingly. Three phases are defined with escalation modifiers:

| Phase | Weeks Postpartum | Escalation Modifier | Guidance Tone |

| Baby Blues | $\leq 2$ | $+0$ | Reassurance | | Watch Closely | $3 – 8$ | $+1$ | Gentle flag | | PPD Risk | $> 8$ | $+2$ | Action-oriented |

The escalation modifier is added directly to the severity score before determining the final escalation level, ensuring the same symptoms trigger stronger responses as time progresses.

  1. Confidence Scoring - Gates the entire analysis based on data sufficiency. With fewer than 3 check-ins, the system flags low confidence and avoids premature conclusions.

Escalation Ladder

All seven signals feed into an escalation level determined by the adjusted severity score (base score + phase modifier) and flag count:

| Level | Condition |

| Red | Crisis override detected, OR score $\geq 10$, OR $\geq 4$ flags | | Orange | Score $\geq 7$, OR $\geq 2$ flags | | Yellow | Score $\geq 5$, OR $\geq 1$ flag | | Green | Otherwise |

The escalation level determines the urgency and tone of the AI-generated partner guidance.

AI Integration

We use the Google Gemini API to generate personalized, context-aware guidance for partners. The ML analysis output (severity, trends, anomalies, phase) is structured into a prompt that produces specific, actionable advice, not generic platitudes.

VitalLens Integration (Web App)

The web application integrates VitalLens to enable contactless vital sign measurement, heart rate and blood pressure, directly through the device camera. These vitals are stored alongside self-reported check-ins and fed into the ML pipeline's masking detection system: if a mother reports normal mood but her vitals show elevated heart rate ($> 100$ bpm) or low HRV ($< 30$ ms), the system flags a potential discrepancy, catching cases where distress may be underreported.

Mobile App & Biometric Scanning

We also began converting the web application into a React Native (Expo) mobile app to unlock native device capabilities. The mobile version is currently running in Expo Go and replicates the core check-in and dashboard flows. However, integrating the Presage SmartSpectra SDK for contactless vital sign monitoring (heart rate, HRV, breathing rate via facial video analysis) has not been fully completed bridging to the native camera through custom React Native modules (SmartSpectraModule.ktSmartSpectraActivity.kt) proved more complex than anticipated within the hackathon timeline, and this remains a work-in-progress.

Challenges we ran into

  • Presage SmartSpectra SDK integration - Bridging the native Presage SDK into React Native required custom Kotlin modules and Gradle configuration. Dependency resolution issues (local project vs. Maven references) and HTTPS requirements for camera access meant the biometric scanning feature couldn't be fully completed within the hackathon window, though the mobile app itself runs in Expo Go.

  • Threshold tuning for trend detection - Our initial approach used sequential indices for regression, which ignored time gaps between check-ins. Switching to actual date distances and per-day slope thresholds ($-0.01$ for worsening) gave more clinically meaningful trend classification.

  • Data normalization mismatches - The ML analysis pipeline outputted data in a different structure than the frontend expected, requiring careful mapping between the two layers.

  • API quota limits - Gemini API rate limits during rapid testing forced us to implement caching and fallback responses.

  • Balancing clinical accuracy with hackathon scope - We wanted every feature to be clinically meaningful, not just technically impressive. This meant cutting features like voice input to focus on getting the severity scoring, phase detection, and escalation logic right.

Accomplishments that we're proud of

We built a fully functional full-stack application in 24 hours — a Flask backend, Supabase PostgreSQL database, complete authentication system with partner-code linking, and a polished frontend with Chart.js visualizations — all within hackathon time constraints.

We implemented 7 real ML techniques from scratch, not just API wrappers. Weighted severity scoring, LinearRegression trend detection, $z$-score anomaly detection, KMeans clustering, rule-based safety flags, postpartum phase detection, and a confidence gating system — all written in Python with NumPy and scikit-learn. This wasn't a chatbot with a skin; the ML layer does real analytical work.

What we learned

  • ML in healthcare requires interpretability. It's not enough to compute a severity score, partners need to understand why the system is concerned. We invested heavily in making flags human-readable.

  • Postpartum context changes everything. A static model that treats week 1 and week 10 the same is clinically irresponsible. Phase-aware analysis was one of our most important design decisions.

  • Sentiment analysis catches what numbers miss. A mother might rate her mood as "fine" while her written notes reveal deep distress. Keyword-based crisis detection on free-text notes was a simple addition with outsized impact. Similarly, our masking detection, cross-referencing self-reported mood with VitalLens vitals, catches physiological stress that self-reports may miss.

  • The best tech is invisible to the user. Partners don't need to know about z-scores or KMeans - they need to know what to do. We learned to translate complex ML outputs into plain-language, actionable guidance.

What's next for BesideHER

Complete the React Native mobile app and Presage SmartSpectra integration. The mobile version is running in Expo Go, but fully bridging the Presage SDK for contactless heart rate, HRV, and breathing rate capture is our top priority. A native mobile experience with biometric scanning would make daily check-ins feel effortless, just open the app, look at the camera, and you're done.

Introduce a therapist/provider dashboard. Partners are the first line of support, but they're not professionals. A read-only dashboard for an opted-in therapist or OB-GYN - showing escalation history, trend summaries, and flagged anomalies, could bridge the gap between at-home monitoring and clinical care.

Share this project:

Updates