o
    !\i$                     @   s   d Z ddlmZmZmZ ddlmZmZ ddlZddl	m
Z
 ddlmZmZ ddlmZ ddlmZmZ dd	lmZ dd
lmZ ddlmZ ddlZeeZG dd dZdS )zFeature engineering    )ListDictOptional)datetime	timedeltaN)Session)MatchMatchStatus)Team)TeamFormDailyFeature)MatchRepository)	EloRating)settingsc                   @   s   e Zd ZdZdefddZdededede	e
ef fd	d
Zdee dede	eef fddZ	ddedededede	e
ef f
ddZdedefddZdedee fddZdS )FeatureBuilderzBuild features for matchesdbc                 C   s   || _ t|| _tj| _d S N)r   r   
match_repor   rolling_window_matchesrolling_window)selfr    r   N/var/www/www-root/data/www/176.119.141.140/sports-predictor/app/ml/features.py__init__   s   
zFeatureBuilder.__init__team_iddateis_homereturnc                 C   sF  | j j|tdd |tdd dd}g }|D ]}|j|kr(|r(||df q|j|kr6|s6||df q|jdd	 dd
 |d| j }|sQddddddS g }g }g }	g }
d}|D ]\}}|r||jpid ||j	pqd |j|j	kr|	d |
d nX|j|j	kr|	d |
d nG|	d |
d n<||j	pd ||jpd |j	|jkr|	d |
d n|j	|jkr|	d |
d n
|	d |
d |s|j
}q]d}|r|| j}|rt|t| nd|rt|t| nd|	rt|	t|	 nd|
rt|
t|
d  |dS d|dS )z1Calculate team form statistics up to a given dateim  days     	from_dateto_datelimitTFc                 S   s
   | d j S )Nr   
match_datexr   r   r   <lambda>1   s   
 z4FeatureBuilder.calculate_team_form.<locals>.<lambda>keyreverseN              @)goals_for_avggoals_against_avg
points_avgform_last_n	days_restr      )r   get_finishedr   home_team_idappendaway_team_idsortr   
home_score
away_scorer'   r   sumlen)r   r   r   r   matchesteam_matchesmatch	goals_forgoals_againstpointsform_pointslast_match_dateis_home_teamr4   r   r   r   calculate_team_form   s~   	







z"FeatureBuilder.calculate_team_formr?   c                    st   i } fdd|D }|j dd d |D ]"}|jtjjkrq|jdu s)|jdu r*qt||j	|j
|j|j q|S )z0Calculate Elo ratings for all teams up to a datec                    s   g | ]	}|j  k r|qS r   r&   ).0mr   r   r   
<listcomp>x   s    z8FeatureBuilder.calculate_elo_ratings.<locals>.<listcomp>c                 S      | j S r   r&   r(   r   r   r   r*   y       z6FeatureBuilder.calculate_elo_ratings.<locals>.<lambda>)r,   N)r:   statusr	   FINISHEDvaluer;   r<   r   calculate_ratingsr7   r9   )r   r?   r   team_ratingshistorical_matchesrA   r   rK   r   calculate_elo_ratingso   s    z$FeatureBuilder.calculate_elo_ratings
   r7   r9   r%   c                 C   s0  | j j|tdd |tdd dd}g }|D ]}|j|kr#|j|ks-|j|kr2|j|kr2|| q|jdd dd	 |d
| }d}d}	d}
|D ]G}|jd
u sV|jd
u rWqJ|j|krw|j|jkrg|d7 }qJ|j|jkrr|	d7 }	qJ|
d7 }
qJ|j|jkr|d7 }qJ|j|jkr|	d7 }	qJ|
d7 }
qJ||	|
dS )z!Calculate head-to-head statisticsi  r   r    r!   r"   c                 S   rM   r   r&   r(   r   r   r   r*      rN   z.FeatureBuilder.calculate_h2h.<locals>.<lambda>Tr+   Nr   )h2h_home_wins	h2h_drawsh2h_away_wins)	r   r6   r   r7   r9   r8   r:   r;   r<   )r   r7   r9   r   r%   r?   h2h_matchesrA   	home_winsdraws	away_winsr   r   r   calculate_h2h   sD   







zFeatureBuilder.calculate_h2hrA   c           
      C   s&  | j |j|jdd}| j |j|jdd}| jjdd}| ||j}||jtj	}||jtj	}| 
|j|j|j}tdi d|jdt d|d	 d
|d d|d d|d d|d|d d|d	 d|d d|d d|d d|d|d d|d d|d d|d }	|	S )z!Build features for a single matchT)r   Fi  )r%   match_idcalculated_athome_goals_for_avgr0   home_goals_against_avgr1   home_points_avgr2   home_form_last_nr3   home_elohome_days_restr4   away_goals_for_avgaway_goals_against_avgaway_points_avgaway_form_last_naway_eloaway_days_restrW   rX   rY   Nr   )rH   r7   r'   r9   r   r6   rU   getr   INITIAL_RATINGr^   r   idr   utcnow)
r   rA   	home_form	away_formall_matcheselo_ratingsre   rk   h2hfeaturer   r   r   build_features_for_match   sV   	
z'FeatureBuilder.build_features_for_matchrv   c                 C   s   |j pd|jpd|jpd|jpd|jpd|jpd|jpd|jp d|jp$d|j	p(d|j
p,d|jp0dt|jp5dt|jp;dt|jpAdgS )z&Convert feature to vector for ML modelr.   g     p@r/   r   )ra   rb   rc   rd   re   rf   rg   rh   ri   rj   rk   rl   floatrW   rX   rY   )r   rv   r   r   r   build_feature_vector   s    z#FeatureBuilder.build_feature_vectorN)rV   )__name__
__module____qualname____doc__r   r   intr   boolr   strrx   rH   r   r   rU   r^   r   rw   ry   r   r   r   r   r      sB    

U

!

4'r   )r}   typingr   r   r   r   r   pandaspdsqlalchemy.ormr   app.core.db.models.matchr   r	   app.core.db.models.teamr
   app.core.db.models.featurer   r   )app.core.db.repositories.match_repositoryr   
app.ml.elor   app.core.configr   logging	getLoggerrz   loggerr   r   r   r   r   <module>   s    
