Log of the loss (error) summed over all entries

    The negative of the logarithm of the frequency (probability) of the predicted
    label given the true binary label for a category.

    Arguments:
      predicted (np.array of float): 2-D table of probabilities for each
        category (columns) and each record (rows)
      actual (np.array of float): True binary labels for each category
        Should only have a single 1 on each row indicating the one
        correct category (column)

    Based On:
        https://www.kaggle.com/wiki/LogarithmicLoss
        http://scikit-learn.org/stable/modules/model_evaluation.html#log-loss

def log_loss(actual, predicted):
    """Log of the loss (error) summed over all entries

    The negative of the logarithm of the frequency (probability) of the predicted
    label given the true binary label for a category.

    Arguments:
      predicted (np.array of float): 2-D table of probabilities for each
        category (columns) and each record (rows)
      actual (np.array of float): True binary labels for each category
        Should only have a single 1 on each row indicating the one
        correct category (column)

    Based On:
        https://www.kaggle.com/wiki/LogarithmicLoss
        http://scikit-learn.org/stable/modules/model_evaluation.html#log-loss
    """

    predicted, actual = np.array(predicted), np.array(actual)

    small_value = 1e-15
    predicted[predicted < small_value] = small_value
    predicted[predicted > 1 - small_value] = 1. - small_value
    return (-1. / len(actual)) * np.sum(
        actual * np.log(predicted) + (1. - actual) * np.log(1. - predicted))