CoolFace
Apppublic

Aluode/PerceptionLabPortable

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
random.py102 linesDownload Raw Back to utils
1"""Utilities for random sampling."""
2
3# Authors: The scikit-learn developers
4# SPDX-License-Identifier: BSD-3-Clause
5
6import array
7
8import numpy as np
9import scipy.sparse as sp
10
11from . import check_random_state
12from ._random import sample_without_replacement
13
14__all__ = ["sample_without_replacement"]
15
16
17def _random_choice_csc(n_samples, classes, class_probability=None, random_state=None):
18    """Generate a sparse random matrix given column class distributions
19
20    Parameters
21    ----------
22    n_samples : int,
23        Number of samples to draw in each column.
24
25    classes : list of size n_outputs of arrays of size (n_classes,)
26        List of classes for each column.
27
28    class_probability : list of size n_outputs of arrays of \
29        shape (n_classes,), default=None
30        Class distribution of each column. If None, uniform distribution is
31        assumed.
32
33    random_state : int, RandomState instance or None, default=None
34        Controls the randomness of the sampled classes.
35        See :term:`Glossary <random_state>`.
36
37    Returns
38    -------
39    random_matrix : sparse csc matrix of size (n_samples, n_outputs)
40
41    """
42    data = array.array("i")
43    indices = array.array("i")
44    indptr = array.array("i", [0])
45
46    for j in range(len(classes)):
47        classes[j] = np.asarray(classes[j])
48        if classes[j].dtype.kind != "i":
49            raise ValueError("class dtype %s is not supported" % classes[j].dtype)
50        classes[j] = classes[j].astype(np.int64, copy=False)
51
52        # use uniform distribution if no class_probability is given
53        if class_probability is None:
54            class_prob_j = np.empty(shape=classes[j].shape[0])
55            class_prob_j.fill(1 / classes[j].shape[0])
56        else:
57            class_prob_j = np.asarray(class_probability[j])
58
59        if not np.isclose(np.sum(class_prob_j), 1.0):
60            raise ValueError(
61                "Probability array at index {0} does not sum to one".format(j)
62            )
63
64        if class_prob_j.shape[0] != classes[j].shape[0]:
65            raise ValueError(
66                "classes[{0}] (length {1}) and "
67                "class_probability[{0}] (length {2}) have "
68                "different length.".format(
69                    j, classes[j].shape[0], class_prob_j.shape[0]
70                )
71            )
72
73        # If 0 is not present in the classes insert it with a probability 0.0
74        if 0 not in classes[j]:
75            classes[j] = np.insert(classes[j], 0, 0)
76            class_prob_j = np.insert(class_prob_j, 0, 0.0)
77
78        # If there are nonzero classes choose randomly using class_probability
79        rng = check_random_state(random_state)
80        if classes[j].shape[0] > 1:
81            index_class_0 = np.flatnonzero(classes[j] == 0).item()
82            p_nonzero = 1 - class_prob_j[index_class_0]
83            nnz = int(n_samples * p_nonzero)
84            ind_sample = sample_without_replacement(
85                n_population=n_samples, n_samples=nnz, random_state=random_state
86            )
87            indices.extend(ind_sample)
88
89            # Normalize probabilities for the nonzero elements
90            classes_j_nonzero = classes[j] != 0
91            class_probability_nz = class_prob_j[classes_j_nonzero]
92            class_probability_nz_norm = class_probability_nz / np.sum(
93                class_probability_nz
94            )
95            classes_ind = np.searchsorted(
96                class_probability_nz_norm.cumsum(), rng.uniform(size=nnz)
97            )
98            data.extend(classes[j][classes_j_nonzero][classes_ind])
99        indptr.append(len(indices))
100
101    return sp.csc_matrix((data, indices, indptr), (n_samples, len(classes)), dtype=int)
102 
Aluode/PerceptionLabPortable · CoolFace