optuna-hpf 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- optuna_hpf-0.1.0/.claude/settings.local.json +23 -0
- optuna_hpf-0.1.0/.gitignore +13 -0
- optuna_hpf-0.1.0/CLAUDE.md +49 -0
- optuna_hpf-0.1.0/PKG-INFO +204 -0
- optuna_hpf-0.1.0/README.md +176 -0
- optuna_hpf-0.1.0/hpf/__init__.py +7 -0
- optuna_hpf-0.1.0/hpf/analyzer.py +249 -0
- optuna_hpf-0.1.0/hpf/cli.py +308 -0
- optuna_hpf-0.1.0/hpf/formatters/__init__.py +3 -0
- optuna_hpf-0.1.0/hpf/formatters/code_gen.py +145 -0
- optuna_hpf-0.1.0/hpf/formatters/report.py +304 -0
- optuna_hpf-0.1.0/hpf/llm/__init__.py +6 -0
- optuna_hpf-0.1.0/hpf/llm/base.py +259 -0
- optuna_hpf-0.1.0/hpf/llm/ollama_client.py +150 -0
- optuna_hpf-0.1.0/hpf/llm/openai_client.py +129 -0
- optuna_hpf-0.1.0/hpf/llm/setup_wizard.py +454 -0
- optuna_hpf-0.1.0/hpf/models.py +90 -0
- optuna_hpf-0.1.0/hpf/range_suggester.py +423 -0
- optuna_hpf-0.1.0/pyproject.toml +48 -0
- optuna_hpf-0.1.0/tests/__init__.py +0 -0
- optuna_hpf-0.1.0/tests/test_analyzer.py +190 -0
- optuna_hpf-0.1.0/tests/test_code_gen.py +161 -0
- optuna_hpf-0.1.0/tests/test_llm.py +190 -0
- optuna_hpf-0.1.0/tests/test_range_suggester.py +219 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Skill(update-config)",
|
|
5
|
+
"Bash(gh --version)",
|
|
6
|
+
"Bash(git --version)",
|
|
7
|
+
"Bash(gh auth:*)",
|
|
8
|
+
"Bash(git add:*)",
|
|
9
|
+
"Bash(git commit:*)",
|
|
10
|
+
"Bash(gh repo:*)",
|
|
11
|
+
"Bash(git tag:*)",
|
|
12
|
+
"Bash(git push:*)",
|
|
13
|
+
"Bash(gh release:*)",
|
|
14
|
+
"Bash(curl -s https://pypi.org/pypi/hpf/json)",
|
|
15
|
+
"Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\(d['info']['name'], d['info']['version']\\)\")",
|
|
16
|
+
"Bash(curl -s -o /dev/null -w \"hpranges: %{http_code}\\\\n\" https://pypi.org/pypi/hpranges/json)",
|
|
17
|
+
"Bash(curl -s -o /dev/null -w \"hyperparameter-finder: %{http_code}\\\\n\" https://pypi.org/pypi/hyperparameter-finder/json)",
|
|
18
|
+
"Bash(curl -s -o /dev/null -w \"optuna-hpf: %{http_code}\\\\n\" https://pypi.org/pypi/optuna-hpf/json)",
|
|
19
|
+
"Bash(curl -s -o /dev/null -w \"hpfinder: %{http_code}\\\\n\" https://pypi.org/pypi/hpfinder/json)",
|
|
20
|
+
"Bash(curl -s -o /dev/null -w \"optuna-ranger: %{http_code}\\\\n\" https://pypi.org/pypi/optuna-ranger/json)"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Activate venv (always do this first)
|
|
9
|
+
source .venv/bin/activate
|
|
10
|
+
|
|
11
|
+
# Run tests
|
|
12
|
+
python -m pytest tests/ -v --tb=short
|
|
13
|
+
|
|
14
|
+
# Run a single test file
|
|
15
|
+
python -m pytest tests/test_analyzer.py -v
|
|
16
|
+
|
|
17
|
+
# Install in editable mode (after pulling changes)
|
|
18
|
+
pip install -e ".[dev]"
|
|
19
|
+
|
|
20
|
+
# Run the CLI
|
|
21
|
+
hpf analyze --study <name> --file <path.db>
|
|
22
|
+
hpf setup
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Architecture
|
|
26
|
+
|
|
27
|
+
The pipeline is linear: `StudyAnalyzer → RangeSuggester → LLMClient → Reporter`
|
|
28
|
+
|
|
29
|
+
**`hpf/models.py`** — all shared dataclasses (`AnalysisResult`, `ParameterStats`, `ParameterSuggestion`, `HPFReport`). Every module imports from here; never duplicate these types.
|
|
30
|
+
|
|
31
|
+
**`hpf/analyzer.py`** — `StudyAnalyzer.analyze(study, model_type)` filters complete trials, sorts by objective direction, takes top-K% (floor 3), and builds `ParameterStats` per parameter. Uses Optuna's `FloatDistribution`, `IntDistribution`, `CategoricalDistribution` to detect type and scale.
|
|
32
|
+
|
|
33
|
+
**`hpf/range_suggester.py`** — `RangeSuggester.suggest(analysis)` applies a 4-rule waterfall per numeric param: LOG_SCALE → EXPAND → NARROW → KEEP. Uses numpy for percentile calculations. Also contains `_generate_optuna_code()`.
|
|
34
|
+
|
|
35
|
+
**`hpf/llm/`** — abstract `LLMClient` base with `_build_prompt()` shared logic. `OllamaClient` and `OpenAIClient` are concrete implementations. `SetupWizard` saves config to `~/.hpf/config.json`.
|
|
36
|
+
|
|
37
|
+
**`hpf/formatters/report.py`** — `Reporter.print_report(HPFReport)` renders the full terminal output using `rich`. Order: welcome banner → study summary → parameter table → LLM panel → code block → next steps.
|
|
38
|
+
|
|
39
|
+
**`hpf/formatters/code_gen.py`** — standalone `generate_optuna_code(suggestions, study_name)` function, no external state.
|
|
40
|
+
|
|
41
|
+
**`hpf/cli.py`** — two Typer commands: `analyze` (full pipeline) and `setup` (wizard). Error handling with rich panels.
|
|
42
|
+
|
|
43
|
+
## Key design rules
|
|
44
|
+
|
|
45
|
+
- Optuna-only for HPO framework support (no Ray Tune, HyperOpt, etc. yet)
|
|
46
|
+
- LLM is always optional — all statistical analysis works without it
|
|
47
|
+
- `ParameterStats.best_values` are raw sampled values (not normalized); the suggester works in the original parameter space
|
|
48
|
+
- Categorical params use `best_values` as a set membership check (not numeric comparisons)
|
|
49
|
+
- The `boundary_threshold` in `RangeSuggester` is a fraction of the range, not an absolute value
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: optuna-hpf
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Automatically find optimal hyperparameter search ranges for Optuna studies
|
|
5
|
+
Keywords: automl,hyperparameter,machine-learning,optimization,optuna
|
|
6
|
+
Classifier: Development Status :: 3 - Alpha
|
|
7
|
+
Classifier: Intended Audience :: Developers
|
|
8
|
+
Classifier: Intended Audience :: Science/Research
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
13
|
+
Requires-Python: >=3.10
|
|
14
|
+
Requires-Dist: numpy>=1.24
|
|
15
|
+
Requires-Dist: ollama>=0.2
|
|
16
|
+
Requires-Dist: openai>=1.0
|
|
17
|
+
Requires-Dist: optuna>=3.0
|
|
18
|
+
Requires-Dist: pydantic-settings>=2.0
|
|
19
|
+
Requires-Dist: pydantic>=2.0
|
|
20
|
+
Requires-Dist: rich>=13.0
|
|
21
|
+
Requires-Dist: scipy>=1.10
|
|
22
|
+
Requires-Dist: typer>=0.9
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest-cov; extra == 'dev'
|
|
25
|
+
Requires-Dist: pytest-mock; extra == 'dev'
|
|
26
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# hpf — Hyperparameter Finder
|
|
30
|
+
|
|
31
|
+
**Stop guessing search ranges.** `hpf` analyzes your completed Optuna studies and tells you exactly how to adjust your hyperparameter bounds before the next run — with statistical reasoning and optional LLM-powered explanations.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## The Problem
|
|
36
|
+
|
|
37
|
+
When you set up an Optuna study, you pick search ranges somewhat arbitrarily:
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
lr = trial.suggest_float("lr", 1e-5, 1.0) # is 1.0 even worth searching?
|
|
41
|
+
depth = trial.suggest_int("max_depth", 1, 20) # are trials wasting time on depth 1–3?
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
After 100+ trials, most of that space was wasted. `hpf` looks at where your best trials actually landed and tells you how to tighten, expand, or rescale each parameter for the next run.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## What it does
|
|
49
|
+
|
|
50
|
+
1. **Loads** your completed Optuna study (SQLite, PostgreSQL, or in-memory)
|
|
51
|
+
2. **Identifies** the top-K% best trials (default: top 20%)
|
|
52
|
+
3. **Analyzes** each hyperparameter:
|
|
53
|
+
- Boundary detection — did optima cluster near the edge? → **expand**
|
|
54
|
+
- Cluster analysis — did optima occupy only a tiny subregion? → **narrow**
|
|
55
|
+
- Scale detection — do values span multiple orders of magnitude on a linear scale? → **switch to log**
|
|
56
|
+
4. **Outputs** a color-coded terminal report with confidence levels and reasoning
|
|
57
|
+
5. **Generates** a ready-to-paste Optuna search space you can drop into your objective function
|
|
58
|
+
6. **Optionally explains** everything in plain English via a local LLM (Ollama) or API (OpenAI / Groq / Together / any OpenAI-compatible endpoint)
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Installation
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install hpf
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Or from source:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
git clone https://github.com/ParamChordiya/hpf.git
|
|
72
|
+
cd hpf
|
|
73
|
+
pip install -e .
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Quick start
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# First-time setup (configure your LLM — optional but recommended)
|
|
82
|
+
hpf setup
|
|
83
|
+
|
|
84
|
+
# Analyze a study stored in SQLite
|
|
85
|
+
hpf analyze --study my_xgboost_study --file study.db
|
|
86
|
+
|
|
87
|
+
# Analyze with model type hint for better LLM tips
|
|
88
|
+
hpf analyze --study my_study --file study.db --model-type xgboost
|
|
89
|
+
|
|
90
|
+
# Skip LLM, just show statistical analysis
|
|
91
|
+
hpf analyze --study my_study --file study.db --no-llm
|
|
92
|
+
|
|
93
|
+
# Use a custom storage URL (PostgreSQL, etc.)
|
|
94
|
+
hpf analyze --study my_study --storage "postgresql://user:pass@host/db"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## LLM setup
|
|
100
|
+
|
|
101
|
+
`hpf` supports two modes for AI-powered explanations:
|
|
102
|
+
|
|
103
|
+
### Option 1: Local model via Ollama (free, private)
|
|
104
|
+
|
|
105
|
+
1. Install [Ollama](https://ollama.ai)
|
|
106
|
+
2. Pull a model: `ollama pull llama3`
|
|
107
|
+
3. Run `hpf setup` and select option 1
|
|
108
|
+
|
|
109
|
+
### Option 2: OpenAI-compatible API
|
|
110
|
+
|
|
111
|
+
Works with OpenAI, Groq, Together AI, Anyscale, or any provider with an OpenAI-compatible endpoint.
|
|
112
|
+
|
|
113
|
+
Run `hpf setup` and select option 2. You'll be prompted for:
|
|
114
|
+
- API key
|
|
115
|
+
- Base URL (leave blank for OpenAI, or enter e.g. `https://api.groq.com/openai/v1`)
|
|
116
|
+
- Model name (default: `gpt-4o-mini`)
|
|
117
|
+
|
|
118
|
+
Config is saved to `~/.hpf/config.json`.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Example output
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
╭─────────────────────────────────────────╮
|
|
126
|
+
│ HPF — Hyperparameter Finder v0.1.0 │
|
|
127
|
+
╰─────────────────────────────────────────╯
|
|
128
|
+
|
|
129
|
+
Study: my_xgboost_study │ 300 trials │ best: 0.9412 │ direction: maximize
|
|
130
|
+
|
|
131
|
+
┌──────────────────┬───────┬──────────────────┬──────────────────┬───────────┬────┐
|
|
132
|
+
│ Parameter │ Type │ Original │ Suggested │ Action │ ● │
|
|
133
|
+
├──────────────────┼───────┼──────────────────┼──────────────────┼───────────┼────┤
|
|
134
|
+
│ learning_rate │ FLOAT │ [0.001, 1.0] │ [0.001, 1.0] LOG │ LOG_SCALE │ ● │
|
|
135
|
+
│ max_depth │ INT │ [1, 20] │ [3, 9] │ NARROW │ ● │
|
|
136
|
+
│ n_estimators │ INT │ [50, 500] │ [50, 1500] │ EXPAND │ ● │
|
|
137
|
+
│ subsample │ FLOAT │ [0.5, 1.0] │ [0.5, 1.0] │ KEEP │ ● │
|
|
138
|
+
└──────────────────┴───────┴──────────────────┴──────────────────┴───────────┴────┘
|
|
139
|
+
|
|
140
|
+
╭─── Updated Search Space ────────────────────────────────────────────╮
|
|
141
|
+
│ def objective(trial): │
|
|
142
|
+
│ learning_rate = trial.suggest_float("learning_rate", │
|
|
143
|
+
│ 0.001, 1.0, log=True) │
|
|
144
|
+
│ max_depth = trial.suggest_int("max_depth", 3, 9) │
|
|
145
|
+
│ n_estimators = trial.suggest_int("n_estimators", 50, 1500) │
|
|
146
|
+
│ subsample = trial.suggest_float("subsample", 0.5, 1.0) │
|
|
147
|
+
╰─────────────────────────────────────────────────────────────────────╯
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Python API
|
|
153
|
+
|
|
154
|
+
You can also use `hpf` directly in your code:
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
import optuna
|
|
158
|
+
from hpf.analyzer import StudyAnalyzer
|
|
159
|
+
from hpf.range_suggester import RangeSuggester
|
|
160
|
+
from hpf.formatters.report import Reporter
|
|
161
|
+
from hpf.models import HPFReport
|
|
162
|
+
from hpf.formatters.code_gen import generate_optuna_code
|
|
163
|
+
|
|
164
|
+
study = optuna.load_study(study_name="my_study", storage="sqlite:///study.db")
|
|
165
|
+
|
|
166
|
+
analyzer = StudyAnalyzer(top_k_percent=20)
|
|
167
|
+
analysis = analyzer.analyze(study, model_type="xgboost")
|
|
168
|
+
|
|
169
|
+
suggester = RangeSuggester()
|
|
170
|
+
suggestions = suggester.suggest(analysis)
|
|
171
|
+
|
|
172
|
+
code = generate_optuna_code(suggestions, study.study_name)
|
|
173
|
+
report = HPFReport(analysis=analysis, suggestions=suggestions, llm_explanation=None, optuna_code=code)
|
|
174
|
+
|
|
175
|
+
Reporter().print_report(report)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## How the analysis works
|
|
181
|
+
|
|
182
|
+
| Signal | Action | Example |
|
|
183
|
+
|---|---|---|
|
|
184
|
+
| Best trials' mean/median within 10% of a boundary | **EXPAND** | `n_estimators` best at 490–500 → expand upper bound |
|
|
185
|
+
| Best trials span <30% of original range | **NARROW** | `max_depth` best in 3–7 out of 1–20 → narrow to 3–9 |
|
|
186
|
+
| Values span >100× ratio on linear scale | **LOG SCALE** | `lr` from 0.001–0.5 on linear → switch to log |
|
|
187
|
+
| Well-distributed across range | **KEEP** | `subsample` best from 0.6–0.95 → keep as is |
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Requirements
|
|
192
|
+
|
|
193
|
+
- Python 3.10+
|
|
194
|
+
- Optuna 3.0+
|
|
195
|
+
|
|
196
|
+
Optional:
|
|
197
|
+
- `ollama` Python package + [Ollama](https://ollama.ai) running locally
|
|
198
|
+
- `openai` package + API key for cloud LLM
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## License
|
|
203
|
+
|
|
204
|
+
MIT
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# hpf — Hyperparameter Finder
|
|
2
|
+
|
|
3
|
+
**Stop guessing search ranges.** `hpf` analyzes your completed Optuna studies and tells you exactly how to adjust your hyperparameter bounds before the next run — with statistical reasoning and optional LLM-powered explanations.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## The Problem
|
|
8
|
+
|
|
9
|
+
When you set up an Optuna study, you pick search ranges somewhat arbitrarily:
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
lr = trial.suggest_float("lr", 1e-5, 1.0) # is 1.0 even worth searching?
|
|
13
|
+
depth = trial.suggest_int("max_depth", 1, 20) # are trials wasting time on depth 1–3?
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
After 100+ trials, most of that space was wasted. `hpf` looks at where your best trials actually landed and tells you how to tighten, expand, or rescale each parameter for the next run.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## What it does
|
|
21
|
+
|
|
22
|
+
1. **Loads** your completed Optuna study (SQLite, PostgreSQL, or in-memory)
|
|
23
|
+
2. **Identifies** the top-K% best trials (default: top 20%)
|
|
24
|
+
3. **Analyzes** each hyperparameter:
|
|
25
|
+
- Boundary detection — did optima cluster near the edge? → **expand**
|
|
26
|
+
- Cluster analysis — did optima occupy only a tiny subregion? → **narrow**
|
|
27
|
+
- Scale detection — do values span multiple orders of magnitude on a linear scale? → **switch to log**
|
|
28
|
+
4. **Outputs** a color-coded terminal report with confidence levels and reasoning
|
|
29
|
+
5. **Generates** a ready-to-paste Optuna search space you can drop into your objective function
|
|
30
|
+
6. **Optionally explains** everything in plain English via a local LLM (Ollama) or API (OpenAI / Groq / Together / any OpenAI-compatible endpoint)
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install hpf
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Or from source:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
git clone https://github.com/ParamChordiya/hpf.git
|
|
44
|
+
cd hpf
|
|
45
|
+
pip install -e .
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Quick start
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# First-time setup (configure your LLM — optional but recommended)
|
|
54
|
+
hpf setup
|
|
55
|
+
|
|
56
|
+
# Analyze a study stored in SQLite
|
|
57
|
+
hpf analyze --study my_xgboost_study --file study.db
|
|
58
|
+
|
|
59
|
+
# Analyze with model type hint for better LLM tips
|
|
60
|
+
hpf analyze --study my_study --file study.db --model-type xgboost
|
|
61
|
+
|
|
62
|
+
# Skip LLM, just show statistical analysis
|
|
63
|
+
hpf analyze --study my_study --file study.db --no-llm
|
|
64
|
+
|
|
65
|
+
# Use a custom storage URL (PostgreSQL, etc.)
|
|
66
|
+
hpf analyze --study my_study --storage "postgresql://user:pass@host/db"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## LLM setup
|
|
72
|
+
|
|
73
|
+
`hpf` supports two modes for AI-powered explanations:
|
|
74
|
+
|
|
75
|
+
### Option 1: Local model via Ollama (free, private)
|
|
76
|
+
|
|
77
|
+
1. Install [Ollama](https://ollama.ai)
|
|
78
|
+
2. Pull a model: `ollama pull llama3`
|
|
79
|
+
3. Run `hpf setup` and select option 1
|
|
80
|
+
|
|
81
|
+
### Option 2: OpenAI-compatible API
|
|
82
|
+
|
|
83
|
+
Works with OpenAI, Groq, Together AI, Anyscale, or any provider with an OpenAI-compatible endpoint.
|
|
84
|
+
|
|
85
|
+
Run `hpf setup` and select option 2. You'll be prompted for:
|
|
86
|
+
- API key
|
|
87
|
+
- Base URL (leave blank for OpenAI, or enter e.g. `https://api.groq.com/openai/v1`)
|
|
88
|
+
- Model name (default: `gpt-4o-mini`)
|
|
89
|
+
|
|
90
|
+
Config is saved to `~/.hpf/config.json`.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Example output
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
╭─────────────────────────────────────────╮
|
|
98
|
+
│ HPF — Hyperparameter Finder v0.1.0 │
|
|
99
|
+
╰─────────────────────────────────────────╯
|
|
100
|
+
|
|
101
|
+
Study: my_xgboost_study │ 300 trials │ best: 0.9412 │ direction: maximize
|
|
102
|
+
|
|
103
|
+
┌──────────────────┬───────┬──────────────────┬──────────────────┬───────────┬────┐
|
|
104
|
+
│ Parameter │ Type │ Original │ Suggested │ Action │ ● │
|
|
105
|
+
├──────────────────┼───────┼──────────────────┼──────────────────┼───────────┼────┤
|
|
106
|
+
│ learning_rate │ FLOAT │ [0.001, 1.0] │ [0.001, 1.0] LOG │ LOG_SCALE │ ● │
|
|
107
|
+
│ max_depth │ INT │ [1, 20] │ [3, 9] │ NARROW │ ● │
|
|
108
|
+
│ n_estimators │ INT │ [50, 500] │ [50, 1500] │ EXPAND │ ● │
|
|
109
|
+
│ subsample │ FLOAT │ [0.5, 1.0] │ [0.5, 1.0] │ KEEP │ ● │
|
|
110
|
+
└──────────────────┴───────┴──────────────────┴──────────────────┴───────────┴────┘
|
|
111
|
+
|
|
112
|
+
╭─── Updated Search Space ────────────────────────────────────────────╮
|
|
113
|
+
│ def objective(trial): │
|
|
114
|
+
│ learning_rate = trial.suggest_float("learning_rate", │
|
|
115
|
+
│ 0.001, 1.0, log=True) │
|
|
116
|
+
│ max_depth = trial.suggest_int("max_depth", 3, 9) │
|
|
117
|
+
│ n_estimators = trial.suggest_int("n_estimators", 50, 1500) │
|
|
118
|
+
│ subsample = trial.suggest_float("subsample", 0.5, 1.0) │
|
|
119
|
+
╰─────────────────────────────────────────────────────────────────────╯
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Python API
|
|
125
|
+
|
|
126
|
+
You can also use `hpf` directly in your code:
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
import optuna
|
|
130
|
+
from hpf.analyzer import StudyAnalyzer
|
|
131
|
+
from hpf.range_suggester import RangeSuggester
|
|
132
|
+
from hpf.formatters.report import Reporter
|
|
133
|
+
from hpf.models import HPFReport
|
|
134
|
+
from hpf.formatters.code_gen import generate_optuna_code
|
|
135
|
+
|
|
136
|
+
study = optuna.load_study(study_name="my_study", storage="sqlite:///study.db")
|
|
137
|
+
|
|
138
|
+
analyzer = StudyAnalyzer(top_k_percent=20)
|
|
139
|
+
analysis = analyzer.analyze(study, model_type="xgboost")
|
|
140
|
+
|
|
141
|
+
suggester = RangeSuggester()
|
|
142
|
+
suggestions = suggester.suggest(analysis)
|
|
143
|
+
|
|
144
|
+
code = generate_optuna_code(suggestions, study.study_name)
|
|
145
|
+
report = HPFReport(analysis=analysis, suggestions=suggestions, llm_explanation=None, optuna_code=code)
|
|
146
|
+
|
|
147
|
+
Reporter().print_report(report)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## How the analysis works
|
|
153
|
+
|
|
154
|
+
| Signal | Action | Example |
|
|
155
|
+
|---|---|---|
|
|
156
|
+
| Best trials' mean/median within 10% of a boundary | **EXPAND** | `n_estimators` best at 490–500 → expand upper bound |
|
|
157
|
+
| Best trials span <30% of original range | **NARROW** | `max_depth` best in 3–7 out of 1–20 → narrow to 3–9 |
|
|
158
|
+
| Values span >100× ratio on linear scale | **LOG SCALE** | `lr` from 0.001–0.5 on linear → switch to log |
|
|
159
|
+
| Well-distributed across range | **KEEP** | `subsample` best from 0.6–0.95 → keep as is |
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Requirements
|
|
164
|
+
|
|
165
|
+
- Python 3.10+
|
|
166
|
+
- Optuna 3.0+
|
|
167
|
+
|
|
168
|
+
Optional:
|
|
169
|
+
- `ollama` Python package + [Ollama](https://ollama.ai) running locally
|
|
170
|
+
- `openai` package + API key for cloud LLM
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## License
|
|
175
|
+
|
|
176
|
+
MIT
|