← All Use Cases
🐾
Box-Behnken Design

Tropical Fish Tank Health

Box-Behnken design to maximize fish vitality and minimize algae by tuning water change frequency, feeding amount, and light duration

Summary

This experiment investigates tropical fish tank health. Box-Behnken design to maximize fish vitality and minimize algae by tuning water change frequency, feeding amount, and light duration.

The design varies 3 factors: water change pct (%/week), ranging from 10 to 40, feed g day (g/day), ranging from 0.5 to 3.0, and light hrs (hrs), ranging from 6 to 12. The goal is to optimize 2 responses: vitality score (pts) (maximize) and algae level (pts) (minimize). Fixed conditions held constant across all runs include tank L = 200, fish count = 20.

A Box-Behnken design was chosen because it efficiently fits quadratic models with 3 continuous factors while avoiding extreme corner combinations — requiring only 15 runs instead of the 8 needed for a full factorial at two levels.

Quadratic response surface models were fitted to capture potential curvature and factor interactions. The RSM contour plots below visualize how pairs of factors jointly affect each response.

Key Findings

For vitality score, the most influential factors were feed g day (56.7%), water change pct (34.3%), light hrs (9.0%). The best observed value was 7.8 (at water change pct = 40, feed g day = 3, light hrs = 9).

For algae level, the most influential factors were feed g day (67.5%), water change pct (17.9%), light hrs (14.6%). The best observed value was 2.1 (at water change pct = 40, feed g day = 1.75, light hrs = 6).

Recommended Next Steps

Experimental Setup

Factors

FactorLowHighUnit
water_change_pct1040%/week
feed_g_day0.53.0g/day
light_hrs612hrs

Fixed: tank_L = 200, fish_count = 20

Responses

ResponseDirectionUnit
vitality_score↑ maximizepts
algae_level↓ minimizepts

Configuration

use_cases/170_fish_tank_health/config.json
{ "metadata": { "name": "Tropical Fish Tank Health", "description": "Box-Behnken design to maximize fish vitality and minimize algae by tuning water change frequency, feeding amount, and light duration" }, "factors": [ { "name": "water_change_pct", "levels": [ "10", "40" ], "type": "continuous", "unit": "%/week" }, { "name": "feed_g_day", "levels": [ "0.5", "3.0" ], "type": "continuous", "unit": "g/day" }, { "name": "light_hrs", "levels": [ "6", "12" ], "type": "continuous", "unit": "hrs" } ], "fixed_factors": { "tank_L": "200", "fish_count": "20" }, "responses": [ { "name": "vitality_score", "optimize": "maximize", "unit": "pts" }, { "name": "algae_level", "optimize": "minimize", "unit": "pts" } ], "settings": { "operation": "box_behnken", "test_script": "use_cases/170_fish_tank_health/sim.sh" } }

Experimental Matrix

The Box-Behnken Design produces 15 runs. Each row is one experiment with specific factor settings.

Runwater_change_pctfeed_g_daylight_hrs
1250.56
2251.759
3401.7512
4401.756
5251.759
6251.759
7101.7512
8400.59
9250.512
104039
11101.756
1225312
13100.59
141039
152536

Step-by-Step Workflow

1

Preview the design

Terminal
$ doe info --config use_cases/170_fish_tank_health/config.json
2

Generate the runner script

Terminal
$ doe generate --config use_cases/170_fish_tank_health/config.json \ --output use_cases/170_fish_tank_health/results/run.sh --seed 42
3

Execute the experiments

Terminal
$ bash use_cases/170_fish_tank_health/results/run.sh
4

Analyze results

Terminal
$ doe analyze --config use_cases/170_fish_tank_health/config.json
5

Get optimization recommendations

Terminal
$ doe optimize --config use_cases/170_fish_tank_health/config.json
6

Multi-objective optimization

With 2 competing responses, use --multi to find the best compromise via Derringer–Suich desirability.

Terminal
$ doe optimize --config use_cases/170_fish_tank_health/config.json --multi
7

Generate the HTML report

Terminal
$ doe report --config use_cases/170_fish_tank_health/config.json \ --output use_cases/170_fish_tank_health/results/report.html

Features Exercised

FeatureValue
Design typebox_behnken
Factor typescontinuous (all 3)
Arg styledouble-dash
Responses2 (vitality_score ↑, algae_level ↓)
Total runs15

Analysis Results

Generated from actual experiment runs using the DOE Helper Tool.

Response: vitality_score

Top factors: feed_g_day (56.7%), water_change_pct (34.3%), light_hrs (9.0%).

ANOVA

SourceDFSSMSFp-value
SourceDFSSMSFp-value
water_change_pct20.84300.42156.0220.0254
feed_g_day22.38021.190117.0010.0013
light_hrs20.05300.02650.3790.6963
LackofFit67.10101.1835
PureError20.1400
Error87.24100.0700
Total1410.51730.7512

Pareto Chart

Pareto chart for vitality_score

Main Effects Plot

Main effects plot for vitality_score

Normal Probability Plot of Effects

Normal probability plot for vitality_score

Half-Normal Plot of Effects

Half-normal plot for vitality_score

Model Diagnostics

Model diagnostics for vitality_score

Response: algae_level

Top factors: feed_g_day (67.5%), water_change_pct (17.9%), light_hrs (14.6%).

ANOVA

SourceDFSSMSFp-value
SourceDFSSMSFp-value
water_change_pct21.07620.53817.6870.0137
feed_g_day213.34736.673695.3380.0000
light_hrs20.70870.35435.0620.0380
LackofFit611.30121.8835
PureError20.1400
Error811.44120.0700
Total1426.57331.8981

Pareto Chart

Pareto chart for algae_level

Main Effects Plot

Main effects plot for algae_level

Normal Probability Plot of Effects

Normal probability plot for algae_level

Half-Normal Plot of Effects

Half-normal plot for algae_level

Model Diagnostics

Model diagnostics for algae_level

Response Surface Plots

3D surfaces fitted with quadratic RSM. Red dots are observed data points.

algae level feed g day vs light hrs

RSM surface: algae level feed g day vs light hrs

algae level water change pct vs feed g day

RSM surface: algae level water change pct vs feed g day

algae level water change pct vs light hrs

RSM surface: algae level water change pct vs light hrs

vitality score feed g day vs light hrs

RSM surface: vitality score feed g day vs light hrs

vitality score water change pct vs feed g day

RSM surface: vitality score water change pct vs feed g day

vitality score water change pct vs light hrs

RSM surface: vitality score water change pct vs light hrs

Multi-Objective Optimization

When responses compete, Derringer–Suich desirability finds the best compromise. Each response is scaled to a 0–1 desirability, then combined via a weighted geometric mean.

Overall Desirability
D = 0.8196

Per-Response Desirability

ResponseWeightDesirabilityPredictedDir
vitality_score 1.5
0.7038
7.00 0.7038 7.00 pts
algae_level 1.5
0.9545
2.10 0.9545 2.10 pts

Recommended Settings

FactorValue
water_change_pct40 %/week
feed_g_day0.5 g/day
light_hrs9 hrs

Source: from observed run #4

Trade-off Summary

Sacrifice = how much worse than single-objective best.

ResponsePredictedBest ObservedSacrifice
algae_level2.102.10+0.00

Top 3 Runs by Desirability

RunDFactor Settings
#50.7067water_change_pct=40, feed_g_day=1.75, light_hrs=12
#100.6908water_change_pct=25, feed_g_day=1.75, light_hrs=9

Model Quality

ResponseType
algae_level0.0486linear

Full Multi-Objective Output

doe optimize --multi
============================================================ MULTI-OBJECTIVE OPTIMIZATION Method: Derringer-Suich Desirability Function ============================================================ Overall desirability: D = 0.8196 Response Weight Desirability Predicted Direction --------------------------------------------------------------------- vitality_score 1.5 0.7038 7.00 pts ↑ algae_level 1.5 0.9545 2.10 pts ↓ Recommended settings: water_change_pct = 40 %/week feed_g_day = 0.5 g/day light_hrs = 9 hrs (from observed run #4) Trade-off summary: vitality_score: 7.00 (best observed: 7.80, sacrifice: +0.80) algae_level: 2.10 (best observed: 2.10, sacrifice: +0.00) Model quality: vitality_score: R² = 0.8888 (quadratic) algae_level: R² = 0.0486 (linear) Top 3 observed runs by overall desirability: 1. Run #4 (D=0.8196): water_change_pct=40, feed_g_day=0.5, light_hrs=9 2. Run #5 (D=0.7067): water_change_pct=40, feed_g_day=1.75, light_hrs=12 3. Run #10 (D=0.6908): water_change_pct=25, feed_g_day=1.75, light_hrs=9

Full Analysis Output

doe analyze
=== Main Effects: vitality_score === Factor Effect Std Error % Contribution -------------------------------------------------------------- feed_g_day 0.9429 0.2238 56.7% water_change_pct 0.5714 0.2238 34.3% light_hrs 0.1500 0.2238 9.0% === ANOVA Table: vitality_score === Source DF SS MS F p-value ----------------------------------------------------------------------------- water_change_pct 2 0.8430 0.4215 6.022 0.0254 feed_g_day 2 2.3802 1.1901 17.001 0.0013 light_hrs 2 0.0530 0.0265 0.379 0.6963 Lack of Fit 6 7.1010 1.1835 16.907 0.0569 Pure Error 2 0.1400 0.0700 Error 8 7.2410 0.0700 Total 14 10.5173 0.7512 === Summary Statistics: vitality_score === water_change_pct: Level N Mean Std Min Max ------------------------------------------------------------ 10 4 6.6000 0.4899 6.0000 7.0000 25 7 6.8714 0.8883 5.5000 7.7000 40 4 6.3000 1.1860 4.9000 7.8000 feed_g_day: Level N Mean Std Min Max ------------------------------------------------------------ 0.5 4 6.5000 1.1633 4.9000 7.5000 1.75 7 7.0429 0.6754 6.0000 7.8000 3 4 6.1000 0.6683 5.5000 7.0000 light_hrs: Level N Mean Std Min Max ------------------------------------------------------------ 12 4 6.7000 1.1225 5.5000 7.8000 6 4 6.5500 0.6856 5.7000 7.2000 9 7 6.6714 0.9376 4.9000 7.7000 === Main Effects: algae_level === Factor Effect Std Error % Contribution -------------------------------------------------------------- feed_g_day 2.4250 0.3557 67.5% water_change_pct 0.6429 0.3557 17.9% light_hrs 0.5250 0.3557 14.6% === ANOVA Table: algae_level === Source DF SS MS F p-value ----------------------------------------------------------------------------- water_change_pct 2 1.0762 0.5381 7.687 0.0137 feed_g_day 2 13.3473 6.6736 95.338 0.0000 light_hrs 2 0.7087 0.3543 5.062 0.0380 Lack of Fit 6 11.3012 1.8835 26.908 0.0363 Pure Error 2 0.1400 0.0700 Error 8 11.4412 0.0700 Total 14 26.5733 1.8981 === Summary Statistics: algae_level === water_change_pct: Level N Mean Std Min Max ------------------------------------------------------------ 10 4 4.2000 1.6553 2.1000 6.1000 25 7 4.0571 1.5109 2.4000 6.9000 40 4 4.7000 1.0924 4.0000 6.3000 feed_g_day: Level N Mean Std Min Max ------------------------------------------------------------ 0.5 4 5.1750 1.5692 3.7000 6.9000 1.75 7 4.6143 0.7819 4.0000 6.3000 3 4 2.7500 0.8505 2.1000 4.0000 light_hrs: Level N Mean Std Min Max ------------------------------------------------------------ 12 4 4.6250 1.7988 2.5000 6.9000 6 4 4.1000 1.6228 2.4000 6.3000 9 7 4.1571 1.1731 2.1000 6.1000

Optimization Recommendations

doe optimize
=== Optimization: vitality_score === Direction: maximize Best observed run: #10 water_change_pct = 40 feed_g_day = 3 light_hrs = 9 Value: 7.8 RSM Model (linear, R² = 0.3459, Adj R² = 0.1675): Coefficients: intercept +6.6467 water_change_pct +0.6250 feed_g_day -0.2125 light_hrs +0.1375 RSM Model (quadratic, R² = 0.9099, Adj R² = 0.7477): Coefficients: intercept +7.0000 water_change_pct +0.6250 feed_g_day -0.2125 light_hrs +0.1375 water_change_pct*feed_g_day +0.3500 water_change_pct*light_hrs -0.3500 feed_g_day*light_hrs +0.6250 water_change_pct^2 -0.1375 feed_g_day^2 +0.3375 light_hrs^2 -0.8625 Curvature analysis: light_hrs coef=-0.8625 concave (has a maximum) feed_g_day coef=+0.3375 convex (has a minimum) water_change_pct coef=-0.1375 concave (has a maximum) Notable interactions: feed_g_day*light_hrs coef=+0.6250 (synergistic) water_change_pct*feed_g_day coef=+0.3500 (synergistic) water_change_pct*light_hrs coef=-0.3500 (antagonistic) Predicted optimum (from quadratic model, at observed points): water_change_pct = 40 feed_g_day = 3 light_hrs = 9 Predicted value: 7.9625 Surface optimum (via L-BFGS-B, quadratic model): water_change_pct = 40 feed_g_day = 3 light_hrs = 9.71739 Predicted value: 8.0118 Model quality: Excellent fit — surface predictions are reliable. Factor importance: 1. water_change_pct (effect: 1.2, contribution: 43.3%) 2. light_hrs (effect: 1.0, contribution: 35.1%) 3. feed_g_day (effect: 0.6, contribution: 21.5%) === Optimization: algae_level === Direction: minimize Best observed run: #4 water_change_pct = 40 feed_g_day = 1.75 light_hrs = 6 Value: 2.1 RSM Model (linear, R² = 0.0930, Adj R² = -0.1544): Coefficients: intercept +4.2667 water_change_pct +0.2750 feed_g_day -0.1750 light_hrs +0.4500 RSM Model (quadratic, R² = 0.8100, Adj R² = 0.4679): Coefficients: intercept +5.8000 water_change_pct +0.2750 feed_g_day -0.1750 light_hrs +0.4500 water_change_pct*feed_g_day -0.1500 water_change_pct*light_hrs +1.4000 feed_g_day*light_hrs +0.3000 water_change_pct^2 -0.6250 feed_g_day^2 -0.7250 light_hrs^2 -1.5250 Curvature analysis: light_hrs coef=-1.5250 concave (has a maximum) feed_g_day coef=-0.7250 concave (has a maximum) water_change_pct coef=-0.6250 concave (has a maximum) Notable interactions: water_change_pct*light_hrs coef=+1.4000 (synergistic) Predicted optimum (from quadratic model, at observed points): water_change_pct = 25 feed_g_day = 1.75 light_hrs = 9 Predicted value: 5.8000 Surface optimum (via L-BFGS-B, quadratic model): water_change_pct = 40 feed_g_day = 3 light_hrs = 6 Predicted value: 0.7250 Model quality: Good fit — general trends are captured, some noise remains. Factor importance: 1. light_hrs (effect: 1.9, contribution: 55.8%) 2. feed_g_day (effect: 0.7, contribution: 22.2%) 3. water_change_pct (effect: 0.7, contribution: 22.0%)
← Previous: Backyard Chicken Egg Production Next: Dog Training Effectiveness →