
    Q3jT                     v   d Z ddlmZ ddlmZmZ ddlmZ ddlZ	ddl
Z
ddlmZ ddlmZ ddlmZ dd	lmZmZmZmZmZ dd
lmZ dZdZddgddgddgddgddgddggZg dZddgddgddgddgddgddggZg dZg dZd Z d Z!e
jD                  jG                  de$e	jJ                  g      d        Z&d Z'e
jD                  jG                  deez         d        Z(d Z)d Z*d Z+e
jD                  jG                  de$e	jJ                  g      d        Z,d  Z-e
jD                  jG                  d!g d"      d#        Z.d$ Z/y)%zG
Testing for export functions of decision trees (sklearn.tree.export).
    )StringIO)finditersearch)dedentN)RandomState)is_classifier)NotFittedError)DecisionTreeClassifierDecisionTreeRegressorexport_graphvizexport_text	plot_tree_rgb_to_hexstring)ginilog_loss)squared_errorabsolute_errorpoisson      )r   r   r   r   r   r      )r   r   r         ?r   r   )r   r   r   r   r   r   c                  $    t        d      dk(  sJ y)z
    Test that _rgb_to_hexstring correctly converts an RGB tuple to a hex color string.

    A previous bug caused incorrect hex color string generation for zero values
    in the RGB tuple.
    )r      r   z#00ff00Nr        K/DATA/.local/lib/python3.12/site-packages/sklearn/tree/tests/test_export.pytest_rgb_to_hexstringr!   #   s     [)Y666r   c            
      f   t        dddd      } | j                  t        t               t	        | d       }d}||k(  sJ t	        | ddgd 	      }d
}||k(  sJ t	        | ddgd 	      }d}||k(  sJ t	        | ddgd       }d}||k(  sJ t	        | ddgd       }d}||k(  sJ t	        | dddddd d      }d}||k(  sJ t	        | ddd       }d}||k(  sJ t	        | ddd d      }d}||k(  sJ t        dddd      } | j                  t        t
        t              } t	        | ddd        }d!}||k(  sJ t        ddd"d      } | j                  t        t               t	        | ddd ddd#      }d$}||k(  sJ t        d%      } | j                  t        t               t	        | dd &      }d'}y )(Nr   r   r   	max_depthmin_samples_split	criterionrandom_stateout_filea  digraph Tree {
node [shape=box, fontname="helvetica"] ;
edge [fontname="helvetica"] ;
0 [label="x[0] <= 0.0\ngini = 0.5\nsamples = 6\nvalue = [3, 3]"] ;
1 [label="gini = 0.0\nsamples = 3\nvalue = [3, 0]"] ;
0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
2 [label="gini = 0.0\nsamples = 3\nvalue = [0, 3]"] ;
0 -> 2 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
}feature0feature1feature_namesr)     digraph Tree {
node [shape=box, fontname="helvetica"] ;
edge [fontname="helvetica"] ;
0 [label="feature0 <= 0.0\ngini = 0.5\nsamples = 6\nvalue = [3, 3]"] ;
1 [label="gini = 0.0\nsamples = 3\nvalue = [3, 0]"] ;
0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
2 [label="gini = 0.0\nsamples = 3\nvalue = [0, 3]"] ;
0 -> 2 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
}z
feature"0"z
feature"1"a  digraph Tree {
node [shape=box, fontname="helvetica"] ;
edge [fontname="helvetica"] ;
0 [label="feature\"0\" <= 0.0\ngini = 0.5\nsamples = 6\nvalue = [3, 3]"] ;
1 [label="gini = 0.0\nsamples = 3\nvalue = [3, 0]"] ;
0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
2 [label="gini = 0.0\nsamples = 3\nvalue = [0, 3]"] ;
0 -> 2 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
}yesnoclass_namesr)     digraph Tree {
node [shape=box, fontname="helvetica"] ;
edge [fontname="helvetica"] ;
0 [label="x[0] <= 0.0\ngini = 0.5\nsamples = 6\nvalue = [3, 3]\nclass = yes"] ;
1 [label="gini = 0.0\nsamples = 3\nvalue = [3, 0]\nclass = yes"] ;
0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
2 [label="gini = 0.0\nsamples = 3\nvalue = [0, 3]\nclass = no"] ;
0 -> 2 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
}z"yes"z"no"a  digraph Tree {
node [shape=box, fontname="helvetica"] ;
edge [fontname="helvetica"] ;
0 [label="x[0] <= 0.0\ngini = 0.5\nsamples = 6\nvalue = [3, 3]\nclass = \"yes\""] ;
1 [label="gini = 0.0\nsamples = 3\nvalue = [3, 0]\nclass = \"yes\""] ;
0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
2 [label="gini = 0.0\nsamples = 3\nvalue = [0, 3]\nclass = \"no\""] ;
0 -> 2 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
}TFsans)filledimpurity
proportionspecial_charactersroundedr)   fontnamea  digraph Tree {
node [shape=box, style="filled, rounded", color="black", fontname="sans"] ;
edge [fontname="sans"] ;
0 [label=<x<SUB>0</SUB> &le; 0.0<br/>samples = 100.0%<br/>value = [0.5, 0.5]>, fillcolor="#ffffff"] ;
1 [label=<samples = 50.0%<br/>value = [1.0, 0.0]>, fillcolor="#e58139"] ;
0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
2 [label=<samples = 50.0%<br/>value = [0.0, 1.0]>, fillcolor="#399de5"] ;
0 -> 2 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
}r   )r$   r2   r)   zdigraph Tree {
node [shape=box, fontname="helvetica"] ;
edge [fontname="helvetica"] ;
0 [label="x[0] <= 0.0\ngini = 0.5\nsamples = 6\nvalue = [3, 3]\nclass = y[0]"] ;
1 [label="(...)"] ;
0 -> 1 ;
2 [label="(...)"] ;
0 -> 2 ;
})r$   r5   r)   node_idsa;  digraph Tree {
node [shape=box, style="filled", color="black", fontname="helvetica"] ;
edge [fontname="helvetica"] ;
0 [label="node #0\nx[0] <= 0.0\ngini = 0.5\nsamples = 6\nvalue = [3, 3]", fillcolor="#ffffff"] ;
1 [label="(...)", fillcolor="#C0C0C0"] ;
0 -> 1 ;
2 [label="(...)", fillcolor="#C0C0C0"] ;
0 -> 2 ;
})sample_weight)r5   r6   r)   a  digraph Tree {
node [shape=box, style="filled", color="black", fontname="helvetica"] ;
edge [fontname="helvetica"] ;
0 [label="x[0] <= 0.0\nsamples = 6\nvalue = [[3.0, 1.5, 0.0]\n[3.0, 1.0, 0.5]]", fillcolor="#ffffff"] ;
1 [label="samples = 3\nvalue = [[3, 0, 0]\n[3, 0, 0]]", fillcolor="#e58139"] ;
0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
2 [label="x[0] <= 1.5\nsamples = 3\nvalue = [[0.0, 1.5, 0.0]\n[0.0, 1.0, 0.5]]", fillcolor="#f1bd97"] ;
0 -> 2 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
3 [label="samples = 2\nvalue = [[0, 1, 0]\n[0, 1, 0]]", fillcolor="#e58139"] ;
2 -> 3 ;
4 [label="samples = 1\nvalue = [[0.0, 0.5, 0.0]\n[0.0, 0.0, 0.5]]", fillcolor="#e58139"] ;
2 -> 4 ;
}r   )r5   leaves_parallelr)   rotater9   r:   aT  digraph Tree {
node [shape=box, style="filled, rounded", color="black", fontname="sans"] ;
graph [ranksep=equally, splines=polyline] ;
edge [fontname="sans"] ;
rankdir=LR ;
0 [label="x[0] <= 0.0\nsquared_error = 1.0\nsamples = 6\nvalue = 0.0", fillcolor="#f2c09c"] ;
1 [label="squared_error = 0.0\nsamples = 3\nvalue = -1.0", fillcolor="#ffffff"] ;
0 -> 1 [labeldistance=2.5, labelangle=-45, headlabel="True"] ;
2 [label="squared_error = 0.0\nsamples = 3\nvalue = 1.0", fillcolor="#e58139"] ;
0 -> 2 [labeldistance=2.5, labelangle=45, headlabel="False"] ;
{rank=same ; 0} ;
{rank=same ; 1; 2} ;
}r$   )r5   r)   zdigraph Tree {
node [shape=box, style="filled", color="black", fontname="helvetica"] ;
edge [fontname="helvetica"] ;
0 [label="gini = 0.0\nsamples = 6\nvalue = 6.0", fillcolor="#ffffff"] ;
})	r
   fitXyr   y2wr   
y_degraded)clf	contents1	contents2s      r    test_graphviz_toyrI   .   s   
 qFC GGAqM  d3I	  	!!!  J
3dI	  	!!!  L,7$I	   	!!!  %NI	 " 	!!!  '61BTRI	 " 	!!!  	I	 $ 	!!!  qdTRI		  	!!!  qtI
	  	!!! !qFC ''!Rq'
)CD54PI	 4 	!!!  qORSC GGAqMI	 . 	!!! !1
-CGGAzD4@I	 r   constructorc                     t        dddd      }|j                  t        t               t	        | | ddg      d       }d}||k(  sJ t	        | | d	d
g      d       }d}||k(  sJ y )Nr   r   r   r#   r*   r+   r,   r.   r/   r0   r1   r3   )r
   r@   rA   rB   r   )rJ   rF   rG   rH   s       r    /test_graphviz_feature_class_names_array_supportrL   ;  s     !qFC GGAqM  ;
J'?@4I	  	!!!  eT]3dI	 " 	!!!r   c                     t        dd      } t               }t        j                  t              5  t        | |       d d d        | j                  t        t               d}t        j                  t        |      5  t        | d dg       d d d        d}t        j                  t        |      5  t        | d g d	       d d d        d
}t        j                  t        |      5  t        | d ddg       d d d        d}t        j                  t        |      5  t        | j                  t        t              j                         d d d        t               }t        j                  t              5  t        | |g        d d d        y # 1 sw Y   SxY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   vxY w# 1 sw Y   y xY w)Nr   r   )r$   r%   z?Length of feature_names, 1 does not match number of features, 2matchar-   z?Length of feature_names, 3 does not match number of features, 2)rP   bcz"All feature names must be strings.r   zis not an estimator instancer2   )r
   r   pytestraisesr	   r   r@   rA   rB   
ValueError	TypeErrortree_
IndexError)rF   outmessages      r    test_graphviz_errorsr]   q  sL   
 1
BC *C	~	&S! 
' GGAqM PG	z	1T#7 
2 PG	z	1TA 
2 3G	z	1T#q: 
2 -G	y	01++, 
1 *C	z	"Sb1 
#	"7 
'	& 
2	1 
2	1
 
2	1
 
1	0
 
#	"sG   F=F2F)(F5.G7GFF&)F25F>G
Gr&   c                 L   t               }| t        v }|rt        nt        } |d|       }|rt        D cg c]  }|dz   	 c}nt        }|j                  t        |       t        ||       t        d|j                               D ]  }| |j                         v rJ  y c c}w )Nr   )r'   r&   r   r(   z\[.*?samples.*?\])r   REG_CRITERIONSr   r
   rB   r@   rA   r   r   getvaluegroup)r&   dot_datais_regTreerF   yiy_findings           r    ,test_criterion_in_gradient_boosting_graphvizrh     s    zH.(F$* 0FD
A
3C!'1	1R"q&1	QBGGArNC(+0(2C2C2EFGMMO+++ G	 
s   B!c            
      D   t        d      } t        d      }t        | j                  d      |j                  d      f| j                  d      |j                  dd      ft	        dd	
      t        d	d      f      D ]  \  }}}|j                  ||       dD ]   }t        |d |d      }t        d|      D ];  }t        t        d|j                               j                               |d	z   k  r;J  t        |      rd}nd}t        ||      D ];  }t        t        d|j                               j                               |d	z   k(  r;J  t        d|      D ];  }t        t        d|j                               j                               |d	z   k(  r;J   " y )Nr      )   r   )     )rk   )rl   )sizer   r   )r'   r$   r$   r'   )rm   r   T)r)   	precisionr7   zvalue = \d+\.\d+z\.\d+zgini = \d+\.\d+zsquared_error = \d+\.\d+z<= \d+\.\d+)r   ziprandom_samplerandintr   r
   r@   r   r   lenr   ra   r   )	rng_regrng_clfrA   rB   rF   rp   rb   rg   patterns	            r    test_precisionrx     s   !nG!nG			v	&(=(=i(HI			t	$gooago&FG!qA>"QQ?	
	1c 	1I&diDH $$7B6(GMMO<BBDEUVVVV C S!,5 $GX66(GMMO<BBDEUVVVV 7 $NH=6(GMMO<BBDEUVVVV >1  r   c                  R   t        dd      } | j                  t        t               d}t	        j
                  t        |      5  t        | dg       d d d        d}t	        j
                  t        |      5  t        | dg	       d d d        y # 1 sw Y   >xY w# 1 sw Y   y xY w)
Nr   r   ro   z,feature_names must contain 2 elements, got 1rN   rP   rQ   zWhen `class_names` is an array, it should contain as many items as `decision_tree.classes_`. Got 1 while the tree was fitted with 2 classes.rT   )r
   r@   rA   rB   rU   rV   rW   r   )rF   err_msgs     r    test_export_text_errorsr{     s    
 11
=CGGAqM<G	z	1Cu- 
2	/ 
 
z	1CcU+ 
2	1 
2	1 
2	1s   B9BBB&c                  J   t        dd      } | j                  t        t               t	        d      j                         }t        |       |k(  sJ t        | d      |k(  sJ t        | d      |k(  sJ t	        d      j                         }t        | d	      |k(  sJ t	        d
      j                         }t        | d      |k(  sJ ddgddgddgddgddgddgddgg}g d}t        dd      } | j                  ||       t	        d      j                         }t        | d      |k(  sJ ddgddgddgddgddgddgg}ddgddgddgddgddgddgg}t        dd      }|j                  ||       t	        d      j                         }t        |d      |k(  sJ t        |dd      |k(  sJ dgdgdgdgdgdgg}t        dd      }|j                  ||       t	        d      j                         }t        |ddg      |k(  sJ t        |dddg      |k(  sJ y )Nr   r   ro   zh
    |--- feature_1 <= 0.00
    |   |--- class: -1
    |--- feature_1 >  0.00
    |   |--- class: 1
    r?   
   z
    |--- feature_1 <= 0.00
    |   |--- weights: [3.00, 0.00] class: -1
    |--- feature_1 >  0.00
    |   |--- weights: [0.00, 3.00] class: 1
    T)show_weightsz\
    |- feature_1 <= 0.00
    | |- class: -1
    |- feature_1 >  0.00
    | |- class: 1
    r   )spacingr   r   )r   r   r   r   r   r   r   rm   z{
    |--- feature_1 <= 0.00
    |   |--- class: -1
    |--- feature_1 >  0.00
    |   |--- truncated branch of depth 2
    zy
    |--- feature_1 <= 0.0
    |   |--- value: [-1.0, -1.0]
    |--- feature_1 >  0.0
    |   |--- value: [1.0, 1.0]
    )decimals)r   r~   zq
    |--- first <= 0.0
    |   |--- value: [-1.0, -1.0]
    |--- first >  0.0
    |   |--- value: [1.0, 1.0]
    first)r   r-   )r   r~   r-   )r
   r@   rA   rB   r   lstripr   r   )rF   expected_reportX_ly_lX_moy_moregX_singles           r    test_export_textr     s   
 11
=CGGAqM	 fh  s...sa(O;;;sb)_<<<	 fh  s./AAA	 fh  sA&/9998b"XBx!Q!Q!Q"a
IC
"C
 11
=CGGC	 fh  sa(O;;;Hr2hR1a&1a&1a&ADHr2hR1a&1a&1a&AD
!!
<CGGD$	 fh  sQ'?:::sQT:oMMMrdRD1#sQC0H
!!
<CGGHd	 fh  sQwi@OSSSC!$wiP		r   c                    t        dd      }|j                  t        t               t	        d      j                         }t        | | ddg            |k(  sJ t	        d      j                         }t        | | d	d
g            |k(  sJ y )Nr   r   ro   zX
    |--- b <= 0.00
    |   |--- class: -1
    |--- b >  0.00
    |   |--- class: 1
    rP   rR   rQ   zk
    |--- feature_1 <= 0.00
    |   |--- class: cat
    |--- feature_1 >  0.00
    |   |--- class: dog
    catdogrT   )r
   r@   rA   rB   r   r   r   )rJ   rF   r   s      r    2test_export_text_feature_class_names_array_supportr   6  s     !11
=CGGAqM	 fh  s+sCj*ABoUUU	 fh  sUEN(CDWWWr   c                    t        dddd      }|j                  t        t               ddg}t	        ||      }t        |      dk(  sJ |d	   j                         d
k(  sJ |d   j                         dk(  sJ |d   j                         dk(  sJ |d   j                         dk(  sJ |d   j                         dk(  sJ y )Nr   r   entropyr#   
first featsepal_widthrQ   rk   r   z:first feat <= 0.0
entropy = 1.0
samples = 6
value = [3, 3]r   z(entropy = 0.0
samples = 3
value = [3, 0]True  z(entropy = 0.0
samples = 3
value = [0, 3]rm     False)r
   r@   rA   rB   r   rt   get_text)pyplotrF   r-   nodess       r    test_plot_tree_entropyr   R  s     !qIAC GGAqM "=1Mc7Eu:??aJ	K	K 8"NNNN8(***8"NNNN8)+++r   fontsize)Nr}      c                    t        dddd      }|j                  t        t               ddg}t	        ||      }t        |      dk(  sJ t        fd	|D              sJ |d
   j                         dk(  sJ |d   j                         dk(  sJ |d   j                         dk(  sJ |d   j                         dk(  sJ |d   j                         dk(  sJ y )Nr   r   r   r#   r   r   )r-   r   rk   c              3   D   K   | ]  }|j                         k(    y wN)get_fontsize).0noder   s     r    	<genexpr>z&test_plot_tree_gini.<locals>.<genexpr>y  s      Eut4$$&(2us    r   z7first feat <= 0.0
gini = 0.5
samples = 6
value = [3, 3]r   z%gini = 0.0
samples = 3
value = [3, 0]r   z%gini = 0.0
samples = 3
value = [0, 3]rm   r   )r
   r@   rA   rB   r   rt   allr   )r   r   rF   r-   r   s    `   r    test_plot_tree_ginir   h  s    !	C GGAqM "=1McJEu:??EuEEEEaG	H	H 8"KKKK8(***8"KKKK8)+++r   c                     t               }t        j                  t              5  t	        |       d d d        y # 1 sw Y   y xY wr   )r   rU   rV   r	   r   )r   rF   s     r    test_not_fitted_treer     s)    

!C	~	&# 
'	&	&s	   9A)0__doc__ior   rer   r   textwrapr   numpynprU   numpy.randomr   sklearn.baser   sklearn.exceptionsr	   sklearn.treer
   r   r   r   r   sklearn.tree._exportr   CLF_CRITERIONSr_   rA   rB   rC   rD   rE   r!   rI   markparametrizelistarrayrL   r]   rh   rx   r{   r   r   r   r   r   r   r   r    <module>r      s        $ & -  3%? 	"XBx"bAq6Aq6Aq6:	1gAwQ!Q!Q!Q8
7JZ rxx(892" :2"j"2J n~&EF, G,%WP,Vr rxx(89X :X6,, ^4, 5,6r   