













Studia grazie alle numerose risorse presenti su Docsity
Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium
Prepara i tuoi esami
Studia grazie alle numerose risorse presenti su Docsity
Prepara i tuoi esami con i documenti condivisi da studenti come te su Docsity
Trova i documenti specifici per gli esami della tua università
Preparati con lezioni e prove svolte basate sui programmi universitari!
Rispondi a reali domande d’esame e scopri la tua preparazione
Riassumi i tuoi documenti, fagli domande, convertili in quiz e mappe concettuali
Studia con prove svolte, tesine e consigli utili
Togliti ogni dubbio leggendo le risposte alle domande fatte da altri studenti come te
Esplora i documenti più scaricati per gli argomenti di studio più popolari
Ottieni i punti per scaricare
Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium
Una panoramica sugli algoritmi e sulla complessità computazionale, con particolare focus sugli algoritmi di allineamento delle sequenze biologiche e sugli algoritmi di ispirazione biologica come il machine learning. Vengono discusse le proprietà fondamentali degli algoritmi, la differenza tra linguaggi di programmazione e linguaggi naturali, l'analisi della complessità computazionale, il funzionamento degli algoritmi di allineamento globale e locale, e alcuni esempi di algoritmi di ispirazione biologica come le reti neurali, le support vector machine e gli alberi di decisione. Inoltre, il documento include una breve introduzione alla sintassi e ai simboli di python per la programmazione. Complessivamente, il documento offre una solida base teorica e pratica sugli algoritmi e la loro implementazione informatica, con particolare attenzione alle applicazioni in ambito biologico e bioinformatico.
Tipologia: Sintesi del corso
1 / 21
Questa pagina non è visibile nell’anteprima
Non perderti parti importanti!














Anno I, Semestre I
“ Insieme ordinato di istruzioni eseguibili e non ambigue, che definiscono un processo che termina” ( → es. Protocollo sperimentale) Input → Algoritmo → Output Es. Problema di somma: (dati) (risultato) 2, 2 → 2 + 2 → 4 → Possono esistere più algoritmi per risolvere uno stesso problema → L’algoritmo deve essere in grado di risolvere il problema qualsiasi siano i dati Proprietà fondamentali degli algoritmi N.B. Se un algoritmo non le soddisfa, è una “procedura”, ed è impossibile a livello informatico
“ Algoritmo espresso in un linguaggio di programmazione di alto livello” Linguaggio di programmazione → Linguaggio formale , univocamente interpretabile (vs naturale , soggetto a interpretazione) ▪ Ogni linguaggio di programmazione ha una sintassi ben definita ▪ Uno stesso algoritmo può essere implementato con linguaggi di programm. diversi
▪ È indipendente dalla sintassi specifica di un linguaggio di programmazione ▪ Deve essere comprensibile e leggibile Rappresentazione grafica → Flow chart Rappresentazione scritta → Pseudocodice , linguaggio intuitivo che descrive le istruzioni di un algoritmo, a metà tra linguaggio formale e naturale
“ Paradigma di programmazione (= metodologia) usato per la stesura di programmi” → Basato su tre strutture di controllo fondamentali
Un algoritmo è tanto più efficiente quanto più sfrutta al meglio le risorse del computer:
2b. Problemi NP-completi Problemi per i quali non sono ancora stati trovati algoritmi efficienti ma non c’è certezza che tali algoritmi non esistano: se venisse fornita una soluzione, si potrebbe verificare in un tempo di calcolo polinomiale. → es. percorso di Hamilton *[Una macchina di Turing è una macchina ideale o un modello di calcolo che manipola dati potenzialmente infiniti secondo regole precise. In una macchina di Turing deterministica , l'insieme di regole prescrive al massimo una azione da eseguire per ogni data situazione , mentre in una macchina di Turing non deterministica le regole di governo specificano più di una possibile azione in determinate situazioni: lo stato successivo non è completamente determinato dallo stato attuale.]
Le banche dati biologiche sono archivi elettronici ben strutturati per memorizzare , classificare e reperire grandi quantità di dati nel tempo. Contengono informazioni derivanti da analisi in vivo, in vitro e in silico , e dalla letteratura scientifica. ▪ Banche dati primarie → banche dati contenenti sequenze di acidi nucleici (DNA, RNA)
L’allineamento multiplo è un problema NP-completo : per confrontare più sequenze contemporaneamente si utilizzano tecniche euristiche. Se si applicasse l’algoritmo di Needleman-Wunsch esso avrebbe complessità computazionale esponenziale 𝑂(𝑛 con 𝑘 ) 𝑘 ≥ 3
Per le ricerche in banche dati si utilizzano metodi euristici : l’uso dell’algoritmo di allineamento comporterebbe tempi fisici di calcolo proibitivi , in quanto bisogna confrontare la propria sequenza con molti milioni di sequenze memorizzate. → es. BLAST ( Basic Local Alignment Search Tool ): tecnica euristica per effettuare allineamenti locali fra sequenze di nucleotidi (es. blastn) o amminoacidi (es. blastp)
L’ assemblaggio di un genoma è la ricostruzione della sua sequenza intera. Avviene in due step:
a) Generare frammenti tronchi che dall’estremità 5’ si estendono ciascuno fino al primo, al secondo, al terzo, ecc. fino all’ultimo nucleotide dello stesso tipo presente nella sequenza. b) Separare i frammenti tronchi tramite elettroforesi su gel, e identificare le posizioni in cui si trovano tutti i nucleotidi del tipo preso in esame. c) Ripetere le operazioni per gli altri tre tipi di nucleotidi.
Metodo chimico (Gilbert-Maxam) Vantaggio: lettura accurata
Obiettivo Concatenare le read per formare contig , sequenze contigue di dimensioni maggiori idealmente corrispondenti a diverse porzioni del genoma. → L’assemblaggio del genoma è un problema NP-hard Difficoltà • Lunghezza limitata e imprecisioni delle read
Gli algoritmi di ispirazione biologica sono tecniche euristiche sfruttate per trovare soluzioni non esatte, ma soddisfacenti, a problemi NP-hard come il folding proteico o il docking molecolare , per i quali non è possibile trovare la soluzione esatta con un algoritmo classico. Prevedere il folding proteico senza ricorrere a metodi sperimentali ⟶ [es. cristallografia a oppure prevedere come avviene il docking molecolare significa raggi X, risonanza risolvere un problema di ottimizzazione : la struttura nativa, o il magnetica nucleare complesso enzima-ligando, è quello che minimizza il valore (NMR), microscopia dell’energia libera associata alla struttura. crio-elettronica] Un problema di ottimizzazione ha generalmente un numero molto alto o infinito di soluzioni: ogni potenziale soluzione può essere caratterizzata da un valore che rappresenta la sua qualità, definito sulla base di una funzione di fitness. Fra tutte le potenziali soluzioni, si vuole trovare la soluzione ottima , cioè quella che ha valore di minimo/massimo globale nella funzione di fitness. Esempi di algoritmi di ispirazione biologica
Il machine learning è una branca dell’ intelligenza artificiale ( = insieme di tecniche che tentano di programmare i computer in modo che essi ragionino e agiscano come esseri umani ) che comprende algoritmi che programmano un computer in modo che esso possa apprendere in maniera automatizzata , fornendo loro “esempi guida”, cioè informazioni derivate da osservazioni della realtà, che il computer deve saper generalizzare in modo da saper interpretare correttamente dati che l’algoritmo non ha mai elaborato in passato. N.B. “Apprendere” è un problema di ottimizzazione , la cui soluzione è il modello che restituisce l’errore minimo: la “qualità” dei modelli è valutata su una funzione obiettivo o loss
Una strategia per ottimizzare i risultati è la k-fold cross-validation , ovvero la divisione del dataset in K subsets : si addestrano e si valutano un numero k di modelli, utilizzando come training set tutti i K subsets meno uno, che sarà il validation set. Dalla combinazione delle valutazioni dei vari modelli durante le validazioni si ottiene una stima della capacità di predizione del modello.
Una rete neurale è un algoritmo di ML formato da layer di neuroni (unità minime di calcolo) interconnessi , i quali collaborano per risolvere un problema di classificazione (con l’uso del supervised learning ). Il neurone riceve degli input x noti da altri neuroni, a ciascuno dei quali è associato un weight w non noto : il neurone calcola quindi un output , applicando una funzione di attivazione alla sommatoria pesata degli input. I weights dipendono dall’importanza dell’input associato, e sono appresi dalla rete neurale tramite esempi di input-output : inoltre, durante il training, l’output finale ( label ) è confrontato con il label effettivo per calcolare un valore di errore loss , che viene propagato all’indietro attraverso la rete neurale per perfezionare i weights ( backpropagation , apprendere dagli errori) in modo da minimizzare la funzione obiettivo. I neuroni sono distribuiti su più layer :
Le SVM sono metodi di machine learning supervisionato per problemi di regressione e classificazione. L’obiettivo di una SVM è determinare un iperpiano in uno spazio a n dimensioni (con n = n. di feature) che permette di separare al meglio due classi di dati, rappresentabili come punti nello spazio a n dimensioni. L’iperpiano deve avere la massima distanza dai punti delle due classi: per trovare l’iperpiano ottimale, si usano i support vector , che sono i dati delle due classi più vicini all’iperpiano stesso.
Gli alberi di decisione sono metodi di machine learning supervisionato per problemi di regressione e classificazione. Consistono in una sequenza di verifica di condizioni , e possono essere rappresentati graficamente tramite una struttura ad albero: ▪ Radice Il livello più alto dell’albero ▪ Foglie I livelli più bassi: corrispondono alle decisioni ▪ Rami Le condizioni testate passando da foglia a foglia (sì/no)
Scikit-learn ( sklearn ) è la principale libreria per fare machine learning in Python.
\n \t Sequenze di escape : introducono rispettivamente un ritorno a capo e un tab in output. ==/!=/<> /<=/>= Espressioni booleane che restituiscono come valori di tipo True e False and or not in Operatori logici che possono lavorare su espressioni booleane.
print() (^) Funzione di stampa. type() (^) Restituisce la categoria di un dato. int() float() str() Converte l’argomento in un dato della categoria desiderata. import <> import <> as from <> import Importa moduli aggiuntivi → es. import math help() (^) Restituisce informazioni sull’argomento. dir() (^) Restituisce l’elenco delle funzioni di un modulo. def <>(): #implementazione Definisce una nuova funzione: se termina con return <>, è una funzione produttiva , altrimenti è detta funzione vuota. input() (^) Lettura di una stringa inserita dall’utente alla console durante l’esecuzione: ha per argomento la stringa che l’utente visualizza prima di inserire l’input. lambda x,y: x*y (^) Crea una funzione lambda , una funzione anonima implementata direttamente nella chiamata stessa di un’altra funzione: essa viene eseguita una volta, e poi “dimenticata”.
<> = [] oppure list() Crea una lista : per accedere ad un elemento della lista, ne si scrive il nome seguito da [] con all’interno l’ indice dell’elemento. [N.B. in Python gli indici positivi partono da zero , e quelli negativi da -1.] Le liste sono mutabili , concatenabili (+), ripetibili più volte (*). Per estrarre una porzione di lista si usa l’operatore [n:]/[:n]/[m:n]con l’elemento di indice n escluso. Per clonare l’intera lista si può usare [:] oppure deepcopy() dal modulo copy. Le sequenze di DNA in Python si rappresentano come liste: una stringa infatti è letta da Python come lista di caratteri. .append() .extend() Aggiungono rispettivamente un elemento e una lista in coda alla lista. .sort() (^) Dispone gli elementi della lista in ordine crescente. del <>[] (^) Rimuove un elemento o un intervallo dalla lista specificandone l’ indice. .index() (^) Restituisce l’indice in cui si trova un elemento. min(), max() (^) Restituiscono rispettivamente il valore minimo e massimo di una lista. sum() (^) Restituisce la somma degli elementi numerici di una lista. range(m) range(m,n) range(m,n,p) Crea una lista di numeri naturali. range(m)crea una lista da 0 a m-1, range(m,n)da m a n-1, range(m,n,p)da m a n-1 procedendo per intervalli di p numeri. .find() (^) Ricerca una sotto-stringa in una stringa e ne riporta la prima occorrenza. .split(x) (^) Scompone una stringa in una lista di sotto-stringhe, dividendola con il carattere separatore x. map(f, A) (^) Restituisce un iteratore , nella quale la funzione f è stata applicata ad ogni elemento della lista A. filter(f, A) (^) Restituisce un iteratore composto dai soli elementi di A per i quali la funzione f restituisce il valore True. reduce(f(a, b), A) (^) Applica una funzione f che accetta due elementi e restituisce un valore su ogni elemento della lista, e accumulando i risultati parziali restituisce un valore in output. [N.B. definita nel modulo functools] <> = () oppure tuple() Crea una tupla. Le tuple sono sequenze di valori immutabili , ed è possibile assegnarne gli elementi a più variabili mediante unpacking. set([]) (^) Crea un insieme usando dei valori di partenza. Gli insiemi sono contenitori non ordinati , che non ammettono ripetizioni. Gli insiemi supportano le operazioni della teoria degli insiemi:
while
def Fibonacci(n): if n==0: return 0 if n==1: return 1 return Fibonacci(n-1)+Fibonacci(n-2) for i in range(11): print(i, Fibonacci(i)) A = [i+1 for i in range(11)] B = [i for i in A if i%2==0] → List comprehension C = {x*2 for i in range(-10,11) if abs(i)>1} → Set comprehension print(A, B, C) from functools import reduce mult = reduce(lambda x,y: xy, [1,2,3,4,5]) → Funzione lambda print(mult)
Nella OOP è possibile specificare delle classi , tipi personalizzati di dato : la classe è la descrizione astratta di un concetto (es. cane ), e contiene al suo interno un insieme di oggetti , le istanze della classe. Ogni classe può avere degli attributi , le caratteristiche della classe (es. razza, colore del pelo, peso ), e dei metodi , le operazioni che quella classe può eseguire (es. scodinzolare(), correre(), abbaiare() ). Ad ogni oggetto parte di una classe corrispondono dei valori specifici degli attributi; usando la OOP è possibile programmare facendo interagire oggetti tra di loro. [N.B. In Python si chiama un oggetto con nome_classe(nome_oggetto)] Il costruttore è la prima funzionalità che viene eseguita alla creazione di un oggetto concreto. Nel costruttore si può inserire tutto il codice che “mette in moto” l’oggetto. ▪ Il costruttore si definisce con la funzione def init(): ▪ Il costruttore può ricevere argomenti: il primo argomento è sempre chiamato self. Nel costruttore si possono definire gli attributi della classe: si assegnano all’oggetto usato in quel momento gli attributi come variabili. es. class P def init(self): self.x =
1. Richiesta di accesso al file → open() Dopo aver specificato la modalità di accesso, il Sistema Operativo verifica se il file esiste oppure no, e se può essere aperto con la modalità richiesta. 2. Operazioni N.B. se il programma ottiene l’accesso, nessun altro programma può accedere al file ▪ Lettura → con .readlines() si ottiene una lista delle linee del testo (str) ▪ Scrittura → con open(<>, “ w ”): .write(“str\n”) si scrive all’interno di un file vuoto ▪ Appendere → con open(<>, “ a ”): .write(“str\n”) si scrive all’interno di un file esistente 3. Rilascio del file : gli altri programmi possono di nuovo accedere al file.