
    +tWj'                     `    S r SSKrSSKrSSKJrJrJrJ	r	J
r
  SSKJr  SSKJr   " S S5      rg)u3  
Фреймворк для сравнения моделей на Walk-Forward кросс-валидации.

Позволяет запустить один раз и получить таблицу метрик для всех моделей
на одних и тех же данных и сплитах.
    N)accuracy_scoreprecision_scorerecall_scoref1_scoreconfusion_matrix)WalkForwardSplit)loggerc                       \ rS rSrSrSS\S\S\4S jjrSS\S	\	R                  S
\	R                  4S jjrS\R                  4S jrS\R                  4S jrS rS\4S jrS\R                  4S jrSrg)BenchmarkFramework   ue  
Фреймворк для сравнения моделей на одинаковых Walk-Forward сплитах.

Args:
    n_splits: Количество фолдов для Walk-Forward CV
    test_size: Размер тестового окна (float 0-1 или int)
    gap: Зазор между train и test в баров

Example:
    >>> benchmark = BenchmarkFramework(n_splits=5, test_size=0.2, gap=5)
    >>> benchmark.evaluate_model('RandomForest', lambda: RandomForestClassifier(), X, y)
    >>> benchmark.evaluate_model('XGBoost', lambda: XGBClassifier(), X, y)
    >>> benchmark.print_summary()
n_splits	test_sizegapc                 >    [        XUS9U l        / U l        / U l        g)u   
Инициализация BenchmarkFramework.

Args:
    n_splits: Количество фолдов
    test_size: Размер тестового окна (0.2 = 20%)
    gap: Зазор между train и test (баров)
)r   r   r   N)r   cvresultsmodel_params)selfr   r   r   s       1/home/ai/projects/AI_Strategy/models/benchmark.py__init__BenchmarkFramework.__init__   s!     #HsS    N
model_nameyy_truec                 D	   [         R                  " SU S35        [        UR                  5      S:  =(       a    UR                  S   S:  nU(       a  SS/OS/nU R                  R                  U[        U" 5       5      S.5        [        U R                  R                  U5      5       GH  u  nu  p[        U[        R                  5      (       a  UR                  U	   UR                  U
   pOX9   X:   pXI   XJ   pU" 5       n[        US5      (       a   UR                  X5        O[         R"                  " SU S35        M  [        US5      (       Ga5   U(       a  [        U[$        [&        45      (       a  UR)                  U5      n[        U[$        5      (       aG  [*        R,                  " U Vs/ s H  nUSS2S4   PM     sn5      nUS:  R/                  [0        5      nOUSS2S4   S:  R/                  [0        5      nOUR)                  U5      n[        U[$        5      (       a  [*        R,                  " U5      nUR2                  S:X  a  US:  R/                  [0        5      nO1USS2S4   S:  R/                  [0        5      nOUR7                  U5      nU(       a(  UR2                  S:X  a  [*        R,                  " UU/5      n[        U5       H  u  nnU(       a	  USS2U4   OUnU(       a	  USS2U4   OUn[*        R8                  " U5      n[        U5      S:X  a"  [         R:                  " S	US-    SU S35        Mq   [=        UU5      n[?        UUSS9n[A        UUSS9n[C        UUSS9n[E        UUSS/S9RG                  5       u  nnn n!U RH                  R                  UUS-   UUUUUUU!UU S.5        M     GM     [         R                  " SU S35        g! [          a+  n[         R"                  " S	US-    S
U 35         SnAGMj  SnAff = fs  snf ! [          a<  n[         R4                  " S	US-    SU S35        UR7                  U5      n SnAGNSnAff = f! [          a+  n[         R4                  " S	US-    SU 35         SnAGM  SnAff = f)u_  
Запускает кросс-валидацию для одной модели.
X может быть np.ndarray (для sklearn) или pd.DataFrame (для LSTM экспертов).

Args:
    model_name: Имя модели для отчета
    model_factory: Функция, возвращающая свежий инстанс модели (вызывается на каждом фолде)
    X: Feature matrix (n_samples, n_features) или DataFrame (для LSTM)
    y: Target vector or matrix (n_samples, n_targets) or (n_samples,)
    y_true: Optional ground truth for additional analysis
z--- Benchmarking: z ---   LongShortTarget)ModelParamsfitzFold z fit error: Nu   Модель u!    не имеет метода fitpredict_probag      ?z predict_proba error: z, trying predictz: z% has only one class, skipping metricsr   )zero_division)labels)r!   Foldr    Accuracy	PrecisionRecallF1TNTPFPFNz: metrics error: z--- Completed: z ---
)%r	   infolenshaper   appendstr	enumerater   split
isinstancepd	DataFrameilochasattrr#   	Exceptionerrorlisttupler$   npcolumn_stackastypeintndimwarningpredictuniquedebugr   r   r   r   r   ravelr   )"r   r   model_factoryXr   r   is_multioutputtarget_namesfold	train_idxtest_idxX_trainX_testy_trainy_testmodeleprobspprobs_arrayy_predinamey_ty_punique_classesaccprecrecf1tnfpfntps"                                     r   evaluate_model!BenchmarkFramework.evaluate_model,   s.    	(D9: QWW)<aggaj1n,:(
 	  -/*"
 	
 ,5TWW]]15E+F'D'9!R\\**"#&&"3QVVH5E"#,lAKV "OE ue$$IIg/
 }ZL8YZ[ uo..3%*UT5M*J*J % 3 3F ;%eT22*,//E:REq1QT7E:R*SK&1S&8%@%@%EF&+AqDkS&8%@%@%EF % 3 3F ;%eT22$&OOE$:E ::?&+sl%:%:3%?F&+AqDkS&8%@%@%EF
 v. &++"2&&)9: %\24&4fQTl&&4fQTl& "$3~&!+LL5a4&8]!^_(c2C*31ED&sCqAC!#s!<B &6c31v%N%T%T%VNBBLL''!+ $q"&$'%)"%     ) ' 3q ,Gx 	oj\89Y ! LL5aQC!@A ;S ! 3NNU46(2HK[#\]"]]62F3V ! NNU46(2CA3#GHso   O$AP!4P
P!'P!A$P!,P!	A7Q*$
P.PPP!!
Q'+1Q""Q'*
R4RRreturnc                 B    [         R                  " U R                  5      $ )u;   Возвращает DataFrame с результатами.)r8   r9   r   )r   s    r   get_resultsBenchmarkFramework.get_results   s    ||DLL))r   c                    U R                   (       d  [        R                  " 5       $ U R                  5       nUR	                  SS/5      R                  / SQSS/SS/SS/S.5      R                  S5      nUR                  R                   Vs/ s H  nSR                  U5      PM     snUl        UR                  5       nU$ s  snf )	u\   Возвращает DataFrame с суммарными метриками по фолдам.r!   r    )meanstdminmaxro   rp   r(   r)   r*   r+      _)r   r8   r9   rl   groupbyaggroundcolumnsvaluesjoinreset_index)r   dfsummarycols       r   get_summaryBenchmarkFramework.get_summary   s    ||<<>!**gx01555 %uo5/	7
 
 58 	 5<OO4J4JK4JS388C=4JK%%' Ls   Cc                 2   U R                  5       nUR                  (       a  [        R                  " S5        g[        R                  " S5        [        R                  " S5        [        R                  " S5        [        UR                  5       5        [        R                  " S5        [        R                  " SU R                  R                  [        U R                  5      UR                  R                  5       5        [        R                  " S5        g)uN   Выводит красивую таблицу метрик в консоль.zNo results to summarize.NzG
======================================================================z%BENCHMARK SUMMARY (Mean across folds)zF======================================================================u6   Total evaluations: %d folds × %d models × %d targets)r   emptyr	   rE   r0   print	to_stringr   r   r1   r   indexnunique)r   r}   s     r   print_summary BenchmarkFramework.print_summary   s    88NN56O$;<HbllnO$L77##S):):%;RXX=M=M=O	QHr   c                     U R                   R                  (       a  0 $ 0 nU R                   R                  5        H@  u  p#US   nUS   nXE4nXa;  a  / X'   X   R                  U/ SQ   R                  S   5        MB     U$ )u   
Возвращает confusion matrix для каждой модели и фолда.

Returns:
    dict: {'Model': {'Fold N': confusion_matrix}}
r!   r'   )r,   r-   r.   r/   r   )r   r   iterrowsr3   rz   )r   cm_dictru   rowrU   rN   keys          r   get_confusion_matrices)BenchmarkFramework.get_confusion_matrices   s     <<Ill++-FALEv;D-C!!L$< = D DQ GH . r   c                     U R                  5       nXS   S:H     nUR                  S5      R                  SSSSS.5      R                  5       n/ SQUl        U$ )u   
Сравнивает модели и возвращает таблицу с лучшими показателями.

Returns:
    pd.DataFrame: Сравнение моделей
r    r   r!   rr   rs   )r!   zBest AccuracyzBest PrecisionzBest RecallzBest F1)rl   rv   rw   r|   ry   )r   r~   summary_longbests       r   compare_models!BenchmarkFramework.compare_models   so     ""$ x0F:; ##G,00	2
 
 ;= 	 ^r   )r   r   r   )   g?r   )N)__name__
__module____qualname____firstlineno____doc__rC   floatr   r4   r@   ndarrayrh   r8   r9   rl   r   r   dictr   r   __static_attributes__ r   r   r   r      s     U s t: t:2:: t:WYWaWa t:l*R\\ *R\\ &" . r   r   )r   pandasr8   numpyr@   sklearn.metricsr   r   r   r   r   utils.cvr   utils.loggerr	   r   r   r   r   <module>r      s*      e e % g gr   