which algorithm uses a multidimension array of average probabilities Is there an algorithm that returns the mean probability of response from a multi-dimensional matrix?
For example, if I have a set of features:


*

*customerClass = poor / middle / rich

*category = 11 / 20 / 35

*offerValue = $1 / $2 / $3
and a response:


*

*usesCoupon = FALSE / TRUE


Assuming I have enough samples, I want to predict the probability for a new sample (customerClass = rich, category = 20, offerValue = $1) as the average probability for the population with the same three-dimensional value (rich, 20, $1).
 A: The following function f will find the probability you're after. It's important that the input vector x is of the same length and in the same order as the rows of your data frame df, or else the duplicated function will not work as intended. You will need to customize this function to handle missing data & work with different dependent variable columns, as usesCoupon is assumed.
f = function(x, df){
    # x is a vector of inputs the same length & order
    # as the second dimension of df without usesCoupon
    features = df[, !(colnames(df) %in% c('usesCoupon'))]
    rows = duplicated(rbind(x, features))[-1]
    how.many.true = as.numeric(df[rows,]$usesCoupon == TRUE)
    return(mean(how.many.true))
}

I imagine there are more efficient ways to do this, but this should work fine for manageable data sets.
A: You are looking for the mean response of answers from the subset of your data. You can completely describe the subset by the index (customerClass, category, offerValue) and the responses (n_uses_coupon, n_total). This could be stored in a pair of dictionaries:
uses_coupon = dict()
all_responses = dict()

To 'train' your model, simply insert data into the dictionaries:
def fit_on_sample(customerClass, category, offerValue, response):
    if (customerClass, category, offerValue) not in all_responses:
        all_responses[customerClass, category, offerValue] = 0
        uses_coupon[customerClass, category, offerValue] = 0
    if response:
        uses_coupon[customerClass, category, offerValue] += 1
    all_responses[customerClass, category, offerValue] += 1

def fit(samples, responses)
    for (customerClass, category, offerValue), response in zip(samples, responses):
        fit_on_sample(customerClass, category, offerValue, response)

To make predictions with this model, simple lookup the counts and calculate the mean:
def predict(customerClass, category, offerValue, threshold=0.5, response_on_missing=None):
    if (customerClass, category, offerValue) in all_responses:
        used_coupon = uses_coupon[customerClass, category, offerValue]
        total_responses = all_responses[customerClass, category, offerValue]
        score = int(used_coupon) / total_responses
        return int(score >= threshold)
    else:
        return response_on_missing

If you wrap this in a class you can use multiple instances of it:
class LocalMeanPredictor(object):
    def __init__(self):
        self.uses_coupon = dict()
        self.all_responses = dict()

    def fit_on_sample(self, customerClass, category, offerValue, response):
        if (customerClass, category, offerValue) not in self.all_responses:
            self.all_responses[customerClass, category, offerValue] = 0
            self.uses_coupon[customerClass, category, offerValue] = 0
        if response:
            self.uses_coupon[customerClass, category, offerValue] += 1
        self.all_responses[customerClass, category, offerValue] += 1

    def fit(self, samples, responses)
        for (customerClass, category, offerValue), response in zip(samples, responses):
            self.fit_on_sample(customerClass, category, offerValue, response)

    def predict_with_sample_size(self, customerClass, category, offerValue, response_on_missing=None):
        if (customerClass, category, offerValue) in self.all_responses:
            used_coupon = self.uses_coupon[customerClass, category, offerValue]
            total_responses = self.all_responses[customerClass, category, offerValue]
            score = int(used_coupon) / total_responses
            return int(score >= threshold), total_responses
        else:
            return response_on_missing, 0

    def predict(self, customerClass, category, offerValue, response_on_missing=None):
        return predict_with_sample_size(customerClass, category, offerValue, response_on_missing)[0]

I also added a predict_with_sample size method which will allow you to use this method when you have sufficient data, and switch to a slower algorithm when your data is too sparse.
You may also wish to research k-nearest-neighbours algorithms, particularly if you find too many predictions have a sample size less than is adequate. The algorithm is simple to understand and available in most libraries. (See scikit-learn for python.)
http://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm
Finally, you should still perform train-test splits on your data and validate that the model can generalise to new samples.
http://en.wikipedia.org/wiki/Cross-validation_(statistics)
