o
    qÛh h  ã                   @   s¼   d Z ddlZddlZddlmZmZmZm	Z	m
Z
 ddlmZmZ ddlZddlmZmZmZmZ ddlmZ ddlmZ G d	d
„ d
eƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZdS )z¤
Enhanced Multi-Armed Bandit Algorithms with Data and Clustering Integration.
These algorithms use the new data and clustering layers for improved recommendations.
é    N)ÚListÚDictÚAnyÚOptionalÚTuple)ÚABCÚabstractmethodé   )Ú	RandomMABÚEpsilonGreedyMABÚUpperConfidenceBoundMABÚThompsonSamplingMAB)ÚDataManager)ÚClusteringManagerc                   @   s†   e Zd ZdZdedededefdd„Zedd	ed
e	e
ef dejfdd„ƒZddee dee d	efdd„Zde	e
ef fdd„ZdS )ÚEnhancedMABBasez'Base class for enhanced MAB algorithms.Ún_armsÚn_suggestionsÚdata_managerÚclustering_managerc                 C   sR   || _ || _|| _|| _t |¡| _t |¡| _t |¡| _i | _	i | _
i | _d S ©N)r   r   r   r   ÚnpÚzerosÚ
arm_countsÚarm_rewardsÚ
arm_valuesZuser_contextsÚcluster_insightsÚprice_optimization)Úselfr   r   r   r   © r   úg/Users/divyeshpatel/Desktop/sahana/Recommender/recommender_rl/rl_recommender/enhanced_mab_algorithms.pyÚ__init__   s   
zEnhancedMABBase.__init__NÚuser_idÚcontextÚreturnc                 C   s   dS )z3Select multiple arms (products) for recommendation.Nr   )r   r!   r"   r   r   r   Úselect_multiple_arms(   s   z$EnhancedMABBase.select_multiple_armsÚarmsÚrewardsc                 C   sV   t ||ƒD ]#\}}| j|  d7  < | j|  |7  < | j| | j|  | j|< qdS )z'Update algorithm with observed rewards.r	   N)Úzipr   r   r   )r   r%   r&   r!   ÚarmÚrewardr   r   r   Úupdate-   s
   ýzEnhancedMABBase.updatec              	   C   s:   | j | j| j ¡ | j ¡ | j ¡ t | j¡t | j¡dœS )z*Get information about the algorithm state.)r   r   r   r   r   Útotal_pullsÚtotal_reward)r   r   r   Útolistr   r   r   Úsum©r   r   r   r   Úget_algorithm_info4   s   

ùz"EnhancedMABBase.get_algorithm_info©NNr   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Úintr   r   r    r   r   Ústrr   r   Úndarrayr$   r   Úfloatr*   r0   r   r   r   r   r      s    
ÿ
ÿ$ r   c                       sl  e Zd ZdZ	d(dededededed	ef‡ fd
d„Zd)dede	e
ef dejfdd„Zd*dede	e
ef de	e
ef fdd„Zde	e
ef dejfdd„Zde	e
ef dejfdd„Zdede	e
ef dejfdd„Zdede	e
ef dejfdd„Zdeeeef  dejfdd „Zdeeeef  dejfd!d"„Zd#e	e
ef dejfd$d%„Zdejfd&d'„Z‡  ZS )+ÚEnhancedEpsilonGreedyMABz;Enhanced Epsilon-Greedy algorithm with clustering insights.çš™™™™™¹?çš™™™™™É?r   r   r   r   ÚepsilonÚexploration_bonusc                    s"   t ƒ  ||||¡ || _|| _d S r   )Úsuperr    r=   r>   )r   r   r   r   r   r=   r>   ©Ú	__class__r   r   r    D   s   
z!EnhancedEpsilonGreedyMAB.__init__Nr!   r"   r#   c                 C   s>   |du r|   ¡ S |  ||¡}t ¡ | jk r|  |¡S |  |¡S )z3Select arms using enhanced epsilon-greedy strategy.N)Ú_basic_arm_selectionÚ_get_enhanced_contextÚrandomr=   Ú_exploration_selectionÚ_exploitation_selection)r   r!   r"   Úenhanced_contextr   r   r   r$   K   s   

z-EnhancedEpsilonGreedyMAB.select_multiple_armsc           	   
   C   ó¬   i }z9| j  |¡}||d< | jr/| j |¡}||d< | j ¡ }||d< | jjddd}||d< |r9| |¡ W |S W |S  tyU } ztd|› ƒ W Y d	}~|S d	}~ww ©
z6Get enhanced context using data and clustering layers.Ú
user_stateÚuser_clusterr   Úpurchaseç333333Ó?)Z	min_scoreÚoptimal_pricesu(   âš ï¸  Error getting enhanced context: N©	r   Úget_user_stater   Úget_user_clusterZget_clustering_insightsZget_optimal_price_ranger*   Ú	ExceptionÚprint©	r   r!   r"   rG   rJ   rK   ÚinsightsrN   Úer   r   r   rC   \   ó*   
úý€ýz.EnhancedEpsilonGreedyMAB._get_enhanced_contextc              
   C   sÚ   zO|  dd¡}|  di ¡}t | j¡}|d| jd  7 }|dur.|dkr.|r.||  ||¡7 }|  dg ¡}|r=||  |¡7 }t |¡| j d… ddd… }|W S  t	yl } zt
d	|› ƒ |  ¡ W  Y d}~S d}~ww )
z6Select arms for exploration using clustering insights.rK   éÿÿÿÿr   ç      ð?r	   Nr   rN   u(   âš ï¸  Error in exploration selection: )Úgetr   r   r   r   Ú_get_cluster_exploration_bonusÚ_get_price_exploration_bonusÚargsortr   rR   rS   rB   )r   r"   rK   r   Zexploration_scoresrN   Úselected_armsrV   r   r   r   rE   {   s"    €þz/EnhancedEpsilonGreedyMAB._exploration_selectionc           	   
   C   sÞ   zQt  | j¡}| di ¡}| di ¡}||  |¡7 }| dd¡}|dur0|dkr0||  ||¡7 }| dg ¡}|r?||  |¡7 }t  |¡| j d… ddd… }|W S  t	yn } zt
d|› ƒ |  ¡ W  Y d}~S d}~ww )	z>Select arms for exploitation using learned values and context.rJ   ÚpreferencesrK   rX   Nr   rN   u)   âš ï¸  Error in exploitation selection: )r   Úcopyr   rZ   Ú_get_preference_bonusÚ_get_cluster_exploitation_bonusÚ_get_price_exploitation_bonusr]   r   rR   rS   rB   )	r   r"   Zcombined_scoresrJ   r_   rK   rN   r^   rV   r   r   r   rF   ™   s$    €þz0EnhancedEpsilonGreedyMAB._exploitation_selectionrK   rU   c              
   C   óŠ   t  | j¡}z$|dkr|d7 }W |S |dkr|d7 }W |S |dkr(|d7 }W |S W |S  tyD } ztd|› ƒ W Y d}~|S d}~ww )	z,Get exploration bonus based on user cluster.r   rM   r	   r<   é   gš™™™™™Ù?u1   âš ï¸  Error getting cluster exploration bonus: N©r   r   r   rR   rS   )r   rK   rU   ÚbonusrV   r   r   r   r[   ¸   ó$   
	ø
ú
úý€ýz7EnhancedEpsilonGreedyMAB._get_cluster_exploration_bonusc              
   C   rd   )	z-Get exploitation bonus based on user cluster.r   r<   r	   r;   re   rM   u2   âš ï¸  Error getting cluster exploitation bonus: Nrf   )r   rK   r"   rg   rV   r   r   r   rb   Ë   rh   z8EnhancedEpsilonGreedyMAB._get_cluster_exploitation_bonusrN   c              
   C   óP   t  | j¡}z|d7 }W |S  ty' } ztd|› ƒ W Y d}~|S d}~ww )z2Get exploration bonus based on price optimization.r;   u/   âš ï¸  Error getting price exploration bonus: Nrf   ©r   rN   rg   rV   r   r   r   r\   Þ   ó   
ý€ýz5EnhancedEpsilonGreedyMAB._get_price_exploration_bonusc              
   C   ri   )z3Get exploitation bonus based on price optimization.r<   u0   âš ï¸  Error getting price exploitation bonus: Nrf   rj   r   r   r   rc   ì   rk   z6EnhancedEpsilonGreedyMAB._get_price_exploitation_bonusr_   c              
   C   s~   t  | j¡}z| di ¡}| di ¡}|r|d7 }|r"|d7 }W |S W |S  ty> } ztd|› ƒ W Y d}~|S d}~ww )z$Get bonus based on user preferences.Úfavorite_categoriesÚfavorite_brandsr;   u(   âš ï¸  Error getting preference bonus: N)r   r   r   rZ   rR   rS   )r   r_   rg   rl   rm   rV   r   r   r   ra   ú   s    
úý€ýz.EnhancedEpsilonGreedyMAB._get_preference_bonusc                 C   sF   t   ¡ | jk rtj j| j| jddS t | j¡| j d… ddd… S )ú$Basic arm selection without context.F©ÚreplaceNrX   )rD   r=   r   Úchoicer   r   r]   r   r/   r   r   r   rB     s   "z-EnhancedEpsilonGreedyMAB._basic_arm_selection)r;   r<   r1   r   )r2   r3   r4   r5   r6   r   r   r9   r    r   r7   r   r   r8   r$   rC   rE   rF   r[   rb   r   r   r\   rc   ra   rB   Ú__classcell__r   r   r@   r   r:   A   s,    þÿÿþþ"(    r:   c                       sÔ   e Zd ZdZ	ddededededed	ef‡ fd
d„Zddede	e
ef dejfdd„Zddee dee defdd„Zde	e
ef dejfdd„Zddede	e
ef de	e
ef fdd„Zdejfdd„Z‡  ZS )ÚEnhancedContextualMABz4Enhanced Contextual MAB algorithm with rich context.é   ç{®Gáz„?r   r   r   r   Úcontext_dimÚlearning_ratec                    sB   t ƒ  ||||¡ || _|| _tj ||¡d | _g | _g | _	d S )Nru   )
r?   r    rv   rw   r   rD   ÚrandnÚthetaÚcontext_historyZreward_history)r   r   r   r   r   rv   rw   r@   r   r   r      s   
zEnhancedContextualMAB.__init__Nr!   r"   r#   c                 C   s~   |du r|   ¡ S |  ||¡}|  |¡}t | j|¡}tj dd| j¡}||7 }t 	|¡| j
 d… ddd… }| j |¡ |S )z)Select arms using contextual information.Nr   r;   rX   )rB   rC   Ú_context_to_vectorr   Údotry   rD   Únormalr   r]   r   rz   Úappend)r   r!   r"   rG   Úcontext_vectorZexpected_rewardsZexploration_noiser^   r   r   r   r$   '  s   
 z*EnhancedContextualMAB.select_multiple_armsr%   r&   c           	      C   s¢   | j sdS | j  d¡}t||ƒD ]>\}}t | j| |¡}|| }| j|  | j| | 7  < | j|  d7  < | j|  |7  < | j| | j|  | j	|< qdS )z$Update contextual bandit parameters.Nr   r	   )
rz   Úpopr'   r   r|   ry   rw   r   r   r   )	r   r%   r&   r!   r   r(   r)   Z
predictionÚerrorr   r   r   r*   A  s   õzEnhancedContextualMAB.updatec              
   C   sL  t  | j¡}zûd}| di ¡}|ra| dd¡dkrdnd||< |d7 }| dd¡d	kr-dnd||< |d7 }| d
d¡}|durCt|ƒnd||< |d7 }| dd¡}|durYt|ƒnd||< |d7 }| di ¡}|r‹t| dd¡dƒd ||< |d7 }t| dd¡dƒd ||< |d7 }| dd¡}|dur£|dkr£|d ||< |d7 }| dg ¡}	|	r·t|	ƒd ||< |d7 }| dd¡}
|
d ||< |d7 }| dd¡}|d ||< |d7 }|| jk rît j dd¡||< |d7 }|| jk sÜt j	 
|¡}|dkrÿ|| }W |S W |S  ty% } ztd|› ƒ t j dd| j¡}W Y d}~|S d}~ww )z-Convert context dictionary to feature vector.r   rJ   Úengagement_levelÚlowÚhighrY   g        r	   ÚmediumÚexploration_scoreg      à?NÚ
cluster_idÚsession_contextZduration_hoursé   Zinteraction_countéd   rK   rX   é
   rN   Úcurrent_houré   Úcurrent_dayé   é   r;   u,   âš ï¸  Error converting context to vector: )r   r   rv   rZ   r9   ÚminÚlenrD   r}   ÚlinalgÚnormrR   rS   )r   r"   Zfeature_vectorÚidxrJ   r†   r‡   rˆ   rK   rN   rŒ   rŽ   r”   rV   r   r   r   r{   W  sf   

þ
ùü€üz(EnhancedContextualMAB._context_to_vectorc           	   
   C   rH   rI   rO   rT   r   r   r   rC   ™  rW   z+EnhancedContextualMAB._get_enhanced_contextc                 C   ó   t jj| j| jddS ©rn   Fro   ©r   rD   rq   r   r   r/   r   r   r   rB   ¸  ó   z*EnhancedContextualMAB._basic_arm_selection)rt   ru   r1   r   )r2   r3   r4   r5   r6   r   r   r9   r    r   r7   r   r   r8   r$   r   r*   r{   rC   rB   rr   r   r   r@   r   rs     s"    þÿÿþþ" (Brs   c                       s(  e Zd ZdZ	d!dededededee f
‡ fdd	„Z	d
ee
 fdd„Zd"dedeee
f d
ejfdd„Zdeej deee
f d
ejfdd„Zdejdeee
f d
ejfdd„Zd!dee dee def‡ fdd„Zdee fdd„Zd!dedeee
f d
eee
f fdd„Zd
ejfdd „Z‡  ZS )#ÚEnhancedEnsembleMABzAEnhanced ensemble MAB combining multiple algorithms with context.Nr   r   r   r   Ú
algorithmsc                    s\   t ƒ  ||||¡ |pg d¢| _|  ¡ | _t t| jƒ¡t| jƒ | _t 	t| jƒ¡| _
d S )N)Úepsilon_greedyÚucbÚthompson)r?   r    r›   Ú_initialize_base_algorithmsÚbase_algorithmsr   Úonesr’   Úalgorithm_weightsr   Úalgorithm_performances)r   r   r   r   r   r›   r@   r   r   r    À  s
   
zEnhancedEnsembleMAB.__init__r#   c                 C   s’   g }| j D ]A}|dkr| t| j| jdd¡ q|dkr)| t| j| jdd¡ q|dkr8| t| j| jƒ¡ q|dkrF| t| j| jƒ¡ q|S )	zInitialize base MAB algorithms.rœ   r;   )r=   r   g       @)Úcrž   rD   )r›   r~   r   r   r   r   r   r
   )r   r    Zalg_namer   r   r   rŸ   Í  s   
€z/EnhancedEnsembleMAB._initialize_base_algorithmsr!   r"   c           	      C   sÚ   | j s|  ¡ S |  ||¡}g }| j D ]R}z!t|dƒr$| ¡ }| |¡ ntjj| j	| j
dd}| |¡ W q tyd } z#tdt|ƒj› d|› ƒ tjj| j	| j
dd}| |¡ W Y d}~qd}~ww |  ||¡}|S )z)Select arms using ensemble of algorithms.r$   Fro   u   âš ï¸  Error in algorithm ú: N)r    rB   rC   Úhasattrr$   r~   r   rD   rq   r   r   rR   rS   Útyper2   Ú_weighted_voting)	r   r!   r"   rG   Úall_recommendationsÚ	algorithmÚrecommendationsrV   Zfinal_recommendationsr   r   r   r$   Ý  s(   


€€ýz(EnhancedEnsembleMAB.select_multiple_armsr©   c           
   
   C   sØ   zGt  | j¡}t|ƒD ]#\}}| j| }|D ]}d|  kr#| jk r-n q||  |7  < qq|  ||¡}t  |¡| j d… ddd… }|W S  tyk }	 zt	d|	› ƒ t j
j| j| jddW  Y d}	~	S d}	~	ww )z.Combine recommendations using weighted voting.r   NrX   u"   âš ï¸  Error in weighted voting: Fro   )r   r   r   Ú	enumerater¢   Ú_apply_context_adjustmentsr]   r   rR   rS   rD   rq   )
r   r©   r"   Ú	arm_votesÚir«   Úweightr(   r^   rV   r   r   r   r¨   ú  s"   
€þ "€þz$EnhancedEnsembleMAB._weighted_votingr®   c           	   
   C   s–   z/t  |¡}| di ¡}| di ¡}|r	 | dd¡}|dur$|dkr$	 | dg ¡}|r-	 |W S  tyJ } ztd|› ƒ |W  Y d}~S d}~ww )	z-Apply context-based adjustments to arm votes.rJ   r_   rK   rX   Nr   rN   u,   âš ï¸  Error applying context adjustments: )r   r`   rZ   rR   rS   )	r   r®   r"   Zadjusted_votesrJ   r_   rK   rN   rV   r   r   r   r­     s$   
€þz.EnhancedEnsembleMAB._apply_context_adjustmentsr%   r&   c                    sx   | j D ])}z| ||¡ W q ty, } ztdt|ƒj› d|› ƒ W Y d}~qd}~ww |  |¡ tƒ  |||¡ dS )zUpdate ensemble algorithm.u!   âš ï¸  Error updating algorithm r¥   N)r    r*   rR   rS   r§   r2   Ú_update_ensemble_weightsr?   )r   r%   r&   r!   rª   rV   r@   r   r   r*   5  s   
&€ÿ
zEnhancedEnsembleMAB.updatec              
   C   s°   z=|rt  |¡nd}tt| jƒƒD ]}d| j|  d|  | j|< qt  | j¡dkr;t  | j¡}|t  |¡ | _W dS W dS  t	yW } zt
d|› ƒ W Y d}~dS d}~ww )z.Update algorithm weights based on performance.r   gÍÌÌÌÌÌì?r;   u)   âš ï¸  Error updating ensemble weights: N)r   ÚmeanÚranger’   r    r£   r.   Úexpr¢   rR   rS   )r   r&   Ú
avg_rewardr¯   Úexp_performancesrV   r   r   r   r±   D  s   þ€ÿz,EnhancedEnsembleMAB._update_ensemble_weightsc           	   
   C   rH   rI   rO   rT   r   r   r   rC   W  rW   z)EnhancedEnsembleMAB._get_enhanced_contextc                 C   r–   r—   r˜   r/   r   r   r   rB   v  r™   z(EnhancedEnsembleMAB._basic_arm_selectionr   r1   )r2   r3   r4   r5   r6   r   r   r   r7   r    r   rŸ   r   r   r8   r$   r¨   r­   r9   r*   r±   rC   rB   rr   r   r   r@   r   rš   ½  s$    þÿÿþ"&"$"(rš   )r5   Únumpyr   ÚpandasÚpdÚtypingr   r   r   r   r   Úabcr   r   rD   Úmabalgorithmsr
   r   r   r   Údbr   Ú
clusteringr   r   r:   rs   rš   r   r   r   r   Ú<module>   s    - X &