slang.spectrop

Spectral projectors

class slang.spectrop.GeneralProjectionLearner(chain=({'type': 'pca', 'args': {'n_components': 5}}), indices=None, n_freq=1025)[source]
project(X)[source]

Projection within original space (remains same dimensions, no reduction)

transform(X)[source]

Projection within projected space (reduces dimensions)

class slang.spectrop.IpcaProj(n_components=None, *, whiten=False, copy=True, batch_size=None)[source]
fit(X, y=None)[source]

Fit the model with X, using minibatches of size batch_size.

Parameters
  • X ({array-like, sparse matrix} of shape (n_samples, n_features)) – Training data, where n_samples is the number of samples and n_features is the number of features.

  • y (Ignored) – Not used, present for API consistency by convention.

Returns

self – Returns the instance itself.

Return type

object

class slang.spectrop.LdaProj(solver='svd', shrinkage=None, priors=None, n_components=None, store_covariance=False, tol=0.0001, covariance_estimator=None)[source]
class slang.spectrop.LinregProj(*, fit_intercept=True, normalize='deprecated', copy_X=True, n_jobs=None, positive=False)[source]
fit(X, y, sample_weight=None)

Fit linear model.

Parameters
  • X ({array-like, sparse matrix} of shape (n_samples, n_features)) – Training data.

  • y (array-like of shape (n_samples,) or (n_samples, n_targets)) – Target values. Will be cast to X’s dtype if necessary.

  • sample_weight (array-like of shape (n_samples,), default=None) –

    Individual weights for each sample.

    New in version 0.17: parameter sample_weight support to LinearRegression.

Returns

self – Fitted Estimator.

Return type

object

class slang.spectrop.MyLDA(n_components=None)[source]
class slang.spectrop.PcaProj(n_components=None, *, copy=True, whiten=False, svd_solver='auto', tol=0.0, iterated_power='auto', random_state=None)[source]
fit(X, y=None)[source]

Fit the model with X.

Parameters
  • X (array-like of shape (n_samples, n_features)) – Training data, where n_samples is the number of samples and n_features is the number of features.

  • y (Ignored) – Ignored.

Returns

self – Returns the instance itself.

Return type

object

class slang.spectrop.PcaProjWithDelegation(*args, **kwargs)[source]
class slang.spectrop.Projector(scalings_: numpy.ndarray = array([[9.75609756e-04, 9.75609756e-04, 9.75609756e-04, ..., 9.75609756e-04, 9.75609756e-04, 9.75609756e-04], [1.95312500e-03, 1.95312500e-03, 1.95312500e-03, ..., 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], [3.90625000e-03, 3.90625000e-03, 3.90625000e-03, ..., 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], ..., [2.50000000e-01, 2.50000000e-01, 2.50000000e-01, ..., 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], [5.00000000e-01, 5.00000000e-01, 0.00000000e+00, ..., 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], [1.00000000e+00, 0.00000000e+00, 0.00000000e+00, ..., 0.00000000e+00, 0.00000000e+00, 0.00000000e+00]]), mat_mult: numpy.ndarray = <function dot>)[source]
Projector(scalings_: numpy.ndarray = array([[9.75609756e-04, 9.75609756e-04, 9.75609756e-04, …,

9.75609756e-04, 9.75609756e-04, 9.75609756e-04],

[1.95312500e-03, 1.95312500e-03, 1.95312500e-03, …,

0.00000000e+00, 0.00000000e+00, 0.00000000e+00],

[3.90625000e-03, 3.90625000e-03, 3.90625000e-03, …,

0.00000000e+00, 0.00000000e+00, 0.00000000e+00],

…, [2.50000000e-01, 2.50000000e-01, 2.50000000e-01, …,

0.00000000e+00, 0.00000000e+00, 0.00000000e+00],

[5.00000000e-01, 5.00000000e-01, 0.00000000e+00, …,

0.00000000e+00, 0.00000000e+00, 0.00000000e+00],

[1.00000000e+00, 0.00000000e+00, 0.00000000e+00, …,

0.00000000e+00, 0.00000000e+00, 0.00000000e+00]]), mat_mult: numpy.ndarray = <function dot at 0x7f66fb2379d0>)

mat_mult()

dot(a, b, out=None)

Dot product of two arrays. Specifically,

  • If both a and b are 1-D arrays, it is inner product of vectors (without complex conjugation).

  • If both a and b are 2-D arrays, it is matrix multiplication, but using matmul() or a @ b is preferred.

  • If either a or b is 0-D (scalar), it is equivalent to multiply() and using numpy.multiply(a, b) or a * b is preferred.

  • If a is an N-D array and b is a 1-D array, it is a sum product over the last axis of a and b.

  • If a is an N-D array and b is an M-D array (where M>=2), it is a sum product over the last axis of a and the second-to-last axis of b:

    dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])
    
Parameters
  • a (array_like) – First argument.

  • b (array_like) – Second argument.

  • out (ndarray, optional) – Output argument. This must have the exact kind that would be returned if it was not used. In particular, it must have the right type, must be C-contiguous, and its dtype must be the dtype that would be returned for dot(a,b). This is a performance feature. Therefore, if these conditions are not met, an exception is raised, instead of attempting to be flexible.

Returns

output – Returns the dot product of a and b. If a and b are both scalars or both 1-D arrays then a scalar is returned; otherwise an array is returned. If out is given, then it is returned.

Return type

ndarray

Raises

ValueError – If the last dimension of a is not the same size as the second-to-last dimension of b.

See also

vdot

Complex-conjugating dot product.

tensordot

Sum products over arbitrary axes.

einsum

Einstein summation convention.

matmul

‘@’ operator as method with out parameter.

linalg.multi_dot

Chained dot product.

Examples

>>> np.dot(3, 4)
12

Neither argument is complex-conjugated:

>>> np.dot([2j, 3j], [2j, 3j])
(-13+0j)

For 2-D arrays it is the matrix product:

>>> a = [[1, 0], [0, 1]]
>>> b = [[4, 1], [2, 2]]
>>> np.dot(a, b)
array([[4, 1],
       [2, 2]])
>>> a = np.arange(3*4*5*6).reshape((3,4,5,6))
>>> b = np.arange(3*4*5*6)[::-1].reshape((5,4,6,3))
>>> np.dot(a, b)[2,3,2,1,2,2]
499128
>>> sum(a[2,3,2,:] * b[1,2,:,2])
499128
class slang.spectrop.Residues(scalings_: numpy.ndarray = array([[9.75609756e-04, 9.75609756e-04, 9.75609756e-04, ..., 9.75609756e-04, 9.75609756e-04, 9.75609756e-04], [1.95312500e-03, 1.95312500e-03, 1.95312500e-03, ..., 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], [3.90625000e-03, 3.90625000e-03, 3.90625000e-03, ..., 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], ..., [2.50000000e-01, 2.50000000e-01, 2.50000000e-01, ..., 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], [5.00000000e-01, 5.00000000e-01, 0.00000000e+00, ..., 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], [1.00000000e+00, 0.00000000e+00, 0.00000000e+00, ..., 0.00000000e+00, 0.00000000e+00, 0.00000000e+00]]), mat_mult: numpy.ndarray = <function dot>)[source]
class slang.spectrop.SpectralProjector(scalings_: numpy.ndarray = array([[9.75609756e-04, 9.75609756e-04, 9.75609756e-04, ..., 9.75609756e-04, 9.75609756e-04, 9.75609756e-04], [1.95312500e-03, 1.95312500e-03, 1.95312500e-03, ..., 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], [3.90625000e-03, 3.90625000e-03, 3.90625000e-03, ..., 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], ..., [2.50000000e-01, 2.50000000e-01, 2.50000000e-01, ..., 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], [5.00000000e-01, 5.00000000e-01, 0.00000000e+00, ..., 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], [1.00000000e+00, 0.00000000e+00, 0.00000000e+00, ..., 0.00000000e+00, 0.00000000e+00, 0.00000000e+00]]), mat_mult: numpy.ndarray = <function dot>, chk_fft: Callable = functools.partial(<function chk_to_spectrum>, chk_size=2048, window=array([0.00000000e+00, 2.35539484e-06, 9.42155716e-06, ..., 9.42155716e-06, 2.35539484e-06, 0.00000000e+00]), amplitude_func=<ufunc 'absolute'>))[source]
SpectralProjector(scalings_: numpy.ndarray = array([[9.75609756e-04, 9.75609756e-04, 9.75609756e-04, …,

9.75609756e-04, 9.75609756e-04, 9.75609756e-04],

[1.95312500e-03, 1.95312500e-03, 1.95312500e-03, …,

0.00000000e+00, 0.00000000e+00, 0.00000000e+00],

[3.90625000e-03, 3.90625000e-03, 3.90625000e-03, …,

0.00000000e+00, 0.00000000e+00, 0.00000000e+00],

…, [2.50000000e-01, 2.50000000e-01, 2.50000000e-01, …,

0.00000000e+00, 0.00000000e+00, 0.00000000e+00],

[5.00000000e-01, 5.00000000e-01, 0.00000000e+00, …,

0.00000000e+00, 0.00000000e+00, 0.00000000e+00],

[1.00000000e+00, 0.00000000e+00, 0.00000000e+00, …,

0.00000000e+00, 0.00000000e+00, 0.00000000e+00]]), mat_mult: numpy.ndarray = <function dot at 0x7f66fb2379d0>, chk_fft: Callable = functools.partial(<function chk_to_spectrum at 0x7f66e8236040>, chk_size=2048, window=array([0.00000000e+00, 2.35539484e-06, 9.42155716e-06, …,

9.42155716e-06, 2.35539484e-06, 0.00000000e+00]), amplitude_func=<ufunc ‘absolute’>))

static mk_chk_fft(chk_size=None, window=<function hanning>, amplitude_func=<ufunc 'absolute'>)

Make a chk_fft function that will compute the fft (with given amplitude and window). Note that this output chk_fft function will enforce a fixed chk_size (given explicitly, or through the size of the window (if window is given as an array)

>>> chk_size = 4 * 5
>>> f = mk_chk_fft(chk_size)
>>> chk = 4 * list(range(chk_size // 4))
>>> f(chk)
array([19.        , 10.214421  ,  0.40774689,  4.34150779,  8.09801978,
        4.30684381,  0.26711259,  2.61514496,  5.04588504,  2.6255033 ,
        0.21962565])
>>> # verifying that it's pickable
>>> import pickle
>>> import numpy as np
>>> ff = pickle.loads(pickle.dumps(f))
>>> assert np.allclose(ff(chk), ff(chk))
class slang.spectrop.SpectralProjectorLearner(learner, chk_fft=functools.partial(<function chk_to_spectrum>, chk_size=2048, window=array([0.00000000e+00, 2.35539484e-06, 9.42155716e-06, ..., 9.42155716e-06, 2.35539484e-06, 0.00000000e+00]), amplitude_func=<ufunc 'absolute'>), mat_mult=<function dot>)[source]
class slang.spectrop.SpectralProjectorSupervisedFitter(n_components=None, scalings_=None, chk_fft=functools.partial(<function chk_to_spectrum>, chk_size=2048, window=array([0.00000000e+00, 2.35539484e-06, 9.42155716e-06, ..., 9.42155716e-06, 2.35539484e-06, 0.00000000e+00]), amplitude_func=<ufunc 'absolute'>))[source]
class slang.spectrop.SpectralProjectorUnsupervisedFitter(target_variance=0.95, max_n_components=inf, min_n_components=1, scalings_=None, chk_fft=functools.partial(<function chk_to_spectrum>, chk_size=2048, window=array([0.00000000e+00, 2.35539484e-06, 9.42155716e-06, ..., 9.42155716e-06, 2.35539484e-06, 0.00000000e+00]), amplitude_func=<ufunc 'absolute'>))[source]
class slang.spectrop.TargettedVariancePCA(target_variance=0.95, max_n_components=inf, min_n_components=1)[source]
slang.spectrop.ascertain_array(iterable)[source]

Getting an array from an iterable

slang.spectrop.decreasing_integer_geometric_sequence(start: int = 1025, scale_factor=0.5) → list[source]

Generate decreasing positive integers in by multiplying numbers by a constant (between 0 and 1) repeatedly. Numbers of ther sequence will all be integers and not repeat (so often not a true geometri sequence). All sequences will end with 1. An error will be raised if scale_factor is not between 0 and 1 (exclusive).

>>> decreasing_integer_geometric_sequence(128)
[128, 64, 32, 16, 8, 4, 2, 1]
>>> decreasing_integer_geometric_sequence(10, 0.3)
[10, 3, 1]
>>> decreasing_integer_geometric_sequence(10, 0.7)
[10, 7, 5, 3, 2, 1]

And to see that we indeed don’t get duplicates of the true geometric sequence.

>>> decreasing_integer_geometric_sequence(10, 0.9999)
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
slang.spectrop.instantiate_class_and_inject_attributes(cls, **kwargs)[source]

instantiates a class with the given kwargs, picking those arguments that are in the signature of cls to use for the __init__, and adding attributes to the constructed object with the remaining. :param cls: class to insantiate :param kwargs: keyword args (some for the class __init__, and others to inject) :return: An (possibly enhanced) class instance >>> class C: … def __init__(self, a, b=3): … self.a = a … self.b = b … >>> c = instantiate_class_and_inject_attributes(C, a=10, foo=’bar’) >>> c.__dict__ {‘a’: 10, ‘b’: 3, ‘foo’: ‘bar’} >>> c = instantiate_class_and_inject_attributes(C, a=10, foo=’bar’, bar=’foo’, b=1000) >>> c.__dict__ {‘a’: 10, ‘b’: 1000, ‘foo’: ‘bar’, ‘bar’: ‘foo’} >>> try: … c = instantiate_class_and_inject_attributes(C, foo=’bar’, bar=’foo’, b=1000) … except TypeError: # expected … pass

slang.spectrop.keep_only_indices(indices, input_size=1025)[source]

Makes a matrix which when a spectra is multiplied with it, only the entires in the list indices are kept :param indices: a list of indices to keep :param input_size: the total number of frequencies in the spectra :return: a matrix of size (input_size, len(indices))

slang.spectrop.learn_chain_proj_matrix(X, y=None, chain=({'type': 'pca', 'args': {'n_components': 5}}), indices=None, input_size=1025)[source]

A function successively learning a projections matrix on the residue of the previous one. The projections matrices are then concatenated and return as one single projection matrix. Note that the final projection matrix may not produce fvs of the size the sum of the components of each part, i.e., care must be taken to ensure each classes called must be able to produce the required number of components. For example, if the number of classes is 10, then lda can only produce 9 dimensions. To obtain say 12 dimension, the user will need to chain two lda’s, for example with size 9 and 3 respectively.

Parameters
  • X – the fvs, an array of size n*k

  • y – the classes, an array of size n

  • chain – a tuple of dictionaries each containing the type of projection along with its parameters

  • indices – the indices of the spectra to work with, anything else is discarded

  • input_size – the total number of entries from the spectra. Only needed if n_freq is not None, in order to determine the size of the freq_selection_matrix

Returns

a single projection matrix

slang.spectrop.learn_spect_proj(X, y=None, spectral_proj_name='pca', clustering_meth='KMeans', clustering_options=('KMeans', 'SpectralClustering', 'AffinityPropagation', 'AgglomerativeClustering', 'Birch', 'MeanShift'), kwargs_feat=None, kwargs_clust=None)[source]

Function to learn each of the important spectral projection

Parameters
  • X – the fvs, an array of size n*k

  • y – the classes, an array of size n

  • spectral_proj_name – a string of the name of the featurizer

  • args – extra argument to be passed to the featurizer class

Returns

a matrix in the form of a numpy array

slang.spectrop.logarithmic_bands_matrix(n_buckets=None, n_freqs: int = 1025, factor: float = 2) → numpy.ndarray[source]

Makes a spectral projection matrix that puts more importance on low frequencies than high ones. Importance both in weight and in precision. By a factor of 2 by default, but can be any amount. Note that the factor here is the inverse of the geometric factor of decreasing_integer_geometric_sequence.

Note that the sum of the frequencies of the bands is constant from band to band. Not sure if that’s the best choice, or if equal weight through out is the best choice. We can discuss what both mean at a later date.

Important here is to understand my intent, to see how well I achieve it. - The features “build on each other”. That is, if you ask (within the same (n_freqs, factor) set) for 7 features in your fv, the first 5 will be the same as if you asked for only 5. This makes it easier to compare fvs between projects, and possibly even “add to existing features”. - Note that the first feature is always total energy. - Lower frequencies are given less importance – both in precision and in weight. - The linear algebraists that are listening will note what the vector space generated actually is, compared to that created by disjoint bands.

>>> print(*logarithmic_bands_matrix(n_freqs=8).tolist(), sep='\n')
[0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125]
[0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0]
[0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
[1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
>>> print(*logarithmic_bands_matrix(n_freqs=8, factor=1.5).tolist(), sep='\n')
[0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125]
[0.2, 0.2, 0.2, 0.2, 0.2, 0.0, 0.0, 0.0]
[0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0]
[0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
[1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
slang.spectrop.make_band_matrix(buckets, n_freq=1025)[source]

Given a list of n list of indices, make a matrix of size n by n_freq where the entries of row k are 0 everywhere except at the index in the k list of buckets, where the entries are the inverse of the length of that bucket

Parameters
  • buckets – a list of list containing the indices of non zero entries of the corresponding row

  • n_freq – the number of column of the matrix

Returns

a len(buckets) by n_freq matrix

>>> buckets = make_buckets(n_buckets=15, freqs_weighting=lambda x: np.log(x + 0.001), freq_range=(200, 1000))
>>> M = make_band_matrix(buckets, n_freq=1025)
>>> print(M.shape)
(15, 1025)
>>> # the matrix sends each of the 200 first unitary vector to the zero vector (not below is not a mathematical proof of that, but solid clue)
>>> vec = [1] * 200 + [0] * (1025 - 200)
>>> print(np.dot(M, vec))
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
>>> # after that, we get non zero output (in general at least)
>>> vec = [1] * 200 + [1] + [0] * (1025 - 201)
>>> print(np.dot(M, vec))
[0.01612903 0.         0.         0.         0.         0.
 0.         0.         0.         0.         0.         0.
 0.         0.         0.        ]
slang.spectrop.make_band_matrix_row(list_entries, row_len)[source]

Makes a row for the spectral bucket matrix. The row is zero everywhere except on the entries of index in list_entries where it is 1 / len(list_entries)

Parameters
  • list_entries – the indices of non zero entries of the row

  • row_len – the length of the row

Returns

an array of length row_len as described above

>>> make_band_matrix_row([3], 5)
array([0., 0., 0., 1., 0.])
>>> make_band_matrix_row([0, 3], 5)
array([0.5, 0. , 0. , 0.5, 0. ])
slang.spectrop.make_buckets(n_buckets=15, freqs_weighting=<function <lambda>>, freq_range=(0, 1025), non_empty_bucket=True, reverse=False)[source]

Create greedily buckets starting by aggregating lower frequencies, when the sum of the frequencies values so far exceed the number of buckets created times the target average value for a single bucket, a new bucket is created with or without the last term according to which choice will be closest.

Parameters
  • n_buckets – final number of buckets

  • freqs_weighting – any function assigning a non-negative value to each element in the freq_range If given a list, the function will be assumed to be the one to one mapping the frequencies to the value in the list

  • freq_range – the range of frequencies considered, inclusive on both ends

  • non_empty_bucket – if set to true, all buckets will have at least one element

  • reverse – if set to true, will start aggregating higher frequencies instead, which for an increasing weight

function will aggregate the higher frequencies into larger bins as typical :return: a partition of freq_range

>>> buckets = make_buckets(n_buckets=15, freqs_weighting=lambda x: np.log(x + 0.001), freq_range=(200, 1000))
>>> len(buckets) == 15
True
>>> buckets[0][0] # the first bucket starts at the first term of freq_range
200
>>> buckets[-1][-1] # the last bucket ends at the last term of freq_range - 1
999
slang.spectrop.mk_chk_fft(chk_size=None, window=<function hanning>, amplitude_func=<ufunc 'absolute'>)[source]

Make a chk_fft function that will compute the fft (with given amplitude and window). Note that this output chk_fft function will enforce a fixed chk_size (given explicitly, or through the size of the window (if window is given as an array)

>>> chk_size = 4 * 5
>>> f = mk_chk_fft(chk_size)
>>> chk = 4 * list(range(chk_size // 4))
>>> f(chk)
array([19.        , 10.214421  ,  0.40774689,  4.34150779,  8.09801978,
        4.30684381,  0.26711259,  2.61514496,  5.04588504,  2.6255033 ,
        0.21962565])
>>> # verifying that it's pickable
>>> import pickle
>>> import numpy as np
>>> ff = pickle.loads(pickle.dumps(f))
>>> assert np.allclose(ff(chk), ff(chk))
slang.spectrop.projection(basis, vectors)[source]

The vectors live in a k dimensional space S and the columns of the basis are vectors of the same space spanning a subspace of S. Gives a representation of the projection of vector into the space spanned by basis in term of the basis.

Parameters
  • basis – an n-by-k array, a matrix whose vertical columns are the vectors of the basis

  • vectors – an m-by-k array, a vector to be represented in the basis

Returns

an m-by-k array

slang.spectrop.reducing_proj(basis, vectors)[source]

What we actually use to get fvs from spectras

slang.spectrop.residue(scalings, X)[source]

find the residue of each of vectors after projection in basis

residues will be vectors in the original space (same number of dimensions)

Parameters
  • scalings – an n-by-m array, spanning a vector space A

  • X – an n-by-k array

Returns

an n-by-l array, the residues of vectors with the respect of the projection in basis

>>> A = np.array([[1,0],[0,1]])
>>> B = np.array([[2,3]])
>>> print(residue(A, B))
[[0 0]]
>>> A = np.array([[1,0],[0,0]])
>>> B = np.array([[2,3]])
>>> print(residue(A, B))
[[0 3]]