chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
from prml.preprocess.gaussian import GaussianFeature
|
||||
from prml.preprocess.label_transformer import LabelTransformer
|
||||
from prml.preprocess.polynomial import PolynomialFeature
|
||||
from prml.preprocess.sigmoidal import SigmoidalFeature
|
||||
|
||||
|
||||
__all__ = [
|
||||
"GaussianFeature",
|
||||
"LabelTransformer",
|
||||
"PolynomialFeature",
|
||||
"SigmoidalFeature"
|
||||
]
|
||||
@@ -0,0 +1,55 @@
|
||||
import numpy as np
|
||||
|
||||
|
||||
class GaussianFeature(object):
|
||||
"""
|
||||
Gaussian feature
|
||||
|
||||
gaussian function = exp(-0.5 * (x - m) / v)
|
||||
"""
|
||||
|
||||
def __init__(self, mean, var):
|
||||
"""
|
||||
construct gaussian features
|
||||
|
||||
Parameters
|
||||
----------
|
||||
mean : (n_features, ndim) or (n_features,) ndarray
|
||||
places to locate gaussian function at
|
||||
var : float
|
||||
variance of the gaussian function
|
||||
"""
|
||||
if mean.ndim == 1:
|
||||
mean = mean[:, None]
|
||||
else:
|
||||
assert mean.ndim == 2
|
||||
assert isinstance(var, float) or isinstance(var, int)
|
||||
self.mean = mean
|
||||
self.var = var
|
||||
|
||||
def _gauss(self, x, mean):
|
||||
return np.exp(-0.5 * np.sum(np.square(x - mean), axis=-1) / self.var)
|
||||
|
||||
def transform(self, x):
|
||||
"""
|
||||
transform input array with gaussian features
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : (sample_size, ndim) or (sample_size,)
|
||||
input array
|
||||
|
||||
Returns
|
||||
-------
|
||||
output : (sample_size, n_features)
|
||||
gaussian features
|
||||
"""
|
||||
if x.ndim == 1:
|
||||
x = x[:, None]
|
||||
else:
|
||||
assert x.ndim == 2
|
||||
assert np.size(x, 1) == np.size(self.mean, 1)
|
||||
basis = [np.ones(len(x))]
|
||||
for m in self.mean:
|
||||
basis.append(self._gauss(x, m))
|
||||
return np.asarray(basis).transpose()
|
||||
@@ -0,0 +1,65 @@
|
||||
import numpy as np
|
||||
|
||||
|
||||
class LabelTransformer(object):
|
||||
"""
|
||||
Label encoder decoder
|
||||
|
||||
Attributes
|
||||
----------
|
||||
n_classes : int
|
||||
number of classes, K
|
||||
"""
|
||||
|
||||
def __init__(self, n_classes:int=None):
|
||||
self.n_classes = n_classes
|
||||
|
||||
@property
|
||||
def n_classes(self):
|
||||
return self.__n_classes
|
||||
|
||||
@n_classes.setter
|
||||
def n_classes(self, K):
|
||||
self.__n_classes = K
|
||||
self.__encoder = None if K is None else np.eye(K)
|
||||
|
||||
@property
|
||||
def encoder(self):
|
||||
return self.__encoder
|
||||
|
||||
def encode(self, class_indices:np.ndarray):
|
||||
"""
|
||||
encode class index into one-of-k code
|
||||
|
||||
Parameters
|
||||
----------
|
||||
class_indices : (N,) np.ndarray
|
||||
non-negative class index
|
||||
elements must be integer in [0, n_classes)
|
||||
|
||||
Returns
|
||||
-------
|
||||
(N, K) np.ndarray
|
||||
one-of-k encoding of input
|
||||
"""
|
||||
if self.n_classes is None:
|
||||
self.n_classes = np.max(class_indices) + 1
|
||||
|
||||
return self.encoder[class_indices]
|
||||
|
||||
def decode(self, onehot:np.ndarray):
|
||||
"""
|
||||
decode one-of-k code into class index
|
||||
|
||||
Parameters
|
||||
----------
|
||||
onehot : (N, K) np.ndarray
|
||||
one-of-k code
|
||||
|
||||
Returns
|
||||
-------
|
||||
(N,) np.ndarray
|
||||
class index
|
||||
"""
|
||||
|
||||
return np.argmax(onehot, axis=1)
|
||||
@@ -0,0 +1,57 @@
|
||||
import itertools
|
||||
import functools
|
||||
import numpy as np
|
||||
|
||||
|
||||
class PolynomialFeature(object):
|
||||
"""
|
||||
polynomial features
|
||||
|
||||
transforms input array with polynomial features
|
||||
|
||||
Example
|
||||
=======
|
||||
x =
|
||||
[[a, b],
|
||||
[c, d]]
|
||||
|
||||
y = PolynomialFeatures(degree=2).transform(x)
|
||||
y =
|
||||
[[1, a, b, a^2, a * b, b^2],
|
||||
[1, c, d, c^2, c * d, d^2]]
|
||||
"""
|
||||
|
||||
def __init__(self, degree=2):
|
||||
"""
|
||||
construct polynomial features
|
||||
|
||||
Parameters
|
||||
----------
|
||||
degree : int
|
||||
degree of polynomial
|
||||
"""
|
||||
assert isinstance(degree, int)
|
||||
self.degree = degree
|
||||
|
||||
def transform(self, x):
|
||||
"""
|
||||
transforms input array with polynomial features
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : (sample_size, n) ndarray
|
||||
input array
|
||||
|
||||
Returns
|
||||
-------
|
||||
output : (sample_size, 1 + nC1 + ... + nCd) ndarray
|
||||
polynomial features
|
||||
"""
|
||||
if x.ndim == 1:
|
||||
x = x[:, None]
|
||||
x_t = x.transpose()
|
||||
features = [np.ones(len(x))]
|
||||
for degree in range(1, self.degree + 1):
|
||||
for items in itertools.combinations_with_replacement(x_t, degree):
|
||||
features.append(functools.reduce(lambda x, y: x * y, items))
|
||||
return np.asarray(features).transpose()
|
||||
@@ -0,0 +1,62 @@
|
||||
import numpy as np
|
||||
|
||||
|
||||
class SigmoidalFeature(object):
|
||||
"""
|
||||
Sigmoidal features
|
||||
|
||||
1 / (1 + exp((m - x) @ c)
|
||||
"""
|
||||
|
||||
def __init__(self, mean, coef=1):
|
||||
"""
|
||||
construct sigmoidal features
|
||||
|
||||
Parameters
|
||||
----------
|
||||
mean : (n_features, ndim) or (n_features,) ndarray
|
||||
center of sigmoid function
|
||||
coef : (ndim,) ndarray or int or float
|
||||
coefficient to be multplied with the distance
|
||||
"""
|
||||
if mean.ndim == 1:
|
||||
mean = mean[:, None]
|
||||
else:
|
||||
assert mean.ndim == 2
|
||||
if isinstance(coef, int) or isinstance(coef, float):
|
||||
if np.size(mean, 1) == 1:
|
||||
coef = np.array([coef])
|
||||
else:
|
||||
raise ValueError("mismatch of dimension")
|
||||
else:
|
||||
assert coef.ndim == 1
|
||||
assert np.size(mean, 1) == len(coef)
|
||||
self.mean = mean
|
||||
self.coef = coef
|
||||
|
||||
def _sigmoid(self, x, mean):
|
||||
return np.tanh((x - mean) @ self.coef * 0.5) * 0.5 + 0.5
|
||||
|
||||
def transform(self, x):
|
||||
"""
|
||||
transform input array with sigmoidal features
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : (sample_size, ndim) or (sample_size,) ndarray
|
||||
input array
|
||||
|
||||
Returns
|
||||
-------
|
||||
output : (sample_size, n_features) ndarray
|
||||
sigmoidal features
|
||||
"""
|
||||
if x.ndim == 1:
|
||||
x = x[:, None]
|
||||
else:
|
||||
assert x.ndim == 2
|
||||
assert np.size(x, 1) == np.size(self.mean, 1)
|
||||
basis = [np.ones(len(x))]
|
||||
for m in self.mean:
|
||||
basis.append(self._sigmoid(x, m))
|
||||
return np.asarray(basis).transpose()
|
||||
Reference in New Issue
Block a user