[Python] Creazione albero stocastico solo con dizionari

Antonio Piepoli piepoli.antonio a gmail.com
Lun 17 Set 2012 17:00:47 CEST


Grazie per la risposta, forse non sarei potuto essere più confusionario.

Ti spiego qual'è l'obbiettivo.
Ho un file csv pieno di record in questa forma <Cognome, Nome, Data di
nascita>.
Da questo file devo creare un file di training per un classificatore
binario (le due classi saranno math o unmatch).

Voglio leggere riga per riga il file (e questo lo faccio con la libreria
csv) e per ognuno scegliere (al 50%) se da questo sarà generato un record
di math o di unmatch. A seconda della scelta il record subirà un
"trattamento" specifico (probabilmente solo in caso di match ha senso
stabilire un trattamento specifico ma questo è ancora da valutare).
Che cosa sarebbe questo trattamento ? Per ogni attributo (Cognome, Nome
etc) voglio scegliere (con una certa probabilità) se subirà 1 errore 2
errori o 0 erorri. Una volta generato questo record confronterò attributo
per attributo i due record con delle metriche (Edit distance o simili) e
produrrò un vettore di numeri che userò per fare il training del
classificatore.
Come dicevo probabilmente non riserverò nessun trattamento specifico per
gli unmatch, semplicemente prenderò un record a caso dal file e lo
accoppierò come ho spiegato prima per la classe Unmatch.

quell è l'idea;
quindi stavo pensando di usare un dizionario per tutte le scelte di
probabilità ed un array per scandire i livelli obbligati e decisi in
partenza del record.
Quindi dico, all'inizio scegli se sarà un match o no, se sarà un match
prendi il vettore match, prendi il primo elemento match[0] che si chiama
"match_surname". Questo match_surname è un altro dizionario che mi dirà
cosa fare sul surname. Cioè mi dirà quale funzione scegliere.

Sì avevo già intenzione di usare le funzioni come oggetto come mi hai detto
tu. Quello che non riesco a fare è fare la stessa cosa per i dizionari;
cioè match[0] è "match_surname" (una stringa), voglio che lo script prenda
il dizionario che ha lo stesso nome della stringa... che scelga la funzione
e che la applichi... per poi passare al passo successivo di match ->
match[1] etc ... spero di essermi spiegato meglio.

ho corretto l'errore in choose:

def choose(d):
    index = 0
    keys = d.keys()
    r = random.random()
    while (r > 0):
          r -= d[keys[index]]
        index += 1
    return keys[index-1]




Il giorno 17 settembre 2012 14:02, Daniele Varrazzo <piro a develer.com> ha
scritto:

> On 2012-09-17 11:11, Antonio Piepoli wrote:
>
>> Salve a tutti,
>>
>> premetto che questa domanda è molto stupida ma non riesco a trovare una
>> soluzione.
>> Diciamo che ho un vettore la cui lunghezza è già nota a priori. Ogni
>> elemento del vettore deve subire una funzione; il punto è che la funzione
>> cambia sia da elemento ad elemento ed in generare è scelta con una certa
>> probabilità.
>>
>> stavo pensando a qualcosa di questo tipo
>>
>> first_stage = {'match':0.5, 'unmatch':0.5}
>> match = ['match_surname','match_name']
>> unmatch = ['unmatch_surname','unmatch_**name']
>>
>> match_surname = {'1_error':0.5, '2_error':0.3, 'no_error':0.2}
>> match_name = {'1_error':0.5, '2_error':0.3, 'no_error':0.2}
>>
>> for record in records:
>>   destiny = choose(first_stage)
>>      for step in destiny:
>>          function = choose(step)
>>          function(record[desiny.index(**record)])
>>
>
> Questo "record[desiny.index(record)]"**, a parte il typo, non ho capito
> assolutamente cosa sia. "desiny/destiny" è una lista di due stringhe: che
> ci fa quell'index(record)? Cos'è records?
>
>
>
>  la funzione choose prende un dizionario fatto in quel modo e mi
>> restituisce
>> un valore (stringa):
>>
>> def choose(d):
>>     index = -1
>>     keys = d.keys()
>>     r = random.random()
>>     while (r > 0):
>>           r -= d[keys[index]]
>>         index += 1
>>     return keys[index]
>>
>
> Questa funzione non mi sembra funzionare come credi: sembra dipendere
> dall'ordine delle chiavi, non dal valore associato.
>
>
>     In [30]: vv = [ choose({'1_error':0.5, '2_error':0.3, 'no_error':0.2})
> for i in range(10000) ]
>
>     In [31]: len(vv)
>     Out[31]: 10000
>
>     In [34]: len([v for v in vv if v == '1_error'])
>     Out[34]: 2997
>
>     In [35]: len([v for v in vv if v == '2_error'])
>     Out[35]: 2024
>
>     In [36]: len([v for v in vv if v == 'no_error'])
>     Out[36]: 4979
>
>
>
>  posso associare a quella stringa una variabile/funzione con quel nome ?
>> stessa cosa dicasi per i vettori. È una cosa che mi consigliate di fare ?
>>
>
> Nota che in Python puoi usare le funzioni direttamente come oggetti. Puoi
> scrivere match = [match_surname, match_name], dove prima avevi definito
> "def match_surname(arg): ...". E poi usare match[0](record) o
> match[1](record) per richiamare una delle due.
>
> Un trucchetto per scegliere un elemento di una lista con una certa
> distribuzione potrebbe essere:
>
>     def makedist(items, probs, size=100):
>         """La funzione è volutamente non documentata e oneliner
>         per spingerti a pensare cosa fa.
>         """
>         return sum(([i] * int(float(p) / sum(probs) * size) for i, p in
> zip(items, probs)), [])
>
>     In [61]: dist = makedist(['1_error', '2_error', 'no_error'], [0.5,
> 0.3, 0.2])
>
>     In [62]: vv = [ random.choice(dist) for i in range(10000) ]
>
>     In [63]: len([v for v in vv if v == '1_error'])
>     Out[63]: 5022
>
>     In [64]: len([v for v in vv if v == '2_error'])
>     Out[64]: 3002
>
>     In [65]: len([v for v in vv if v == 'no_error'])
>     Out[65]: 1976
>
> Nota, anche qui, che se serve gli elementi in items possono essere
> funzioni, non stringhe. Quindi se hai una famiglia di funzioni f1, f2, ...
> associate a probabilità p1, p2, ... puoi fare qualcosa tipo.
>
>     dist = makedist([f1, f2, ...], [p1, p2, ...])
>
>     for record in records:
>         random.choice(dist)(record)
>
> --
> Daniele Varrazzo - Develer S.r.l.
> http://www.develer.com
> ______________________________**_________________
> Python mailing list
> Python a lists.python.it
> http://lists.python.it/**mailman/listinfo/python<http://lists.python.it/mailman/listinfo/python>
>



-- 
Antonio Piepoli
-------------- parte successiva --------------
Un allegato HTML è stato rimosso...
URL: <http://lists.python.it/pipermail/python/attachments/20120917/2bc92c7a/attachment-0001.html>


Maggiori informazioni sulla lista Python