Bug: `to_one_hot()` produces incorrect output for documented `(N, 1)` label arrays
- Dominant language
- Python
- Stars
- 7k
- Forks
- 2.3k
- PR merge metrics
- No merged PRs in 30d
Description
### Description
The `to_one_hot()` utility is documented to accept label arrays of shape `(N,)` or `(N, 1)`.
However, when a valid `(N, 1)` input is provided, the generated one-hot encoding is incorrect due to NumPy broadcasting during advanced indexing.
### File
`deepchem/metrics/metric.py`
### Current Implementation
```python
y_hot[np.arange(N), y.astype(np.int64)] = 1
```
When `y` has shape `(N, 1)`, NumPy broadcasts the indexing arrays instead of performing element-wise indexing, resulting in incorrect assignments across the output matrix.
### Expected Behavior
For:
```python
y = np.array([[0],
[1],
[0]])
```
`to_one_hot(y)` should return:
```python
[[1. 0.]
[0. 1.]
[1. 0.]]
```
### Actual Behavior
The current implementation returns:
```python
[[1. 1.]
[1. 1.]
[1. 1.]]
```
### Impact
This bug affects a documented input shape and can silently generate invalid one-hot encodings.
Potential consequences include:
* Incorrect classification metrics
* Corrupted evaluation results
* Incorrect training targets for classification workflows
* Silent failures that are difficult to detect
### Steps to Reproduce
```python
import numpy as np
from deepchem.metrics import to_one_hot
y = np.array([[0], [1], [0]])
print(to_one_hot(y))
```
Output:
```python
[[1. 1.]
[1. 1.]
[1. 1.]]
```
### Root Cause
The indexing operation:
```python
y_hot[np.arange(N), y.astype(np.int64)] = 1
```
assumes that `y` is one-dimensional.
When `y` has shape `(N, 1)`, NumPy broadcasting changes the indexing semantics and writes to unintended locations in the output array.
### Suggested Fix
Convert `y` to a one-dimensional array before performing advanced indexing:
```python
y = np.asarray(y).reshape(-1)
```
or an equivalent flattening operation before constructing the one-hot representation.
### Additional Notes
The function documentation explicitly states that inputs of shape `(N, 1)` are supported, so the current behavior violates the documented contract.
Contributor guide
Research direction
Start in deepchem/metrics/metric.py and inspect to_one_hot() together with its documented input-shape handling. Reproduce the issue with the provided (N, 1) NumPy label array, then verify that the output matches the expected one-hot matrix and that the existing one-dimensional input behavior remains correct.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- numpy, python
- Domain
- machine-learning
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 85/100