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
Input type: Vector (length: 4)
Categories:
a
b
×
Small
Big
×
Actual0
Actual1
×
ClassifyAs0
ClassifyAs1

Use a simple pattern :
In[]:=
ConditionalCategoricalDistribution[{"b"},test]
Out[]=
CategoricalDistribution
Input type: Vector (length: 3)
Categories:
Big
Small
×
Actual0
Actual1
×
ClassifyAs0
ClassifyAs1

Use a more complex pattern :
In[]:=
ConditionalCategoricalDistribution[{"b","Small"},test]
Out[]=
CategoricalDistribution
Input type: Vector (length: 2)
Categories:
Actual0
Actual1
×
ClassifyAs0
ClassifyAs1

Use a yet more complex pattern :
In[]:=
ConditionalCategoricalDistribution[{_,"Small",_,"ClassifyAs1"},test]
Out[]=
CategoricalDistribution
Input type: Vector (length: 2)
Categories:
a
b
×
Actual0
Actual1

Use rules to specify the conditions :
In[]:=
ConditionalCategoricalDistribution[{2"Small",4"ClassifyAs1"},test]
Out[]=
CategoricalDistribution
Input type: Vector (length: 2)
Categories:
a
b
×
Actual0
Actual1
