https://github.com/pilillo/apostasi
so far yet so close
https://github.com/pilillo/apostasi
Last synced: 7 months ago
JSON representation
so far yet so close
- Host: GitHub
- URL: https://github.com/pilillo/apostasi
- Owner: pilillo
- License: apache-2.0
- Created: 2022-09-17T07:34:39.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2022-12-29T17:23:15.000Z (over 3 years ago)
- Last Synced: 2024-06-20T23:59:05.290Z (about 2 years ago)
- Language: Go
- Size: 17.6 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# 🌍 Apostasi 🏺
A collection of approximate nearest neighbor (k-NN) algorithms implemented in Go.
## Algorithms
### 🔥 HNSW (Hierarchical Navigable Small World)
**Status**: ✅
A state-of-the-art graph-based algorithm for approximate nearest neighbor search. Features:
- **Logarithmic search complexity**: O(log N) expected time
- **Multi-layer graph structure**: Hierarchical search from coarse to fine
- **High recall and precision**: Excellent accuracy vs speed trade-off
- **Dynamic insertion**: Add vectors incrementally
- **Configurable parameters**: Tune for your specific use case
**Quick Start**:
```go
// Create index for 128D vectors
index := hnsw.NewHNSWIndex(128, 16, 0.5)
// Insert vectors
index.Insert(vector1)
index.Insert(vector2)
// Search for 10 nearest neighbors
results, _ := index.Search(queryVector, 10)
```
See [`hnsw/README.md`](hnsw/README.md) for detailed documentation and [`examples/hnsw_example.go`](examples/hnsw_example.go) for a complete example.
### LSH (Locality Sensitive Hashing)
**Status**: ✅
Random-hyperplane hashing to bucketize vectors and explore nearby buckets.
- See [`lsh/README.md`](lsh/README.md)
- Example: [`examples/lsh_example.go`](examples/lsh_example.go)
### Annoy (Approximate Nearest Neighbors Oh Yeah)
**Status**: ✅
Multiple random-projection trees with best-first search.
- See [`annoy/README.md`](annoy/README.md)
## Unified Interface
All indices provide a consistent interface:
- Insert(vector []float64) error
- Search(query []float64, k int) ([]SearchResult, error)
- GetStats() map[string]interface{}
- GetNode(id) interface{}
Notes:
- All algorithms now support dynamic insertion
- HNSW supports dynamic insertion with optimal performance
- LSH assigns sequential IDs on insert
- Annoy dynamically splits leaves when capacity exceeds k
## Getting Started
```bash
# Clone the repository
git clone https://github.com/pilillo/apostasi.git
cd apostasi
# Run tests
go test ./...
# Try the examples
cd examples
# HNSW example
go run hnsw_example.go
# LSH example
go run lsh_example.go
# Annoy example
go run annoy_example.go
```
## Performance Comparison
| Algorithm | Search Time | Memory Usage | Accuracy | Dynamic Updates |
|-----------|-------------|-------------|----------|-----------------|
| **HNSW** | O(log N) | Medium | High | ✅ Yes |
| **LSH** | ~O(1) | Low | Medium | ✅ Yes |
| **Annoy** | O(log N) | Low | Medium | ✅ Yes |
## License
See [LICENSE](LICENSE) for details.