Possible Success With ConditionalCategoricalDistribution
Possible Success With ConditionalCategoricalDistribution
Seth J. Chandler
I' ve thought more about how to implement ConditionalCategoricalDistribution. Here’s a current version that is more general than the one I proposed earlier. I am likely going to make this into a ResourceFunction. Comments welcome.
Let the conditions be expressed as a pattern :
In[]:=
ConditionalCategoricalDistribution[pattern_List,cd_]:=Module[{interpretedPattern=PadRight[pattern,Length[Information[cd,"Categories"]],_]},CategoricalDistribution[KeyMap[Part[#,Flatten@Position[interpretedPattern,Verbatim[_]|All,1]]&][KeySelect[Information[cd,"Probabilities"],MatchQ[#,interpretedPattern/.All_]&]]]]
Let the conditions be expressed as a list of rules of the sort that one would use in defining a SparseArray:
In[]:=
ConditionalCategoricalDistribution[pattern:{__Rule},cd_]:=Module[{interpretedPattern=Normal[SparseArray[pattern,Length[Information[cd,"Categories"]],_]]},CategoricalDistribution[KeyMap[Part[#,Flatten@Position[interpretedPattern,Verbatim[_]|All,1]]&][KeySelect[Information[cd,"Probabilities"],MatchQ[#,interpretedPattern/.All_]&]]]]
Create some test data
In[]:=
MixtureCategoricalDistribution::unsamecomponentdomains="The domains of the components are `1`; the component domains must be identical for the function to work.";
In[]:=
MixtureCategoricalDistribution::multivariatemixture="The domain of the components is `1`; the mixture must be univariate for the function to work.";
In[]:=
MixtureCategoricalDistribution[mixture_CategoricalDistribution,components:{__CategoricalDistribution}]:=Catch[Module[{multipliers,mixtureCategories,componentCategories},mixtureCategories=Information[mixture,"Categories"];If[ArrayDepth[Information[mixture,"ProbabilityArray"]]>1,(Message[MixtureCategoricalDistribution::multivariatemixture,mixtureCategories];Throw[$Failed])];componentCategories=Map[Information[#,"Categories"]&,components];If[UnsameQ@@componentCategories,(Message[MixtureCategoricalDistribution::unsamecomponentdomains,componentCategories];Throw[$Failed])];multipliers=Information[mixture,"ProbabilityArray"];CategoricalDistribution[Join[{mixtureCategories},If[ArrayDepth[Information[components[[1]],"ProbabilityArray"]]1,{componentCategories[[1]]},componentCategories[[1]]]],MapThread[Times,{multipliers,Map[Information[#,"ProbabilityArray"]&,components]}]]]]
In[]:=
test=MixtureCategoricalDistributions[CategoricalDistribution[{"a","b"},{0.4,0.6}],{MixtureCategoricalDistributions[CategoricalDistribution[{"Small","Big"},{0.3,0.7}],{CategoricalDistribution[{{"Actual0","Actual1"},{"ClassifyAs0","ClassifyAs1"}},{{20,30},{40,50}}],CategoricalDistribution[{{"Actual0","Actual1"},{"ClassifyAs0","ClassifyAs1"}},{{50,20},{90,190}}]}],MixtureCategoricalDistributions[CategoricalDistribution[{"Small","Big"},{0.1,0.9}],{CategoricalDistribution[{{"Actual0","Actual1"},{"ClassifyAs0","ClassifyAs1"}},{{2,30},{40,55}}],CategoricalDistribution[{{"Actual0","Actual1"},{"ClassifyAs0","ClassifyAs1"}},{{50,20},{90,192}}]}]}]
Out[]=
CategoricalDistribution
Use a simple pattern :
In[]:=
ConditionalCategoricalDistribution[{"b"},test]
Out[]=
CategoricalDistribution
Use a more complex pattern :
In[]:=
ConditionalCategoricalDistribution[{"b","Small"},test]
Out[]=
CategoricalDistribution
Use a yet more complex pattern :
In[]:=
ConditionalCategoricalDistribution[{_,"Small",_,"ClassifyAs1"},test]
Out[]=
CategoricalDistribution
Use rules to specify the conditions :
In[]:=
ConditionalCategoricalDistribution[{2"Small",4"ClassifyAs1"},test]
Out[]=
CategoricalDistribution
