'Return the log-likelihood of each sample.
See. "Pattern Recognition and Machine Learning"
by C. Bishop, 12.2.1 p. 574
or http://www.miketipping.com/papers/met-mppca.pdf
Parameters
X : array, shape(n_samples, n_features)
The data.
Returns
ll : array, shape (n_samples,)
Log-likelihood of each sample under the current model'

def score_samples(self, X):

    check_is_fitted(self, 'mean_')
    X = check_array(X)
    Xr = (X - self.mean_)
    n_features = X.shape[1]
    log_like = np.zeros(X.shape[0])
    precision = self.get_precision()
    log_like = ((-0.5) * (Xr * np.dot(Xr, precision)).sum(axis=1))
    log_like -= (0.5 * ((n_features * log((2.0 * np.pi))) - fast_logdet(precision)))
    return log_like
