LSTM & le false promesse

Di recente mi sono imbattuto in un articolo che mostra come l’applicazione si tecniche di ML basate su LSTM possano generare risultati migliori rispetto a una strategia B&H. La prima osservazione è che il singolo titolo non fa testo, occorre avere un paniere sufficientemente ampio per dimostrare che un algoritmo di ML sia efficace.

Subito dopo ho voluto provare l’algoritmo, conscio dei risultati scadenti che ho sempre ottenuto tramite LSTM mi sono chiesto quali fossero gli elementi che rendono quest’implementazione LSTM così efficace, anche solo per un singolo caso. Soprattutto perché risultati così buoni li ho ottenuti solo con ‘lookahead bias’ ossia i dati che alimentano il calcolo contengono informazioni sullo stato futuro.

Questo ovviamente è possibile solo per errori o sviste di programmazione. Quindi mi sono messo a caccia della chiave vincente o dell’errore. Devo essere sincero il codice è di buona qualità e trovare la chiave di volta non è stato semplice. Le serie temporali sono sempre ostiche, basta uno shift sbagliato e salta tutto, in questo caso non c’è stato bisogno di uno shift per fare la magia, che si verifica nel punto in cui viene preparato il dataset di test e il risultato. Precisamente il passaggio magico (o incriminato che dir si voglia) è quello indicato con In [17]

scaler=MinMaxScaler(feature_range=(0,1))
dg=pd.DataFrame(scaler.fit_transform(dfm[["High","Low","Open","Close","Volume","fd_cm_open",\
                                          "mv_avg_12","mv_avg_24","fd_nm_open"]].values))
dg0=dg[[0,1,2,3,4,5,6,7]]


window=4
dfw=create_window(dg0,window)

X_dfw=np.reshape(dfw.values,(dfw.shape[0],window+1,8))
print(X_dfw.shape)
print(dfw.iloc[:4,:])
print(X_dfw[0,:,:])

y_dfw=np.array(dg[8][window:])

Guardando nel dettaglio come vengono costruiti i vari campi scopriamo che i valori in ingresso per High, Low, Open, Close sono il valore medio del mese corrente, ossia dal primo giorno del mese all’ultimo giorno del mese e che il valore di cui si vuole fare la previsione è il primo valore del mese successivo. Va da se che la previsione è falsata dai valori medi del mese corrente.

L’errore è indotto dal fatto che l’algoritmo lavora sul primo giorno mese. Intuitivamente se a gennaio stimo il mese di febbraio, un conto è stimare il valore del primo giorno di febbraio, un conto è stimare il valore l’ultimo giorno di febbraio. Una correzione veloce consiste nel shiftare i due valore relativi all’apertura del mese corrente e del prossimo mese di -1. E’ quindi sufficiente inserire questo blocco di codice

#run once
dfm["fd_nm_open"] = dfm["fd_nm_open"].shift(-1)
dfm["fd_cm_open"] = dfm["fd_cm_open"].shift(-1)
dfm=dfm.dropna()

E quindi la verifica visiva che stiamo guardando i dati giusti

print(dfm[["High","Low","Open","Close","Volume","fd_cm_open", "mv_avg_12","mv_avg_24","fd_nm_open"]].head(1))
print(df.loc['1975-02'].mean())
print(df.loc['1975-02'].iloc[0].loc['Close'])
print(df.loc['1975-03'].iloc[0].loc['Close'])

Il risultato è il seguente:

                                High        Low  Open      Close  \
Date                                                               
1975-01-31 00:00:00-05:00  73.546817  71.442273   0.0  72.564091   

                                 Volume  fd_cm_open  mv_avg_12  mv_avg_24  \
Date                                                                        
1975-01-31 00:00:00-05:00  1.966136e+07       77.82   82.84377  95.136477   

                           fd_nm_open  
Date                                   
1975-01-31 00:00:00-05:00   83.029999  
Open      0.000000e+00
High      8.098842e+01
Low       7.889211e+01
Close     8.009684e+01
Volume    2.229684e+07
dtype: float64
77.81999969482422
83.02999877929688

il campo fd_cm_open per il 31 gennaio 1975 contiene il valore di apertura del mese di febbraio, mentre il campo fd_nm_open contiene il valore di apertura del mese di marzo. In pratica posizionandoci il primo giorno di febbraio ci stiamo chiedendo se il primo marzo avremo guadagnato o perso. Per farlo utilizziamo la madia 12 e 24 calcolate sulla media mensile compreso il mese di Gennaio. Ora facciamo girare l’algoritmo con il solito fit e …. vediamo se il risultato rimane positivo.

Atteso il tempo per completare il training ecco a confronto i grafici prima e dopo.

Versione originale
Versione corretta
Versione originale
Versione corretta

Il risultato ottenuto adesso è in linea con le mie aspettative. Non ci sono dati sufficiente per un training che possa generare i risultati così positivi come quelli presentati nell’articolo.

Valgono sempre le considerazioni di base per tutti gli algoritmi che si trovano in giro, se fossero efficaci non verrebbero pubblicati ma sfruttati dal creatore e pubblicati sono quando hanno terminato la loro efficacia. Ossia, non è tutto oro ciò che lucica.

Linux suspend issues

It’s been quite a lot of time that mi HTPC remained turned on, when I tried to suspend the system I had plenty of issues.

First issue is that dvb didn’t resume correctly generating a lot of “m88ds3103 0-0069: i2c wr failed=-6″ errors.” after resume and DVB not working at all. For a HTPC it’s a big issue since the main purpose of the HTPC is view dvb content. It seemed I just needed to remove the m88ds3103 module and insert it again after suspend. Sadly the module showed three usages

htpc@htpc:~$ lsmod |grep m88
m88ds3103 32768 3 cx23885

Removing the cx23885 module still show 2 usages without any clear indication of what is going on:

htpc@htpc:~$ lsmod |grep m88
m88ds3103 32768 2

No way to remove the module. After various tentative I identified the module that kept m88ds3103 busy, it’s the smipcie module, so to remove the m88ds3103 module I first need to remove the smipcie module. From my point of view this should be considered a defect either in the lsmod or in the module itself, since no dependency module is identified.

the second issue is related to the HTPC waking up just after suspending. Again after some researches I found the the HTPC wakes up on any kind on USB UHC event, this means constantly. I found no way to disable this as configuration. So I created my own hook for the suspend, it just disables wake up on USB/UHC before going to sleep executing echo “UHC1” > /proc/acpi/wakeup for all the peripherals.

With this two patches the suspend works smoothly, it just take a while to stop mythtv-backend, but otherwise no issues.

The script is named /usr/lib/pm-utils/sleed.d/50htpc to be put in the folder /usr/lib/pm-utils/sleed.d/

This is the code:

. "${PM_FUNCTIONS}"
suspend_htpc()
{
    service mythtv-status stop
    service mythtv-backend stop
    rmmod cx23885
    rmmod smipcie
    rmmod m88ds3103
     devices="UHC1 UHC2 USB3 UHC4 USB5 UHC6 UHC7"
    for device in ${devices}; do
            if grep -qw ^$device.*enabled /proc/acpi/wakeup; then
                    sudo sh -c "echo $device > /proc/acpi/wakeup"
            fi
    done
}
resume_htpc()
{
   modprobe m88ds3103
   modprobe smipcie
   modprobe cx23885
   service mythtv-backend start
   service mythtv-status start
}
case "$1" in
 hibernate|suspend)
 suspend_htpc
 ;;
 thaw|resume)
 resume_htpc
 ;;
 *) exit $NA
 ;;
 esac

Service menu LG 37LF65

Ogni volta mi dimentico la procedura.

Premere 5 sec il bottone ‘menu’ in alto compare la dicitura RGB (che non c’entra nulla con il service menu). Digitare ripetutamente ‘0’.

 

TBS driver new try

Sometime I try to make the fuc…. TDB 6022 card working on linux without making the other card out of work.

Yesterday I tried to build the TBS saa716x driver against the newest linux media, after patching a little bit everything compiles fine the remote works but the TBS6922 frontend which is already compiled in the TBS distribution generates a kernel oops.

Today I tried the other way, I entirely removed the CX23885 from the TBS tree and replace it with the one found in the latest media_build tree. The result was worst, I couldn’t even build the driver because the media_tree used by TBS developers is really tooooooo old. Kernel_version.h reports version

#define V4L2_VERSION 196608

which corresponds to a very very very very old media_tree linux-media-2011-05-31.tar.bz2

So for me by now no way to make the new cards using CX23885 working with the TBS 6922 card, so the brand new TBS6922 card remains off.

I’m still hoping to get and answer from TBS developers….

 

Enable/disable jounal on running ext root partition

Some times ago, trying to reach better performances on my SDD, I followed the wrong suggestion to disable the journal. This solution isn’t really good because I had some data loss and at almost each reboot the system got in fsck.

Yesterday I decided to go back and restore the journal. Each guide I found online was related to non root fs or to boot in maintenance mode. The only thing you need is a ro mountetd fs and usually you fine on internet this command line:

sudo mount -r -o remount /

Which is not enought and you get a busy error message.

The way to go around this issue is to force the remount, so if you want to enable journal:

sudo mount -f -r -o remount /dev/sda6

sudo tune2fs -O has_journal /dev/sda6

Or disable it:

sudo mount -f -r -o remount /dev/sda6

sudo tune2fs -O has_journal /dev/sda6