def estimate_DiscreteMixture(histo, *args, **kargs): """ Estimate a finite mixture of discrete distributions :Parameters: * histo (histogram, mixture_data, convolution_data, compound_data), * distributions (list) : a list of distribution object or distribution label(string) : 'B', 'NB', 'U', 'P', ... * unknown (string): type of unknown distribution: "Sum" or "Elementary". :Keywords: * MinInfBound (int): lower bound to the range of possible values (0 -default- or 1). \ This optional argument cannot be used in conjunction \ with the optional argument InitialDistribution. * InfBoundStatus (string): shifting or not of the distribution: "Free" (default value) or "Fixed". * DistInfBoundStatus (string): shifting or not of the subsequent components of \ the mixture: "Free" (default value) or "Fixed". * NbComponent (string): estimation of the number of components of the mixture: \ "Fixed" (default value) or "Estimated". Le number of estimated \ components is comprised between\ 1 and a maximum number which is given by the number of specified \ parametric distributions in the mandatory arguments \ (all of these distributions are assumed to be unknown). * Penalty (string): type of Penalty function for model selection: \ "AIC" (Akaike Information Criterion), \ "AICc" (corrected Akaike Information Criterion) \ "BIC" (Bayesian Information Criterion - default value). \ "BICc" (corrected Bayesian Information Criterion). \ This optional argument can only be used if the optional argument NbComponent is set at "Estimated". :Examples: .. doctest:: :options: +SKIP >>> estimate_DiscreteMixture(histo, "MIXTURE", "B", dist,...,, MinInfBound=1, InfBoundStatus="Fixed", DistInfBoundStatus="Fixed") >>> estimate_DiscreteMixture(histo, "MIXTURE", "B", "NB",...,, MinInfBound=1, InfBoundStatus="Fixed", DistInfBoundStatus="Fixed", NbComponent="Estimated", Penalty="AIC") >>> Estimate(histo, "MIXTURE", "B", dist, MinInfBound=1, InfBoundStatus="Fixed", DistInfBoundStatus="Fixed") >>> Estimate(histo, "MIXTURE", "B", "NB", MinInfBound=1, InfBoundStatus="Fixed", DistInfBoundStatus="Fixed", NbComponent="Estimated", Penalty="AIC") """ #alias #error.CheckArgumentsLength(args, 1, 1) # get user arguments # list of distributions can be either a list or several arguments # e.g.: estimate_DiscreteMixture(["B","B"]) or estimate_DiscreteMixture("B", "B") if len(args)==1 and type(args[0])==list: distributions = args[0] else: distributions = list(args) InfBoundStatus = kargs.get("InfBoundStatus","Free") DistInfBoundStatus = kargs.get("DistInfBoundStatus", "Free") NbComponent = kargs.get("NbComponent", "Fixed") MinInfBound = kargs.get("MinInfBound", 0) Penalty = error.ParseKargs(kargs, "Penalty", "AIC", likelihood_penalty_type) #should be before the conversion to booleans error.CheckType([MinInfBound, InfBoundStatus, DistInfBoundStatus, NbComponent, Penalty], [int, str, str, str, LikelihoodPenaltyType]) # transform into boolean when needed InfBoundStatus = bool(InfBoundStatus == "Free") DistInfBoundStatus = bool(DistInfBoundStatus == "Free") NbComponent = bool(NbComponent == "Estimated") estimate = [] # list of bool pcomponent = [] # list of distribution ident = [] # list of distribution identifier # Parse list of distribution that could be defined by a distribution, # compound, mixture, convolution or simplya string such as "B", # "Mixture", ... for dist in distributions: if isinstance(dist, str): dist_authorised = ["BINOMIAL", "B", "POISSON", "P", "NB", "NEGATIVE_BINOMIAL"] if dist not in dist_authorised: raise ValueError("""If distribution is a string, then it must be in %s. You provided %s""" % (dist_authorised, dist)) #todo: check that poisson is allowed pcomponent.append(_DiscreteParametric(0, dist_type[dist])) ident.append(dist_type[dist]) estimate.append(True) elif isinstance(dist, _DiscreteParametricModel): pcomponent.append(_DiscreteParametric(dist)) ident.append(None) estimate.append(False) elif type(dist) in [_DiscreteMixture, _Convolution, _Compound]: pcomponent.append(_Distribution(dist)) ident.append(None) estimate.append(False) else: raise ValueError("""In the case of a MIXTURE estimation, argument related to distributions must be either string, or Distribution, Mixture, Convolution, Compound. %s provided""" % dist) # check parameters if not NbComponent and Penalty: raise TypeError(""" Penalty can only be used with NbComponent set to 'Estimated'""") if not NbComponent: # "FIXED" imixt = _DiscreteMixture(pcomponent) ret = histo.discrete_mixture_estimation1(imixt, estimate, MinInfBound, InfBoundStatus, DistInfBoundStatus) return ret else: # "ESTIMATED" ret = histo.discrete_mixture_estimation2(ident, MinInfBound, InfBoundStatus, DistInfBoundStatus, Penalty) return ret
def estimate_DiscreteMixture(histo, *args, **kargs): """ Estimate a finite mixture of discrete distributions :Parameters: * histo (histogram, mixture_data, convolution_data, compound_data), * distributions (list) : a list of distribution object or distribution label(string) : 'B', 'NB', 'U', 'P', ... * unknown (string): type of unknown distribution: "Sum" or "Elementary". :Keywords: * MinInfBound (int): lower bound to the range of possible values (0 -default- or 1). \ This optional argument cannot be used in conjunction \ with the optional argument InitialDistribution. * InfBoundStatus (string): shifting or not of the distribution: "Free" (default value) or "Fixed". * DistInfBoundStatus (string): shifting or not of the subsequent components of \ the mixture: "Free" (default value) or "Fixed". * NbComponent (string): estimation of the number of components of the mixture: \ "Fixed" (default value) or "Estimated". Le number of estimated \ components is comprised between\ 1 and a maximum number which is given by the number of specified \ parametric distributions in the mandatory arguments \ (all of these distributions are assumed to be unknown). * Penalty (string): type of Penalty function for model selection: \ "AIC" (Akaike Information Criterion), \ "AICc" (corrected Akaike Information Criterion) \ "BIC" (Bayesian Information Criterion - default value). \ "BICc" (corrected Bayesian Information Criterion). \ This optional argument can only be used if the optional argument NbComponent is set at "Estimated". :Examples: .. doctest:: :options: +SKIP >>> estimate_DiscreteMixture(histo, "MIXTURE", "B", dist,...,, MinInfBound=1, InfBoundStatus="Fixed", DistInfBoundStatus="Fixed") >>> estimate_DiscreteMixture(histo, "MIXTURE", "B", "NB",...,, MinInfBound=1, InfBoundStatus="Fixed", DistInfBoundStatus="Fixed", NbComponent="Estimated", Penalty="AIC") >>> Estimate(histo, "MIXTURE", "B", dist, MinInfBound=1, InfBoundStatus="Fixed", DistInfBoundStatus="Fixed") >>> Estimate(histo, "MIXTURE", "B", "NB", MinInfBound=1, InfBoundStatus="Fixed", DistInfBoundStatus="Fixed", NbComponent="Estimated", Penalty="AIC") """ #alias #error.CheckArgumentsLength(args, 1, 1) # get user arguments # list of distributions can be either a list or several arguments # e.g.: estimate_DiscreteMixture(["B","B"]) or estimate_DiscreteMixture("B", "B") if len(args) == 1 and type(args[0]) == list: distributions = args[0] else: distributions = list(args) InfBoundStatus = kargs.get("InfBoundStatus", "Free") DistInfBoundStatus = kargs.get("DistInfBoundStatus", "Free") NbComponent = kargs.get("NbComponent", "Fixed") MinInfBound = kargs.get("MinInfBound", 0) Penalty = error.ParseKargs(kargs, "Penalty", "AIC", likelihood_penalty_type) #should be before the conversion to booleans error.CheckType([ MinInfBound, InfBoundStatus, DistInfBoundStatus, NbComponent, Penalty ], [int, str, str, str, LikelihoodPenaltyType]) # transform into boolean when needed InfBoundStatus = bool(InfBoundStatus == "Free") DistInfBoundStatus = bool(DistInfBoundStatus == "Free") NbComponent = bool(NbComponent == "Estimated") estimate = [] # list of bool pcomponent = [] # list of distribution ident = [] # list of distribution identifier # Parse list of distribution that could be defined by a distribution, # compound, mixture, convolution or simplya string such as "B", # "Mixture", ... for dist in distributions: if isinstance(dist, str): dist_authorised = [ "BINOMIAL", "B", "POISSON", "P", "NB", "NEGATIVE_BINOMIAL" ] if dist not in dist_authorised: raise ValueError("""If distribution is a string, then it must be in %s. You provided %s""" % (dist_authorised, dist)) #todo: check that poisson is allowed pcomponent.append(_DiscreteParametric(0, dist_type[dist])) ident.append(dist_type[dist]) estimate.append(True) elif isinstance(dist, _DiscreteParametricModel): pcomponent.append(_DiscreteParametric(dist)) ident.append(None) estimate.append(False) elif type(dist) in [_DiscreteMixture, _Convolution, _Compound]: pcomponent.append(_Distribution(dist)) ident.append(None) estimate.append(False) else: raise ValueError("""In the case of a MIXTURE estimation, argument related to distributions must be either string, or Distribution, Mixture, Convolution, Compound. %s provided""" % dist) # check parameters if not NbComponent and Penalty: raise TypeError(""" Penalty can only be used with NbComponent set to 'Estimated'""") if not NbComponent: # "FIXED" imixt = _DiscreteMixture(pcomponent) ret = histo.discrete_mixture_estimation1(imixt, estimate, MinInfBound, InfBoundStatus, DistInfBoundStatus) return ret else: # "ESTIMATED" ret = histo.discrete_mixture_estimation2(ident, MinInfBound, InfBoundStatus, DistInfBoundStatus, Penalty) return ret
def Mixture(*args): """Construction of a mixture of distributions from elementary distributions and associated weights or from an ASCII file. A mixture is a parametric model of classification where each elementary distribution or component represents a class with its associated weight. :Parameters: * `weight1`, `weight2`, ... (float) - weights of each component. These weights should sum to one (they constitute a discrete distribution). * `dist1`, `dist2`, ... (`_DiscreteParametricModel`, `_DiscreteMixture`, `_Convolution`, `_Compound`) elementary distributions (or components). * `filename` (string) - :Returns: If the construction succeeds, an object of type mixture is returned, otherwise no object is returned. :Examples: .. doctest:: :options: +SKIP >>> Mixture(weight1, dist1, weight2, dist2,...) >>> Mixture(filename) .. seealso:: :func:`~openalea.stat_tool.output.Save`, :func:`~openalea.stat_tool.estimate.Estimate`, :func:`~openalea.stat_tool.simulate.Simulate`. """ error.CheckArgumentsLength(args, 1) types = [ _DiscreteParametricModel, _DiscreteMixture, _Compound, _Convolution ] # filename if (len(args) == 1): error.CheckType([args[0]], [str], arg_id=[1]) result = _DiscreteMixture(args[0]) # build list of weights and distributions else: nb_param = len(args) if ((nb_param % 2) != 0): raise TypeError("Number of parameters must be pair") # Extract weights ands distributions weights = [] dists = [] for i in xrange(nb_param / 2): weights.append(args[i * 2]) error.CheckType([args[i * 2 + 1]], [types], arg_id=[i * 2 + 1]) error.CheckType([args[i * 2]], [float], arg_id=[i * 2]) #dists.append(_Distribution(args[i * 2 + 1])) dists.append((args[i * 2 + 1])) result = _DiscreteMixture(weights, dists) return result
def Mixture(*args): """Construction of a mixture of distributions from elementary distributions and associated weights or from an ASCII file. A mixture is a parametric model of classification where each elementary distribution or component represents a class with its associated weight. :Parameters: * `weight1`, `weight2`, ... (float) - weights of each component. These weights should sum to one (they constitute a discrete distribution). * `dist1`, `dist2`, ... (`_DiscreteParametricModel`, `_DiscreteMixture`, `_Convolution`, `_Compound`) elementary distributions (or components). * `filename` (string) - :Returns: If the construction succeeds, an object of type mixture is returned, otherwise no object is returned. :Examples: .. doctest:: :options: +SKIP >>> Mixture(weight1, dist1, weight2, dist2,...) >>> Mixture(filename) .. seealso:: :func:`~openalea.stat_tool.output.Save`, :func:`~openalea.stat_tool.estimate.Estimate`, :func:`~openalea.stat_tool.simulate.Simulate`. """ error.CheckArgumentsLength(args, 1) types = [_DiscreteParametricModel, _DiscreteMixture, _Compound, _Convolution] # filename if (len(args) == 1): error.CheckType([args[0]], [str], arg_id=[1]) result = _DiscreteMixture(args[0]) # build list of weights and distributions else: nb_param = len(args) if ((nb_param % 2) != 0): raise TypeError("Number of parameters must be pair") # Extract weights ands distributions weights = [] dists = [] for i in xrange(nb_param / 2): weights.append(args[i * 2]) error.CheckType([args[i * 2 + 1]], [types], arg_id=[i * 2 + 1]) error.CheckType([args[i * 2]], [float], arg_id=[i * 2]) #dists.append(_Distribution(args[i * 2 + 1])) dists.append((args[i * 2 + 1])) result = _DiscreteMixture(weights, dists) return result