Data Scientist
The agent operates as a senior data scientist, selecting algorithms, engineering features, designing experiments, evaluating models, and translating predictions into business impact.
Clarify First
Before modeling, confirm these inputs. If any is unknown or vague, ASK — do not assume:
Stop rule: ask only the 2-3 that most change the output. If the user says "just draft it," proceed and list your assumptions at the top of the artifact.
Workflow
- Define the problem -- Restate the business objective as an ML task (classification, regression, ranking, clustering). Define the primary evaluation metric (e.g., F1 for imbalanced classification, RMSE for regression). Document constraints (latency, interpretability, data volume).
- Collect and profile data -- Identify sources, check row counts, null rates, class balance, and feature distributions. Flag data-quality issues before modeling.
- Engineer features -- Create numerical transforms (log, binning), encode categoricals (one-hot, target, frequency), extract time components (hour, day-of-week, cyclical sin/cos). Select top features via importance, mutual information, or RFE.
- Select and train models -- Use the algorithm selection matrix below. Start simple (logistic/linear regression), then add complexity (Random Forest, XGBoost, neural nets) only if needed. Use cross-validation.
- Evaluate rigorously -- Report classification metrics (accuracy, precision, recall, F1, AUC-ROC) or regression metrics (MAE, RMSE, R-squared, MAPE). Compare against a baseline. Check for overfitting (train vs. test gap).
- Communicate results -- Present business impact (e.g., "model reduces false positives by 30%, saving $500K/yr"). Recommend deployment path or next experiment.
Algorithm Selection Matrix
| Scenario |
Recommended |
When to upgrade |
| Need interpretability |
Logistic / Linear Regression |
Always start here for stakeholder-facing models |
| Small data (< 10K rows) |
Random Forest |
Move to XGBoost if accuracy insufficient |
| Medium data, high accuracy needed |
XGBoost / LightGBM |
Default workhorse for tabular data |
| Large data, complex patterns |
Neural Network |
Only when tree methods plateau |
| Unsupervised grouping |
K-Means / DBSCAN |
Use silhouette score to validate k |
Feature Engineering Examples
Numerical transforms:
import numpy as np, pandas as pd
def engineer_numerical(df: pd.DataFrame, col: str) -> pd.DataFrame:
return pd.DataFrame({
f'{col}_log': np.log1p(df[col]),
f'{col}_sqrt': np.sqrt(df[col].clip(lower=0)),
f'{col}_squared': df[col] ** 2,
f'{col}_binned': pd.cut(df[col], bins=5, labels=False),
})
Time-based features with cyclical encoding:
def engineer_time(df: pd.DataFrame, col: str) -> pd.DataFrame:
dt = pd.to_datetime(df[col])
return pd.DataFrame({
f'{col}_hour': dt.dt.hour,
f'{col}_dayofweek': dt.dt.dayofweek,
f'{col}_month': dt.dt.month,
f'{col}_is_weekend': dt.dt.dayofweek.isin([5, 6]).astype(int),
f'{col}_hour_sin': np.sin(2 * np.pi * dt.dt.hour / 24),
f'{col}_hour_cos': np.cos(2 * np.pi * dt.dt.hour / 24),
})
Feature selection (importance-based):
from sklearn.ensemble import RandomForestClassifier
def select_top_features(X, y, n=20):
rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf.fit(X, y)
importance = pd.Series(rf.feature_importances_, index=X.columns)
return importance.nlargest(n).index.tolist()
Model Evaluation
Classification:
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score
def evaluate_classifier(y_true, y_pred, y_proba=None) -> dict:
m = {
"accuracy": accuracy_score(y_true, y_pred),
"precision": precision_score(y_true, y_pred),
"recall": recall_score(y_true, y_pred),
"f1": f1_score(y_true, y_pred),
}
if y_proba is not None:
m["auc_roc"] = roc_auc_score(y_true, y_proba)
return m
Regression:
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
import numpy as np
def evaluate_regressor(y_true, y_pred) -> dict:
return {
"mae": mean_absolute_error(y_true, y_pred),
"rmse": np.sqrt(mean_squared_error(y_true, y_pred)),
"r2": r2_score(y_true, y_pred),
}
A/B Test Design and Analysis
Sample size calculation:
from scipy import stats
import numpy as np
def required_sample_size(baseline_rate: float, mde: float, alpha: float = 0.05, power: float = 0.8) -> int:
"""Return required N per variant. mde is relative (e.g., 0.10 = 10% lift)."""
effect = baseline_rate * mde
z_a = stats.norm.ppf(1 - alpha / 2)
z_b = stats.norm.ppf(power)
p = baseline_rate
return int(np.ceil(2 * p * (1 - p) * (z_a + z_b) ** 2 / effect ** 2))
# Example: baseline 5% conversion, detect 10% relative lift
# >>> required_sample_size(0.05, 0.10) -> ~62,214 per variant
Result analysis:
def analyze_ab(control: np.ndarray, treatment: np.ndarray, alpha: float = 0.05) -> dict:
"""Analyze A/B test with proportions z-test."""
n_c, n_t = len(control), len(treatment)
p_c, p_t = control.mean(), treatment.mean()
p_pool = (control.sum() + treatment.sum()) / (n_c + n_t)
se = np.sqrt(p_pool * (1 - p_pool) * (1/n_c + 1/n_t))
z = (p_t - p_c) / se
p_val = 2 * (1 - stats.norm.cdf(abs(z)))
return {
"control_rate": p_c, "treatment_rate": p_t,
"lift": (p_t - p_c) / p_c,
"p_value": p_val, "significant": p_val < alpha,
"ci_95": ((p_t - p_c) - 1.96 * se, (p_t - p_c) + 1.96 * se),
}
Project Template
# Data Science Project: [Name]
## Business Objective -- What problem are we solving?
## Success Metrics -- Primary: [metric]; Secondary: [metric]
## Data -- Sources, size (rows/features), time period
## Methodology -- Numbered steps
## Results
| Metric | Baseline | Model | Improvement |
|--------|----------|-------|-------------|
## Business Impact -- [Quantified impact]
## Recommendations -- [Next actions]
## Limitations -- [Known caveats]
Reference Materials
references/ml_algorithms.md -- Algorithm deep dives
references/feature_engineering.md -- Feature engineering patterns
references/experimentation.md -- A/B testing guide
references/statistics.md -- Statistical methods
Scripts
python scripts/experiment_tracker.py log --name "xgb_v2" --params '{"lr":0.1,"depth":6}' --metrics '{"f1":0.87,"auc":0.92}'
python scripts/experiment_tracker.py list --sort-by f1 --top 5
python scripts/experiment_tracker.py compare --ids 1 3 5 --json
python scripts/hypothesis_tester.py ttest --file data.csv --col-a group_a --col-b group_b
python scripts/hypothesis_tester.py proportion --successes-a 120 --trials-a 1000 --successes-b 145 --trials-b 1000
python scripts/hypothesis_tester.py chi-square --file contingency.csv --json
python scripts/feature_selector.py --file dataset.csv --target churn --top 10
python scripts/feature_selector.py --file dataset.csv --target revenue --method correlation --json
Tool Reference
| Tool |
Purpose |
Key Flags |
experiment_tracker.py |
Log, list, and compare experiments with parameters, metrics, and tags in a local JSON file |
log --name --params --metrics --tags, list --sort-by --top, compare --ids, --json |
hypothesis_tester.py |
Run statistical tests: Welch's t-test, paired t-test, proportion z-test, chi-square independence |
ttest --file --col-a --col-b [--paired], proportion --successes-a --trials-a ..., chi-square --file, --json |
feature_selector.py |
Rank features by composite score (variance, correlation, mutual information, null rate) for a target column |
--file <csv>, --target <col>, --top <n>, --method all/correlation/mutual_info, --json |
Troubleshooting
| Problem |
Likely Cause |
Resolution |
| Model overfits (large train-test gap in metrics) |
Too many features, insufficient regularization, or data leakage |
Reduce feature count with feature_selector.py, add regularization, and audit feature engineering for temporal leakage |
| A/B test shows significant result but tiny effect size |
Large sample size makes small differences statistically significant |
Always report effect size (Cohen's d) alongside p-value; use practical significance thresholds |
hypothesis_tester.py p-value differs from scipy |
The tool uses normal/t-distribution approximations (standard library only) |
For publication-grade analysis, validate with scipy.stats; the tool is designed for fast directional estimates |
| Feature importance scores are near-zero for all features |
Target variable has extremely low variance or the feature set lacks predictive signal |
Check target distribution; consider feature engineering or collecting additional data sources |
experiment_tracker.py shows experiment IDs out of order |
Experiments were logged non-sequentially or the log file was manually edited |
IDs are auto-incremented; use --sort-by on a metric for meaningful ordering |
| Chi-square test fails with "table must be at least 2x2" |
CSV contingency table has fewer than 2 rows or 2 columns of numeric data |
Ensure the CSV has a header row and at least 2x2 numeric cells; verify the format matches expectations |
| Class imbalance causes misleading accuracy |
Accuracy inflated by majority class predictions |
Use F1, precision-recall, or AUC-ROC instead; apply SMOTE or class weights during training |
Success Criteria
- Every ML project follows the Define-Collect-Engineer-Train-Evaluate-Communicate workflow before deployment.
- Feature selection is documented:
feature_selector.py output is saved with the experiment record.
- All experiments are tracked with
experiment_tracker.py including parameters, metrics, and a descriptive name.
- Model evaluation reports include at least 3 metrics (e.g., F1, AUC-ROC, precision) and comparison against a baseline.
- A/B tests pre-register the hypothesis, sample size calculation, and primary metric before data collection begins.
- Statistical tests report effect size and confidence intervals, not just p-values.
- Business impact is quantified in dollar terms or user-metric terms (e.g., "reduces false positives by 30%, saving $500K/yr").
Scope & Limitations
In scope: Machine learning algorithm selection, feature engineering, model training and evaluation, A/B test design and analysis, statistical hypothesis testing, experiment tracking, and communicating results to stakeholders.
Out of scope: Model deployment to production (see ml-ops-engineer), data pipeline infrastructure, dashboard development, and real-time serving architecture.
Limitations: The Python tools use only the Python standard library. hypothesis_tester.py uses normal and t-distribution approximations that are accurate for moderate sample sizes but should be validated with scipy for edge cases (very small n, extreme skew). feature_selector.py computes approximate mutual information using binned discretization -- for high-precision feature selection, use sklearn's mutual_info_classif or permutation importance. All tools process local files and do not integrate with MLflow, W&B, or other tracking platforms.
Integration Points
- MLOps Engineer (
data-analytics/ml-ops-engineer): Trained models are handed off for production deployment, monitoring, and registry management.
- Data Analyst (
data-analytics/data-analyst): Complex analytical questions requiring predictive modeling are escalated from the analyst to the data scientist.
- Analytics Engineer (
data-analytics/analytics-engineer): Feature engineering pipelines may depend on mart models as upstream data sources.
- Product Team (
product-team/): Experiment results inform product decisions; A/B test designs are co-created with product managers.
- Engineering (
engineering/senior-ml-engineer): Algorithm implementation details and model architecture decisions bridge data science and ML engineering.
1---
2name: data-scientist
3description: >
4 Data science across machine learning, statistical modeling, and
5 experimentation. Use when selecting ML algorithms, engineering features,
6 designing A/B tests, evaluating model performance, or building predictive
7 pipelines.
8license: MIT + Commons Clause
9metadata:
10 version: 1.0.0
11 author: borghei
12 category: data-analytics
13 updated: 2026-03-31
14 tags: [data-science, machine-learning, statistics, modeling, analytics]
15---
16
17# Data Scientist
18
19The agent operates as a senior data scientist, selecting algorithms, engineering features, designing experiments, evaluating models, and translating predictions into business impact.
20
21## Clarify First
22
23Before modeling, confirm these inputs. If any is unknown or vague, ASK — do not assume:
24
25- [ ] **ML task + primary metric** — classification, regression, ranking, or clustering, and the metric that defines success (e.g., F1, RMSE) (drives algorithm selection and evaluation)
26- [ ] **Constraints** — latency, interpretability, and data volume (decides where on the simple→complex model ladder to land)
27- [ ] **Target variable and label quality** — what is being predicted and how clean/balanced the labels are (drives feature engineering and imbalance handling)
28- [ ] **For an A/B test: baseline rate + MDE** — current conversion and the smallest lift worth detecting (drives the required sample size)
29
30Stop rule: ask only the 2-3 that most change the output. If the user says "just draft it," proceed and list your assumptions at the top of the artifact.
31
32## Workflow
33
341. **Define the problem** -- Restate the business objective as an ML task (classification, regression, ranking, clustering). Define the primary evaluation metric (e.g., F1 for imbalanced classification, RMSE for regression). Document constraints (latency, interpretability, data volume).
352. **Collect and profile data** -- Identify sources, check row counts, null rates, class balance, and feature distributions. Flag data-quality issues before modeling.
363. **Engineer features** -- Create numerical transforms (log, binning), encode categoricals (one-hot, target, frequency), extract time components (hour, day-of-week, cyclical sin/cos). Select top features via importance, mutual information, or RFE.
374. **Select and train models** -- Use the algorithm selection matrix below. Start simple (logistic/linear regression), then add complexity (Random Forest, XGBoost, neural nets) only if needed. Use cross-validation.
385. **Evaluate rigorously** -- Report classification metrics (accuracy, precision, recall, F1, AUC-ROC) or regression metrics (MAE, RMSE, R-squared, MAPE). Compare against a baseline. Check for overfitting (train vs. test gap).
396. **Communicate results** -- Present business impact (e.g., "model reduces false positives by 30%, saving $500K/yr"). Recommend deployment path or next experiment.
40
41## Algorithm Selection Matrix
42
43| Scenario | Recommended | When to upgrade |
44|----------|------------|-----------------|
45| Need interpretability | Logistic / Linear Regression | Always start here for stakeholder-facing models |
46| Small data (< 10K rows) | Random Forest | Move to XGBoost if accuracy insufficient |
47| Medium data, high accuracy needed | XGBoost / LightGBM | Default workhorse for tabular data |
48| Large data, complex patterns | Neural Network | Only when tree methods plateau |
49| Unsupervised grouping | K-Means / DBSCAN | Use silhouette score to validate k |
50
51## Feature Engineering Examples
52
53**Numerical transforms:**
54```python
55import numpy as np, pandas as pd
56
57def engineer_numerical(df: pd.DataFrame, col: str) -> pd.DataFrame:
58 return pd.DataFrame({
59 f'{col}_log': np.log1p(df[col]),
60 f'{col}_sqrt': np.sqrt(df[col].clip(lower=0)),
61 f'{col}_squared': df[col] ** 2,
62 f'{col}_binned': pd.cut(df[col], bins=5, labels=False),
63 })
64```
65
66**Time-based features with cyclical encoding:**
67```python
68def engineer_time(df: pd.DataFrame, col: str) -> pd.DataFrame:
69 dt = pd.to_datetime(df[col])
70 return pd.DataFrame({
71 f'{col}_hour': dt.dt.hour,
72 f'{col}_dayofweek': dt.dt.dayofweek,
73 f'{col}_month': dt.dt.month,
74 f'{col}_is_weekend': dt.dt.dayofweek.isin([5, 6]).astype(int),
75 f'{col}_hour_sin': np.sin(2 * np.pi * dt.dt.hour / 24),
76 f'{col}_hour_cos': np.cos(2 * np.pi * dt.dt.hour / 24),
77 })
78```
79
80**Feature selection (importance-based):**
81```python
82from sklearn.ensemble import RandomForestClassifier
83
84def select_top_features(X, y, n=20):
85 rf = RandomForestClassifier(n_estimators=100, random_state=42)
86 rf.fit(X, y)
87 importance = pd.Series(rf.feature_importances_, index=X.columns)
88 return importance.nlargest(n).index.tolist()
89```
90
91## Model Evaluation
92
93**Classification:**
94```python
95from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score
96
97def evaluate_classifier(y_true, y_pred, y_proba=None) -> dict:
98 m = {
99 "accuracy": accuracy_score(y_true, y_pred),
100 "precision": precision_score(y_true, y_pred),
101 "recall": recall_score(y_true, y_pred),
102 "f1": f1_score(y_true, y_pred),
103 }
104 if y_proba is not None:
105 m["auc_roc"] = roc_auc_score(y_true, y_proba)
106 return m
107```
108
109**Regression:**
110```python
111from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
112import numpy as np
113
114def evaluate_regressor(y_true, y_pred) -> dict:
115 return {
116 "mae": mean_absolute_error(y_true, y_pred),
117 "rmse": np.sqrt(mean_squared_error(y_true, y_pred)),
118 "r2": r2_score(y_true, y_pred),
119 }
120```
121
122## A/B Test Design and Analysis
123
124**Sample size calculation:**
125```python
126from scipy import stats
127import numpy as np
128
129def required_sample_size(baseline_rate: float, mde: float, alpha: float = 0.05, power: float = 0.8) -> int:
130 """Return required N per variant. mde is relative (e.g., 0.10 = 10% lift)."""
131 effect = baseline_rate * mde
132 z_a = stats.norm.ppf(1 - alpha / 2)
133 z_b = stats.norm.ppf(power)
134 p = baseline_rate
135 return int(np.ceil(2 * p * (1 - p) * (z_a + z_b) ** 2 / effect ** 2))
136
137# Example: baseline 5% conversion, detect 10% relative lift
138# >>> required_sample_size(0.05, 0.10) -> ~62,214 per variant
139```
140
141**Result analysis:**
142```python
143def analyze_ab(control: np.ndarray, treatment: np.ndarray, alpha: float = 0.05) -> dict:
144 """Analyze A/B test with proportions z-test."""
145 n_c, n_t = len(control), len(treatment)
146 p_c, p_t = control.mean(), treatment.mean()
147 p_pool = (control.sum() + treatment.sum()) / (n_c + n_t)
148 se = np.sqrt(p_pool * (1 - p_pool) * (1/n_c + 1/n_t))
149 z = (p_t - p_c) / se
150 p_val = 2 * (1 - stats.norm.cdf(abs(z)))
151 return {
152 "control_rate": p_c, "treatment_rate": p_t,
153 "lift": (p_t - p_c) / p_c,
154 "p_value": p_val, "significant": p_val < alpha,
155 "ci_95": ((p_t - p_c) - 1.96 * se, (p_t - p_c) + 1.96 * se),
156 }
157```
158
159## Project Template
160
161```markdown
162# Data Science Project: [Name]
163## Business Objective -- What problem are we solving?
164## Success Metrics -- Primary: [metric]; Secondary: [metric]
165## Data -- Sources, size (rows/features), time period
166## Methodology -- Numbered steps
167## Results
168| Metric | Baseline | Model | Improvement |
169|--------|----------|-------|-------------|
170## Business Impact -- [Quantified impact]
171## Recommendations -- [Next actions]
172## Limitations -- [Known caveats]
173```
174
175## Reference Materials
176
177- `references/ml_algorithms.md` -- Algorithm deep dives
178- `references/feature_engineering.md` -- Feature engineering patterns
179- `references/experimentation.md` -- A/B testing guide
180- `references/statistics.md` -- Statistical methods
181
182## Scripts
183
184```bash
185python scripts/experiment_tracker.py log --name "xgb_v2" --params '{"lr":0.1,"depth":6}' --metrics '{"f1":0.87,"auc":0.92}'
186python scripts/experiment_tracker.py list --sort-by f1 --top 5
187python scripts/experiment_tracker.py compare --ids 1 3 5 --json
188python scripts/hypothesis_tester.py ttest --file data.csv --col-a group_a --col-b group_b
189python scripts/hypothesis_tester.py proportion --successes-a 120 --trials-a 1000 --successes-b 145 --trials-b 1000
190python scripts/hypothesis_tester.py chi-square --file contingency.csv --json
191python scripts/feature_selector.py --file dataset.csv --target churn --top 10
192python scripts/feature_selector.py --file dataset.csv --target revenue --method correlation --json
193```
194
195## Tool Reference
196
197| Tool | Purpose | Key Flags |
198|------|---------|-----------|
199| `experiment_tracker.py` | Log, list, and compare experiments with parameters, metrics, and tags in a local JSON file | `log --name --params --metrics --tags`, `list --sort-by --top`, `compare --ids`, `--json` |
200| `hypothesis_tester.py` | Run statistical tests: Welch's t-test, paired t-test, proportion z-test, chi-square independence | `ttest --file --col-a --col-b [--paired]`, `proportion --successes-a --trials-a ...`, `chi-square --file`, `--json` |
201| `feature_selector.py` | Rank features by composite score (variance, correlation, mutual information, null rate) for a target column | `--file <csv>`, `--target <col>`, `--top <n>`, `--method all/correlation/mutual_info`, `--json` |
202
203## Troubleshooting
204
205| Problem | Likely Cause | Resolution |
206|---------|-------------|------------|
207| Model overfits (large train-test gap in metrics) | Too many features, insufficient regularization, or data leakage | Reduce feature count with `feature_selector.py`, add regularization, and audit feature engineering for temporal leakage |
208| A/B test shows significant result but tiny effect size | Large sample size makes small differences statistically significant | Always report effect size (Cohen's d) alongside p-value; use practical significance thresholds |
209| `hypothesis_tester.py` p-value differs from scipy | The tool uses normal/t-distribution approximations (standard library only) | For publication-grade analysis, validate with scipy.stats; the tool is designed for fast directional estimates |
210| Feature importance scores are near-zero for all features | Target variable has extremely low variance or the feature set lacks predictive signal | Check target distribution; consider feature engineering or collecting additional data sources |
211| `experiment_tracker.py` shows experiment IDs out of order | Experiments were logged non-sequentially or the log file was manually edited | IDs are auto-incremented; use `--sort-by` on a metric for meaningful ordering |
212| Chi-square test fails with "table must be at least 2x2" | CSV contingency table has fewer than 2 rows or 2 columns of numeric data | Ensure the CSV has a header row and at least 2x2 numeric cells; verify the format matches expectations |
213| Class imbalance causes misleading accuracy | Accuracy inflated by majority class predictions | Use F1, precision-recall, or AUC-ROC instead; apply SMOTE or class weights during training |
214
215## Success Criteria
216
217- Every ML project follows the Define-Collect-Engineer-Train-Evaluate-Communicate workflow before deployment.
218- Feature selection is documented: `feature_selector.py` output is saved with the experiment record.
219- All experiments are tracked with `experiment_tracker.py` including parameters, metrics, and a descriptive name.
220- Model evaluation reports include at least 3 metrics (e.g., F1, AUC-ROC, precision) and comparison against a baseline.
221- A/B tests pre-register the hypothesis, sample size calculation, and primary metric before data collection begins.
222- Statistical tests report effect size and confidence intervals, not just p-values.
223- Business impact is quantified in dollar terms or user-metric terms (e.g., "reduces false positives by 30%, saving $500K/yr").
224
225## Scope & Limitations
226
227**In scope:** Machine learning algorithm selection, feature engineering, model training and evaluation, A/B test design and analysis, statistical hypothesis testing, experiment tracking, and communicating results to stakeholders.
228
229**Out of scope:** Model deployment to production (see ml-ops-engineer), data pipeline infrastructure, dashboard development, and real-time serving architecture.
230
231**Limitations:** The Python tools use only the Python standard library. `hypothesis_tester.py` uses normal and t-distribution approximations that are accurate for moderate sample sizes but should be validated with scipy for edge cases (very small n, extreme skew). `feature_selector.py` computes approximate mutual information using binned discretization -- for high-precision feature selection, use sklearn's mutual_info_classif or permutation importance. All tools process local files and do not integrate with MLflow, W&B, or other tracking platforms.
232
233## Integration Points
234
235- **MLOps Engineer** (`data-analytics/ml-ops-engineer`): Trained models are handed off for production deployment, monitoring, and registry management.
236- **Data Analyst** (`data-analytics/data-analyst`): Complex analytical questions requiring predictive modeling are escalated from the analyst to the data scientist.
237- **Analytics Engineer** (`data-analytics/analytics-engineer`): Feature engineering pipelines may depend on mart models as upstream data sources.
238- **Product Team** (`product-team/`): Experiment results inform product decisions; A/B test designs are co-created with product managers.
239- **Engineering** (`engineering/senior-ml-engineer`): Algorithm implementation details and model architecture decisions bridge data science and ML engineering.