Wikibooks itwikibooks https://it.wikibooks.org/wiki/Pagina_principale MediaWiki 1.47.0-wmf.22 first-letter Media Speciale Discussione Utente Discussioni utente Wikibooks Discussioni Wikibooks File Discussioni file MediaWiki Discussioni MediaWiki Template Discussioni template Aiuto Discussioni aiuto Categoria Discussioni categoria Progetto Discussioni progetto Ripiano Discussioni ripiano TimedText TimedText talk Modulo Discussioni modulo Evento Discussioni evento Disposizioni foniche di organi a canne 0 34638 502148 502048 2026-10-04T22:52:09Z ~2026-46067-79 54720 /* */ 502148 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} Le disposizioni foniche attualmente presenti in questo libro sono '''5171'''. == Per il lettore == Ciascun organo a canne è uno strumento a sé, con una propria dignità indissolubilmente legata alla sua unicità. Non troveremo mai un organo uguale ad un altro, neppure nei rarissimi casi di strumenti costruiti in serie: avranno sempre qualcosa che li distinguerà fra di loro. Come poter, dunque, descrivere uno strumento unico, in maniera tale che, senza suonarlo o ascoltarlo, sia possibile capire come è fatto? Grazie alla sua disposizione fonica: essa è l'elenco dei registri che compongono lo strumento, riportati in base alla loro appartenenza alle varie "divisioni" (manuale/i ed eventualmente pedale). Pertanto si tratta di un elemento fondamentale, l'unica vera grande ed esaustiva descrizione dello strumento, dal momento che un organo si differenzia da un altro fondamentalmente per i registri che ha. Questo wikilibro si prefigge il compito di racchiudere al suo interno le disposizioni foniche di organi del presente e del passato, raggruppate in base alla loro collocazione all'interno di edifici che, per sviluppi culturali ed esigenze liturgiche, sono per la maggior parte destinati al culto. La presente opera si rivolge, dunque, non solo allo studioso di organaria ed organologia, ma anche al curioso che vuol sapere come è fatto l'organo della chiesa tot, all'appassionato, all'organista che ha l'esigenza di conoscere le caratteristiche di un tal organo, a chiunque, in poche parole, sia interessato all'argomento. == Per il contributore == Chiunque voglia contribuire all'edificazione del presente wikilibro, è il benvenuto, ed è pregato di seguire, per amor di uniformità, lo schema che può vedere nelle pagine già presenti. Sono tuttavia doverose alcune raccomandazioni tecniche. Una volta inserite una o più disposizioni foniche, il contributore è pregato di aggiornare il numero all'inizio di questa pagina. === Dei titoli === I titoli delle singole pagine seguono sempre questo schema: Stato/Regione (o altra divisione amministrativa analoga)/Provincia (o altra divisione amministrativa analoga)/Comune/Località (che può essere anche il comune stesso, comunque si ripete) - Edificio Ad esempio: Italia/Lombardia/Città metropolitana di Milano/Milano/Milano - Cattedrale di Santa Maria Nascente Nei nomi delle chiese, si scrive solo: ''Chiesa di...'', oppure ''Santuario di...'', oppure ''Basilica di...'', ''Cattedrale di...'' o ''Cattedrale metropolitana di...'', non ''Basilica Cattedrale Primaziale Metropolitana Santuario Protoecclesia di...''. Sono altresì bandite le abbreviazioni (come ad esempio ''S.'' al posto di ''Santo/Santa/Sacro''). Se in un edificio ci sono più organi, vanno tutti nella stessa pagina. Le singole pagine non sono per organo, ma per edificio. === Delle tabelle riassuntive === Le tabelle riassuntive a inizio pagina, seguono questo schema: * '''Costruttore:''' [nome e] cognome del costruttore/ditta costruttrice con, in caso, tra parentesi e in corsivo, il numero d'opera * '''Anno:''' anno di costruzione (in caso, in nota, data dell'inaugurazione) * '''Restauri/modifiche:''' elenco: nome di chi ha fatto il restauro e, tra parentesi, anno e tipologia di intervento * '''Registri:''' numero dei registri (in caso di registri spezzati, ciascuno vale 1 e non 1/2) * '''Canne:''' numero di canne * '''Trasmissione:''' meccanica/pneumatico-tubolare/elettrica/elettronica/ecc. nel caso di mista, si scrive mista e poi si specifica tra parentesi * '''Consolle:''' tipologia della consolle (a finestra, mobile/fissa indipendente, appoggiata, rivolta, ecc.) e posizione (al centro del coro, al centro della parete anteriore della cassa, su apposita cantoria, ecc.) * '''Tastiere:''' n° di tastiere e di note ed estensione tra parentesi * '''Pedaliera:''' tipologia di pedaliera (a leggio, dritta, concava, concavo-radiale), n° di note ed estensione tra parentesi * '''Collocazione:''' n° dei corpi, posizione dei corpi. Esempio: * '''Costruttore:''' Pinco Pallino (''Opus 100'') * '''Anno:''' 2019-2020 * '''Restauri/modifiche:''' Tizio Caio (2102, restauro conservativo), Sempronio (2156, modifiche e ampliamento) * '''Registri:''' 36 * '''Canne:''' 3.562 * '''Trasmissione:''' mista (meccanica per i manuali e il pedale, elettronica per i registri) * '''Consolle:''' a finestra, al centro della parete anteriore della cassa * '''Tastiere:''' 3 di 56 note (''Do<small>1</small>''-''Sol<small>5</small>'') * '''Pedaliera:''' concavo-radiale di 30 note (''Do<small>1</small>''-''Fa<small>3</small>'') * '''Collocazione:''' in due corpi contrapposti, sulla cantoria in controfacciata Nel caso di ottave scavezze: * '''Tastiera:''' 1 di 50 note con prima ottava scavezza (''Do<small>1</small>''-''Fa<small>5</small>'', Bassi/Soprani ''Do#<small>3</small>''/''Re<small>3</small>'') * '''Pedaliera:''' a leggio di 18 note con prima ottava scavezza (''Do<small>1</small>''-''Sol#<small>2</small>''), priva di registri propri e costantemente unita al manuale Non sono ammesse abbreviazioni, come ad esempio i nomi degli organari. === Delle disposizioni foniche === * I nomi delle divisioni vengono scritti nel seguente modo: '''I - ''Grand'Organo'''''; quello del pedale così: '''Pedale'''; * il nome della seconda o terza tastiera si riporta semplicemente, dopo il numero ordinale romano, come '''''Espressivo''''' e non come Recitativo, essendo un'impropria italianizzazione del francese ''Récit''; * nel caso di aggettivi dopo il nome del manuale, essi sono riportati con la prima lettera minuscola (ad esempio: '''VI - ''Organo antico aperto'''''); * qualora i registri, sulla consolle, siano raggruppati per Concerto e Ripieno (ad esempio come avviene per la maggior parte degli organi ottocenteschi italiani), si segua questo schema ([[Disposizioni foniche di organi a canne/Italia/Toscana/Provincia di Siena/Montalcino/Montisi - Chiesa delle Sante Flora e Lucilla|qui un esempio]]) e, nel caso di più manuali, si premetta sempre il numero e il nome (ad esempio: '''I - Organo eco ''Concerto'''''); * all'interno di ogni divisione vi sono due colonne, divise da doppia stanghetta verticale (<code><nowiki>||</nowiki></code>), che rispettivamente, da sinistra a destra, sono: 1) nome del registro con eventualmente indicato il numero di file, 2) altezza del registro in piedi con eventualmente specificata l'appartenenza ai soli Bassi o ai soli Soprani (esempio: <code><nowiki>Ripieno 5 file || 2' Soprani</nowiki></code>); * tutti i nomi registri sono scritti con la prima lettera maiuscola, mentre le parole seguenti devono iniziare con la minuscola (ad esempio: ''Ripieno acuto 5 file'' e '''non''' ''Ripieno Acuto 5 File''), ad eccezione delle disposizioni in tedesco o nelle lingue che richiedono la maiuscola anche per tutti i sostantivi - nel caso non sia possibile reperire l'altezza in piedi delle mutazioni composte, si sposta il numero di file nel campo dell'altezza in piedi (esempio: <code><nowiki>Ripieno || 5 file</nowiki></code>); * le mutazioni sono scritte con il numero intero separato da quello frazionario tramite un punto, così: ''5.1/3<nowiki>'</nowiki>''; qualora l'altezza sia solo frazionaria, si omette lo ''0.'' iniziale, così: ''1/4<nowiki>'</nowiki>'' e '''non''' ''0.1/4<nowiki>'</nowiki>''; * nel caso di mutazioni composte, l'altezza in piedi è riportata solo relativamente alla prima fila, ad eccezione di quelle a due file (per non occupare troppo spazio) - qualora le altezze delle file successive presentino delle anomalie, si inseriscono in nota. * i registri ad ancia sono scritti in rosso quando sono riportati così sulla consolle; * non si inserisce il numero ordinale davanti a ciascun registro; * non si riportano le unioni e gli accoppiamenti, né gli annullatori; * il Tremolo si riporta all'interno di ciascuna divisione; * gli accessori (ad esempio: Uccelliera, Zampogna ecc.) si riportano nel seguente modo prima della disposizione fonica: '''Accessori''': ''Uccelliera''; ''Zampogna''; * non sono ammesse abbreviazioni. Quindi, in poche parole, questa disposizione '''non''' va bene (mettiamo che sulla consolle i registri ad ancia siano scritti '''in nero'''): {| border="0" cellspacing="0" cellpadding="20" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" | colspan=2 | '''Prima tastiera - ''Grand'Organo''''' ---- |- |Principale || 8' |- |Ottava || 4' |- |XV || 2' |- |XIX || 1.1/3' |- |XXII || 1' |- |Ripieno Acuto 3 File || 0.1/2' |- |Flauto a Camino || 8' |- |Sesquialtera 2 File || 2.2/3'-1.3/5' |- |<span style="color:#8b0000;">Tromba</span> || <span style="color:#8b0000;">8' bassi</span> |- |<span style="color:#8b0000;">Tromba</span> || <span style="color:#8b0000;">8' soprani</span> |- |Tremolo |- |} | style="vertical-align:top" | {| border="0" | colspan=2 | '''Seconda tastiera - ''Espressivo''''' ---- |- |Bordone || 8' |- |Viola di Gamba || 8' |- |Flauto a Cuspide || 4' |- |Nazardo || 2.2/3' |- |Ottavino || 2' |- |Decimino || 1.1/3' |- |Pienino 3 File || 1'-0.2/3'-0.1/2' |- |Voce Celeste 2 File || 8' |- |<span style="color:#8b0000;">Tromba Armonica</span> ||<span style="color:#8b0000;">8'</span> |- |Tremolo |- |} | style="vertical-align:top" | {| border="0" | colspan=2 | '''Pedale''' ---- |- |Contrabbasso || 16' |- |Bordone || 16' |- |Basso || 8' |- |Ottava || 4' |- |<span style="color:#8b0000;">Trombone</span> || <span style="color:#8b0000;">16'</span> |- |<span style="color:#8b0000;">Tromba Bassa</span> || <span style="color:#8b0000;">8'</span> |- |} |} Questa, invece, va bene: {| border="0" cellspacing="0" cellpadding="20" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" | colspan=2 | '''I - ''Grand'Organo''''' ---- |- |Principale || 8' |- |Ottava || 4' |- |XV || 2' |- |XIX || 1.1/3' |- |XXII || 1' |- |Ripieno acuto 3 file || 1/2' |- |Flauto a camino || 8' |- |Sesquialtera 2 file || 2.2/3'-1.3/5' |- |Tromba || 8' Bassi |- |Tromba || 8' Soprani |- |Tremolo |- |} | style="vertical-align:top" | {| border="0" | colspan=2 | '''II - ''Espressivo''''' ---- |- |Bordone || 8' |- |Viola di gamba || 8' |- |Flauto a cuspide || 4' |- |Nazardo || 2.2/3' |- |Ottavino || 2' |- |Decimino || 1.3/5' |- |Pienino 3 file || 1' |- |Voce celeste 2 file || 8' |- |Tromba armonica || 8' |- |Tremolo |- |} | style="vertical-align:top" | {| border="0" | colspan=2 | '''Pedale''' ---- |- |Contrabbasso || 16' |- |Bordone || 16' |- |Basso || 8' |- |Ottava || 4' |- |Trombone || 16' |- |Tromba bassa || 8' |- |} |} == Libri correlati == * {{libro|Organo a canne}} [[Categoria:Disposizioni foniche di organi a canne| ]] [[Categoria:Musica]] [[Categoria:Dewey 786]] {{alfabetico|D}} {{Avanzamento|0%|9 giugno 2020}} fmbkfkba7tzs5xdt4brpvu9nvmtkge5 Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi 0 36372 502143 501142 2026-10-04T21:53:15Z ~2026-46067-79 54720 /* */ 502143 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} Disposizioni foniche della [[w:Provincia di Lodi|provincia di Lodi]] raggruppate per comune: * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Lodi|Lodi]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Lodi Vecchio|Lodi Vecchio]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Abbadia Cerreto|Abbadia Cerreto]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Boffalora D'Adda|Boffalora D'Adda]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Borghetto Lodigiano|Borghetto Lodigiano]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Casalmaiocco|Casalmaiocco]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Casalpusterlengo|Casalpusterlengo]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Castelgerundo|Castelgerundo]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Castelnuovo Bocca d'Adda|Castelnuovo Bocca d'Adda]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Castiglione d'Adda|Castiglione d'Adda]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Cavenago d'Adda|Cavenago d'Adda]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Codogno|Codogno]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Comazzo|Comazzo]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Cornegliano Laudensa|Cornegliano Laudense]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Corno Giovine|Corno Giovine]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Crespiatica|Crespiatica]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Corte Palasio|Corte Palasio]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Fombio|Fombio]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Graffignana|Graffignana]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Guardamiglio|Guardamiglio]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Mairago|Mairago]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Maleo|Maleo]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Marudo|Marudo]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Massalengo|Massalengo]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Merlino|Merlino]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Montanaso Lombardo|Montanaso Lombardo]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Ospedaletto Lodigiano|Ospedaletto Lodigiano]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Orio Litta|Orio Litta]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Sant' Angelo Lodigiano|Sant' Angelo Lodigiano]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Salerano sul Lambro|Salerano sul Lambro]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/San Fiorano|San Fiorano]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/San Martino in strada|San Martino in strada]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/San Rocco al Porto|San Rocco al Porto]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Santo Stefano Lodigiano|Santo Stefano Lodigiano]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Sordio|Sordio]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Turano Lodigiano|Turano Lodigiano]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Valera Fratta|Valera Fratta]] * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Zelo Buon Persico|Zelo Buon Persico]] {{Avanzamento|40%|5 dicembre 2019}} [[Categoria:Disposizioni foniche di organi a canne]] ifhpqp5nv5q4hhdvqu1l1qauitrvniq Storia della letteratura italiana/Edmondo De Amicis 0 37160 502142 488274 2026-10-04T21:04:18Z Hippias 18281 modifiche stilistiche 502142 wikitext text/x-wiki {{Storia della letteratura italiana|sezione=6}} Negli anni ottanta dell'Ottocento si colloca l'attività letteraria di Edmondo De Amicis, conosciuto per essere l'autore del romanzo ''Cuore'', uno dei testi più popolari della letteratura italiana per ragazzi. Entra anche nella [[../Questione della lingua nell'Ottocento|questione della lingua]] con il saggio ''L'idioma gentile'' (1905). == La vita == [[Immagine:Edmondo De Amicis.jpg|thumb|left|Edmondo De Amicis]] Edmondo De Amicis nasce il 21 ottobre 1846 a Oneglia. È di famiglia benestante: il padre Francesco è regio banchiere di sali e tabacchi, mentre la madre, Teresa Busseti, fa parte dell'alta borghesia. Allievo dell'accademia militare di Modena, diventa ufficiale sottotenente. Nel 1866 partecipa alla battaglia di Custoza, assistendo alla sconfitta dei Sabaudi. Lascia l'esercito nel 1867, conservando, tuttavia, lo spirito patriottico tipico del periodo risorgimentale che leggiamo nelle sue opere, attraverso valori di disciplina militare come valido metodo educativo. Diventa giornalista militare e si trasferisce a Firenze per assumere la direzione de ''L'Italia militare'', organo del Ministero di Guerra. Riassume l'esperienza di questo periodo in una serie di bozzetti, riuniti nella raccolta ''La vita militare'' (1868). L'anno seguente vi aggiunge il bozzetto-reportage ''L'esercito italiano durante il colera del 1867''.<ref>{{cita news|autore= Piero Meli|url=|titolo=Edmondo De Amicis e i fantasmi letterari del colera in Sicilia|pubblicazione=La Sicilia|data= 22 dicembre 2012|accesso=}}</ref> Il ventiduenne Edmondo è poi assunto nel 1868 dal giornale ''la Nazione'' di Firenze,<ref>{{cita news|autore=|url= http://www.lanazione.it/firenze/2009/01/18/145189-giornale_ragazzini_grandi_firme.shtml |titolo=Il giornale dei ragazzini |pubblicazione=La Nazione|data=18 gennaio 2009|accesso=}}</ref> dove lavora come inviato militare, in Italia e all'estero, e assiste tra l'altro alla presa di Roma del 1870. Le sue corrispondenze di questo periodo formano vari libri-diari di viaggio: ''Spagna'' (1872), ''Ricordi di Londra'' (1873), ''Olanda'' (1874), ''Marocco'' (1876), ''Costantinopoli'' (1878/1879), ''Ricordi di Parigi'' (1879). Dopo questo periodo De Amicis si stanzia definitivamente in Piemonte. Nel periodo 1882-1884 è a Pinerolo, dove scrive ''Alle porte d'Italia'', dedicato alla città e ai territori valligiani circostanti. Dal 1879 si stabilisce a Torino, dove termina, ispirato dalla vita scolastica dei suoi figli Ugo e Furio, la sua opera più famosa. Il 17 ottobre 1886 (il primo giorno di scuola di quell'anno), la casa editrice milanese Treves pubblica ''Cuore'', una raccolta di episodi ambientati in una classe elementare di Torino, che ha subito grande successo. Il libro è di forte carattere educativo-pedagogico ed è molto apprezzato anche perché ricco di spunti morali attorno ai miti affettivi (da cui il titolo) e patriottici del recente Risorgimento. Tuttavia è ampiamente criticato dai cattolici per l'assenza totale di tradizioni religiose (i bambini di ''Cuore'' non festeggiano nemmeno il Natale), specchio politico delle aspre controversie tra il Regno d'Italia e la Chiesa cattolica dopo la presa di Roma del 1870. Nel 1889 De Amicis si avvicina al socialismo, a cui aderisce nel 1896. Questo mutamento è visibile nelle sue opere successive, in cui presta molta attenzione alle difficili condizioni delle fasce sociali più povere e vengono completamente superate le idee nazionalistiche che avevano animato ''Cuore''. Amico di Filippo Turati, collabora a giornali legati al Partito Socialista come la ''Critica sociale'' e ''La lotta di classe''. Dopo il successo di ''Cuore'' seguono altri libri come ''Sull'oceano'' (1889), sulle condizioni dei poverissimi emigranti italiani e poi ''Il romanzo di un maestro'' (1890), ''Amore e ginnastica'' (1892), ''La maestrina degli operai'' (1895) e ''La carrozza di tutti'' (1899), ritratto della città di Torino vista da un tram. Inoltre scrisse per ''Il grido del popolo'' di Torino numerosi articoli d'ispirazione socialista, che furono poi raccolti nel libro ''Questione sociale'' (1894). Gli ultimi anni sono rattristati sia dalla morte della madre Teresa, sia dai continui screzi con la moglie Teresa Boassi, che aveva sposato nel 1875.<ref>{{cita web| url=http://www.simonel.com/santini/saggi32.html |autore=Maria Santini | titolo=La scellerata e l'egocentrico: Teresa ed Edmondo De Amicis |accesso=22 settembre }} </ref> Nel 1903 è eletto socio dell'Accademia della Crusca.<ref>{{cita web | url=http://213.225.214.179/fabitaliano2/globale/accademico.asp?_method=trovaaccademico&pcount=1&p0=chiave%20=%20660 | titolo=Edmondo de Amicis | opera=Accademia della Crusca | accesso=7 giugno 2009}}</ref> Il ministro Vittorio Emanuele Orlando lo chiama (insieme a [[../Antonio Fogazzaro|Fogazzaro]]) a far parte del Consiglio Superiore dell'Istruzione. Le ultime sue opere sono ''L'idioma gentile'' (1905), i ''Ricordi d'un viaggio in Sicilia'' e ''Nuovi ritratti letterari e artistici''. Tornato nella sua natìa Liguria, De Amicis muore improvvisamente per un'emorragia cerebrale l'11 marzo 1908. == ''Cuore'' == {{vedi pedia|Cuore (romanzo)}} {{vedi source|Cuore (1889)}} [[File:Cuore - pic 9.png|thumb|La piccola vedetta lombarda in un'illustrazione del 1886]] L'opera più importante e conosciuta di De Amicis è ''Cuore'', un libro di lettura per ragazzi che ha grande fortuna nel sistema educativo italiano durante l'età post-unitaria. La trama ruota interamente attorno al mondo della scuola, che viene descritto attraverso le pagine del diario di Enrico Bottini, un bambino di terza elementare proveniente da una famiglia borghese. Il libro si presenta quindi come un insieme di scene e bozzetti che hanno per protagonisti i compagni di classe di Enrico, che appartengono a diverse classi sociali.<ref name="Baldi128">{{cita libro | autore1=Guido Baldi | autore2= Silvia Russo | autore3= Mario Razetti | autore4= Giusepper Zaccaria | titolo=La Scapigliatura, il Verismo, il Decadentismo | opera= Moduli di letteratura | anno=2002 | editore=Paravia | città=Torino | p=128 }}</ref> Alcuni di questi personaggi sono rimasti celebri: Garrone, il quattordicenne forte e generoso, che si comporta già come un uomo; Derossi, il migliore della classe oltre che il più bello e ammirato, sempre pronto ad aiutare i compagni nello studio; Nobis, l'aristocratico snob; il figlio del muratore, chiamato «muratorino»; Precossi, il figlio del fabbro; Crossi, il figlio dell'erbivendola; l'«infame» Franti, ragazzo svogliato e irrispettoso, che a metà del libro viene cacciato da scuola. In questo modo viene delineato il quadro della società torinese dell'età umbertina, nelle sue diverse componenti. La narrazione dei fatti, che percorre l'intero anno scolastico 1881-1882, è interrotta dai messaggi ammonitori che i genitori di Enrico lasciano nel suo diario, e dalla trascrizione dei racconti edificati che il maestro fa leggere agli studenti ogni mese. Tra questi, alcuni sono diventati famosi, come ''La piccola vedetta lombarda'' e ''Il tamburino sardo''.<ref name="Baldi128" /> Il libro ha un evidente scopo educativo: formare la futura classe dirigente del nuovo stato unitario (rappresentata dal piccolo borghese Enrico) e trasmettere un sistema valori valido per tutte le classi sociali del regno. Tra questi principi morali ci sono il rispetto della famiglia, il patriottismo, il culto dell'esercito e del Risorgimento, il rispetto per le istituzioni e in particolare per il re, la condanna dei comportamenti critici o irrispettosi verso lo stato vigente. A questo si aggiungono poi la fede nel progresso e l'esaltazione di virtù come la laboriosità, l'altruismo, la solidarietà tra le classi sociali.<ref name="Baldi128" /> Grazie alla sua ampia diffusione, ''Cuore'' diventa parte della formazione culturale di generazioni di ragazzi, fino agli anni cinquanta. Attraverso la scuola, De Amicis cerca infatti un comune terreno nazionale e offre agli studenti di tutte le parti d'Italia una serie di valori civili laici elaborati dalla borghesia post-risorgimentale.<ref>{{cita libro | autore1=Giulio Ferroni | titolo=Profilo storico della letteratura italiana | anno=2002 | editore=Einaudi | città=Torino | p=819 }}</ref> == Note == <references /> == Altri progetti == {{interprogetto}} {{Avanzamento|100%|29 gennaio 2026}} [[Categoria:Storia della letteratura italiana|De Amicis]] csgamuyuv8rgtuuveko705f4a0sqfrk Storia della letteratura italiana/Antonio Fogazzaro 0 38389 502141 488275 2026-10-04T20:50:31Z Hippias 18281 modifiche stilistiche 502141 wikitext text/x-wiki {{Storia della letteratura italiana|sezione=6}} Nelle sue opere, Antonio Fogazzaro tenta di coniugare la tradizione cattolica con le istanze della modernità. La sua narrativa, in cui sopravvivono ideali risorgimentali ed elementi di ascendenza romantica, si caratterizza per una maggiore attenzione agli stati d'animo dei personaggi e per il suo interesse per temi come l'irrazionale, il sogno e il mistero, aspetti che in parte lo avvicinano alle tendenze del [[../Decadentismo|decadentismo]] che si diffondono in Europa negli ultimi decenni del secolo. == La vita == [[File:Photograph of Antonio Fogazzaro.jpg|thumb|left|Antonio Fogazzaro nei primi anni del Novecento]] Antonio Fogazzaro nasce a Vicenza il 25 marzo 1842 in una ricca famiglia borghese, profondamente cattolica e di ferventi sentimenti patriottici.<ref name="Pazzaglia931">{{cita libro| Mario | Pazzaglia | Letteratura italiana: testi e critica con lineamenti di storia letteraria | 1979 |Zanichelli | Bologna | volume=3 |p=931}}</ref> Educato in vari istituti religiosi, ha tra i suoi insegnanti di liceo l'abate Giacomo Zanella, poeta e in seguito docente di letteratura italiana a Padova. Trascorre inoltre le ferie a Oria in Valsolda sul lago di Lugano, paese di origine della madre, un luogo che torna più volte nella sua opera.<ref>{{cita libro | autore1=Guido Baldi | autore2=Silvia Giusso | autore3=Mario Razetti | autore4=Giuseppe Zaccaria | titolo=La Scapigliatura, il Verismo, il Decadentismo | opera=Moduli di letteratura | anno=2002 | editore=Paravia | città=Torino | p=186 }}</ref> Inizia a studiare giurisprudenza a Padova, ma si laurea a Torino, dove il padre è emigrato per fuggire al governo austriaco. Nel 1865 si trasferisce a Milano, dove entra in contatto con gli ambienti della [[../Scapigliatura|scapigliatura]].<ref name="Pazzaglia931" /> Nel 1866 sposa la contessa Margherita Lampertico di Valmanara, da cui ha tre figli. Si dedica alla professione di avvocato fino al 1869, anno in cui torna a Vicenza e si occupa esclusivamente di letteratura. Pubblica la sua prima opera nel 1874, la novella in versi ''Miranda''.<ref name="Baldi187">{{cita libro | autore1=Guido Baldi | autore2=Silvia Giusso | autore3=Mario Razetti | autore4=Giuseppe Zaccaria | titolo=La Scapigliatura, il Verismo, il Decadentismo | opera=Moduli di letteratura | anno=2002 | editore=Paravia | città=Torino | p=187 }}</ref> Gli anni settanta sono segnati da un periodo di crisi religiosa, durante il quale legge opere di argomento filosofico-religioso, tra le quali ''La filosofia del Credo'' di Auguste Joseph Alphonse Gratry. Tornato al cattolicesimo, riflette sulla conciliazione tra scienze e fede, tema che è al centro di varie conferenze che tiene in giro per l'Italia. Si interessa, in quest'ottica, anche all'evoluzionismo, a cui dedica i saggi raccolti in ''Ascensioni umane'' (1899). Aderisce inoltre al movimento modernista, secondo il quale è necessario un rinnovamento della Chiesa che però non contraddica la tradizione cattolica, e a cui possano partecipare anche laici dotati di una certa sensibilità culturale.<ref name="Ferroni820">{{cita libro | Giulio | Ferroni | Profilo storico della letteratura italiana | 2003 | Einaudi | Torino | p=820 }}</ref> È possibile riconoscere i riflessi di questi studi in molte sue opere e in tutti i suoi romanzi.<ref name="Baldi187 /> A questi principi è ispirato il romanzo ''Il Santo'' (1905), che però è condannato dalla Chiesa e messo all'Indice. Lo scrittore accetta la condanna e si sottomette alla censura,<ref name="Pazzaglia931" /> pur continuando a difendere le sue tesi attraverso articoli e conferenze. Ormai conosciuto anche a livello internazionale, nel 1896 Fogazzaro diventa senatore a vita. Alla fine del 1910 pubblica il suo ultimo romanzo, ''Leila'', scritto durante l'isolamento in cui si è ritrovato dopo la censura vaticana; anche questo è però messo all'Indice. Muore a Vicenza il 7 marzo 1911, durante un'operazione chirurgica.<ref name="Baldi187 /> == Oltre il realismo == [[File:Picture of Fogazzaro by Perozzi.jpg|thumb|Antonio Fogazzaro nei primi anni dieci]] Durante la vita, Fogazzaro è stato uno scrittore di successo e i suoi romanzi hanno conosciuto grande popolarità. Con gli anni, i critici hanno ridimensionato la sua importanza, ma la sua opera rimane comunque un punto di riferimento per comprendere i gusti e le tendenze letterarie diffuse negli ultimi decenni dell'Ottocento.<ref name="Pazzaglia931" /> Già dai primi romanzi la narrativa di Fogazzaro si discosta sensibilmente dal [[../Verismo|verismo]]. La sua è una prosa evocatrice, che si apre all'irrazionale e a elementi tipici del decadentismo, come il sogno, l'analisi degli aspetti più torbidi dell'animo umano, le suggestioni provenienti dalla musica e dai paesaggi, le corrispondenze segrete tra le anime.<ref name="Baldi187 /><ref name="Petronio803">{{cita libro | Giuseppe | Petronio | L'attività letteraria in Italia | 1969 | Palumbo | Palermo | p=803}}</ref> Alla narrativa realista oppone un'arte trasfiguratrice, che da un lato è influenzata dal lirismo tipico del [[../Romanticismo|Romanticismo nordico]], dall'altro assorbe le novità provenienti dalla letteratura decadente contemporanea.<ref name="Pazzaglia931" /> Secondo Pazzaglia «il suo vero nucleo poetico è costituito da una sensualità inquieta e turbata, in apparente contrasto con un misticismo vago e un po' torbido, ma ad esso sostanzialmente connessa».<ref name="Pazzaglia932">{{cita libro| Mario | Pazzaglia | Letteratura italiana: testi e critica con lineamenti di storia letteraria | 1979 |Zanichelli | Bologna | volume=3 |p=932}}</ref> Petronio scrive invece che il suo stile «tende a suggerire impressioni ed emozioni, sottile, vibratile, lirico più che narrativo».<ref name="Petronio803 /> Fogazzaro inoltre tenta di dare vita a una letteratura cattolica moderna, un filone che in Italia ha scarso seguito, diversamente da quanto accade invece in altre nazioni.<ref name="Baldi187 /><ref name="Petronio803" /> A differenza di [[../Alessandro Manzoni|Manzoni]], il cattolicesimo di Fogazzaro non si basa su questioni morali ben definite, ma piuttosto ricerca raffinate esperienze spirituali sia nei rapporti tra le persone sia nella natura, che è pervasa di mistero e nella quale si agitano forze arcane. I protagonisti delle sue opere sono inoltre personaggi superiori per sensibilità e raffinatezza, che si distaccano dagli uomini comuni rimanendo però ancorati alla morale borghese. Fogazzaro asseconda quindi i gusti e le contraddizioni del pubblico borghese a cui si rivolge, che da un lato è irrequieto e desideroso di innovazioni, ma dall'altro rimane legato a posizioni conservatrici.<ref name="Pazzaglia932" /> == ''Malombra'' == {{vedi source|Malombra}} Fogazzaro esordisce con la novella in versi ''Miranda'' (1874), a cui seguono le liriche raccolte in ''Valsolda'' (1876). Al 1881 risale la pubblicazione del suo primo romanzo, ''Malombra'', che ha grande fortuna di pubblico. Nel romanzo sono già presenti i temi principali che caratterizzano la produzione letteraria di Fogazzaro, come il mistero, l'ascolto delle voci della natura, l'inconscio, la sensualità, la religiosità. Nel complesso, come scrive Pazzaglia, si tratta di un romanzo «d'atmosfere, piuttosto che di fatti»,<ref name="Pazzaglia932" /> sospeso tra le suggestioni suscitate dai luoghi e dalla musica, e una sottile indagine psicologica.<ref name="Ferroni820" /> Dopo ''Malombra'', l'autore pubblica altre opere in cui si concentra su motivi etici e politici, collegandoli però a temi come l'amore e il sentimento: ''Daniele Cortis'' (1884), ''Fedele a altri racconti'' (1887), ''Il mistero del poeta'' (1888). == ''Piccolo mondo antico'' == {{vedi source|Piccolo mondo antico}} L'opera più famosa di Fogazzaro è ''Piccolo mondo antico''. Pubblicato nel 1895, il romanzo racconta del contrasto tra le personalità dei due protagonisti, Franco e Luisa, sullo sfondo del Lago Maggiore negli anni del Risorgimento. In questo libro è possibile riconoscere una tendenza al realismo di ascendenza manzoniana. La psicologia dei personaggi non è torbida e irrequieta come negli esempi precedenti, quindi meno lontana dalla realtà quotidiana, e il romanzo è nel complesso dotato di equilibrio e limpidezza. Tuttavia non si può parlare di realismo in senso proprio, poiché i personaggi, i luoghi e gli eventi sono avvolti da un senso di sogno e di nostalgia per il passato (molti spunti e riferimenti, infatti, provengono dai ricordi giovanili dell'autore).<ref>{{cita libro| Mario | Pazzaglia | Letteratura italiana: testi e critica con lineamenti di storia letteraria | 1979 |Zanichelli | Bologna | volume=3 |p=933}}</ref> A ''Piccolo mondo antico'' seguono ''Piccolo mondo moderno'' (1900) e ''Il Santo'' (1905), che hanno per protagonista Pietro Maironi, figlio di Franco e Luisa. Pietro ha una personalità contraddittoria, che passa dalla sensualità autodistruttiva alla convinzione di essere chiamato a svolgere una missione per il bene della Chiesa. Nel ''Santo'' Pietro partecipa alla fondazione di un movimento per la rigenerazione della Chiesa; il romanzo è narrato con un tono rarefatto, che sottolinea la volontà di elevazione del protagonista. Come già ricordato, questo libro è condannato dalla Chiesa: pur accettando la censura, Fogazzaro non rinuncia a difendere le proprie convinzioni, rimanendo però sostanzialmente isolato. La stessa sorte spetta anche al successivo ''Leila'' (1907). La critica oggi giudica con severità questi ultimi romanzi, che all'epoca sono stati invece molto apprezzati dal pubblico, e i temi affrontati sembrano lontani anche dal cattolicesimo attuale; tuttavia sono una testimonianza del malessere che serpeggia in Italia all'inizio del Novecento.<ref>{{cita libro | Giulio | Ferroni | Profilo storico della letteratura italiana | 2003 | Einaudi | Torino | pp=822-823 }}</ref> == Note == <references /> == Altri progetti == {{Interprogetto}} {{Avanzamento|100%|29 gennaio 2026}} [[Categoria:Storia della letteratura italiana|Fogazzaro]] 2yxyhn37h45qcf7ffzkc35pkvjafgr7 Software libero a scuola/LTSP 0 41902 502089 498612 2026-10-04T18:05:57Z Eumolpo 4673 ortografia 502089 wikitext text/x-wiki {{Software libero a scuola}} {{orfano}}{{w}} [[toc]] =Preambolo= || Licenza GNU FDL Copyleft 2009 Joris Fabrizio Rossi È garantito il permesso di copiare, distribuire e/o modificare questo documento secondo i termini della Licenza per Documentazione Libera GNU (GNU FDL) versione 1.3 o ogni versione successiva pubblicata dalla Free Software Foundation; senza Sezioni Non Modificabili, senza Testi di Copertina e senza Testi di Retro Copertina. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License (GNU FDL), Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts and no BackCover Texts || Parti di questo documento soprattutto nelle sezioni tecniche e nelle constatazioni politiche economiche sono tratte dalla Presentazione di Fabrizio Rossi per suo volere espresso dalla nota di copyright del documento rilasciamo questa pagina con la licenza GNU FDL. Un sentito ringraziamento a Fabrizio per avere condiviso il suo prezioso lavoro e mi ha permesso di documentare il lavoro fatto su LTSP in una maniera molto bella e veloce. Questo è un estratto del documento originale con integrate alcune sezioni specifiche per WiildOs. Per leggere il documento originale di Federico clicca [http://www.riminilug.it/tiki-download_file.php?fileId=569 qui]. Ringrazio OutOfBound, una persona che si occupa da tempo in Piemonte di trashware e reti informatiche nelle scuole e che mi ha passato un ottimo script per auto-configurare LTSP. Questo mi ha incentivato a migliorarlo e a mettere a disposizione di tutti il lavoro effettuato in questo documento e all'interno di WiildOs. ---- =LTSP= Immaginiamo di avere un laboratorio informatico con computer vecchi e datati o semplicemente di voler provare WiildOs nella nostra rete di computer. Come facciamo? Abbiamo due soluzioni o ci facciamo comprare, se abbiamo i soldi, un laboratorio nuovo (magari con tecnologie mobili) o facciamo girare su ogni macchina una live di WiildOs oppure facciamo girare LTSP su una macchina sola. Sulle altre macchine chiamate client non andremo ad installare nulla. In questo modo potrete realizzare laboratori scolastici e reti aziendali a bassissimo costo anche riciclando vecchi computer. Questa soluzione non è moda; è una tecnologia stabile e solida economica, ecologica e professionale; un modello ideale per ambienti didattici e amministrativi. LTSP è una soluzione assai utilizzata in Europa e nel Mondo ma in Italia conosce solo alcune sperimentazioni felici ma numericamente limitate. Favoriamo il riuso informatico; abbiamo tanta capacità di calcolo e intelligenza collettiva buttata nell'immondizia: un problema, ma anche una risorsa. Evoluzione tecnologica e oculate strategie di marketing (da abiurare) favoriscono un'obsolescenza precoce dell'hardware, inducendo l'abbandono dei “vecchi” computer per macchine in grado di supportare nuovi standard. Il risultato è la dismissione di enormi quantità di hardware ancora perfettamente funzionante. Il problema ecologico posto dai rifiuti elettronici (altamente inquinanti) ha condotto in tempi recenti alle normative RAEE (Rifiuti di Apparecchiature Elettriche ed Elettroniche), che introducono regole tecniche ed economiche per uno smaltimento più oculato, a fronte della mera rottamazione praticata in precedenza. Tra le conseguenze delle succitate normative, (semplificando) se ne può ricavare una di un certo rilievo: le aziende pubbliche e private che conferiscono con un atto formale a scuole, associazioni, etc. gli apparati obsoleti, in pratica, vengono sollevate dalle relative tasse di smaltimento. Una condizione che, di fatto, rende disponibili ingenti quantità di computer riciclabili, trasformando un problema ecologico in una risorsa economica di importanza significativa. ---- =LTSP in WiildOs= LTSP sarà integrato in WiildOs 3.0 e permetterà di fare questa piccola magia avviando direttamente la live di WiildOs. Se la soluzione ti piace puoi decidere di installare WiildOs sul server; in questo modo potrai manutenere solo il server, configurerai e installerai i programmi solo una volta per tutti. Si spera che questo piccolo contributo possa promuovere l'utilizzo di questa tecnologia e renderla a portata di tutto perseguendo la filosofia del rendere tutto facile con un tocco magico. ==Thin client== La modalità con cui partirà LTSP su WiildOs è quella thin client. Con una configurazione thin client i computer del laboratorio si avvieranno da rete acquisendo una piccola immagine del sistema operativo e utilizzeranno tutte le risorse del server. La cpu e la ram locale non verranno usate. Questo è particolarmente adatto nel caso in cui si abbiano macchine veramente scarse. In WiildOs abbiamo optato per una configurazione thin client in quanto pesa poco nella dimensione della iso e utilizza meno risorse di rete ed è una configurazione più adatta alle prove live. L'installazione prevede di poter accedere ai dischi locali in modo da poter memorizzare i dati sull'hard disk opzionale del client e utilizzare dispositivi di memorizzazione usb, cdrom e dvd. ==Fat client== Lasciamo al lettore l'esercizio e il completamento della pagina nel caso voglia installare WiildOs e cambiare le configurazioni in modo da farla lavorare come ''fat client'' o come sistema misto thin/fat client. LTSP permette di lavorare anche con fat client. Un fat client acquisisce una immagine del sistema operativo grande e completa, dopodichè è autonomo dal server e usa la cpu e la sua ram locale. Le nuove versioni di LTSP permettono di configurare un server LTSP che fornisce sia le funzionalità di thin client che di fat client a seconda delle prestazioni del singolo client. Quindi nel caso in cui decidiate di installare un server LTSP con WiildOs vi consigliamo di passare a una configurazione fat client. Leggi come fare nella [https:''help.ubuntu.com/community/UbuntuLTSP/FatClients documentazione di Ubuntu]. ---- =Requisiti hardware= ==Server== Va bene un computer recente di buone prestazioni con due schede di rete. Un computer con CPU dual core 3.1 GHz con 4GB di ram è in grado di gestire una aula informatica con 25 client. Un piccolo consiglio cercate l'associazione di trashware (riuso informatico) più vicina a voi spesso si trovano dei buoni server dismessi. Si tratta di server con tre, quattro anni di anzianità dismessi da scuole, banche, assicurazioni e aziende nel terziario avanzato. Potete provare anche a fare una questua, questo non è accattonaggio ma è riuso informatico. ==Client== Va bene qualunque computer funzionante dotato di una interfaccia di rete. computer possono essere anche privi di hard disk. Se non aveste computer di riciclo vi ricordo che i computer datati (completi di monitor, tastiera e mouse) utilizzabili come thin client sono reperibili gratuitamente dalle dismissioni di enti pubblici ed imprese private. ==Rete== LTSP è basato sul trasferimento massivo di dati tra il server e i thin client. E' pertanto necessario disporre di banda sufficiente affinché la gestione risulti fluida: tra singoli thin client e switch di rete sono sufficienti connessioni a 100Mbps; tra server e switch di rete sono opportune connessioni Gigabps, specialmente con un numero elevato di thin client (con un numero limitato di client funzionano comunque dignitosamente anche connessioni a 100Mbps). Per semplicità di gestione è opportuno dotare il server di due interfacce di rete (meglio se prima dell'installazione): una Gigabps per la rete LTSP e una 100Mbps per la connessione Internet (Intranet, etc.). Con LTSP ci servirà un solo computer con due schede di rete che funzionerà da server e su cui girerà WiildOs, tutti gli altri computer si avvieranno da rete grazie a servizi che mette a disposizione il server LTSP. E' possibile usare anche una singola interfaccia di rete, procurando però che la gestione DHCP sia effettuata dal server LTSP, una normale rete con uno switch o hub collegato ai client e al server è sufficiente. ---- =Avvia il server LTSP= Prima di tutto avvia WiildOs come al solito. Una volta partito il sistema vai su "Preferenze" e clicca su "LTSP". Aspetta pazientemente in pochi secondo sarà tutto pronto. <span style="display: block; text-align: center;"> </span> Ecco fatto adesso il tuo servizio LTSP è già in funzione. ---- =Avvia i client= Non devi fare altro che andare nel bios dei client e configurare di partire da rete. Questo passaggio va fatto una volta sola. Per fare questo avvia i terminali entra nel Bios ed anticipa nella fase di boot l'avvio da rete. Questa funzione può avere nomi diversi come "network boot", "pxe boot", "boot from NIC" (NIC sta per network interface) o nomi simili di solito seguiti con il nome della scheda di rete, una volta anticipata la voce e salvati i cambiamenti il computer proverà ogni volta ad avviarsi da rete e caricherà WiildOs attraverso il servizio LTSP ogni qual volta sarà disponibile. Qualora il server non fosse disponibile il client si avvierà come al solito dagli altri dispositivi; il computer si comporterà dunque come prima. Nella figura potete vedere come si fa a selezionare il boot da rete con uno dei Bios più diffusi. ---- =Come funziona= Questo paragrafo è riservato a chi volesse approfondire come funziona LTSP, quali sono le configurazioni in WiildOs e come è stato messo a punto il servizio di plug and play. Cosa succede quando parte un client LTSP # Il client fa una richiesta dhcp # Il server dhcp che gira sul server LTSP risponde e le informazioni di dove si trova il kernel minimale # Il client richiede il kernel minimale attraverso il servizio tftp che gira sul server LTSP # Il server tftp che gira sul server LTSP invia l'immagine del kernel minimale # Il client riceve l'immagine e la fa girare. Monterà le directory del server con nbd # Il client fa il login al sistema grafico del server ltsp attraverso ldm # Il client ha completato l'avvio e ha a disposizione l'interfaccia grafica Allora tutta la configurazione e avviamento dei servizi è fatta con uno script che si chiama start-ltsp-server ed è nella cartella /usr/local/bin questo script è un avanzamento e una personalizzazione di uno script sviluppato da OutOfBound, che da anni si occupa di trashware e server LTSP. Cosa fa lo script? # classifica le schede di rete e ne discrimina una come interna, una come esterna # configura il server dnsmasq sulla scheda interna # Configura il natting tra la scheda interna e esterna # Configura il servizio ltsp # Avvia tutti i servizi necessari all'esecuzione di LTSP In cosa è stato personalizzato lo script di OutOfBound per far girare più agevolmente LTSP su WiildOs live: # Un po' di bug-fixing e refactoring del codice # Si utilizza dnsmasq come server dhcp/tftp al posto del più pesante dell'isc-dhp-server # Si utilizzano connessioni in chiaro per velocizzare la comunicazione tra i client e il server e diminuire l'uso di cpu. La sicurezza non è lo scopo del progetto. # I client effettuano l'autologin attraverso una auto configurazione costante del servizio LTSP che viene aggiornata ogni volta che avviene il rilascio di un IP da parte di dnsmasq. Esempio: collego una macchina con mac address 2c:27:d7:a5:45:da a cui viene assegnato dal servizio dnsmasq l'indirizzo 192.168.30.40. L'hostname della macchina sarà ltsp040 e la password anche ltsp040. Queste informazioni andranno inserite dinamicamente nel file di configurazione di ltsp in modo che il client sia in grado di fare un autologin. Per maggiori informazioni fai man dnsmasq e guarda il file dhcp-scrip nella directory /usr/local/bin 5. Non è più necessario ricostruire l'immagine a runtime o rigenerare le chiavi ssh all'avvio. Tutto è già precostruito all'interno di WiildOs; in questo modo i tempi di attesa per far salire il servizio sono veramente stupefacenti. In cosa è migliorabile? # Migliore gestione con una singola interfaccia di rete soprattutto nel caso ci sia anche un altro server dhcp attivo sulla rete # Sviluppare un sistema che possa passare alla modalità fat client, particolarmente utile in installazioni fisse soprattutto se si ha a disposizione hardware con almeno un giga di ram. Sarebbe così un peccato non utilizzare quella risorsa... [[Categoria:Software libero a scuola|LTSP]] 7567xmub5stupvyr4s5t2p73vzizw2v Disposizioni foniche di organi a canne/Italia/Sicilia/Città metropolitana di Palermo/Chiusa Sclafani/Chiusa Sclafani - Chiesa di Maria Santissima Assunta 0 46880 502090 397123 2026-10-04T18:06:53Z Musico93 54867 /* */ 502090 wikitext text/x-wiki {{disposizioni foniche di organi a canne}} * '''Costruttore:''' Laudani e Giudici * '''Anno:''' 1912 * '''Restauri:''' Bottega Organaria di Giuliano Colletti * '''Registri:''' 8 * '''Canne:''' ? * '''Trasmissione:''' meccanica per il manuale; pneumatica per il pedale * '''Consolle:''' a finestra * '''Tastiere:''' 1 di 56 tasti (do1-sol5) * '''Pedaliera:''' di 27 note (do1-re3) * '''Collocazione:''' in cantoria sopra la porta d'ingresso * '''Accessori:''' Unione Ped, Tiratutti * '''Note:''' ''parte del materiale fonico facente parte del precedente organo (La Grassa forse)'' {| border="0" cellspacing="0" cellpadding="20" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" | colspan=2 | '''I ''' ---- |- |Principale || 8' |- |Dulciana || 8' |- |Bordone || 8' |- |Viola |- |Unda Maris |- |Ottava |- |Decima Quinta |- |} | style="vertical-align:top" | {| border="0" | colspan=2 | '''Pedale''' ---- |- |Contrabassi |- |} |} == Bibliografia == * {{cita libro|autore=Giovan Battista Vaglica|titolo=Gli organi antichi nel territorio monrealese|città=Palermo|editore=Augustinus|anno=1991|isbn=no}} {{Avanzamento|100%|15 settembre 2020}} [[Categoria:Disposizioni foniche di organi a canne]] hgf8tw9qw07pckfvnerdnw5qolhyqg9 502091 502090 2026-10-04T18:08:40Z Musico93 54867 /* */ 502091 wikitext text/x-wiki {{disposizioni foniche di organi a canne}} * '''Costruttore:''' Laudani e Giudici * '''Anno:''' 1912 * '''Restauri:''' Bottega Organaria di Giuliano Colletti * '''Registri:''' 8 * '''Canne:''' ? * '''Trasmissione:''' meccanica per il manuale; pneumatica per il pedale * '''Consolle:''' a finestra * '''Tastiere:''' 1 di 56 tasti (do1-sol5) * '''Pedaliera:''' di 27 note (do1-re3) * '''Collocazione:''' in cantoria sopra la porta d'ingresso * '''Accessori:''' Unione Ped, Tiratutti * '''Note:''' Strumento interamente in cassa espressiva; ''parte del materiale fonico facente parte del precedente organo (La Grassa forse)'' {| border="0" cellspacing="0" cellpadding="20" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" | colspan=2 | '''I ''' ---- |- |Principale || 8' |- |Dulciana || 8' |- |Bordone || 8' |- |Viola |- |Unda Maris |- |Ottava |- |Decima Quinta |- |} | style="vertical-align:top" | {| border="0" | colspan=2 | '''Pedale''' ---- |- |Contrabassi |- |} |} == Bibliografia == * {{cita libro|autore=Giovan Battista Vaglica|titolo=Gli organi antichi nel territorio monrealese|città=Palermo|editore=Augustinus|anno=1991|isbn=no}} {{Avanzamento|100%|15 settembre 2020}} [[Categoria:Disposizioni foniche di organi a canne]] pp4f3ehrjjf8immn31qhlb26kymqu8s Disposizioni foniche di organi a canne/Italia/Piemonte/Città metropolitana di Torino/San Germano Chisone/San Germano Chisone - Chiesa Evangelica Valdese 0 49081 502149 495230 2026-10-04T23:12:58Z Gabor512 39720 disposizione fonica 502149 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} * '''Costruttore:''' Luigi Berutti di Torino (TO) * '''Anno:''' 1938 * '''Restauri/modifiche:''' Ditta Tamburini (1971, restauro conservativo), Francesco II Vegezzi-Bossi (1980, restauro e ampliamento)<ref>Aggiunta del 2° manuale in cassa espressiva</ref> * '''Registri:''' 18 * '''Canne:''' ? * '''Trasmissione:''' elettrica * '''Consolle:''' fissa indipendente al centro della cantoria, rivolta verso la navata * '''Tastiere:''' 2 di 61 note ciascuna (''Do<sup>1</sup>''-''Do<sup>6</sup>'') * '''Pedaliera:''' concavo-radiale di 32 note (''Do<sup>1</sup>''-''Sol<sup>3</sup>'') * '''Collocazione:''' in due corpi divisi simmetrici, su cantoria in controfacciata {| border="0" cellspacing="10" cellpadding="40" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" | colspan=8 | '''I - ''Grand'Organo''''' ---- |- |Principale || 8' |- |Flauto || 8' |- |Ottava eolina || 8' |- |Ottava || 4' |- |Decima V || 2' |- |Decima IX || 1.1/3' |- |Ripieno || 4 file<ref>aziona XV e XIX + XXII e XXVI</ref> |- |Tromba || 8' |- |} | style="vertical-align:top" | {| border="0" | colspan=3 | '''II - ''Espressivo''''' ---- |- |Bordone || 8' |- |Celeste || 8'<ref>da ''Do<sup>2</sup>''</ref> |- |Flauto || 4' |- |Flauto || 2' |- |Ripieno || 3 file |- |Oboe || 8' |- |Tremolo |- |} | style="vertical-align:top" | {| border="0" | colspan=3 | '''Pedale''' ---- |- |Contrabbasso || 16'<ref>In realtà combinazione ''Subbasso 16' '' + ''Ottava 8' ''</ref> |- |Subbasso || 16' |- |Ottava || 8' |- |Bordone || 8' |- |} |} == Note == <references/> == Bibliografia == {{cita libro| nome= Silvio| cognome= Sorrentino|titolo= Organalia: 100 organi della Provincia di Torino|città=Torino|anno=2009|}} == Collegamenti esterni == * {{cita web|url=http://www.organalia.org/images/Archivio2008/quindicesimo.pdf|titolo=Organalia 2008 - San Germano Chisone|accesso=05 aprile 2021}} {{Avanzamento|100%|30 aprile 2026}} [[Categoria:Disposizioni foniche di organi a canne]] dy1eb9r0a9mpv757d283zf96yxbeimo 502150 502149 2026-10-04T23:15:13Z Gabor512 39720 502150 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} * '''Costruttore:''' Luigi Berutti di Torino (TO) * '''Anno:''' 1938 * '''Restauri/modifiche:''' Ditta Tamburini (1971, restauro conservativo), Francesco II Vegezzi-Bossi (1980, restauro e ampliamento)<ref>Aggiunta del 2° manuale in cassa espressiva</ref> * '''Registri:''' 18 * '''Canne:''' ? * '''Trasmissione:''' elettrica * '''Consolle:''' fissa indipendente al centro della cantoria, rivolta verso la navata * '''Tastiere:''' 2 di 61 note ciascuna (''Do<sup>1</sup>''-''Do<sup>6</sup>'') * '''Pedaliera:''' concavo-radiale di 32 note (''Do<sup>1</sup>''-''Sol<sup>3</sup>'') * '''Collocazione:''' in due corpi divisi simmetrici, su cantoria in controfacciata {| border="0" cellspacing="10" cellpadding="40" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" | colspan=8 | '''I - ''Grand'Organo''''' ---- |- |Principale || 8' |- |Flauto || 8' |- |Ottava eolina || 8' |- |Ottava || 4' |- |Decima V || 2' |- |Decima IX || 1.1/3' |- |Ripieno || 4 file<ref>aziona XV e XIX + XXII e XXVI</ref> |- |Tromba || 8' |- |} | style="vertical-align:top" | {| border="0" | colspan=3 | '''II - ''Espressivo''''' ---- |- |Bordone || 8' |- |Celeste || 8'<ref>da ''Do<sup>2</sup>''</ref> |- |Flauto || 4' |- |Flauto || 2' |- |Ripieno || 3 file<ref>XV-XIX-XXII</ref> |- |Oboe || 8' |- |Tremolo |- |} | style="vertical-align:top" | {| border="0" | colspan=3 | '''Pedale''' ---- |- |Contrabbasso || 16'<ref>aziona ''Subbasso 16' '' + ''Ottava 8' ''</ref> |- |Subbasso || 16' |- |Ottava || 8' |- |Bordone || 8' |- |} |} == Note == <references/> == Bibliografia == {{cita libro| nome= Silvio| cognome= Sorrentino|titolo= Organalia: 100 organi della Provincia di Torino|città=Torino|anno=2009|}} == Collegamenti esterni == * {{cita web|url=http://www.organalia.org/images/Archivio2008/quindicesimo.pdf|titolo=Organalia 2008 - San Germano Chisone|accesso=05 aprile 2021}} {{Avanzamento|100%|30 aprile 2026}} [[Categoria:Disposizioni foniche di organi a canne]] 3zlcefwbxahoi55gatj5ksvwrsmlqbg Disposizioni foniche di organi a canne/Italia/Piemonte/Città metropolitana di Torino/Torre Pellice/Torre Pellice - Chiesa Evangelica Valdese 0 49094 502151 495250 2026-10-05T10:02:47Z Gabor512 39720 nuova disposizione fonica 502151 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} [[File:Torre Pellice - Tempio Nuovo - 2023-09-30 21-39-25 001.jpg|400px|centro]] * '''Costruttore:''' Luigi Berutti di Torino (TO) * '''Anno:''' 1920 * '''Restauri/modifiche:''' Carlo Davico (anni 1950, modifiche)<ref>Aggiunta nel ''Flauto in XII'' al posto della ''Voce corale 8' ''</ref>, Ditta Pedrini (1976, modifiche)<ref>Trasformazione della trasmissione, da pneumatica a elettrica, sostituzione della consolle e aggiunta di un ''Principale 8' '' e due file di Ripieno in luogo di una ''Voce celeste'' al 2° manuale</ref>, Renzo Rosso (2001, restauro conservativo), Daniele Michelotto (2026, restauro e ampliamento) * '''Registri:''' 23 * '''Canne:''' 1350 circa * '''Trasmissione:''' elettrica * '''Consolle:''' fissa indipendente al centro della cantoria, rivolta verso la controfacciata * '''Tastiere:''' 2 di 58 note ciascuna (''Do<sup>1</sup>''-''La<sup>5</sup>'') * '''Pedaliera:''' concavo-radiale di 30 note (''Do<sup>1</sup>''-''Fa<sup>3</sup>'')<ref>In origine parallela</ref> * '''Collocazione:''' in due corpi divisi simmetrici, su cantoria in controfacciata {| border="0" cellspacing="10" cellpadding="40" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" | colspan=8 | '''I - ''Grand'Organo''''' ---- |- |Principale || 16'<ref>Prima ottava trasmessa dal Subbasso</ref> |- |Principale || 8' |- |Flauto || 8' |- |Dulciana || 8' |- |Voce umana || 8'<ref>da ''Do<sup>2</sup>''</ref> |- |Ottava || 4' |- |Flauto || 4' |- |Decimaquinta || 2' |- |Ripieno 4 file || 1.1/3' |- |Tromba || 8' |- |} | style="vertical-align:top" | {| border="0" | colspan=3 | '''II - ''Espressivo''''' ---- |- |Principale || 8' |- |Bordone || 8' |- |Viola || 8' |- |Voce celeste || 8' |- |Flauto || 4' |- |Flauto |2' |- |Sesquialtera 2 file || 2.2/3' |- |Ripienino 2 file || 2' |- |Oboe |8' |- |Tremolo |- |} | style="vertical-align:top" | {| border="0" | colspan=3 | '''Pedale''' ---- |- |Contrabbasso || 16' |- |Subbasso || 16' |- |Basso || 8' |- |Bordone || 8' |- |Violoncello || 8' |- |Ottava || 4' |- |Posaune |16' |- |} |} == Note == <references/> == Fonti == Informazioni parzialmente estratte dal testo ''Organalia: 60 organi della Provincia di Torino'',Torino,Editore A.G.G. PRINTING STARS, 2004. == Collegamenti esterni == * {{cita web|url=http://www.organalia.org/images/Archivio2008/nono.pdf|titolo=Organalia 2008 - Torre Pellice|accesso=06 aprile 2021}} {{Avanzamento|100%|30 aprile 2026}} [[Categoria:Disposizioni foniche di organi a canne]] mrjpo2r21wqa5hrqaqsdqua43h7gd2n 502152 502151 2026-10-05T10:07:18Z Gabor512 39720 registri nuovi aggiunti in sede di restauro 502152 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} [[File:Torre Pellice - Tempio Nuovo - 2023-09-30 21-39-25 001.jpg|400px|centro]] * '''Costruttore:''' Luigi Berutti di Torino (TO) * '''Anno:''' 1920 * '''Restauri/modifiche:''' Carlo Davico (anni 1950, modifiche)<ref>Aggiunta nel ''Flauto in XII'' al posto della ''Voce corale 8' ''</ref>, Ditta Pedrini (1976, modifiche)<ref>Trasformazione della trasmissione, da pneumatica a elettrica, sostituzione della consolle e aggiunta di un ''Principale 8' '' e due file di Ripieno in luogo di una ''Voce celeste'' al 2° manuale</ref>, Renzo Rosso (2001, restauro conservativo), Daniele Michelotto (2026, restauro e ampliamento) * '''Registri:''' 23 * '''Canne:''' 1350 circa * '''Trasmissione:''' elettrica * '''Consolle:''' fissa indipendente al centro della cantoria, rivolta verso la controfacciata * '''Tastiere:''' 2 di 58 note ciascuna (''Do<sup>1</sup>''-''La<sup>5</sup>'') * '''Pedaliera:''' concavo-radiale di 30 note (''Do<sup>1</sup>''-''Fa<sup>3</sup>'')<ref>In origine parallela</ref> * '''Collocazione:''' in due corpi divisi simmetrici, su cantoria in controfacciata {| border="0" cellspacing="10" cellpadding="40" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" | colspan=8 | '''I - ''Grand'Organo''''' ---- |- |Principale || 16'<ref>Prima ottava trasmessa dal Subbasso</ref> |- |Principale || 8' |- |Flauto || 8' |- |Dulciana || 8' |- |Voce umana || 8'<ref>da ''Do<sup>2</sup>''</ref> |- |Ottava || 4' |- |Flauto || 4'<ref>al posto della precedente Eolina 4'</ref> |- |Decimaquinta || 2' |- |Ripieno 4 file || 1.1/3' |- |Tromba || 8'<ref>al posto dell'Oboe 8'</ref> |- |} | style="vertical-align:top" | {| border="0" | colspan=3 | '''II - ''Espressivo''''' ---- |- |Principale || 8' |- |Bordone || 8' |- |Viola || 8' |- |Voce celeste || 8'<ref>da Do2, al posto del Concerto Viole</ref> |- |Flauto || 4' |- |Flauto || 2' |- |Sesquialtera 2 file || 2.2/3'<ref>da ''Do<sup>2</sup>''</ref> |- |Ripienino 2 file || 2' |- |Oboe || 8'<ref>spostato dal Grand'Organo</ref> |- |Tremolo |- |} | style="vertical-align:top" | {| border="0" | colspan=3 | '''Pedale''' ---- |- |Contrabbasso || 16' |- |Subbasso || 16' |- |Basso || 8' |- |Bordone || 8' |- |Violoncello || 8' |- |Ottava || 4' |- |Posaune || 16'<ref>inseribile a pedaletto</ref> |- |} |} == Note == <references/> == Fonti == Informazioni parzialmente estratte dal testo ''Organalia: 60 organi della Provincia di Torino'',Torino,Editore A.G.G. PRINTING STARS, 2004. == Collegamenti esterni == * {{cita web|url=http://www.organalia.org/images/Archivio2008/nono.pdf|titolo=Organalia 2008 - Torre Pellice|accesso=06 aprile 2021}} {{Avanzamento|100%|30 aprile 2026}} [[Categoria:Disposizioni foniche di organi a canne]] 7yzl5ir3bkugz9z7xnvv6ezdb1aswsu Disposizioni foniche di organi a canne/Italia/Abruzzo/Provincia di Teramo/Montorio al Vomano 0 60618 502073 501753 2026-10-04T17:57:53Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502073 wikitext text/x-wiki {{disposizioni foniche di organi a canne}} Disposizioni foniche del comune di [[w:Montorio al Vomano|Montorio al Vomano]] raggruppate per edificio: ==Capoluogo== * [[Disposizioni foniche di organi a canne/Italia/Abruzzo/Provincia di Teramo/Montorio al Vomano/Montorio al Vomano - Chiesa di San Rocco|Chiesa di San Rocco]] {{Avanzamento|100%|24 giugno 2026}} [[Categoria:Disposizioni foniche di organi a canne|Montorio al Vomano]] ekmcsfh7cmq9q4wbo1f1bsralfz6r28 Disposizioni foniche di organi a canne/Italia/Veneto/Provincia di Treviso/Cornuda/Cornuda - Santuario di Nostra Signora della Rocca 0 60876 502087 501175 2026-10-04T18:02:05Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502087 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} [[File:Cornuda-Madonna della Rocca-organo Callido.jpg|350|center]] * '''Costruttore:''' Gaetano Callido (Op. tra 280 e 290)<ref>L'organo del Santuario, probabilmente del 1792, è di scuola Veneta e attribuibile a Gaetano Callido. Proveniva da Montalfoglio, frazione di San Lorenzo in Campo (PU), il parroco del luogo, Don Luigi Guiducci, lo aveva acquistato a San Marino (RSM), dalla chiesa di San Francesco, lo cedette alla frazione di Scascoli a Loiano (BO) e successivamente fu acquistato e donato dai confratelli a Don Orazio Mondin, Rettore della Basilica appositamente per essere collocato nel Santuario dopo un accurato lavoro di restauro operato da Alessandro Girotto figlio di Silvano, nel 1972. Alessandro, che iniziava l'attività, ne eseguì il restauro, la costruzione della cassa ornamentale e di contenimento, in quanto sprovvisto e quindi l’installazione. Il concerto inaugurale fu tenuto dal M° Giuseppe De Donà, organista del duomo di Treviso, alla presenza del Vescovo e di numerosi sacerdoti della diocesi che avevano contribuito all'acquisto.</ref> * '''Anno:''' 1792 * '''Restauri/modifiche:''' Alessandro Girotto (restauro, creazione cassa ed installazione, 1972) * '''Registri:''' 16 * '''Canne:''' 533 * '''Trasmissione:''' meccanica * '''Consolle:''' a finestra, al centro dell'organo * '''Tastiere:''' 1 di 47 note con prima ottava scavezza (''Do<sup>1</sup>''-''Re<sup>5</sup>'') * '''Pedaliera:''' scavezza a leggio di 17 note (''Do<sup>1</sup>''-''Sol#<sup>2</sup>'') sempre unita al manuale + pedale del ''Rollante'' * '''Collocazione:''' in corpo unico, al centro della cantoria in controfacciata * '''Accessori:''' ''Tiratutti'', ''Rollante'' * '''Note:''' divisione Bassi/Soprani dal ''Do#<sup>3</sup>'' {| border="0" cellspacing="0" cellpadding="20" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" | colspan=2 | '''Colonna di destra esterna - ''Concerto''''' ---- |- |Voce umana || Soprani |- |Flauto in VIII || Soprani |- |Flauto in XII || Soprani |- |Cornetta |- |Tromboncini || Bassi |- |Tromboncini || Soprani |- |Contrabbassi<ref>al pedale</ref> |- |} | style="vertical-align:top" | {| border="0" | colspan=2 | '''Colonna di destra interna - ''Ripieno''''' ---- |- |Principale || 8' Bassi |- |Principale || 8' Soprani |- |Ottava || 4' |- |Decimaquinta || 2' |- |Decimanona || 1.1/3' |- |Vigesima seconda || 1' |- |Vigesima sesta || |- |Vigesima nona || |- |} |} == Note == <references/> == Altri progetti == {{interprogetto|w=Santuario della Madonna della Rocca (Cornuda)|w_preposizione=sul|w_etichetta=Santuario della Madonna della Rocca a Cornuda}} {{Avanzamento|100%|23 agosto 2026}} [[Categoria:Disposizioni foniche di organi a canne|Cornuda - Santuario di Nostra Signora della Rocca]] 6156agrwhnedy64wm5ow2zcrbfe8jpt Disposizioni foniche di organi a canne/Italia/Piemonte/Provincia di Alessandria/Arquata Scrivia/Arquata Scrivia - Chiesa di San Giacomo Maggiore 0 61067 502084 501482 2026-10-04T18:00:43Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502084 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} [[File:Arquata S.-S.Giacomo-organo Locatelli.jpg|350px|center|Arquata S.-S.Giacomo-organo Locatelli]] * '''Costruttore:''' Giacomo Locatelli (Op. 10) * '''Anno:''' 1875 * '''Restauri/modifiche:''' F.lli Piccinelli (restauro, 1975) * '''Registri:''' 23 * '''Canne:''' ? * '''Trasmissione:''' meccanica * '''Consolle:''' a finestra, al centro dell'organo * '''Tastiere:''' 1 di 61 note con prima ottava cromatica (''Do<sup>1</sup>''-''Do<sup>6</sup>'')<ref name=A>ricostruzione del 1975</ref> * '''Pedaliera:''' parallela piana di 24 pedali e 12 note (''Do<sup>1</sup>''-''Si<sup>2</sup>'') con prima ottava cromatica<ref name=A/> * '''Collocazione:''' in corpo unico, al centro della cantoria in controfacciata * '''Accessori:''' : 2 pedali a destra della pedaliera per: ''Tirapieno'', ''Combinazione preparabile''; 4 pedaletti sopra la pedaliera per: ''Unione tasto/pedale'', ''Ripienino'', ''Ance'', ''Terzamano'' {| border="0" cellspacing="0" cellpadding="20" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" | colspan=2 | '''Colonna di destra interna - ''Concerto''''' ---- |- |Terzamano |- |Cornetto a 3 canne soprani |- |Fagotto || 8' bassi |- |Tromba || 8' soprani |- |Clarone || 4' bassi<ref name=A/> |- |Violoncello || 16' soprani |- |Viola || 4' bassi |- |Flutta || 8' soprani |- |Flauto in VIII bassi |- |Flauto in VIII soprani |- |Ottavino soprani |- |Voce umana || 8' soprani |- |} | style="vertical-align:top" | {| border="0" | colspan=2 | '''Colonna di destra esterna - ''Ripieno''''' ---- |- |Principale || 16' bassi |- |Principale || 16' soprani |- |Principale || 8' bassi |- |Principale || 8' soprani |- |Ottava || bassi |- |Ottava || soprani |- |Decimaquinta || |- |Decimanona || |- |Vigesimaseconda || |- |Vigesimasesta e Vigesimanona |- |Contrabasso e Ottave || 16'<sup>(al Pedale)</sup> |- |Trombone|| 8' <sup>(al Pedale)</sup> |- |} |} == Note == <references/> == Altri progetti == {{interprogetto|w=Chiesa di San Giacomo Apostolo (Arquata Scrivia)|w_preposizione=sulla|w_etichetta=Chiesa di San Giacomo Apostolo ad Arquata Scrivia}} {{Avanzamento|100%|1 settembre 2026}} [[Categoria:Disposizioni foniche di organi a canne|Arquata Scrivia - Chiesa di San Giacomo Maggiore]] r8q4bes4wxktab7tvi34egddsm5mof2 Disposizioni foniche di organi a canne/Italia/Lazio/Città metropolitana di Roma/Mandela/Mandela - Chiesa di San Nicola di Bari 0 61114 502076 501677 2026-10-04T17:59:05Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502076 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} {{Doppia immagine|center|Mandela-S.Nicola di Bari-organo Michelotto.jpg|350|Mandela-S.Nicola di Bari-consolle organo Michelotto.jpg|345}} * '''Costruttore:''' F. Girotto di Albignasego (PD) * '''Anno:''' anni '70 del XX sec. * '''Restauri/modifiche:''' ? (ricollocato, 2015) * '''Registri:''' 22 * '''Canne:''' ? * '''Trasmissione:''' elettrica * '''Consolle:''' mobile indipendente, nel transetto sinistro * '''Tastiere:''' 2 di 61 note (''Do<sup>1</sup>''-''Do<sup>6</sup>'') * '''Pedaliera:''' concavo radiale di 32 note (''Do<sup>1</sup>''-''Sol<sup>3</sup>'') * '''Collocazione:''' in corpo unico, su cantoria, in controfacciata {| border="0" cellspacing="0" cellpadding="20" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" | colspan=2 | '''I - ''Grand'Organo''''' ---- |- |Principale || 8' |- |Ottava || 4' |- |XV || |- |XIX || |- |XXII || |- |Flauto dolce || 8' |- |<span style="color:#8b0000;">Tromba</span> || <span style="color:#8b0000;">8'</span> |} | style="vertical-align:top" | {| border="0" | colspan=2 | '''II - ''Espressivo''''' ---- |- |Principale dolce || 8' |- |Bordone || 8' |- |Flauto || 4' |- |Flauto in XII |- |Flautino || 2' |- |Terza || 1.3/5' |- |Ripieno 3 file |- |<span style="color:#8b0000;">Tromba</span> || <span style="color:#8b0000;">8'</span> |- |Voce flebile || 8' |- |Tremolo |- |} | style="vertical-align:top" | {| border="0" | colspan=2 | '''Pedale''' ---- |- |Subbasso || 16' |- |Basso || 8' |- |Bordone || 8' |- |Flauto || 4' |- |<span style="color:#8b0000;">Tromba</span> || <span style="color:#8b0000;">8'</span> |- |<span style="color:#8b0000;">Chiarina</span> || <span style="color:#8b0000;">4'</span> |- |} |} {{Avanzamento|100%|16 settembre 2026}} [[Categoria:Disposizioni foniche di organi a canne|Mandela - Chiesa di San Nicola di Bari]] otcc4t2tea7iq087oqwun95bppytt69 Disposizioni foniche di organi a canne/Italia/Piemonte/Provincia di Alessandria/Cassano Spinola/Cassano Spinola - Chiesa di San Pietro Apostolo 0 61120 502085 501732 2026-10-04T18:00:53Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502085 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} {{Doppia immagine|center|Cassano Spinola-S.Pietro Ap.-organo Balbiani.jpg|300|Cassano Spinola-S.Pietro Ap.-consolle organo Balbiani.jpg|300}} * '''Costruttore:''' Balbiani * '''Anno:''' 1926 * '''Restauri/modifiche:''' sì * '''Registri:''' 11 * '''Canne:''' ? * '''Trasmissione:''' pneumatica * '''Consolle:''' addossata alla parete anteriore della cassa * '''Tastiere:''' 2 di 58 note (''Do<sup>1</sup>''-''La<sup>5</sup>'') * '''Pedaliera:''' dritta di 30 note (''Do<sup>1</sup>''-''Fa<sup>3</sup>'') * '''Collocazione:''' in corpo unico, al centro della cantoria in controfacciata {| border="0" cellspacing="0" cellpadding="20" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" | colspan=2 | '''I - ''Grand'Organo''''' ---- |- |Pieno |- |Ottava || 4' |- |Principale || 8' |- |Dolce || 8' |- |Tromba || 8' |- |} | style="vertical-align:top" | {| border="0" | colspan=2 | '''II - ''Espressivo''''' ---- |- |Bordone || 8' |- |Gamba || 8' |- |Flauto || 4' |- |Concerto viole || 8' |- |Tremolo |- |} | style="vertical-align:top" | {| border="0" | colspan=2 | '''Pedale''' ---- |- |Subbasso || 16' |- |Basso || 8' |- |} |} == Altri progetti == {{interprogetto|w=Chiesa di San Pietro Apostolo (Cassano Spinola)|w_preposizione=sulla|w_etichetta=chiesa di San Pietro Apostolo a Cassano Spinola}} {{Avanzamento|100%|19 settembre 2026}} [[Categoria:Disposizioni foniche di organi a canne|Cassano Spinola - Chiesa di San Pietro Apostolo]] 9yqi21euip7he0ro52uu3d5zhu3yybs Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Monza e della Brianza/Monza/Monza - Chiesa di San Biagio 0 61122 502083 501748 2026-10-04T18:00:31Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502083 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} * '''Costruttore:''' Fratelli Aletti * '''Anno:''' 1880 * '''Restauri/modifiche:''' Alessandro Corno (1982, restauro e ampliamento), Alessandro Corno (1991, manutenzione straordinaria e ampliamento) * '''Registri:''' 70 * '''Canne:''' 2246 * '''Trasmissione:''' elettro-pneumatica * '''Consolle:''' a finestra, al centro della parete anteriore della cassa * '''Tastiere:''' 3 di 61 note (''Do<sup>1</sup>''-''Do<sup>6</sup>'') * '''Pedaliera:''' concavo-radiale di 32 note (''Do<sup>1</sup>''-''Sol<sup>3</sup>'') * '''Collocazione:''' in corpo unico, nel transetto di sinistra {| border="0" cellspacing="0" cellpadding="20" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" | colspan=2 | '''I - ''Espressivo''''' ---- |- |Quintadena || 8' |- |Bordone di legno || 8' |- |Flauto in VIII || 4' |- |Flauto in XII || 2.2/3' |- |Flauto silvestre || 2' |- |Flauto in XVII || 1.3/5' |- |Flauto in XXII || 1' |- |Tre di Ripieno || 1/4' |- |Cromorno || 8' |- |Clarino || 4' |- |} | style="vertical-align:top" | {| border="0" | colspan=2 | '''II - ''Grand'Organo''''' ---- |- |Principale || 16' |- |Principale forte || 8' |- |Principale dolce || 8' |- |Ottava || 4' |- |XII || 2.2/3' |- |XV || 2' |- |XIX || 1.1/3' |- |XXII || 1' |- |Quattro di Ripieno || 2/3' |- |Quintadena || 8' |- |Flauto armonico || 8' |- |Flauto a camino || 4' |- |Ottavino || 2' |- |Sesquialtera (XII - XVII) || 2.2/3' |- |Salizionale || 8' |- |Fiffaro || 8' |- |Tromba || 8' |- |Tuba magna || 16' |- |Tromba orizzontale || 8' |- |Tromba in quinta || 5.1/3' |- |Clarino || 4' |- |Cromorno || 8' |- |} | style="vertical-align:top" | {| border="0" | colspan=2 | '''III - ''Fanfara''' ---- |- |Principale || 8' |- |Flauto || 8' |- |Ottava || 4' |- |Flauto in VIII || 4' |- |XV || 2' |- |XIX || 1.1/3' |- |Tre di Ripieno || 1' |- |Quintadena || 8' |- |Oboe || 8' |- |Cromorno || 8' |- |Tuba orizzontale || 16' |- |Tuba orizzontale || 8' |- |Trombe in quinta || 5.1/3' |- |Clarino || 4' |- |Tremolo |- |} | style="vertical-align:top" | {| border="0" | colspan=2 | '''Pedale''' ---- |- |Basso acustico || 32' |- |Contrabbasso || 16' |- |Gran quinta || 10.2/3' |- |Basso || 8' |- |Quinta bassa || 5.1/3' |- |Bassetto || 4' |- |Subbasso || 16' |- |Bordone || 8' |- |Principale || 16' |- |Ottava || 8' |- |Prestante || 4' |- |Quintadena || 8' |- |Quintadena || 4' |- |Flauto aperto || 2' |- |Controfagotto || 16' |- |Gran quinta di Tromba || 10.2/3' |- |Fagotto || 8' |- |Clarone || 4' |- |Cromorno || 8' |- |Trombina || 4' |- |Tromba orizzontale || 8' |- |Trombe in quinta || 5.1/3' |- |Clarino || 4' |- |Campane nei pedali |- |} |} [[Categoria:Disposizioni foniche di organi a canne|Monza - Chiesa di San Biagio]] 6khk823pmqbapi6eu6t7d3mvmia76om Disposizioni foniche di organi a canne/Italia/Abruzzo/Provincia di Teramo/Sant'Egidio alla Vibrata 0 61124 502074 501756 2026-10-04T17:58:03Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502074 wikitext text/x-wiki {{disposizioni foniche di organi a canne}} Disposizioni foniche del comune di [[w:Sant'Egidio alla Vibrata|Sant'Egidio alla Vibrata]] raggruppate per edificio: ==Capoluogo== * [[Disposizioni foniche di organi a canne/Italia/Abruzzo/Provincia di Teramo/Sant'Egidio alla Vibrata/Sant'Egidio alla Vibrata - Chiesa di Sant'Egidio Abate|Chiesa di Sant'Egidio Abate]] {{Avanzamento|100%|20 settembre 2026}} [[Categoria:Disposizioni foniche di organi a canne|Sant&#39;Egidio alla Vibrata]] 4135x7krnefoopam3x4tn84ipx5vtg1 Disposizioni foniche di organi a canne/Italia/Abruzzo/Provincia di Teramo/Sant'Egidio alla Vibrata/Sant'Egidio alla Vibrata - Chiesa di Sant'Egidio Abate 0 61125 502075 501758 2026-10-04T17:58:13Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502075 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} [[File:S.Egidio alla Vibrata-S.Egidio Ab.-organo Girotto.jpg|300px|center]] IN COSTRUZIONE * '''Costruttore:''' A. Girotto * '''Anno:''' 1984 * '''Restauri/modifiche:''' ? * '''Registri:''' 19 * '''Canne:''' ? * '''Trasmissione:''' elettrica * '''Consolle:''' mobile indipendente * '''Tastiere:''' 2 di note (''Do<sup>1</sup>''-''La<sup>5</sup>'') * '''Pedaliera:''' concavo radiale di note (''Do<sup>1</sup>''-''Fa<sup>3</sup>'') * '''Collocazione:''' su due balconate, alla destra e sinistra dell’interno del presbiterio {| border="0" cellspacing="0" cellpadding="20" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" | colspan=2 | '''I - ''Grand'Organo''''' ---- |- |Tromba || 8' |- |Principale || 8' |- |Flauto || 8' |- |Ottava || 4' |- |Decimaquinta || 2' |- |Ripieno || 4 file |- |} | style="vertical-align:top" | {| border="0" | colspan=2 | '''II - ''Espressivo''''' ---- |- |Bordone || 8' |- |Viola || 8’ |- |Flauto || 4' |- |Nazardo || 2.2/3' |- |Flauto || 2' |- |Terza || 1.3/5' |- |Principalino || 4’ |- |Pienino 3 file || |- |Voce celeste || 8’ |- |Tremolo |- |} | style="vertical-align:top" | {| border="0" | colspan=2 | '''Pedale''' ---- |- |Subbasso || 16' |- |Bordone || 8' |- |Basso || 8’ |- |Tromba || 8' |- |} |} == Note == <references/> == Altri progetti == {{Avanzamento|100%|20 settembre 2026}} [[Categoria:Disposizioni foniche di organi a canne|Sant&#39;Egidio alla Vibrata - Chiesa di Sant&#39;Egidio Abate]] 39aiqt8nyupka5xpbkmyul4s3e6t2z5 Disposizioni foniche di organi a canne/Italia/Liguria/Città metropolitana di Genova/Isola del Cantone 0 61132 502077 501797 2026-10-04T17:59:15Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502077 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} Disposizioni foniche del comune di [[w:Isola del Cantone|Isola del Cantone]] raggruppate per edificio. == Capoluogo == == Frazioni == * [[Disposizioni foniche di organi a canne/Italia/Liguria/Città metropolitana di Genova/Isola del Cantone/Prarolo - Chiesa di San Michele Arcangelo|Prarolo - Chiesa di San Michele Arcangelo]] {{Avanzamento|50%|21 settembre 2026}} [[Categoria:Disposizioni foniche di organi a canne|Isola del Cantone]] 4sbgofkk9ad761zxrnmyekx8bjel8bk Disposizioni foniche di organi a canne/Italia/Liguria/Città metropolitana di Genova/Isola del Cantone/Isola del Cantone - Chiesa di San Michele Arcangelo 0 61133 502078 501790 2026-10-04T17:59:25Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502078 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} {{Doppia immagine|center|Isola del Cantone-S.Michele Arc.-organo a canne.jpg|350|Isola del Cantone-S.Michele Arc.-consolle organo a canne.jpg|348}} * '''Costruttore:''' ? * '''Anno:''' XVIII sec. * '''Restauri/modifiche:''' ? * '''Registri:''' 11 * '''Canne:''' ? * '''Trasmissione:''' meccanica * '''Consolle:''' a finestra, nella parete anteriore della cassa * '''Tastiere:''' 1 di 45 note con prima ottava scavezza (''Do<sup>1</sup>''-''Do<sup>5</sup>'') * '''Pedaliera:''' scavezza a leggio di 13 note (''Do<sup>1</sup>''-''Mi<sup>2</sup>''), costantemente unita al manuale * '''Collocazione:''' in corpo unico, in cantoria, in controfacciata * '''Accessori:''' ''Tirapieno'' * '''Note:''' lo strumento è in mediocre stato di conservazione. Non possiede l’elettroventilatore; i mantici sono azionabili solamente da tre corde poste nel lato destro della cassa {| border="0" cellspacing="0" cellpadding="20" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" | colspan=2 | '''Colonna di destra''' ---- |- |Principale Bassi || 8' |- |Principale Soprani || 8' |- |Ottava Bassi Soprani<ref name=M>sic</ref> |- |Decima Quinta |- |Decima Nona |- |Vigesima Seconda |- |Vigesima Sesta |- |Vigesima Nona |- |Voce Umana |- |Viola Flauto in 8va<ref name=M/> |- |Cornetto<ref name=N>scritta quasi illeggibile</ref> |- |Tirapieno<ref name=N/> |- |} |} == Note == <references/> == Altri progetti == {{interprogetto|w=Chiesa di San Michele Arcangelo (Isola del Cantone)|w_preposizione=sulla|w_etichetta=chiesa di San Michele Arcangelo a Isola del Cantone}} {{Avanzamento|100%|21 settembre 2026}} [[Categoria:Disposizioni foniche di organi a canne|Isola del Cantone - Chiesa di San Michele Arcangelo]] jbpbg7zyw6ngvt84h74k29hks87fw3c Disposizioni foniche di organi a canne/Italia/Liguria/Città metropolitana di Genova/Isola del Cantone/Prarolo - Chiesa di San Michele Arcangelo 0 61134 502079 501798 2026-10-04T17:59:50Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502079 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} {{Doppia immagine|center|Isola del Cantone-S.Michele Arc.-organo a canne.jpg|350|Isola del Cantone-S.Michele Arc.-consolle organo a canne.jpg|348}} * '''Costruttore:''' ? * '''Anno:''' XVIII sec. * '''Restauri/modifiche:''' ? * '''Registri:''' 11 * '''Canne:''' ? * '''Trasmissione:''' meccanica * '''Consolle:''' a finestra, nella parete anteriore della cassa * '''Tastiere:''' 1 di 45 note con prima ottava scavezza (''Do<sup>1</sup>''-''Do<sup>5</sup>'') * '''Pedaliera:''' scavezza a leggio di 13 note (''Do<sup>1</sup>''-''Mi<sup>2</sup>''), costantemente unita al manuale * '''Collocazione:''' in corpo unico, in cantoria, in controfacciata * '''Accessori:''' ''Tirapieno'' * '''Note:''' lo strumento è in mediocre stato di conservazione. Non possiede l’elettroventilatore; i mantici sono azionabili solamente da tre corde poste nel lato destro della cassa {| border="0" cellspacing="0" cellpadding="20" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" | colspan=2 | '''Colonna di destra''' ---- |- |Principale Bassi || 8' |- |Principale Soprani || 8' |- |Ottava Bassi Soprani<ref name=M>sic</ref> |- |Decima Quinta |- |Decima Nona |- |Vigesima Seconda |- |Vigesima Sesta |- |Vigesima Nona |- |Voce Umana |- |Viola Flauto in 8va<ref name=M/> |- |Cornetto<ref name=N>scritta quasi illeggibile</ref> |- |Tirapieno<ref name=N/> |- |} |} == Note == <references/> == Altri progetti == {{interprogetto|w=Chiesa di San Michele Arcangelo (Isola del Cantone)|w_preposizione=sulla|w_etichetta=chiesa di San Michele Arcangelo a Isola del Cantone}} {{Avanzamento|100%|21 settembre 2026}} [[Categoria:Disposizioni foniche di organi a canne|Prarolo - Chiesa di San Michele Arcangelo]] 7pocrppp1kd06nhehkxgavvm8l67v97 Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Cremona/Casalmaggiore/Casalmaggiore - Chiesa di San Sebastiano 0 61141 502080 501975 2026-10-04T18:00:01Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502080 wikitext text/x-wiki * '''Costruttore''': anonimo * '''Anno''': fine del XVIII secolo * '''Restauri'''/modifiche: Giovanni Battista Tonelli di Remedello (1880 ca.). Strumento non funzionante * '''Registri''': manette con incastro sul lato destro della tastiera * '''Canne''':? * '''Trasmissione''': meccanica * '''Consolle''': a finestra, al centro della della cassa * '''Tastiere''': cromatica di 58 note * '''Pedaliera''': a leggio di 13 note (do-si e un pedale per il rollante) * '''Collocazione''': nella cantoria sopra al portale di ingresso '''Manuale''' Principale bassi di 8 Principale soprano di 8 Ottava bassi Ottava soprani Trigesima sesta doppia (sic) Fluta Ottavino soprani Violoncello soprani Fagotto Tromboni (ai pedali) Bassi armonici (ai pedali) [[Categoria:Disposizioni foniche di organi a canne|Casalmaggiore - Chiesa di San Sebastiano]] 0mipfy0wu13pci23nrz5kto2m27ovjy Disposizioni foniche di organi a canne/Italia/Veneto/Provincia di Verona/Verona/Verona - Chiesa di San Pietro in Monastero 0 61153 502088 501915 2026-10-04T18:02:15Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502088 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} * '''Costruttore:''' Gaetano Amigazzi<ref>il frontalino della tastiera recita: ''CAIETANUS AMIGAZZI VERONENSIS MDCCXLVII''</ref> * '''Anno:''' 1747 * '''Restauri/modifiche:''' Romain Legros (2007) * '''Registri:''' 16 * '''Canne:''' * '''Trasmissione:''' meccanica sospesa * '''Consolle:''' a finestra, al centro della cassa * '''Tastiere:''' di 50 tasti con prima ottava scavezza (''Do<small>1</small>-Fa<small>5</small>''), spezzatura bassi/soprani ''Do#<small>3</small>/Re<small>3</small>'' * '''Pedaliera:''' di 18 pedali con prima ottava scavezza (''Do<small>1</small>-Sol#<small>2</small> + Rollante'') costantemente unita alla tastiera * '''Collocazione:''' in cantoria, in controfacciata * '''Accessori:''' {| border="0" cellspacing="0" cellpadding="20" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" |Principale B. |- |Principale S. |- |Ottava |- |XV<sup>a</sup>. |- |XIX<sup>a</sup>. |- |XXII<sup>a</sup>. |- |XXVI<sup>a</sup>. |- |XXIX<sup>a</sup>. |- |Fluta Sop. |- |Flauto XII<sup>a</sup>. |- |Cornetto II<sup>o</sup><ref name=":1">soprani</ref> |- |Cornetto I<sup>o</sup><ref name=":1" /> |- |Voce Umana<ref name=":1" /> |- |Fagotto B.<ref name=":2">in facciata</ref> |- |Oboe Sop.<ref name=":2" /> |- |Contrabassi<ref>al pedale, 12 note reali</ref> |- |} |} == Note == <references /> [[Categoria:Disposizioni foniche di organi a canne|Verona - Chiesa di San Pietro in Monastero]] hroi0dgoc2s2h5qmsirxs97lgkx88nf Disposizioni foniche di organi a canne/Italia/Veneto/Provincia di Vicenza/Bolzano Vicentino/Bolzano Vicentino - Chiesa di Santa Lucia 0 61157 502092 501914 2026-10-04T18:18:13Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502092 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} * '''Costruttore:''' Angelo Agostini * '''Anno:''' 1867 * '''Restauri/modifiche:''' Paccagnella * '''Registri:''' 20 * '''Canne:''' * '''Trasmissione:''' meccanica * '''Consolle:''' a finestra, al centro della parete anteriore della cassa * '''Tastiere:''' di 52 tasti con prima ottava scavezza (''Do<small>1</small>-Sol<small>5</small>''), spezzatura bassi/soprani ''Do#<small>3</small>/Re<small>3</small>'' * '''Pedaliera:''' di 18 pedali con prima ottava scavezza (''Do<small>1</small>-Sol#<small>2</small> + Rollante'') costantemente unita alla tastiera * '''Collocazione:''' in cantoria, in controfacciata * '''Accessori:''' ''Ripieno'' e ''Combinazione libera'' a pedalone, ''Terza Mano'' e ''Tremolo''<ref>scollegato</ref> a pedaletto {| border="0" cellspacing="0" cellpadding="20" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" |Voce Umana<ref name=":1">soprani</ref> |- |Fluta<ref name=":1" /> |- |Flauto XII S. |- |Ottavino S. |- |Violetta 4' B. |- |Fagotto B. |- |Trombe S. |- |Corno Inglese S.<ref>16'</ref> |- |Tromboni ai Pedali |- |} | style="vertical-align:top" | {| border="0" |Principale 8 B. |- |Principale 8 B. |- |Ottava 4 B. |- |Ottava 4 S. |- |Decimaquinta 2' |- |Decimanona 1,1/3' |- |Vigesimaseconda 1' |- |Vigesimasesta |- |Vigesimanona |- |Contrabbassi<ref>al pedale, 12 note reali, unito al successivo</ref> |- |Ottava di Contr.<ref>al pedale, 12 note reali, unito al precedente</ref> |- |} |} == Note == <references /> [[Categoria:Disposizioni foniche di organi a canne|Bolzano Vicentino - Chiesa di Santa Lucia]] 7euvbhw83fquaea3fqt7nxhg68u5x5g Disposizioni foniche di organi a canne/Italia/Veneto/Provincia di Vicenza/Schio/Schio - Sant'Ulderico di Tretto 0 61158 502093 501916 2026-10-04T18:18:22Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502093 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} * '''Costruttore:''' Iseppo Bonatti<ref>costruito per il duomo di Schio</ref> * '''Anno:''' 1738 * '''Restauri/modifiche:''' Gian Battista Zordan (1874, trasferimento e ampliamento), Romain Legros (2001, restauro) * '''Registri:''' 44 * '''Canne:''' * '''Trasmissione:''' meccanica * '''Consolle:''' a finestra, al centro della parete anteriore della cassa * '''Tastiere:''' 2 di 52 tasti con prima ottava scavezza (''Do<small>1</small>-Sol<small>5</small>''), spezzatura bassi/soprani ''Do#<small>3</small>/Re<small>3</small>'' * '''Pedaliera:''' di 18 pedali con prima ottava scavezza (''Do<small>1</small>-Sol#<small>2</small> + Rollante'') * '''Collocazione:''' in cantoria, in controfacciata * '''Accessori:''' ''Tiratutti'' e ''Combinazione libera'' a pedalone, ''Terza Mano'' a pedaletto {| border="0" cellspacing="0" cellpadding="20" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" |'''Positivo''' ---- |- |Principale Basso |- |Principale Soprano |- |Ottava |- |Decima Quinta |- |Decima Nona |- |Vigesima Seconda |- |Flutta Reale<ref name=":1">soprani</ref> |- |Ottavino Soprano<ref name=":2">4'</ref> |- |Flauto XII. Soprano |- |Sedesino Soprano<ref name=":3">2'</ref> |- |Fagotto Basso |- |Clarino Soprano |- |} | style="vertical-align:top" | {| border="0" |'''Grand'Organo e Pedale - ''Concerto''''' ---- |- |Campanini<ref name=":1" /> |- |Trombone Basso |- |Trombe Dolci<ref name=":1" /> |- |Corno Inglese<ref>16', soprani</ref> |- |Fluta Reale<ref name=":1" /> |- |Flaugioletto Soprano<ref name=":3" /> |- |Viola Bassa<ref name=":2" /> |- |Flauto ottava Basso |- |Flauto ottava Soprano |- |Flauto XII |- |Cornetto Primo<ref>2 2/3', soprani</ref> |- |Cornetto Secondo<ref>1 3/5', soprani</ref> |- |Voce Umana<ref name=":1" /> |- |Timballi in 12 Tuoni<ref name=":4">al pedale, 12 note reali</ref> |- |Serpentone<ref>al pedale, 12 note reali, 10'</ref> |- |Tremulo |- |} | style="vertical-align:top" | {| border="0" |'''Grand'Organo e Pedale - ''Ripieno''''' ---- |- |Principale Basso di piedi 8 |- |Principale Soprano di piedi 8 |- |Principale Secondo di piedi 8<ref>intero</ref> |- |Ottava |- |Duodecima |- |Decima Quinta |- |Decima Nona |- |Vigesima Seconda |- |Vigesima Sesta |- |Vigesima Nona |- |Trigesima Terza |- |Trigesima Sesta |- |Controbassi<ref name=":4" /> |- |Ottava Controbassi<ref name=":4" /> |- |Duodecima<ref name=":4" /> |- |Decima Quinta Controbassi<ref name=":4" /> |- |} |} == Note == <references /> [[Categoria:Disposizioni foniche di organi a canne|Schio - Sant&#39;Ulderico di Tretto]] swlpwqcvalggsk7fsmvvw4lpt43h507 Disposizioni foniche di organi a canne/Italia/Veneto/Provincia di Vicenza/Thiene/Rozzampia - Chiesa di Santa Maria della Neve 0 61159 502094 501920 2026-10-04T18:18:33Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502094 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} * '''Costruttore:''' Fratelli Serassi di Bergamo * '''Anno:''' 1830<ref>costruito per la chiesa dei Carmini in Vicenza</ref> * '''Restauri/modifiche:''' Fratelli Serassi (1870, rifacimento), trasferimento a Rozzampia nel 1935, Vincenzo Mascioni (2008, restauro) * '''Registri:''' 32 * '''Canne:''' * '''Trasmissione:''' meccanica * '''Consolle:''' a finestra, al centro della parete anteriore della cassa * '''Tastiere:''' di 58 tasti (''Do<small>1</small>-La<small>5</small>'') * '''Pedaliera:''' di 18 pedali (''Do<small>1</small>-Mi<small>2</small> + Terza Mano'') * '''Collocazione:''' in cantoria, in controfacciata * '''Accessori:''' ''Tiratutti'' e ''Combinazione Libera'' a pedalone, ''distacco Tasto-Pedale'' a pedaletto {| border="0" cellspacing="0" cellpadding="20" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" |Cornetto Primo<ref>4'+2 2/3', soprani</ref> |- |Cornetto Secondo<ref>2'+1 3/5', soprani</ref> |- |Corni di Tuba Dolce<ref>16', soprani</ref> |- |Fagotto Bassi |- |Tromba Soprani |- |Violoncello Bassi<ref name=":1">4'</ref> |- |Corno Inglese Soprani<ref>16'</ref> |- |Violoncello Soprani<ref>8'</ref> |- |Clarone Bassi<ref name=":1" /> |- |Viola Bassi<ref name=":1" /> |- |Flutta Soprani |- |Violetta Bassi<ref>2'</ref> |- |Flauto in VIII Bassi |- |Flauto in VIII Soprani |- |Ottavino Soprani |- |Voce Umana<ref>soprani</ref> |- |} | style="vertical-align:top" | {| border="0" |Principale 16 Bassi<ref>intero</ref> |- |Principale 16 Soprani |- |Principale Bassi |- |Principale Soprani |- |Ottava Bassi |- |Ottava Soprani |- |Duodecima |- |Quintadecima |- |Decimanona |- |Vigesimaseconda |- |Vigesima Sesta e Nona |- |Due di Ripieno |- |Due di Ripieno |- |Contrabassi e Ottave<ref>al pedale, 12 note reali</ref> |- |Tromboni ai Pedali<ref>al pedale, 12 note reali, 12'</ref> |- |Timballi<ref>al pedale, scollegato</ref> |- |} |} == Note == <references /> [[Categoria:Disposizioni foniche di organi a canne|Rozzampia - Chiesa di Santa Maria della Neve]] 4bu7yq42dt0ggdlwehfs15k2d08al7f Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Cremona/Casalmaggiore/Vicobellignano - Chiesa di Santa Maria 0 61165 502081 501966 2026-10-04T18:00:11Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502081 wikitext text/x-wiki * '''Costruttore''': Rotelli e Varesi (1945) con materiale di Giuseppe Rotelli (338 canne), Montesanti (63 canne), Antegnati (157 canne), Autori anonimi tra XVII e XVIII secolo (66 canne), Anonimo del XIX secolo (235 canne), Anonimo del XX sec. (3 canne), Inzoli/Bonizzi (2 canne) * '''Anno''': 1945 * '''Restauri/modifiche''': Inzoli/Bonizzi (restauro, 2009) * '''Registri''': 12 con pomelli estraibili sopra la tastiera * '''Canne''': 864 * '''Trasmissione''': meccanica per la tastiera, pneumatica per i registri e il pedale * '''Consolle''': a finestra * '''Tastiere''': 1 di 56 note * '''Pedaliera''': piana di 27 note * '''Collocazione''': in controfacciata Contrabassi 16 al Ped. Basso 8 al Ped. Principale 16p Principale 8p Flauto in XII Bordone 8p Viola 8p Unda Maris 8p Tromba 8p Flauto 4p Ottava 4p Ripieno 6 file [[Categoria:Disposizioni foniche di organi a canne|Vicobellignano - Chiesa di Santa Maria]] m5gborkbbzu9fsy3uw1ko3intt5690e Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Cremona/Casalmaggiore/Vicobellignano - Chiesa di Santa Maria Assunta 0 61169 502082 501973 2026-10-04T18:00:21Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502082 wikitext text/x-wiki * '''Costruttore:''' Rotelli-Varesi con materiale anonimo di fine XVI (18 canne) Antegnati (157 canne), anonimo del XVII sec. (8 canne), anonimo del XVIII sec. (36 canne), Montesanti (63 canne), Serassi (4 canne), anonimo di metà XIX sec. (235 canne), anonimo del XX sec. (3 canne), Giuseppe Rotelli (338 canne), Inzoli Bonizzi (2 canne) * '''Anno:''' 1945 * '''Restauri/modifiche:''' Inzoli Bonizzi (2009) * '''Registri''': 12 * '''Canne''': 864 * '''Trasmissione''': meccanica per la tastiera, pneumatica per il pedale e i registri * '''Consolle''': a finestra * '''Tastiere''': 1 di 56 note (Do1-fa5) * '''Pedaliera''': piana di 27 note * '''Collocazione''': sulla cantoria in controfacciata * '''Accessori''': Tastiera al Pedale, Ottava Acuta, Mezzo Forte, Ripieno, Tutti, Tremolo Contrabassi 16 al pedale Basso 8 al pedale Principale 16 Principale 8 Flauto in XII 2,2/3 Bordone 8 Viola 8 Unda Maris 8 Tromba 8 Flauto 4 Ottava 4 Ripieno 6 file [[Categoria:Disposizioni foniche di organi a canne|Vicobellignano - Chiesa di Santa Maria Assunta]] 2m1o955a5clarvl7dyw46ivk9cq4rz2 PenuX in R 0 61174 502063 502025 2026-10-04T14:49:03Z Hippias 18281 fix vari 502063 wikitext text/x-wiki = PenuX in R = Benvenuti al corso completo di programmazione R per la modellazione predittiva clinica. == Guida introduttiva == * [[PenuX in R/Guida di base al Machine Learning in R|Guida di base al Machine Learning in R]] == Moduli del Corso == * [[PenuX in R/Unità 1 - Fondamenti del Linguaggio R|Unità 1: Fondamenti di R]] * [[PenuX in R/Unità 2 - Preparazione e Caricamento dei Dati|Unità 2: Preparazione Dati]] * [[PenuX in R/Unità 3 - Analisi Esplorativa dei Dati|Unità 3: Analisi Esplorativa]] * [[PenuX in R/Unità 4 - Costruzione dei Modelli Predittivi|Unità 4: Modelli Predittivi]] * [[PenuX in R/Unità 5 - Valutazione e Validazione dei Modelli|Unità 5: Valutazione]] * [[PenuX in R/Unità 6 - Deployment e Implementazione Clinica|Unità 6: Deployment]] * [[PenuX in R/Unità 7 - Esercitazioni di Machine Learning in R|Unità 7: Esercitazioni di Machine Learning]] == Informazioni == La piattaforma PenuX fornisce strumenti open-source per la predizione clinica precoce di pancreatite acuta grave e sepsi. * [https://github.com/netanelcyber/penux Repository GitHub] * [https://penux.uk Sito del Progetto] == Prerequisiti == * Nessuno per l'Unità 1 * Fondamenti di R (Unità 1) per le Unità 2 e successive * Conoscenza di base di statistica per le Unità 3 e successive == Supporto == Per domande, contatta il progetto PenuX su GitHub. {{Avanzamento|75%|4 ottobre 2026}} {{alfabetico|P}} [[Categoria:PenuX in R| ]] [[Categoria:Programmazione]] [[Categoria:Dewey 005]] r3c8xmd2d49nkpkxln2n41r41al7z4m PenuX in R/Unità 1 - Installazione e configurazione dell'ambiente 0 61175 502072 502007 2026-10-04T17:56:03Z Hippias 18281 orfana 502072 wikitext text/x-wiki {{orfana}} = PenuX in R: Unità 1 - Installazione e configurazione dell'ambiente = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Installare correttamente R e RStudio * Installare e caricare le librerie necessarie (tidyverse, caret, survival, ecc.) * Configurare il tuo ambiente di lavoro * Eseguire controlli diagnostici * Creare uno script di avvio personalizzato == 1.1 Installazione di R e RStudio == === Installazione di R === <syntaxhighlight lang="r"> # Verificare la versione attuale di R R.version # Esempio di output atteso: # Platform: x86_64-pc-linux-gnu (oppure Windows/Mac) # R version 4.0.0 o superiore # Status: Patched o Release </syntaxhighlight> === Installazione di RStudio === Per scaricare RStudio, visita: https://rstudio.com/products/rstudio/download/ Dopo l'installazione, avvia RStudio e verifica che tutto funzioni correttamente. == 1.2 Installazione delle librerie necessarie == === Librerie essenziali === <syntaxhighlight lang="r"> # Installare le librerie principali install.packages(c("tidyverse", "caret", "survival", "data.table", "ggplot2")) # Caricare le librerie library(tidyverse) library(caret) library(survival) library(data.table) library(ggplot2) # Verificare le versioni packageVersion("tidyverse") packageVersion("caret") packageVersion("survival") </syntaxhighlight> === Librerie aggiuntive === <syntaxhighlight lang="r"> # Installare librerie aggiuntive install.packages(c("xgboost", "ranger", "rpart", "e1071", "knitr", "kableExtra", "plotly")) # Queste librerie saranno utilizzate nelle unità successive # per la modellazione avanzata e la visualizzazione </syntaxhighlight> == 1.3 Configurazione dell'ambiente di lavoro == === Gestione delle directory === <syntaxhighlight lang="r"> # Verificare la directory di lavoro attuale getwd() # Impostare una nuova directory di lavoro setwd("~/PenuX_Analysis") # Creare sottodirectory se necessario dir.create("data", showWarnings = FALSE) dir.create("results", showWarnings = FALSE) dir.create("plots", showWarnings = FALSE) # Verificare le directory create list.files(".") </syntaxhighlight> === Configurazione delle opzioni di R === <syntaxhighlight lang="r"> # Impostare le opzioni predefinite options(digits = 4) # Limitare i decimali a 4 cifre options(scipen = 10) # Evitare la notazione scientifica options(width = 100) # Larghezza della console options(max.print = 1000) # Numero massimo di righe da visualizzare # Visualizzare le opzioni attuali getOption("digits") getOption("scipen") </syntaxhighlight> == 1.4 Controlli diagnostici == === Verificare le installazioni === <syntaxhighlight lang="r"> # Elenco di tutte le librerie installate installed_packages <- installed.packages() head(installed_packages) # Verificare se una libreria specifica è installata "caret" %in% rownames(installed.packages()) # Numero totale di librerie installate nrow(installed.packages()) # Librerie attualmente caricate search() </syntaxhighlight> === Test di funzionalità di base === <syntaxhighlight lang="r"> # Test di creazione dei dati test_data <- data.frame( age = c(25, 35, 45, 55, 65), valore = c(10.5, 20.3, 15.8, 22.1, 18.9) ) # Visualizzare i dati print(test_data) # Statistiche di base summary(test_data) # Verificare che tidyverse funzioni test_data %>% filter(age > 30) %>% summarise(media = mean(valore)) </syntaxhighlight> == 1.5 Creazione dello script di avvio == === File .Rprofile === <syntaxhighlight lang="r"> # Creare un file .Rprofile nella directory di lavoro # Il contenuto seguente può essere salvato in ~/.Rprofile o ~/Documents/.Rprofile # ====== Script di avvio PenuX ====== # Caricare le librerie comuni suppressWarnings({ library(tidyverse) library(caret) library(ggplot2) library(data.table) }) # Impostare le opzioni options(digits = 4) options(scipen = 10) options(width = 100) # Visualizzare un messaggio di benvenuto cat("\n=== Benvenuto in PenuX R Analysis ===\n") cat("Directory di lavoro:", getwd(), "\n") cat("Versione di R:", R.version$version.string, "\n") cat("Librerie caricate: tidyverse, caret, ggplot2, data.table\n\n") </syntaxhighlight> === Come creare il file .Rprofile === # Apri un editor di testo (Notepad, Sublime Text, ecc.) # Incolla il contenuto riportato sopra # Salvalo con il nome <code>.Rprofile</code> nella tua directory home # Riavvia R o RStudio affinché le modifiche abbiano effetto == Riepilogo dell'unità 1 == Abbiamo trattato: * Installazione di R e RStudio * Installazione delle librerie essenziali * Configurazione dell'ambiente di lavoro * Controlli diagnostici * Creazione di uno script di avvio personalizzato == Esercizi pratici == # Installa R e RStudio sul tuo computer # Installa tutte le librerie elencate # Verifica che ogni libreria funzioni correttamente # Crea il tuo script .Rprofile personalizzato # Imposta la tua directory di lavoro PenuX == Letture consigliate == * [https://cran.r-project.org/ Il progetto R] * [https://rstudio.com/ RStudio] * [https://www.tidyverse.org/ Tidyverse] * [https://topepo.github.io/caret/ Pacchetto Caret] == Il progetto PenuX == Il codice sorgente, i modelli e la documentazione della piattaforma PenuX sono disponibili pubblicamente con licenza libera: * [[github:netanelcyber/penux|Repository PenuX su GitHub]] * [https://penux.uk Sito del progetto PenuX] c6z5je9j4dnladu49qmpoxtfau32d0e 502104 502072 2026-10-04T18:21:29Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502104 wikitext text/x-wiki {{orfana}} = PenuX in R: Unità 1 - Installazione e configurazione dell'ambiente = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Installare correttamente R e RStudio * Installare e caricare le librerie necessarie (tidyverse, caret, survival, ecc.) * Configurare il tuo ambiente di lavoro * Eseguire controlli diagnostici * Creare uno script di avvio personalizzato == 1.1 Installazione di R e RStudio == === Installazione di R === <syntaxhighlight lang="r"> # Verificare la versione attuale di R R.version # Esempio di output atteso: # Platform: x86_64-pc-linux-gnu (oppure Windows/Mac) # R version 4.0.0 o superiore # Status: Patched o Release </syntaxhighlight> === Installazione di RStudio === Per scaricare RStudio, visita: https://rstudio.com/products/rstudio/download/ Dopo l'installazione, avvia RStudio e verifica che tutto funzioni correttamente. == 1.2 Installazione delle librerie necessarie == === Librerie essenziali === <syntaxhighlight lang="r"> # Installare le librerie principali install.packages(c("tidyverse", "caret", "survival", "data.table", "ggplot2")) # Caricare le librerie library(tidyverse) library(caret) library(survival) library(data.table) library(ggplot2) # Verificare le versioni packageVersion("tidyverse") packageVersion("caret") packageVersion("survival") </syntaxhighlight> === Librerie aggiuntive === <syntaxhighlight lang="r"> # Installare librerie aggiuntive install.packages(c("xgboost", "ranger", "rpart", "e1071", "knitr", "kableExtra", "plotly")) # Queste librerie saranno utilizzate nelle unità successive # per la modellazione avanzata e la visualizzazione </syntaxhighlight> == 1.3 Configurazione dell'ambiente di lavoro == === Gestione delle directory === <syntaxhighlight lang="r"> # Verificare la directory di lavoro attuale getwd() # Impostare una nuova directory di lavoro setwd("~/PenuX_Analysis") # Creare sottodirectory se necessario dir.create("data", showWarnings = FALSE) dir.create("results", showWarnings = FALSE) dir.create("plots", showWarnings = FALSE) # Verificare le directory create list.files(".") </syntaxhighlight> === Configurazione delle opzioni di R === <syntaxhighlight lang="r"> # Impostare le opzioni predefinite options(digits = 4) # Limitare i decimali a 4 cifre options(scipen = 10) # Evitare la notazione scientifica options(width = 100) # Larghezza della console options(max.print = 1000) # Numero massimo di righe da visualizzare # Visualizzare le opzioni attuali getOption("digits") getOption("scipen") </syntaxhighlight> == 1.4 Controlli diagnostici == === Verificare le installazioni === <syntaxhighlight lang="r"> # Elenco di tutte le librerie installate installed_packages <- installed.packages() head(installed_packages) # Verificare se una libreria specifica è installata "caret" %in% rownames(installed.packages()) # Numero totale di librerie installate nrow(installed.packages()) # Librerie attualmente caricate search() </syntaxhighlight> === Test di funzionalità di base === <syntaxhighlight lang="r"> # Test di creazione dei dati test_data <- data.frame( age = c(25, 35, 45, 55, 65), valore = c(10.5, 20.3, 15.8, 22.1, 18.9) ) # Visualizzare i dati print(test_data) # Statistiche di base summary(test_data) # Verificare che tidyverse funzioni test_data %>% filter(age > 30) %>% summarise(media = mean(valore)) </syntaxhighlight> == 1.5 Creazione dello script di avvio == === File .Rprofile === <syntaxhighlight lang="r"> # Creare un file .Rprofile nella directory di lavoro # Il contenuto seguente può essere salvato in ~/.Rprofile o ~/Documents/.Rprofile # ====== Script di avvio PenuX ====== # Caricare le librerie comuni suppressWarnings({ library(tidyverse) library(caret) library(ggplot2) library(data.table) }) # Impostare le opzioni options(digits = 4) options(scipen = 10) options(width = 100) # Visualizzare un messaggio di benvenuto cat("\n=== Benvenuto in PenuX R Analysis ===\n") cat("Directory di lavoro:", getwd(), "\n") cat("Versione di R:", R.version$version.string, "\n") cat("Librerie caricate: tidyverse, caret, ggplot2, data.table\n\n") </syntaxhighlight> === Come creare il file .Rprofile === # Apri un editor di testo (Notepad, Sublime Text, ecc.) # Incolla il contenuto riportato sopra # Salvalo con il nome <code>.Rprofile</code> nella tua directory home # Riavvia R o RStudio affinché le modifiche abbiano effetto == Riepilogo dell'unità 1 == Abbiamo trattato: * Installazione di R e RStudio * Installazione delle librerie essenziali * Configurazione dell'ambiente di lavoro * Controlli diagnostici * Creazione di uno script di avvio personalizzato == Esercizi pratici == # Installa R e RStudio sul tuo computer # Installa tutte le librerie elencate # Verifica che ogni libreria funzioni correttamente # Crea il tuo script .Rprofile personalizzato # Imposta la tua directory di lavoro PenuX == Letture consigliate == * [https://cran.r-project.org/ Il progetto R] * [https://rstudio.com/ RStudio] * [https://www.tidyverse.org/ Tidyverse] * [https://topepo.github.io/caret/ Pacchetto Caret] == Il progetto PenuX == Il codice sorgente, i modelli e la documentazione della piattaforma PenuX sono disponibili pubblicamente con licenza libera: * [[github:netanelcyber/penux|Repository PenuX su GitHub]] * [https://penux.uk Sito del progetto PenuX] [[Categoria:PenuX in R|Unità 1 - Installazione e configurazione dell&#39;ambiente]] psgunz6kjbip9pwt4xxi4ah7z5iq07d PenuX in R/Quiz Unità 1 0 61177 502064 502009 2026-10-04T14:53:50Z Hippias 18281 Hippias ha spostato la pagina [[PenuX in R: Quiz Unità 1]] a [[PenuX in R/Quiz Unità 1]] senza lasciare redirect: [[Aiuto:Convenzioni di nomenclatura|Convenzioni di nomenclatura]]: sottopagino correttamente 502009 wikitext text/x-wiki = PenuX in R: Quiz Unità 1 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Quale funzione crea un vettore in R? * A) vector.new() * B) list.add() * C) c() * D) make() <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. <code>c()</code> combina valori in un vettore. </div> == Domanda 2 == Che cosa restituisce <code>10 %% 3</code>? * A) 3.33 * B) 0 * C) 3 * D) 1 (il resto della divisione) <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. L'operatore <code>%%</code> restituisce il resto: 10 = 3 × 3 + 1. </div> == Domanda 3 == Qual è la differenza principale tra matrice e data frame? * A) La matrice contiene un solo tipo di dato; il data frame può avere colonne di tipi diversi * B) Il data frame contiene solo numeri * C) La matrice può avere solo una riga * D) Non ci sono differenze <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Una matrice è omogenea; un data frame è una tabella con colonne di tipo diverso (numeri, testo, fattori). </div> == Domanda 4 == Quale ciclo conviene usare quando non si conosce in anticipo il numero di iterazioni? * A) for su un vettore di lunghezza fissa * B) while * C) if * D) function <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Il ciclo <code>while</code> continua finché la condizione è vera. </div> == Torna all'unità == [[PenuX in R: Unità 1 - Fondamenti del Linguaggio R|Torna all'Unità 1]] lq7mx5j70usuqnkytx29hxpp3xtv8pm 502096 502064 2026-10-04T18:20:03Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502096 wikitext text/x-wiki = PenuX in R: Quiz Unità 1 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Quale funzione crea un vettore in R? * A) vector.new() * B) list.add() * C) c() * D) make() <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. <code>c()</code> combina valori in un vettore. </div> == Domanda 2 == Che cosa restituisce <code>10 %% 3</code>? * A) 3.33 * B) 0 * C) 3 * D) 1 (il resto della divisione) <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. L'operatore <code>%%</code> restituisce il resto: 10 = 3 × 3 + 1. </div> == Domanda 3 == Qual è la differenza principale tra matrice e data frame? * A) La matrice contiene un solo tipo di dato; il data frame può avere colonne di tipi diversi * B) Il data frame contiene solo numeri * C) La matrice può avere solo una riga * D) Non ci sono differenze <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Una matrice è omogenea; un data frame è una tabella con colonne di tipo diverso (numeri, testo, fattori). </div> == Domanda 4 == Quale ciclo conviene usare quando non si conosce in anticipo il numero di iterazioni? * A) for su un vettore di lunghezza fissa * B) while * C) if * D) function <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Il ciclo <code>while</code> continua finché la condizione è vera. </div> == Torna all'unità == [[PenuX in R: Unità 1 - Fondamenti del Linguaggio R|Torna all'Unità 1]] [[Categoria:PenuX in R|Quiz Unità 1]] 7ewuac7qa01unfl8ax3uy6kib65wyfx 502112 502096 2026-10-04T18:24:08Z Gian BOT 27470 bot: fix link 502112 wikitext text/x-wiki = PenuX in R: Quiz Unità 1 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Quale funzione crea un vettore in R? * A) vector.new() * B) list.add() * C) c() * D) make() <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. <code>c()</code> combina valori in un vettore. </div> == Domanda 2 == Che cosa restituisce <code>10 %% 3</code>? * A) 3.33 * B) 0 * C) 3 * D) 1 (il resto della divisione) <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. L'operatore <code>%%</code> restituisce il resto: 10 = 3 × 3 + 1. </div> == Domanda 3 == Qual è la differenza principale tra matrice e data frame? * A) La matrice contiene un solo tipo di dato; il data frame può avere colonne di tipi diversi * B) Il data frame contiene solo numeri * C) La matrice può avere solo una riga * D) Non ci sono differenze <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Una matrice è omogenea; un data frame è una tabella con colonne di tipo diverso (numeri, testo, fattori). </div> == Domanda 4 == Quale ciclo conviene usare quando non si conosce in anticipo il numero di iterazioni? * A) for su un vettore di lunghezza fissa * B) while * C) if * D) function <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Il ciclo <code>while</code> continua finché la condizione è vera. </div> == Torna all'unità == [[PenuX in R/Unità 1 - Fondamenti del Linguaggio R|Torna all'Unità 1]] [[Categoria:PenuX in R|Quiz Unità 1]] n2nmzrgm8sbss6x5al75290870ai8m0 502127 502112 2026-10-04T18:32:00Z Gian BOT 27470 Bot: aggiunge l'indice 502127 wikitext text/x-wiki {{PenuX in R}} = PenuX in R: Quiz Unità 1 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Quale funzione crea un vettore in R? * A) vector.new() * B) list.add() * C) c() * D) make() <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. <code>c()</code> combina valori in un vettore. </div> == Domanda 2 == Che cosa restituisce <code>10 %% 3</code>? * A) 3.33 * B) 0 * C) 3 * D) 1 (il resto della divisione) <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. L'operatore <code>%%</code> restituisce il resto: 10 = 3 × 3 + 1. </div> == Domanda 3 == Qual è la differenza principale tra matrice e data frame? * A) La matrice contiene un solo tipo di dato; il data frame può avere colonne di tipi diversi * B) Il data frame contiene solo numeri * C) La matrice può avere solo una riga * D) Non ci sono differenze <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Una matrice è omogenea; un data frame è una tabella con colonne di tipo diverso (numeri, testo, fattori). </div> == Domanda 4 == Quale ciclo conviene usare quando non si conosce in anticipo il numero di iterazioni? * A) for su un vettore di lunghezza fissa * B) while * C) if * D) function <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Il ciclo <code>while</code> continua finché la condizione è vera. </div> == Torna all'unità == [[PenuX in R/Unità 1 - Fondamenti del Linguaggio R|Torna all'Unità 1]] [[Categoria:PenuX in R|Quiz Unità 1]] 8wxjthmolvrmskva3fx5tze8dlp96ov PenuX in R/Unità 1 - Fondamenti del Linguaggio R 0 61178 502054 502010 2026-10-04T14:43:42Z Hippias 18281 Hippias ha spostato la pagina [[PenuX in R: Unità 1 - Fondamenti del Linguaggio R]] a [[PenuX in R/Unità 1 - Fondamenti del Linguaggio R]] senza lasciare redirect: [[Aiuto:Convenzioni di nomenclatura|Convenzioni di nomenclatura]]: sottopagino correttamente 502010 wikitext text/x-wiki = PenuX in R: Unità 1 - Fondamenti del Linguaggio R = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Comprendere i tipi di dati di base in R * Lavorare con variabili e funzioni * Utilizzare vettori, matrici e data frame * Scrivere cicli e condizionali * Creare le tue funzioni * Leggere e scrivere file == 1.1 Installazione e Configurazione == === Installare R === <syntaxhighlight lang="bash"> # Ubuntu/Debian sudo apt-get install r-base # macOS brew install r # Windows # Scarica da: https://cran.r-project.org/bin/windows/base/ </syntaxhighlight> === RStudio (IDE Consigliata) === <syntaxhighlight lang="bash"> # Scarica da: https://rstudio.com/products/rstudio/download/ </syntaxhighlight> == 1.2 Tipi di Dati di Base == === Vettori === <syntaxhighlight lang="r"> # Vettore numerico age <- c(25, 30, 35, 40, 45) print(age) # Vettore di testo names <- c("Alice", "Bob", "Carlo", "Diana", "Enrico") print(names) # Vettore logico is_sick <- c(TRUE, FALSE, TRUE, FALSE, TRUE) print(is_sick) # Verificare il tipo class(age) class(names) class(is_sick) # Lunghezza del vettore length(age) # Accesso agli elementi age[1] # Primo elemento age[c(1, 3)] # Elementi 1 e 3 age[age > 30] # Tutti gli elementi > 30 </syntaxhighlight> === Matrici === <syntaxhighlight lang="r"> # Creare una matrice matrix_data <- matrix(1:12, nrow = 3, ncol = 4) print(matrix_data) # Matrice con nomi di righe e colonne data <- matrix( c(65, 72, 58, 81, 92, 76), nrow = 3, ncol = 2, dimnames = list( c("Paziente_1", "Paziente_2", "Paziente_3"), c("Pressione_Sistolica", "Temperatura") ) ) print(data) # Accesso agli elementi data[1, 1] # Riga 1, Colonna 1 data[1, ] # Intera riga 1 data[, 1] # Intera colonna 1 </syntaxhighlight> === Data Frames === <syntaxhighlight lang="r"> # Creare un data frame patients <- data.frame( patient_id = 1:5, name = c("Alice", "Bob", "Carlo", "Diana", "Enrico"), age = c(25, 30, 35, 40, 45), systolic_bp = c(120, 130, 140, 125, 135) ) print(patients) # Accesso alle colonne patients$age patients[["name"]] patients[, "age"] # Accesso alle righe patients[1, ] # Prima riga patients[1:3, ] # Righe 1-3 # Informazioni sul data frame nrow(patients) # Numero di righe ncol(patients) # Numero di colonne head(patients) # Primo 6 righe str(patients) # Struttura summary(patients) # Statistiche </syntaxhighlight> == 1.3 Operazioni di Base == === Operazioni Aritmetiche === <syntaxhighlight lang="r"> # Operazioni aritmetiche 5 + 3 # Addizione 10 - 2 # Sottrazione 4 * 5 # Moltiplicazione 20 / 4 # Divisione 2 ^ 3 # Potenza 10 %% 3 # Resto # Operazioni su vettori vec1 <- c(1, 2, 3, 4, 5) vec2 <- c(2, 2, 2, 2, 2) vec1 + vec2 vec1 * vec2 sqrt(vec1) # Radice quadrata log(vec1) # Logaritmo naturale exp(vec1) # e elevato a potenza </syntaxhighlight> === Operazioni Logiche === <syntaxhighlight lang="r"> # Confronti 5 > 3 # Maggiore di 10 <= 10 # Minore o uguale 8 == 8 # Uguale 5 != 3 # Non uguale # Logica booleana TRUE & FALSE # AND TRUE | FALSE # OR !TRUE # NOT # Su vettori age <- c(25, 30, 35, 40, 45) age > 30 age >= 35 & age < 45 !(age == 30) </syntaxhighlight> == 1.4 Funzioni == === Funzioni Integrate === <syntaxhighlight lang="r"> # Statistiche di base numbers <- c(1, 2, 3, 4, 5) mean(numbers) # Media median(numbers) # Mediana sd(numbers) # Deviazione standard var(numbers) # Varianza min(numbers) # Minimo max(numbers) # Massimo sum(numbers) # Somma prod(numbers) # Prodotto length(numbers) # Lunghezza # Funzioni su testo text <- "Hello World" nchar(text) # Numero di caratteri toupper(text) # Maiuscole tolower(text) # Minuscole substr(text, 1, 5) # Sottostringa paste("Hello", "World") # Concatenazione </syntaxhighlight> === Creare Funzioni Personalizzate === <syntaxhighlight lang="r"> # Funzione semplice greet <- function(name) { message <- paste("Ciao", name) return(message) } greet("Natanele") # Funzione con parametri di default calculate_bmi <- function(weight, height = 1.70) { bmi <- weight / (height ^ 2) return(bmi) } calculate_bmi(70) # height = 1.70 (default) calculate_bmi(70, 1.80) # Funzione che ritorna multipli valori get_statistics <- function(data) { mean_val <- mean(data) sd_val <- sd(data) return(list(mean = mean_val, sd = sd_val)) } stats <- get_statistics(c(1, 2, 3, 4, 5)) stats$mean stats$sd </syntaxhighlight> == 1.5 Cicli e Condizionali == === if-else === <syntaxhighlight lang="r"> # if semplice age <- 25 if (age >= 18) { print("Maggiorenne") } else { print("Minorenne") } # if-else if-else diagnosis <- "Healthy" if (diagnosis == "Healthy") { print("Sei sano") } else if (diagnosis == "Pancreatitis") { print("Pancreatite acuta") } else if (diagnosis == "Sepsis") { print("Sepsi") } else { print("Diagnosi sconosciuta") } # ifelse vettoriale age <- c(20, 30, 40, 50, 60) category <- ifelse(age > 40, "Anziano", "Giovane") print(category) </syntaxhighlight> === Cicli for === <syntaxhighlight lang="r"> # Ciclo for di base for (i in 1:5) { print(paste("Iterazione", i)) } # Ciclo su un vettore names <- c("Alice", "Bob", "Carlo") for (name in names) { print(paste("Ciao", name)) } # Ciclo con break e next for (i in 1:10) { if (i == 3) { next # Salta questa iterazione } if (i == 7) { break # Esci dal ciclo } print(i) } </syntaxhighlight> === Cicli while === <syntaxhighlight lang="r"> # Ciclo while count <- 0 while (count < 5) { print(paste("Count:", count)) count <- count + 1 } # Ciclo con condizione complessa x <- 10 while (x > 0 & x < 20) { print(x) x <- x - 2 } </syntaxhighlight> == 1.6 Lavorare con i Pacchetti == === Installazione e Caricamento === <syntaxhighlight lang="r"> # Installare un pacchetto install.packages("tidyverse") install.packages("ggplot2") # Caricare un pacchetto library(tidyverse) library(ggplot2) # Controllare i pacchetti installati installed.packages() # Rimuovere un pacchetto remove.packages("tidyverse") </syntaxhighlight> === Pacchetti Utili === <syntaxhighlight lang="r"> # tidyverse - Manipolazione dati conveniente library(tidyverse) # ggplot2 - Visualizzazione library(ggplot2) # caret - Machine learning library(caret) # dplyr - Manipolazione dati library(dplyr) # data.table - Tabelle dati veloci library(data.table) </syntaxhighlight> == 1.7 Leggere e Scrivere File == === File CSV === <syntaxhighlight lang="r"> # Leggere un file CSV data <- read.csv("data.csv") # Scrivere un file CSV write.csv(data, "output.csv", row.names = FALSE) # Con opzioni data <- read.csv("data.csv", sep = ",", header = TRUE, encoding = "UTF-8") </syntaxhighlight> === Formato RDS === <syntaxhighlight lang="r"> # Salvare un oggetto R patients <- data.frame(name = c("Alice", "Bob"), age = c(30, 40)) saveRDS(patients, "patients.rds") # Caricare un oggetto R loaded_data <- readRDS("patients.rds") </syntaxhighlight> == 1.8 Esercizi Pratici == === Esercizio 1: Lavorare con i Vettori === <syntaxhighlight lang="r"> # Crea un vettore di 10 età di pazienti ages <- c(45, 52, 38, 61, 55, 48, 72, 41, 58, 50) # Calcola la media mean(ages) # Quanti pazienti hanno più di 50 anni? sum(ages > 50) # Quali sono le età dei pazienti con più di 50 anni? ages[ages > 50] </syntaxhighlight> === Esercizio 2: Creare un Data Frame === <syntaxhighlight lang="r"> # Crea un data frame di pazienti patients <- data.frame( id = 1:5, name = c("Alice", "Bob", "Carlo", "Diana", "Enrico"), age = c(45, 52, 38, 61, 55), systolic_bp = c(140, 150, 120, 155, 145), diagnosis = c("Healthy", "Hypertension", "Healthy", "Pancreatitis", "Sepsis") ) # Stampa i dati print(patients) # Accedi alla colonna age patients$age # Filtra pazienti con diagnosi "Healthy" healthy_patients <- patients[patients$diagnosis == "Healthy", ] print(healthy_patients) </syntaxhighlight> === Esercizio 3: Creare una Funzione === <syntaxhighlight lang="r"> # Scrivi una funzione che calcola la MAP calculate_map <- function(systolic, diastolic) { map <- (systolic + 2 * diastolic) / 3 return(round(map, 2)) } # Testa la funzione calculate_map(140, 90) calculate_map(120, 80) # Usala su un data frame patients$MAP <- mapply(calculate_map, patients$systolic_bp, patients$diastolic_bp) print(patients) </syntaxhighlight> === Esercizio 4: Cicli e Funzioni === <syntaxhighlight lang="r"> # Scrivi un ciclo che stampa statistiche per ogni paziente for (i in 1:nrow(patients)) { cat("Paziente:", patients$name[i], "| Età:", patients$age[i], "| MAP:", patients$MAP[i], "\n") } # Scrivi una funzione che categorizza per età categorize_age <- function(age) { if (age < 40) { return("Giovane") } else if (age < 65) { return("Medio") } else { return("Anziano") } } # Applica a tutti i pazienti patients$age_category <- sapply(patients$age, categorize_age) print(patients) </syntaxhighlight> == 1.9 Verifica della Comprensione == * Qual è la differenza tra un vettore, una matrice e un data frame? * Come si crea una funzione in R? * Quale è la differenza tra un ciclo for e un ciclo while? * Come si legge un file CSV in R? * Come si usa il condizionale if-else? == 1.10 Soluzioni degli Esercizi == === Soluzione Esercizio 1 === <syntaxhighlight lang="r"> ages <- c(45, 52, 38, 61, 55, 48, 72, 41, 58, 50) mean_age <- mean(ages) # 52 count_over_50 <- sum(ages > 50) # 6 ages_over_50 <- ages[ages > 50] # 52, 61, 55, 72, 58, 50 </syntaxhighlight> === Soluzione Esercizio 2 === <syntaxhighlight lang="r"> # Vedi nell'esercizio stesso </syntaxhighlight> == Riepilogo dell'Unità 1 == Abbiamo trattato: * Tipi di dati: vettori, matrici, data frame * Operazioni di base e funzioni * Condizionali e cicli * Creazione di funzioni personalizzate * Utilizzo dei pacchetti * Lettura e scrittura di file * Esercizi pratici == Letture Consigliate == * [https://www.r-project.org/ R Project] * [https://rstudio.com/ RStudio] * [https://r4ds.had.co.nz/ R for Data Science] == Prosegui da Qui == Bene! Ora sei pronto per passare all'Unità 2: Preparazione dei Dati. == Il progetto PenuX == Repository PenuX: https://github.com/netanelcyber/penux Sito PenuX: https://penux.uk == Quiz == [[PenuX in R: Quiz Unità 1|Fai il quiz dell'Unità 1]] luk22act9f4e33fxkhd3nd2jgw8fsbq 502103 502054 2026-10-04T18:21:19Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502103 wikitext text/x-wiki = PenuX in R: Unità 1 - Fondamenti del Linguaggio R = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Comprendere i tipi di dati di base in R * Lavorare con variabili e funzioni * Utilizzare vettori, matrici e data frame * Scrivere cicli e condizionali * Creare le tue funzioni * Leggere e scrivere file == 1.1 Installazione e Configurazione == === Installare R === <syntaxhighlight lang="bash"> # Ubuntu/Debian sudo apt-get install r-base # macOS brew install r # Windows # Scarica da: https://cran.r-project.org/bin/windows/base/ </syntaxhighlight> === RStudio (IDE Consigliata) === <syntaxhighlight lang="bash"> # Scarica da: https://rstudio.com/products/rstudio/download/ </syntaxhighlight> == 1.2 Tipi di Dati di Base == === Vettori === <syntaxhighlight lang="r"> # Vettore numerico age <- c(25, 30, 35, 40, 45) print(age) # Vettore di testo names <- c("Alice", "Bob", "Carlo", "Diana", "Enrico") print(names) # Vettore logico is_sick <- c(TRUE, FALSE, TRUE, FALSE, TRUE) print(is_sick) # Verificare il tipo class(age) class(names) class(is_sick) # Lunghezza del vettore length(age) # Accesso agli elementi age[1] # Primo elemento age[c(1, 3)] # Elementi 1 e 3 age[age > 30] # Tutti gli elementi > 30 </syntaxhighlight> === Matrici === <syntaxhighlight lang="r"> # Creare una matrice matrix_data <- matrix(1:12, nrow = 3, ncol = 4) print(matrix_data) # Matrice con nomi di righe e colonne data <- matrix( c(65, 72, 58, 81, 92, 76), nrow = 3, ncol = 2, dimnames = list( c("Paziente_1", "Paziente_2", "Paziente_3"), c("Pressione_Sistolica", "Temperatura") ) ) print(data) # Accesso agli elementi data[1, 1] # Riga 1, Colonna 1 data[1, ] # Intera riga 1 data[, 1] # Intera colonna 1 </syntaxhighlight> === Data Frames === <syntaxhighlight lang="r"> # Creare un data frame patients <- data.frame( patient_id = 1:5, name = c("Alice", "Bob", "Carlo", "Diana", "Enrico"), age = c(25, 30, 35, 40, 45), systolic_bp = c(120, 130, 140, 125, 135) ) print(patients) # Accesso alle colonne patients$age patients[["name"]] patients[, "age"] # Accesso alle righe patients[1, ] # Prima riga patients[1:3, ] # Righe 1-3 # Informazioni sul data frame nrow(patients) # Numero di righe ncol(patients) # Numero di colonne head(patients) # Primo 6 righe str(patients) # Struttura summary(patients) # Statistiche </syntaxhighlight> == 1.3 Operazioni di Base == === Operazioni Aritmetiche === <syntaxhighlight lang="r"> # Operazioni aritmetiche 5 + 3 # Addizione 10 - 2 # Sottrazione 4 * 5 # Moltiplicazione 20 / 4 # Divisione 2 ^ 3 # Potenza 10 %% 3 # Resto # Operazioni su vettori vec1 <- c(1, 2, 3, 4, 5) vec2 <- c(2, 2, 2, 2, 2) vec1 + vec2 vec1 * vec2 sqrt(vec1) # Radice quadrata log(vec1) # Logaritmo naturale exp(vec1) # e elevato a potenza </syntaxhighlight> === Operazioni Logiche === <syntaxhighlight lang="r"> # Confronti 5 > 3 # Maggiore di 10 <= 10 # Minore o uguale 8 == 8 # Uguale 5 != 3 # Non uguale # Logica booleana TRUE & FALSE # AND TRUE | FALSE # OR !TRUE # NOT # Su vettori age <- c(25, 30, 35, 40, 45) age > 30 age >= 35 & age < 45 !(age == 30) </syntaxhighlight> == 1.4 Funzioni == === Funzioni Integrate === <syntaxhighlight lang="r"> # Statistiche di base numbers <- c(1, 2, 3, 4, 5) mean(numbers) # Media median(numbers) # Mediana sd(numbers) # Deviazione standard var(numbers) # Varianza min(numbers) # Minimo max(numbers) # Massimo sum(numbers) # Somma prod(numbers) # Prodotto length(numbers) # Lunghezza # Funzioni su testo text <- "Hello World" nchar(text) # Numero di caratteri toupper(text) # Maiuscole tolower(text) # Minuscole substr(text, 1, 5) # Sottostringa paste("Hello", "World") # Concatenazione </syntaxhighlight> === Creare Funzioni Personalizzate === <syntaxhighlight lang="r"> # Funzione semplice greet <- function(name) { message <- paste("Ciao", name) return(message) } greet("Natanele") # Funzione con parametri di default calculate_bmi <- function(weight, height = 1.70) { bmi <- weight / (height ^ 2) return(bmi) } calculate_bmi(70) # height = 1.70 (default) calculate_bmi(70, 1.80) # Funzione che ritorna multipli valori get_statistics <- function(data) { mean_val <- mean(data) sd_val <- sd(data) return(list(mean = mean_val, sd = sd_val)) } stats <- get_statistics(c(1, 2, 3, 4, 5)) stats$mean stats$sd </syntaxhighlight> == 1.5 Cicli e Condizionali == === if-else === <syntaxhighlight lang="r"> # if semplice age <- 25 if (age >= 18) { print("Maggiorenne") } else { print("Minorenne") } # if-else if-else diagnosis <- "Healthy" if (diagnosis == "Healthy") { print("Sei sano") } else if (diagnosis == "Pancreatitis") { print("Pancreatite acuta") } else if (diagnosis == "Sepsis") { print("Sepsi") } else { print("Diagnosi sconosciuta") } # ifelse vettoriale age <- c(20, 30, 40, 50, 60) category <- ifelse(age > 40, "Anziano", "Giovane") print(category) </syntaxhighlight> === Cicli for === <syntaxhighlight lang="r"> # Ciclo for di base for (i in 1:5) { print(paste("Iterazione", i)) } # Ciclo su un vettore names <- c("Alice", "Bob", "Carlo") for (name in names) { print(paste("Ciao", name)) } # Ciclo con break e next for (i in 1:10) { if (i == 3) { next # Salta questa iterazione } if (i == 7) { break # Esci dal ciclo } print(i) } </syntaxhighlight> === Cicli while === <syntaxhighlight lang="r"> # Ciclo while count <- 0 while (count < 5) { print(paste("Count:", count)) count <- count + 1 } # Ciclo con condizione complessa x <- 10 while (x > 0 & x < 20) { print(x) x <- x - 2 } </syntaxhighlight> == 1.6 Lavorare con i Pacchetti == === Installazione e Caricamento === <syntaxhighlight lang="r"> # Installare un pacchetto install.packages("tidyverse") install.packages("ggplot2") # Caricare un pacchetto library(tidyverse) library(ggplot2) # Controllare i pacchetti installati installed.packages() # Rimuovere un pacchetto remove.packages("tidyverse") </syntaxhighlight> === Pacchetti Utili === <syntaxhighlight lang="r"> # tidyverse - Manipolazione dati conveniente library(tidyverse) # ggplot2 - Visualizzazione library(ggplot2) # caret - Machine learning library(caret) # dplyr - Manipolazione dati library(dplyr) # data.table - Tabelle dati veloci library(data.table) </syntaxhighlight> == 1.7 Leggere e Scrivere File == === File CSV === <syntaxhighlight lang="r"> # Leggere un file CSV data <- read.csv("data.csv") # Scrivere un file CSV write.csv(data, "output.csv", row.names = FALSE) # Con opzioni data <- read.csv("data.csv", sep = ",", header = TRUE, encoding = "UTF-8") </syntaxhighlight> === Formato RDS === <syntaxhighlight lang="r"> # Salvare un oggetto R patients <- data.frame(name = c("Alice", "Bob"), age = c(30, 40)) saveRDS(patients, "patients.rds") # Caricare un oggetto R loaded_data <- readRDS("patients.rds") </syntaxhighlight> == 1.8 Esercizi Pratici == === Esercizio 1: Lavorare con i Vettori === <syntaxhighlight lang="r"> # Crea un vettore di 10 età di pazienti ages <- c(45, 52, 38, 61, 55, 48, 72, 41, 58, 50) # Calcola la media mean(ages) # Quanti pazienti hanno più di 50 anni? sum(ages > 50) # Quali sono le età dei pazienti con più di 50 anni? ages[ages > 50] </syntaxhighlight> === Esercizio 2: Creare un Data Frame === <syntaxhighlight lang="r"> # Crea un data frame di pazienti patients <- data.frame( id = 1:5, name = c("Alice", "Bob", "Carlo", "Diana", "Enrico"), age = c(45, 52, 38, 61, 55), systolic_bp = c(140, 150, 120, 155, 145), diagnosis = c("Healthy", "Hypertension", "Healthy", "Pancreatitis", "Sepsis") ) # Stampa i dati print(patients) # Accedi alla colonna age patients$age # Filtra pazienti con diagnosi "Healthy" healthy_patients <- patients[patients$diagnosis == "Healthy", ] print(healthy_patients) </syntaxhighlight> === Esercizio 3: Creare una Funzione === <syntaxhighlight lang="r"> # Scrivi una funzione che calcola la MAP calculate_map <- function(systolic, diastolic) { map <- (systolic + 2 * diastolic) / 3 return(round(map, 2)) } # Testa la funzione calculate_map(140, 90) calculate_map(120, 80) # Usala su un data frame patients$MAP <- mapply(calculate_map, patients$systolic_bp, patients$diastolic_bp) print(patients) </syntaxhighlight> === Esercizio 4: Cicli e Funzioni === <syntaxhighlight lang="r"> # Scrivi un ciclo che stampa statistiche per ogni paziente for (i in 1:nrow(patients)) { cat("Paziente:", patients$name[i], "| Età:", patients$age[i], "| MAP:", patients$MAP[i], "\n") } # Scrivi una funzione che categorizza per età categorize_age <- function(age) { if (age < 40) { return("Giovane") } else if (age < 65) { return("Medio") } else { return("Anziano") } } # Applica a tutti i pazienti patients$age_category <- sapply(patients$age, categorize_age) print(patients) </syntaxhighlight> == 1.9 Verifica della Comprensione == * Qual è la differenza tra un vettore, una matrice e un data frame? * Come si crea una funzione in R? * Quale è la differenza tra un ciclo for e un ciclo while? * Come si legge un file CSV in R? * Come si usa il condizionale if-else? == 1.10 Soluzioni degli Esercizi == === Soluzione Esercizio 1 === <syntaxhighlight lang="r"> ages <- c(45, 52, 38, 61, 55, 48, 72, 41, 58, 50) mean_age <- mean(ages) # 52 count_over_50 <- sum(ages > 50) # 6 ages_over_50 <- ages[ages > 50] # 52, 61, 55, 72, 58, 50 </syntaxhighlight> === Soluzione Esercizio 2 === <syntaxhighlight lang="r"> # Vedi nell'esercizio stesso </syntaxhighlight> == Riepilogo dell'Unità 1 == Abbiamo trattato: * Tipi di dati: vettori, matrici, data frame * Operazioni di base e funzioni * Condizionali e cicli * Creazione di funzioni personalizzate * Utilizzo dei pacchetti * Lettura e scrittura di file * Esercizi pratici == Letture Consigliate == * [https://www.r-project.org/ R Project] * [https://rstudio.com/ RStudio] * [https://r4ds.had.co.nz/ R for Data Science] == Prosegui da Qui == Bene! Ora sei pronto per passare all'Unità 2: Preparazione dei Dati. == Il progetto PenuX == Repository PenuX: https://github.com/netanelcyber/penux Sito PenuX: https://penux.uk == Quiz == [[PenuX in R: Quiz Unità 1|Fai il quiz dell'Unità 1]] [[Categoria:PenuX in R|Unità 1 - Fondamenti del Linguaggio R]] 9efvu1jxo7ivffkoiozdc49e7b0d9ep 502119 502103 2026-10-04T18:25:18Z Gian BOT 27470 bot: fix link 502119 wikitext text/x-wiki = PenuX in R: Unità 1 - Fondamenti del Linguaggio R = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Comprendere i tipi di dati di base in R * Lavorare con variabili e funzioni * Utilizzare vettori, matrici e data frame * Scrivere cicli e condizionali * Creare le tue funzioni * Leggere e scrivere file == 1.1 Installazione e Configurazione == === Installare R === <syntaxhighlight lang="bash"> # Ubuntu/Debian sudo apt-get install r-base # macOS brew install r # Windows # Scarica da: https://cran.r-project.org/bin/windows/base/ </syntaxhighlight> === RStudio (IDE Consigliata) === <syntaxhighlight lang="bash"> # Scarica da: https://rstudio.com/products/rstudio/download/ </syntaxhighlight> == 1.2 Tipi di Dati di Base == === Vettori === <syntaxhighlight lang="r"> # Vettore numerico age <- c(25, 30, 35, 40, 45) print(age) # Vettore di testo names <- c("Alice", "Bob", "Carlo", "Diana", "Enrico") print(names) # Vettore logico is_sick <- c(TRUE, FALSE, TRUE, FALSE, TRUE) print(is_sick) # Verificare il tipo class(age) class(names) class(is_sick) # Lunghezza del vettore length(age) # Accesso agli elementi age[1] # Primo elemento age[c(1, 3)] # Elementi 1 e 3 age[age > 30] # Tutti gli elementi > 30 </syntaxhighlight> === Matrici === <syntaxhighlight lang="r"> # Creare una matrice matrix_data <- matrix(1:12, nrow = 3, ncol = 4) print(matrix_data) # Matrice con nomi di righe e colonne data <- matrix( c(65, 72, 58, 81, 92, 76), nrow = 3, ncol = 2, dimnames = list( c("Paziente_1", "Paziente_2", "Paziente_3"), c("Pressione_Sistolica", "Temperatura") ) ) print(data) # Accesso agli elementi data[1, 1] # Riga 1, Colonna 1 data[1, ] # Intera riga 1 data[, 1] # Intera colonna 1 </syntaxhighlight> === Data Frames === <syntaxhighlight lang="r"> # Creare un data frame patients <- data.frame( patient_id = 1:5, name = c("Alice", "Bob", "Carlo", "Diana", "Enrico"), age = c(25, 30, 35, 40, 45), systolic_bp = c(120, 130, 140, 125, 135) ) print(patients) # Accesso alle colonne patients$age patients[["name"]] patients[, "age"] # Accesso alle righe patients[1, ] # Prima riga patients[1:3, ] # Righe 1-3 # Informazioni sul data frame nrow(patients) # Numero di righe ncol(patients) # Numero di colonne head(patients) # Primo 6 righe str(patients) # Struttura summary(patients) # Statistiche </syntaxhighlight> == 1.3 Operazioni di Base == === Operazioni Aritmetiche === <syntaxhighlight lang="r"> # Operazioni aritmetiche 5 + 3 # Addizione 10 - 2 # Sottrazione 4 * 5 # Moltiplicazione 20 / 4 # Divisione 2 ^ 3 # Potenza 10 %% 3 # Resto # Operazioni su vettori vec1 <- c(1, 2, 3, 4, 5) vec2 <- c(2, 2, 2, 2, 2) vec1 + vec2 vec1 * vec2 sqrt(vec1) # Radice quadrata log(vec1) # Logaritmo naturale exp(vec1) # e elevato a potenza </syntaxhighlight> === Operazioni Logiche === <syntaxhighlight lang="r"> # Confronti 5 > 3 # Maggiore di 10 <= 10 # Minore o uguale 8 == 8 # Uguale 5 != 3 # Non uguale # Logica booleana TRUE & FALSE # AND TRUE | FALSE # OR !TRUE # NOT # Su vettori age <- c(25, 30, 35, 40, 45) age > 30 age >= 35 & age < 45 !(age == 30) </syntaxhighlight> == 1.4 Funzioni == === Funzioni Integrate === <syntaxhighlight lang="r"> # Statistiche di base numbers <- c(1, 2, 3, 4, 5) mean(numbers) # Media median(numbers) # Mediana sd(numbers) # Deviazione standard var(numbers) # Varianza min(numbers) # Minimo max(numbers) # Massimo sum(numbers) # Somma prod(numbers) # Prodotto length(numbers) # Lunghezza # Funzioni su testo text <- "Hello World" nchar(text) # Numero di caratteri toupper(text) # Maiuscole tolower(text) # Minuscole substr(text, 1, 5) # Sottostringa paste("Hello", "World") # Concatenazione </syntaxhighlight> === Creare Funzioni Personalizzate === <syntaxhighlight lang="r"> # Funzione semplice greet <- function(name) { message <- paste("Ciao", name) return(message) } greet("Natanele") # Funzione con parametri di default calculate_bmi <- function(weight, height = 1.70) { bmi <- weight / (height ^ 2) return(bmi) } calculate_bmi(70) # height = 1.70 (default) calculate_bmi(70, 1.80) # Funzione che ritorna multipli valori get_statistics <- function(data) { mean_val <- mean(data) sd_val <- sd(data) return(list(mean = mean_val, sd = sd_val)) } stats <- get_statistics(c(1, 2, 3, 4, 5)) stats$mean stats$sd </syntaxhighlight> == 1.5 Cicli e Condizionali == === if-else === <syntaxhighlight lang="r"> # if semplice age <- 25 if (age >= 18) { print("Maggiorenne") } else { print("Minorenne") } # if-else if-else diagnosis <- "Healthy" if (diagnosis == "Healthy") { print("Sei sano") } else if (diagnosis == "Pancreatitis") { print("Pancreatite acuta") } else if (diagnosis == "Sepsis") { print("Sepsi") } else { print("Diagnosi sconosciuta") } # ifelse vettoriale age <- c(20, 30, 40, 50, 60) category <- ifelse(age > 40, "Anziano", "Giovane") print(category) </syntaxhighlight> === Cicli for === <syntaxhighlight lang="r"> # Ciclo for di base for (i in 1:5) { print(paste("Iterazione", i)) } # Ciclo su un vettore names <- c("Alice", "Bob", "Carlo") for (name in names) { print(paste("Ciao", name)) } # Ciclo con break e next for (i in 1:10) { if (i == 3) { next # Salta questa iterazione } if (i == 7) { break # Esci dal ciclo } print(i) } </syntaxhighlight> === Cicli while === <syntaxhighlight lang="r"> # Ciclo while count <- 0 while (count < 5) { print(paste("Count:", count)) count <- count + 1 } # Ciclo con condizione complessa x <- 10 while (x > 0 & x < 20) { print(x) x <- x - 2 } </syntaxhighlight> == 1.6 Lavorare con i Pacchetti == === Installazione e Caricamento === <syntaxhighlight lang="r"> # Installare un pacchetto install.packages("tidyverse") install.packages("ggplot2") # Caricare un pacchetto library(tidyverse) library(ggplot2) # Controllare i pacchetti installati installed.packages() # Rimuovere un pacchetto remove.packages("tidyverse") </syntaxhighlight> === Pacchetti Utili === <syntaxhighlight lang="r"> # tidyverse - Manipolazione dati conveniente library(tidyverse) # ggplot2 - Visualizzazione library(ggplot2) # caret - Machine learning library(caret) # dplyr - Manipolazione dati library(dplyr) # data.table - Tabelle dati veloci library(data.table) </syntaxhighlight> == 1.7 Leggere e Scrivere File == === File CSV === <syntaxhighlight lang="r"> # Leggere un file CSV data <- read.csv("data.csv") # Scrivere un file CSV write.csv(data, "output.csv", row.names = FALSE) # Con opzioni data <- read.csv("data.csv", sep = ",", header = TRUE, encoding = "UTF-8") </syntaxhighlight> === Formato RDS === <syntaxhighlight lang="r"> # Salvare un oggetto R patients <- data.frame(name = c("Alice", "Bob"), age = c(30, 40)) saveRDS(patients, "patients.rds") # Caricare un oggetto R loaded_data <- readRDS("patients.rds") </syntaxhighlight> == 1.8 Esercizi Pratici == === Esercizio 1: Lavorare con i Vettori === <syntaxhighlight lang="r"> # Crea un vettore di 10 età di pazienti ages <- c(45, 52, 38, 61, 55, 48, 72, 41, 58, 50) # Calcola la media mean(ages) # Quanti pazienti hanno più di 50 anni? sum(ages > 50) # Quali sono le età dei pazienti con più di 50 anni? ages[ages > 50] </syntaxhighlight> === Esercizio 2: Creare un Data Frame === <syntaxhighlight lang="r"> # Crea un data frame di pazienti patients <- data.frame( id = 1:5, name = c("Alice", "Bob", "Carlo", "Diana", "Enrico"), age = c(45, 52, 38, 61, 55), systolic_bp = c(140, 150, 120, 155, 145), diagnosis = c("Healthy", "Hypertension", "Healthy", "Pancreatitis", "Sepsis") ) # Stampa i dati print(patients) # Accedi alla colonna age patients$age # Filtra pazienti con diagnosi "Healthy" healthy_patients <- patients[patients$diagnosis == "Healthy", ] print(healthy_patients) </syntaxhighlight> === Esercizio 3: Creare una Funzione === <syntaxhighlight lang="r"> # Scrivi una funzione che calcola la MAP calculate_map <- function(systolic, diastolic) { map <- (systolic + 2 * diastolic) / 3 return(round(map, 2)) } # Testa la funzione calculate_map(140, 90) calculate_map(120, 80) # Usala su un data frame patients$MAP <- mapply(calculate_map, patients$systolic_bp, patients$diastolic_bp) print(patients) </syntaxhighlight> === Esercizio 4: Cicli e Funzioni === <syntaxhighlight lang="r"> # Scrivi un ciclo che stampa statistiche per ogni paziente for (i in 1:nrow(patients)) { cat("Paziente:", patients$name[i], "| Età:", patients$age[i], "| MAP:", patients$MAP[i], "\n") } # Scrivi una funzione che categorizza per età categorize_age <- function(age) { if (age < 40) { return("Giovane") } else if (age < 65) { return("Medio") } else { return("Anziano") } } # Applica a tutti i pazienti patients$age_category <- sapply(patients$age, categorize_age) print(patients) </syntaxhighlight> == 1.9 Verifica della Comprensione == * Qual è la differenza tra un vettore, una matrice e un data frame? * Come si crea una funzione in R? * Quale è la differenza tra un ciclo for e un ciclo while? * Come si legge un file CSV in R? * Come si usa il condizionale if-else? == 1.10 Soluzioni degli Esercizi == === Soluzione Esercizio 1 === <syntaxhighlight lang="r"> ages <- c(45, 52, 38, 61, 55, 48, 72, 41, 58, 50) mean_age <- mean(ages) # 52 count_over_50 <- sum(ages > 50) # 6 ages_over_50 <- ages[ages > 50] # 52, 61, 55, 72, 58, 50 </syntaxhighlight> === Soluzione Esercizio 2 === <syntaxhighlight lang="r"> # Vedi nell'esercizio stesso </syntaxhighlight> == Riepilogo dell'Unità 1 == Abbiamo trattato: * Tipi di dati: vettori, matrici, data frame * Operazioni di base e funzioni * Condizionali e cicli * Creazione di funzioni personalizzate * Utilizzo dei pacchetti * Lettura e scrittura di file * Esercizi pratici == Letture Consigliate == * [https://www.r-project.org/ R Project] * [https://rstudio.com/ RStudio] * [https://r4ds.had.co.nz/ R for Data Science] == Prosegui da Qui == Bene! Ora sei pronto per passare all'Unità 2: Preparazione dei Dati. == Il progetto PenuX == Repository PenuX: https://github.com/netanelcyber/penux Sito PenuX: https://penux.uk == Quiz == [[PenuX in R/Quiz Unità 1|Fai il quiz dell'Unità 1]] [[Categoria:PenuX in R|Unità 1 - Fondamenti del Linguaggio R]] 595z03mzydxr77d75ucb0lp33uv7bm7 502134 502119 2026-10-04T18:33:40Z Gian BOT 27470 Bot: aggiunge l'indice 502134 wikitext text/x-wiki {{PenuX in R}} = PenuX in R: Unità 1 - Fondamenti del Linguaggio R = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Comprendere i tipi di dati di base in R * Lavorare con variabili e funzioni * Utilizzare vettori, matrici e data frame * Scrivere cicli e condizionali * Creare le tue funzioni * Leggere e scrivere file == 1.1 Installazione e Configurazione == === Installare R === <syntaxhighlight lang="bash"> # Ubuntu/Debian sudo apt-get install r-base # macOS brew install r # Windows # Scarica da: https://cran.r-project.org/bin/windows/base/ </syntaxhighlight> === RStudio (IDE Consigliata) === <syntaxhighlight lang="bash"> # Scarica da: https://rstudio.com/products/rstudio/download/ </syntaxhighlight> == 1.2 Tipi di Dati di Base == === Vettori === <syntaxhighlight lang="r"> # Vettore numerico age <- c(25, 30, 35, 40, 45) print(age) # Vettore di testo names <- c("Alice", "Bob", "Carlo", "Diana", "Enrico") print(names) # Vettore logico is_sick <- c(TRUE, FALSE, TRUE, FALSE, TRUE) print(is_sick) # Verificare il tipo class(age) class(names) class(is_sick) # Lunghezza del vettore length(age) # Accesso agli elementi age[1] # Primo elemento age[c(1, 3)] # Elementi 1 e 3 age[age > 30] # Tutti gli elementi > 30 </syntaxhighlight> === Matrici === <syntaxhighlight lang="r"> # Creare una matrice matrix_data <- matrix(1:12, nrow = 3, ncol = 4) print(matrix_data) # Matrice con nomi di righe e colonne data <- matrix( c(65, 72, 58, 81, 92, 76), nrow = 3, ncol = 2, dimnames = list( c("Paziente_1", "Paziente_2", "Paziente_3"), c("Pressione_Sistolica", "Temperatura") ) ) print(data) # Accesso agli elementi data[1, 1] # Riga 1, Colonna 1 data[1, ] # Intera riga 1 data[, 1] # Intera colonna 1 </syntaxhighlight> === Data Frames === <syntaxhighlight lang="r"> # Creare un data frame patients <- data.frame( patient_id = 1:5, name = c("Alice", "Bob", "Carlo", "Diana", "Enrico"), age = c(25, 30, 35, 40, 45), systolic_bp = c(120, 130, 140, 125, 135) ) print(patients) # Accesso alle colonne patients$age patients[["name"]] patients[, "age"] # Accesso alle righe patients[1, ] # Prima riga patients[1:3, ] # Righe 1-3 # Informazioni sul data frame nrow(patients) # Numero di righe ncol(patients) # Numero di colonne head(patients) # Primo 6 righe str(patients) # Struttura summary(patients) # Statistiche </syntaxhighlight> == 1.3 Operazioni di Base == === Operazioni Aritmetiche === <syntaxhighlight lang="r"> # Operazioni aritmetiche 5 + 3 # Addizione 10 - 2 # Sottrazione 4 * 5 # Moltiplicazione 20 / 4 # Divisione 2 ^ 3 # Potenza 10 %% 3 # Resto # Operazioni su vettori vec1 <- c(1, 2, 3, 4, 5) vec2 <- c(2, 2, 2, 2, 2) vec1 + vec2 vec1 * vec2 sqrt(vec1) # Radice quadrata log(vec1) # Logaritmo naturale exp(vec1) # e elevato a potenza </syntaxhighlight> === Operazioni Logiche === <syntaxhighlight lang="r"> # Confronti 5 > 3 # Maggiore di 10 <= 10 # Minore o uguale 8 == 8 # Uguale 5 != 3 # Non uguale # Logica booleana TRUE & FALSE # AND TRUE | FALSE # OR !TRUE # NOT # Su vettori age <- c(25, 30, 35, 40, 45) age > 30 age >= 35 & age < 45 !(age == 30) </syntaxhighlight> == 1.4 Funzioni == === Funzioni Integrate === <syntaxhighlight lang="r"> # Statistiche di base numbers <- c(1, 2, 3, 4, 5) mean(numbers) # Media median(numbers) # Mediana sd(numbers) # Deviazione standard var(numbers) # Varianza min(numbers) # Minimo max(numbers) # Massimo sum(numbers) # Somma prod(numbers) # Prodotto length(numbers) # Lunghezza # Funzioni su testo text <- "Hello World" nchar(text) # Numero di caratteri toupper(text) # Maiuscole tolower(text) # Minuscole substr(text, 1, 5) # Sottostringa paste("Hello", "World") # Concatenazione </syntaxhighlight> === Creare Funzioni Personalizzate === <syntaxhighlight lang="r"> # Funzione semplice greet <- function(name) { message <- paste("Ciao", name) return(message) } greet("Natanele") # Funzione con parametri di default calculate_bmi <- function(weight, height = 1.70) { bmi <- weight / (height ^ 2) return(bmi) } calculate_bmi(70) # height = 1.70 (default) calculate_bmi(70, 1.80) # Funzione che ritorna multipli valori get_statistics <- function(data) { mean_val <- mean(data) sd_val <- sd(data) return(list(mean = mean_val, sd = sd_val)) } stats <- get_statistics(c(1, 2, 3, 4, 5)) stats$mean stats$sd </syntaxhighlight> == 1.5 Cicli e Condizionali == === if-else === <syntaxhighlight lang="r"> # if semplice age <- 25 if (age >= 18) { print("Maggiorenne") } else { print("Minorenne") } # if-else if-else diagnosis <- "Healthy" if (diagnosis == "Healthy") { print("Sei sano") } else if (diagnosis == "Pancreatitis") { print("Pancreatite acuta") } else if (diagnosis == "Sepsis") { print("Sepsi") } else { print("Diagnosi sconosciuta") } # ifelse vettoriale age <- c(20, 30, 40, 50, 60) category <- ifelse(age > 40, "Anziano", "Giovane") print(category) </syntaxhighlight> === Cicli for === <syntaxhighlight lang="r"> # Ciclo for di base for (i in 1:5) { print(paste("Iterazione", i)) } # Ciclo su un vettore names <- c("Alice", "Bob", "Carlo") for (name in names) { print(paste("Ciao", name)) } # Ciclo con break e next for (i in 1:10) { if (i == 3) { next # Salta questa iterazione } if (i == 7) { break # Esci dal ciclo } print(i) } </syntaxhighlight> === Cicli while === <syntaxhighlight lang="r"> # Ciclo while count <- 0 while (count < 5) { print(paste("Count:", count)) count <- count + 1 } # Ciclo con condizione complessa x <- 10 while (x > 0 & x < 20) { print(x) x <- x - 2 } </syntaxhighlight> == 1.6 Lavorare con i Pacchetti == === Installazione e Caricamento === <syntaxhighlight lang="r"> # Installare un pacchetto install.packages("tidyverse") install.packages("ggplot2") # Caricare un pacchetto library(tidyverse) library(ggplot2) # Controllare i pacchetti installati installed.packages() # Rimuovere un pacchetto remove.packages("tidyverse") </syntaxhighlight> === Pacchetti Utili === <syntaxhighlight lang="r"> # tidyverse - Manipolazione dati conveniente library(tidyverse) # ggplot2 - Visualizzazione library(ggplot2) # caret - Machine learning library(caret) # dplyr - Manipolazione dati library(dplyr) # data.table - Tabelle dati veloci library(data.table) </syntaxhighlight> == 1.7 Leggere e Scrivere File == === File CSV === <syntaxhighlight lang="r"> # Leggere un file CSV data <- read.csv("data.csv") # Scrivere un file CSV write.csv(data, "output.csv", row.names = FALSE) # Con opzioni data <- read.csv("data.csv", sep = ",", header = TRUE, encoding = "UTF-8") </syntaxhighlight> === Formato RDS === <syntaxhighlight lang="r"> # Salvare un oggetto R patients <- data.frame(name = c("Alice", "Bob"), age = c(30, 40)) saveRDS(patients, "patients.rds") # Caricare un oggetto R loaded_data <- readRDS("patients.rds") </syntaxhighlight> == 1.8 Esercizi Pratici == === Esercizio 1: Lavorare con i Vettori === <syntaxhighlight lang="r"> # Crea un vettore di 10 età di pazienti ages <- c(45, 52, 38, 61, 55, 48, 72, 41, 58, 50) # Calcola la media mean(ages) # Quanti pazienti hanno più di 50 anni? sum(ages > 50) # Quali sono le età dei pazienti con più di 50 anni? ages[ages > 50] </syntaxhighlight> === Esercizio 2: Creare un Data Frame === <syntaxhighlight lang="r"> # Crea un data frame di pazienti patients <- data.frame( id = 1:5, name = c("Alice", "Bob", "Carlo", "Diana", "Enrico"), age = c(45, 52, 38, 61, 55), systolic_bp = c(140, 150, 120, 155, 145), diagnosis = c("Healthy", "Hypertension", "Healthy", "Pancreatitis", "Sepsis") ) # Stampa i dati print(patients) # Accedi alla colonna age patients$age # Filtra pazienti con diagnosi "Healthy" healthy_patients <- patients[patients$diagnosis == "Healthy", ] print(healthy_patients) </syntaxhighlight> === Esercizio 3: Creare una Funzione === <syntaxhighlight lang="r"> # Scrivi una funzione che calcola la MAP calculate_map <- function(systolic, diastolic) { map <- (systolic + 2 * diastolic) / 3 return(round(map, 2)) } # Testa la funzione calculate_map(140, 90) calculate_map(120, 80) # Usala su un data frame patients$MAP <- mapply(calculate_map, patients$systolic_bp, patients$diastolic_bp) print(patients) </syntaxhighlight> === Esercizio 4: Cicli e Funzioni === <syntaxhighlight lang="r"> # Scrivi un ciclo che stampa statistiche per ogni paziente for (i in 1:nrow(patients)) { cat("Paziente:", patients$name[i], "| Età:", patients$age[i], "| MAP:", patients$MAP[i], "\n") } # Scrivi una funzione che categorizza per età categorize_age <- function(age) { if (age < 40) { return("Giovane") } else if (age < 65) { return("Medio") } else { return("Anziano") } } # Applica a tutti i pazienti patients$age_category <- sapply(patients$age, categorize_age) print(patients) </syntaxhighlight> == 1.9 Verifica della Comprensione == * Qual è la differenza tra un vettore, una matrice e un data frame? * Come si crea una funzione in R? * Quale è la differenza tra un ciclo for e un ciclo while? * Come si legge un file CSV in R? * Come si usa il condizionale if-else? == 1.10 Soluzioni degli Esercizi == === Soluzione Esercizio 1 === <syntaxhighlight lang="r"> ages <- c(45, 52, 38, 61, 55, 48, 72, 41, 58, 50) mean_age <- mean(ages) # 52 count_over_50 <- sum(ages > 50) # 6 ages_over_50 <- ages[ages > 50] # 52, 61, 55, 72, 58, 50 </syntaxhighlight> === Soluzione Esercizio 2 === <syntaxhighlight lang="r"> # Vedi nell'esercizio stesso </syntaxhighlight> == Riepilogo dell'Unità 1 == Abbiamo trattato: * Tipi di dati: vettori, matrici, data frame * Operazioni di base e funzioni * Condizionali e cicli * Creazione di funzioni personalizzate * Utilizzo dei pacchetti * Lettura e scrittura di file * Esercizi pratici == Letture Consigliate == * [https://www.r-project.org/ R Project] * [https://rstudio.com/ RStudio] * [https://r4ds.had.co.nz/ R for Data Science] == Prosegui da Qui == Bene! Ora sei pronto per passare all'Unità 2: Preparazione dei Dati. == Il progetto PenuX == Repository PenuX: https://github.com/netanelcyber/penux Sito PenuX: https://penux.uk == Quiz == [[PenuX in R/Quiz Unità 1|Fai il quiz dell'Unità 1]] [[Categoria:PenuX in R|Unità 1 - Fondamenti del Linguaggio R]] esbnccuaxlqm0121v2cz1w2aylb30xy PenuX in R/Unità 2 - Preparazione e Caricamento dei Dati 0 61179 502056 502011 2026-10-04T14:45:09Z Hippias 18281 Hippias ha spostato la pagina [[PenuX in R: Unità 2 - Preparazione e Caricamento dei Dati]] a [[PenuX in R/Unità 2 - Preparazione e Caricamento dei Dati]] senza lasciare redirect: [[Aiuto:Convenzioni di nomenclatura|Convenzioni di nomenclatura]]: sottopagino correttamente 502011 wikitext text/x-wiki = PenuX in R: Unità 2 - Preparazione e Caricamento dei Dati = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Caricare dati clinici da file CSV, Excel e RDS * Ispezionare la struttura e la qualità di un dataset * Individuare e gestire i valori mancanti * Individuare e trattare i valori anomali (outlier) * Creare nuove variabili (feature engineering) * Codificare le variabili categoriche * Normalizzare e standardizzare le variabili numeriche * Produrre un breve rapporto sulla qualità dei dati '''Prerequisiti''': Unità 1 (Fondamenti del Linguaggio R). == 2.0 Preparazione == <syntaxhighlight lang="r"> install.packages(c("tidyverse", "readxl", "naniar", "caret")) library(tidyverse) library(readxl) library(naniar) library(caret) set.seed(42) </syntaxhighlight> === Dataset di esempio (sintetico) === Per gli esercizi creiamo un dataset clinico sintetico con difetti realistici: valori mancanti, outlier e categorie scritte in modi diversi. Non contiene dati di pazienti reali. <syntaxhighlight lang="r"> n <- 300 raw <- data.frame( patient_id = 1:n, age = round(rnorm(n, 58, 16)), sex = sample(c("M", "F", "m", "f", "Male", "Female"), n, replace = TRUE), weight_kg = round(rnorm(n, 75, 14), 1), height_cm = round(rnorm(n, 170, 10)), systolic_bp = round(rnorm(n, 128, 18)), heart_rate = round(rnorm(n, 84, 14)), creatinine = round(rlnorm(n, log(1.0), 0.35), 2), wbc = round(rnorm(n, 9, 3), 1), diagnosis = sample(c("Healthy", "Pancreatitis", "Sepsis"), n, replace = TRUE, prob = c(0.6, 0.25, 0.15)) ) # Introdurre difetti raw$creatinine[sample(n, 25)] <- NA raw$wbc[sample(n, 15)] <- NA raw$systolic_bp[sample(n, 10)] <- NA raw$heart_rate[c(5, 77)] <- c(900, -20) # errori di inserimento raw$weight_kg[12] <- 750 # virgola decimale mancante write.csv(raw, "pazienti_grezzi.csv", row.names = FALSE) </syntaxhighlight> == 2.1 Caricamento dei dati == === CSV === <syntaxhighlight lang="r"> dati <- read.csv("pazienti_grezzi.csv", stringsAsFactors = FALSE) # Alternativa tidyverse (più veloce, tipi più prevedibili) dati <- read_csv("pazienti_grezzi.csv") # CSV europeo: separatore ";" e virgola decimale # dati <- read.csv2("file_europeo.csv") # dati <- read_csv2("file_europeo.csv") </syntaxhighlight> === Excel === <syntaxhighlight lang="r"> # Elencare i fogli e leggerne uno excel_sheets("pazienti.xlsx") dati <- read_excel("pazienti.xlsx", sheet = 1) # Saltare righe di intestazione e specificare i valori mancanti dati <- read_excel("pazienti.xlsx", skip = 2, na = c("", "NA", "N/D", "-")) </syntaxhighlight> === RDS === <syntaxhighlight lang="r"> saveRDS(dati, "pazienti.rds") dati <- readRDS("pazienti.rds") </syntaxhighlight> '''Buona pratica''': non modificare mai il file originale. Conserva i dati grezzi in una cartella separata e salva i dati puliti in un nuovo file. == 2.2 Ispezione iniziale == <syntaxhighlight lang="r"> dim(dati) # righe e colonne str(dati) # tipi di variabili head(dati) summary(dati) # statistiche e conteggio NA # Valori mancanti per colonna colSums(is.na(dati)) # Percentuale di mancanti round(colMeans(is.na(dati)) * 100, 1) # Righe duplicate sum(duplicated(dati)) sum(duplicated(dati$patient_id)) # Valori distinti delle variabili categoriche table(dati$sex, useNA = "ifany") table(dati$diagnosis, useNA = "ifany") </syntaxhighlight> '''Domande''': * Quali colonne hanno valori mancanti e in che percentuale? * La variabile <code>sex</code> è coerente? == 2.3 Pulizia delle variabili categoriche == <syntaxhighlight lang="r"> dati <- dati %>% mutate( sex = case_when( sex %in% c("M", "m", "Male") ~ "M", sex %in% c("F", "f", "Female") ~ "F", TRUE ~ NA_character_ ), sex = factor(sex, levels = c("F", "M")), diagnosis = factor(diagnosis, levels = c("Healthy", "Pancreatitis", "Sepsis")) ) table(dati$sex) levels(dati$diagnosis) </syntaxhighlight> == 2.4 Valori anomali (outlier) == === Valori fisiologicamente impossibili === Prima di usare metodi statistici, applica i limiti clinici: un battito di 900 al minuto è un errore, non un outlier da "tenere". <syntaxhighlight lang="r"> limiti <- list( age = c(0, 110), weight_kg = c(20, 250), height_cm = c(100, 220), systolic_bp = c(50, 260), heart_rate = c(20, 220), creatinine = c(0.1, 15), wbc = c(0.5, 100) ) for (v in names(limiti)) { fuori <- which(dati[[v]] < limiti[[v]][1] | dati[[v]] > limiti[[v]][2]) if (length(fuori) > 0) { cat(v, ": ", length(fuori), " valori fuori intervallo (righe ", paste(fuori, collapse = ", "), ")\n", sep = "") dati[[v]][fuori] <- NA # trasformare in mancanti } } </syntaxhighlight> === Metodo dell'IQR === <syntaxhighlight lang="r"> rileva_outlier_iqr <- function(x, k = 1.5) { q <- quantile(x, c(0.25, 0.75), na.rm = TRUE) iqr <- q[2] - q[1] x < (q[1] - k * iqr) | x > (q[2] + k * iqr) } out_creat <- rileva_outlier_iqr(dati$creatinine) sum(out_creat, na.rm = TRUE) boxplot(dati$creatinine, main = "Creatinina", horizontal = TRUE) </syntaxhighlight> '''Attenzione''': in medicina un valore estremo può essere clinicamente reale (per esempio creatinina molto alta in insufficienza renale). Non eliminare automaticamente gli outlier statistici: verifica sempre se sono errori o casi veri. == 2.5 Valori mancanti == === Esplorare lo schema dei mancanti === <syntaxhighlight lang="r"> vis_miss(dati) # mappa dei mancanti gg_miss_var(dati) # mancanti per variabile miss_var_summary(dati) </syntaxhighlight> Tipi di dati mancanti: * '''MCAR''': mancano in modo completamente casuale * '''MAR''': la mancanza dipende da altre variabili osservate * '''MNAR''': la mancanza dipende dal valore stesso (per esempio un esame non richiesto perché il paziente sembrava sano) === Strategie === <syntaxhighlight lang="r"> # 1) Eliminare le righe con mancanti (solo se poche) dati_completi <- na.omit(dati) nrow(dati) - nrow(dati_completi) # 2) Imputazione con la mediana (robusta agli outlier) imputa_mediana <- function(x) { x[is.na(x)] <- median(x, na.rm = TRUE) x } dati_imp <- dati %>% mutate(across(where(is.numeric), imputa_mediana)) # 3) Aggiungere un indicatore di "mancante" prima di imputare dati_ind <- dati %>% mutate(creatinine_mancante = as.integer(is.na(creatinine))) # 4) Imputazione k-nearest neighbors con caret pre <- preProcess(dati %>% select(where(is.numeric), -patient_id), method = "knnImpute") dati_knn <- predict(pre, dati %>% select(where(is.numeric), -patient_id)) </syntaxhighlight> '''Nota importante''': <code>knnImpute</code> centra e scala le variabili. Inoltre, ogni parametro di imputazione (mediane, medie) va calcolato '''solo sul training set''' e poi applicato al test set, per evitare la fuga di informazioni (data leakage). == 2.6 Feature engineering == <syntaxhighlight lang="r"> dati_imp <- dati_imp %>% mutate( # Indice di massa corporea bmi = weight_kg / (height_cm / 100)^2, # Categoria BMI bmi_cat = cut(bmi, breaks = c(0, 18.5, 25, 30, Inf), labels = c("Sottopeso", "Normale", "Sovrappeso", "Obeso"), right = FALSE), # Fasce d'età age_group = cut(age, breaks = c(0, 40, 65, Inf), labels = c("<40", "40-64", "65+"), right = FALSE), # Creatinina elevata high_creatinine = creatinine > 1.3, # Rapporto utile in clinica: shock index = FC / PAS shock_index = heart_rate / systolic_bp ) summary(dati_imp %>% select(bmi, shock_index)) table(dati_imp$bmi_cat) </syntaxhighlight> == 2.7 Codifica delle variabili categoriche == <syntaxhighlight lang="r"> # One-hot encoding con caret dummy <- dummyVars(~ sex + age_group, data = dati_imp) codificate <- predict(dummy, newdata = dati_imp) head(codificate) # Combinare con le variabili numeriche dati_modello <- cbind( dati_imp %>% select(where(is.numeric)), as.data.frame(codificate), diagnosis = dati_imp$diagnosis ) # Per un esito binario (sepsi sì/no) dati_modello$sepsis <- factor(ifelse(dati_modello$diagnosis == "Sepsis", "Si", "No"), levels = c("No", "Si")) </syntaxhighlight> '''Suggerimento''': molte funzioni di R (<code>glm</code>, <code>randomForest</code>, <code>train</code>) accettano direttamente i fattori e creano da sole le variabili dummy. == 2.8 Normalizzazione e standardizzazione == <syntaxhighlight lang="r"> numeriche <- c("age", "weight_kg", "systolic_bp", "heart_rate", "creatinine", "wbc", "bmi") # Standardizzazione (z-score): media 0, deviazione standard 1 z <- scale(dati_imp[, numeriche]) # Normalizzazione min-max: valori in [0, 1] min_max <- function(x) (x - min(x)) / (max(x) - min(x)) mm <- as.data.frame(lapply(dati_imp[, numeriche], min_max)) # Con caret (apprende i parametri dal training e li riapplica al test) idx <- createDataPartition(dati_imp$diagnosis, p = 0.7, list = FALSE) train <- dati_imp[idx, ] test <- dati_imp[-idx, ] pp <- preProcess(train[, numeriche], method = c("center", "scale")) train_scalato <- predict(pp, train[, numeriche]) test_scalato <- predict(pp, test[, numeriche]) # usa media e sd del training </syntaxhighlight> '''Quando serve''': kNN, SVM, k-means, regressione penalizzata e reti neurali sono sensibili alla scala. Alberi e Random Forest no. == 2.9 Rapporto sulla qualità dei dati == <syntaxhighlight lang="r"> rapporto_qualita <- function(df) { data.frame( variabile = names(df), tipo = sapply(df, function(x) class(x)[1]), mancanti = sapply(df, function(x) sum(is.na(x))), pct_manc = round(sapply(df, function(x) mean(is.na(x))) * 100, 1), distinti = sapply(df, function(x) length(unique(x))), row.names = NULL ) } rapporto_qualita(dati) rapporto_qualita(dati_imp) </syntaxhighlight> == 2.10 Esercizi pratici == === Esercizio 1: Ispezione === Carica <code>pazienti_grezzi.csv</code> e rispondi: * Quante righe e colonne ha? * Quale colonna ha più valori mancanti? * Quali valori distinti contiene <code>sex</code>? <syntaxhighlight lang="r"> dati <- read.csv("pazienti_grezzi.csv", stringsAsFactors = FALSE) dim(dati) colSums(is.na(dati)) table(dati$sex) </syntaxhighlight> === Esercizio 2: Pulizia === Uniforma <code>sex</code> in "F"/"M" e trasforma in <code>NA</code> la frequenza cardiaca fuori dall'intervallo 20-220. === Esercizio 3: Imputazione === Imputa la creatinina con la mediana '''per diagnosi''' (non con la mediana globale) e confronta il risultato con l'imputazione globale. <syntaxhighlight lang="r"> dati <- dati %>% group_by(diagnosis) %>% mutate(creatinine = ifelse(is.na(creatinine), median(creatinine, na.rm = TRUE), creatinine)) %>% ungroup() </syntaxhighlight> === Esercizio 4: Nuove variabili === Crea BMI, shock index e una variabile binaria <code>tachicardia</code> (frequenza cardiaca &gt; 100). === Esercizio 5: Divisione senza fuga di informazioni === Dividi i dati in training (70%) e test (30%). Calcola media e deviazione standard '''solo sul training''', standardizza entrambi i set e verifica che la media del test '''non''' sia esattamente 0. == 2.11 Soluzioni == === Esercizio 1 === Il dataset ha 300 righe e 10 colonne. La creatinina ha 25 valori mancanti (la più alta), seguita da <code>wbc</code> (15) e <code>systolic_bp</code> (10). La colonna <code>sex</code> contiene sei varianti: M, F, m, f, Male, Female. === Esercizio 2 === <syntaxhighlight lang="r"> dati$sex <- ifelse(toupper(substr(dati$sex, 1, 1)) == "M", "M", "F") dati$heart_rate[dati$heart_rate < 20 | dati$heart_rate > 220] <- NA sum(is.na(dati$heart_rate)) # 2 (i valori 900 e -20) </syntaxhighlight> === Esercizio 3 === L'imputazione per gruppo conserva meglio le differenze tra diagnosi. Con dati reali la creatinina è tipicamente più alta nei pazienti con sepsi, quindi la mediana globale la sottostimerebbe in quel gruppo. Attenzione: l'esito (diagnosi) non deve essere usato per imputare quando il modello dovrà predirlo su nuovi pazienti, perché in produzione la diagnosi non è nota. Questo esercizio serve solo a mostrare l'effetto; nel flusso predittivo si imputa con variabili disponibili al momento della predizione. === Esercizio 4 === <syntaxhighlight lang="r"> dati <- dati %>% mutate(bmi = weight_kg / (height_cm / 100)^2, shock_index = heart_rate / systolic_bp, tachicardia = heart_rate > 100) </syntaxhighlight> === Esercizio 5 === <syntaxhighlight lang="r"> idx <- createDataPartition(dati$diagnosis, p = 0.7, list = FALSE) train <- dati[idx, ] test <- dati[-idx, ] mu <- mean(train$wbc, na.rm = TRUE) s <- sd(train$wbc, na.rm = TRUE) train$wbc_z <- (train$wbc - mu) / s test$wbc_z <- (test$wbc - mu) / s mean(train$wbc_z, na.rm = TRUE) # 0 mean(test$wbc_z, na.rm = TRUE) # vicino a 0, ma non esattamente 0 </syntaxhighlight> La media del test non è 0 perché usa i parametri del training: è il comportamento corretto, perché in produzione i nuovi pazienti verranno standardizzati con i parametri appresi in fase di addestramento. == 2.12 Verifica della comprensione == * Perché non si deve modificare il file dei dati grezzi? * Qual è la differenza tra un valore impossibile e un outlier statistico? * Quando l'eliminazione delle righe con valori mancanti è rischiosa? * Che cos'è la fuga di informazioni (data leakage) e come si evita nella preparazione dei dati? * Perché Random Forest non richiede la standardizzazione, mentre kNN sì? * Che differenza c'è tra MCAR, MAR e MNAR? == Avvertenza == I dati di questa unità sono sintetici e a scopo didattico. Con dati clinici reali rispetta sempre le norme sulla privacy (anonimizzazione e GDPR) e consulta un esperto clinico per decidere come trattare valori anomali e mancanti. == Riepilogo dell'Unità 2 == Abbiamo trattato: * Caricamento da CSV, Excel e RDS * Ispezione di struttura e qualità * Pulizia delle variabili categoriche * Valori impossibili e outlier * Strategie per i valori mancanti * Feature engineering clinico (BMI, shock index) * Codifica, normalizzazione e standardizzazione * Prevenzione della fuga di informazioni * Rapporto sulla qualità dei dati == Letture Consigliate == * [https://r4ds.hadley.nz/ R for Data Science] * [https://topepo.github.io/caret/pre-processing.html Pre-processing con caret] * [https://naniar.njtierney.com/ Pacchetto naniar per i valori mancanti] == Prosegui da Qui == Ora i dati sono puliti: passa all'Unità 3, Analisi Esplorativa dei Dati. == Il progetto PenuX == Repository PenuX: https://github.com/netanelcyber/penux Sito PenuX: https://penux.uk == Quiz == [[PenuX in R: Quiz Unità 2|Fai il quiz dell'Unità 2]] fgcmhioztxv8jxvwna6higs4tlg17nz 502105 502056 2026-10-04T18:21:45Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502105 wikitext text/x-wiki = PenuX in R: Unità 2 - Preparazione e Caricamento dei Dati = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Caricare dati clinici da file CSV, Excel e RDS * Ispezionare la struttura e la qualità di un dataset * Individuare e gestire i valori mancanti * Individuare e trattare i valori anomali (outlier) * Creare nuove variabili (feature engineering) * Codificare le variabili categoriche * Normalizzare e standardizzare le variabili numeriche * Produrre un breve rapporto sulla qualità dei dati '''Prerequisiti''': Unità 1 (Fondamenti del Linguaggio R). == 2.0 Preparazione == <syntaxhighlight lang="r"> install.packages(c("tidyverse", "readxl", "naniar", "caret")) library(tidyverse) library(readxl) library(naniar) library(caret) set.seed(42) </syntaxhighlight> === Dataset di esempio (sintetico) === Per gli esercizi creiamo un dataset clinico sintetico con difetti realistici: valori mancanti, outlier e categorie scritte in modi diversi. Non contiene dati di pazienti reali. <syntaxhighlight lang="r"> n <- 300 raw <- data.frame( patient_id = 1:n, age = round(rnorm(n, 58, 16)), sex = sample(c("M", "F", "m", "f", "Male", "Female"), n, replace = TRUE), weight_kg = round(rnorm(n, 75, 14), 1), height_cm = round(rnorm(n, 170, 10)), systolic_bp = round(rnorm(n, 128, 18)), heart_rate = round(rnorm(n, 84, 14)), creatinine = round(rlnorm(n, log(1.0), 0.35), 2), wbc = round(rnorm(n, 9, 3), 1), diagnosis = sample(c("Healthy", "Pancreatitis", "Sepsis"), n, replace = TRUE, prob = c(0.6, 0.25, 0.15)) ) # Introdurre difetti raw$creatinine[sample(n, 25)] <- NA raw$wbc[sample(n, 15)] <- NA raw$systolic_bp[sample(n, 10)] <- NA raw$heart_rate[c(5, 77)] <- c(900, -20) # errori di inserimento raw$weight_kg[12] <- 750 # virgola decimale mancante write.csv(raw, "pazienti_grezzi.csv", row.names = FALSE) </syntaxhighlight> == 2.1 Caricamento dei dati == === CSV === <syntaxhighlight lang="r"> dati <- read.csv("pazienti_grezzi.csv", stringsAsFactors = FALSE) # Alternativa tidyverse (più veloce, tipi più prevedibili) dati <- read_csv("pazienti_grezzi.csv") # CSV europeo: separatore ";" e virgola decimale # dati <- read.csv2("file_europeo.csv") # dati <- read_csv2("file_europeo.csv") </syntaxhighlight> === Excel === <syntaxhighlight lang="r"> # Elencare i fogli e leggerne uno excel_sheets("pazienti.xlsx") dati <- read_excel("pazienti.xlsx", sheet = 1) # Saltare righe di intestazione e specificare i valori mancanti dati <- read_excel("pazienti.xlsx", skip = 2, na = c("", "NA", "N/D", "-")) </syntaxhighlight> === RDS === <syntaxhighlight lang="r"> saveRDS(dati, "pazienti.rds") dati <- readRDS("pazienti.rds") </syntaxhighlight> '''Buona pratica''': non modificare mai il file originale. Conserva i dati grezzi in una cartella separata e salva i dati puliti in un nuovo file. == 2.2 Ispezione iniziale == <syntaxhighlight lang="r"> dim(dati) # righe e colonne str(dati) # tipi di variabili head(dati) summary(dati) # statistiche e conteggio NA # Valori mancanti per colonna colSums(is.na(dati)) # Percentuale di mancanti round(colMeans(is.na(dati)) * 100, 1) # Righe duplicate sum(duplicated(dati)) sum(duplicated(dati$patient_id)) # Valori distinti delle variabili categoriche table(dati$sex, useNA = "ifany") table(dati$diagnosis, useNA = "ifany") </syntaxhighlight> '''Domande''': * Quali colonne hanno valori mancanti e in che percentuale? * La variabile <code>sex</code> è coerente? == 2.3 Pulizia delle variabili categoriche == <syntaxhighlight lang="r"> dati <- dati %>% mutate( sex = case_when( sex %in% c("M", "m", "Male") ~ "M", sex %in% c("F", "f", "Female") ~ "F", TRUE ~ NA_character_ ), sex = factor(sex, levels = c("F", "M")), diagnosis = factor(diagnosis, levels = c("Healthy", "Pancreatitis", "Sepsis")) ) table(dati$sex) levels(dati$diagnosis) </syntaxhighlight> == 2.4 Valori anomali (outlier) == === Valori fisiologicamente impossibili === Prima di usare metodi statistici, applica i limiti clinici: un battito di 900 al minuto è un errore, non un outlier da "tenere". <syntaxhighlight lang="r"> limiti <- list( age = c(0, 110), weight_kg = c(20, 250), height_cm = c(100, 220), systolic_bp = c(50, 260), heart_rate = c(20, 220), creatinine = c(0.1, 15), wbc = c(0.5, 100) ) for (v in names(limiti)) { fuori <- which(dati[[v]] < limiti[[v]][1] | dati[[v]] > limiti[[v]][2]) if (length(fuori) > 0) { cat(v, ": ", length(fuori), " valori fuori intervallo (righe ", paste(fuori, collapse = ", "), ")\n", sep = "") dati[[v]][fuori] <- NA # trasformare in mancanti } } </syntaxhighlight> === Metodo dell'IQR === <syntaxhighlight lang="r"> rileva_outlier_iqr <- function(x, k = 1.5) { q <- quantile(x, c(0.25, 0.75), na.rm = TRUE) iqr <- q[2] - q[1] x < (q[1] - k * iqr) | x > (q[2] + k * iqr) } out_creat <- rileva_outlier_iqr(dati$creatinine) sum(out_creat, na.rm = TRUE) boxplot(dati$creatinine, main = "Creatinina", horizontal = TRUE) </syntaxhighlight> '''Attenzione''': in medicina un valore estremo può essere clinicamente reale (per esempio creatinina molto alta in insufficienza renale). Non eliminare automaticamente gli outlier statistici: verifica sempre se sono errori o casi veri. == 2.5 Valori mancanti == === Esplorare lo schema dei mancanti === <syntaxhighlight lang="r"> vis_miss(dati) # mappa dei mancanti gg_miss_var(dati) # mancanti per variabile miss_var_summary(dati) </syntaxhighlight> Tipi di dati mancanti: * '''MCAR''': mancano in modo completamente casuale * '''MAR''': la mancanza dipende da altre variabili osservate * '''MNAR''': la mancanza dipende dal valore stesso (per esempio un esame non richiesto perché il paziente sembrava sano) === Strategie === <syntaxhighlight lang="r"> # 1) Eliminare le righe con mancanti (solo se poche) dati_completi <- na.omit(dati) nrow(dati) - nrow(dati_completi) # 2) Imputazione con la mediana (robusta agli outlier) imputa_mediana <- function(x) { x[is.na(x)] <- median(x, na.rm = TRUE) x } dati_imp <- dati %>% mutate(across(where(is.numeric), imputa_mediana)) # 3) Aggiungere un indicatore di "mancante" prima di imputare dati_ind <- dati %>% mutate(creatinine_mancante = as.integer(is.na(creatinine))) # 4) Imputazione k-nearest neighbors con caret pre <- preProcess(dati %>% select(where(is.numeric), -patient_id), method = "knnImpute") dati_knn <- predict(pre, dati %>% select(where(is.numeric), -patient_id)) </syntaxhighlight> '''Nota importante''': <code>knnImpute</code> centra e scala le variabili. Inoltre, ogni parametro di imputazione (mediane, medie) va calcolato '''solo sul training set''' e poi applicato al test set, per evitare la fuga di informazioni (data leakage). == 2.6 Feature engineering == <syntaxhighlight lang="r"> dati_imp <- dati_imp %>% mutate( # Indice di massa corporea bmi = weight_kg / (height_cm / 100)^2, # Categoria BMI bmi_cat = cut(bmi, breaks = c(0, 18.5, 25, 30, Inf), labels = c("Sottopeso", "Normale", "Sovrappeso", "Obeso"), right = FALSE), # Fasce d'età age_group = cut(age, breaks = c(0, 40, 65, Inf), labels = c("<40", "40-64", "65+"), right = FALSE), # Creatinina elevata high_creatinine = creatinine > 1.3, # Rapporto utile in clinica: shock index = FC / PAS shock_index = heart_rate / systolic_bp ) summary(dati_imp %>% select(bmi, shock_index)) table(dati_imp$bmi_cat) </syntaxhighlight> == 2.7 Codifica delle variabili categoriche == <syntaxhighlight lang="r"> # One-hot encoding con caret dummy <- dummyVars(~ sex + age_group, data = dati_imp) codificate <- predict(dummy, newdata = dati_imp) head(codificate) # Combinare con le variabili numeriche dati_modello <- cbind( dati_imp %>% select(where(is.numeric)), as.data.frame(codificate), diagnosis = dati_imp$diagnosis ) # Per un esito binario (sepsi sì/no) dati_modello$sepsis <- factor(ifelse(dati_modello$diagnosis == "Sepsis", "Si", "No"), levels = c("No", "Si")) </syntaxhighlight> '''Suggerimento''': molte funzioni di R (<code>glm</code>, <code>randomForest</code>, <code>train</code>) accettano direttamente i fattori e creano da sole le variabili dummy. == 2.8 Normalizzazione e standardizzazione == <syntaxhighlight lang="r"> numeriche <- c("age", "weight_kg", "systolic_bp", "heart_rate", "creatinine", "wbc", "bmi") # Standardizzazione (z-score): media 0, deviazione standard 1 z <- scale(dati_imp[, numeriche]) # Normalizzazione min-max: valori in [0, 1] min_max <- function(x) (x - min(x)) / (max(x) - min(x)) mm <- as.data.frame(lapply(dati_imp[, numeriche], min_max)) # Con caret (apprende i parametri dal training e li riapplica al test) idx <- createDataPartition(dati_imp$diagnosis, p = 0.7, list = FALSE) train <- dati_imp[idx, ] test <- dati_imp[-idx, ] pp <- preProcess(train[, numeriche], method = c("center", "scale")) train_scalato <- predict(pp, train[, numeriche]) test_scalato <- predict(pp, test[, numeriche]) # usa media e sd del training </syntaxhighlight> '''Quando serve''': kNN, SVM, k-means, regressione penalizzata e reti neurali sono sensibili alla scala. Alberi e Random Forest no. == 2.9 Rapporto sulla qualità dei dati == <syntaxhighlight lang="r"> rapporto_qualita <- function(df) { data.frame( variabile = names(df), tipo = sapply(df, function(x) class(x)[1]), mancanti = sapply(df, function(x) sum(is.na(x))), pct_manc = round(sapply(df, function(x) mean(is.na(x))) * 100, 1), distinti = sapply(df, function(x) length(unique(x))), row.names = NULL ) } rapporto_qualita(dati) rapporto_qualita(dati_imp) </syntaxhighlight> == 2.10 Esercizi pratici == === Esercizio 1: Ispezione === Carica <code>pazienti_grezzi.csv</code> e rispondi: * Quante righe e colonne ha? * Quale colonna ha più valori mancanti? * Quali valori distinti contiene <code>sex</code>? <syntaxhighlight lang="r"> dati <- read.csv("pazienti_grezzi.csv", stringsAsFactors = FALSE) dim(dati) colSums(is.na(dati)) table(dati$sex) </syntaxhighlight> === Esercizio 2: Pulizia === Uniforma <code>sex</code> in "F"/"M" e trasforma in <code>NA</code> la frequenza cardiaca fuori dall'intervallo 20-220. === Esercizio 3: Imputazione === Imputa la creatinina con la mediana '''per diagnosi''' (non con la mediana globale) e confronta il risultato con l'imputazione globale. <syntaxhighlight lang="r"> dati <- dati %>% group_by(diagnosis) %>% mutate(creatinine = ifelse(is.na(creatinine), median(creatinine, na.rm = TRUE), creatinine)) %>% ungroup() </syntaxhighlight> === Esercizio 4: Nuove variabili === Crea BMI, shock index e una variabile binaria <code>tachicardia</code> (frequenza cardiaca &gt; 100). === Esercizio 5: Divisione senza fuga di informazioni === Dividi i dati in training (70%) e test (30%). Calcola media e deviazione standard '''solo sul training''', standardizza entrambi i set e verifica che la media del test '''non''' sia esattamente 0. == 2.11 Soluzioni == === Esercizio 1 === Il dataset ha 300 righe e 10 colonne. La creatinina ha 25 valori mancanti (la più alta), seguita da <code>wbc</code> (15) e <code>systolic_bp</code> (10). La colonna <code>sex</code> contiene sei varianti: M, F, m, f, Male, Female. === Esercizio 2 === <syntaxhighlight lang="r"> dati$sex <- ifelse(toupper(substr(dati$sex, 1, 1)) == "M", "M", "F") dati$heart_rate[dati$heart_rate < 20 | dati$heart_rate > 220] <- NA sum(is.na(dati$heart_rate)) # 2 (i valori 900 e -20) </syntaxhighlight> === Esercizio 3 === L'imputazione per gruppo conserva meglio le differenze tra diagnosi. Con dati reali la creatinina è tipicamente più alta nei pazienti con sepsi, quindi la mediana globale la sottostimerebbe in quel gruppo. Attenzione: l'esito (diagnosi) non deve essere usato per imputare quando il modello dovrà predirlo su nuovi pazienti, perché in produzione la diagnosi non è nota. Questo esercizio serve solo a mostrare l'effetto; nel flusso predittivo si imputa con variabili disponibili al momento della predizione. === Esercizio 4 === <syntaxhighlight lang="r"> dati <- dati %>% mutate(bmi = weight_kg / (height_cm / 100)^2, shock_index = heart_rate / systolic_bp, tachicardia = heart_rate > 100) </syntaxhighlight> === Esercizio 5 === <syntaxhighlight lang="r"> idx <- createDataPartition(dati$diagnosis, p = 0.7, list = FALSE) train <- dati[idx, ] test <- dati[-idx, ] mu <- mean(train$wbc, na.rm = TRUE) s <- sd(train$wbc, na.rm = TRUE) train$wbc_z <- (train$wbc - mu) / s test$wbc_z <- (test$wbc - mu) / s mean(train$wbc_z, na.rm = TRUE) # 0 mean(test$wbc_z, na.rm = TRUE) # vicino a 0, ma non esattamente 0 </syntaxhighlight> La media del test non è 0 perché usa i parametri del training: è il comportamento corretto, perché in produzione i nuovi pazienti verranno standardizzati con i parametri appresi in fase di addestramento. == 2.12 Verifica della comprensione == * Perché non si deve modificare il file dei dati grezzi? * Qual è la differenza tra un valore impossibile e un outlier statistico? * Quando l'eliminazione delle righe con valori mancanti è rischiosa? * Che cos'è la fuga di informazioni (data leakage) e come si evita nella preparazione dei dati? * Perché Random Forest non richiede la standardizzazione, mentre kNN sì? * Che differenza c'è tra MCAR, MAR e MNAR? == Avvertenza == I dati di questa unità sono sintetici e a scopo didattico. Con dati clinici reali rispetta sempre le norme sulla privacy (anonimizzazione e GDPR) e consulta un esperto clinico per decidere come trattare valori anomali e mancanti. == Riepilogo dell'Unità 2 == Abbiamo trattato: * Caricamento da CSV, Excel e RDS * Ispezione di struttura e qualità * Pulizia delle variabili categoriche * Valori impossibili e outlier * Strategie per i valori mancanti * Feature engineering clinico (BMI, shock index) * Codifica, normalizzazione e standardizzazione * Prevenzione della fuga di informazioni * Rapporto sulla qualità dei dati == Letture Consigliate == * [https://r4ds.hadley.nz/ R for Data Science] * [https://topepo.github.io/caret/pre-processing.html Pre-processing con caret] * [https://naniar.njtierney.com/ Pacchetto naniar per i valori mancanti] == Prosegui da Qui == Ora i dati sono puliti: passa all'Unità 3, Analisi Esplorativa dei Dati. == Il progetto PenuX == Repository PenuX: https://github.com/netanelcyber/penux Sito PenuX: https://penux.uk == Quiz == [[PenuX in R: Quiz Unità 2|Fai il quiz dell'Unità 2]] [[Categoria:PenuX in R|Unità 2 - Preparazione e Caricamento dei Dati]] oovdalrfgrjgb9mtjpmhsyt3vg1cv8s 502120 502105 2026-10-04T18:25:28Z Gian BOT 27470 bot: fix link 502120 wikitext text/x-wiki = PenuX in R: Unità 2 - Preparazione e Caricamento dei Dati = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Caricare dati clinici da file CSV, Excel e RDS * Ispezionare la struttura e la qualità di un dataset * Individuare e gestire i valori mancanti * Individuare e trattare i valori anomali (outlier) * Creare nuove variabili (feature engineering) * Codificare le variabili categoriche * Normalizzare e standardizzare le variabili numeriche * Produrre un breve rapporto sulla qualità dei dati '''Prerequisiti''': Unità 1 (Fondamenti del Linguaggio R). == 2.0 Preparazione == <syntaxhighlight lang="r"> install.packages(c("tidyverse", "readxl", "naniar", "caret")) library(tidyverse) library(readxl) library(naniar) library(caret) set.seed(42) </syntaxhighlight> === Dataset di esempio (sintetico) === Per gli esercizi creiamo un dataset clinico sintetico con difetti realistici: valori mancanti, outlier e categorie scritte in modi diversi. Non contiene dati di pazienti reali. <syntaxhighlight lang="r"> n <- 300 raw <- data.frame( patient_id = 1:n, age = round(rnorm(n, 58, 16)), sex = sample(c("M", "F", "m", "f", "Male", "Female"), n, replace = TRUE), weight_kg = round(rnorm(n, 75, 14), 1), height_cm = round(rnorm(n, 170, 10)), systolic_bp = round(rnorm(n, 128, 18)), heart_rate = round(rnorm(n, 84, 14)), creatinine = round(rlnorm(n, log(1.0), 0.35), 2), wbc = round(rnorm(n, 9, 3), 1), diagnosis = sample(c("Healthy", "Pancreatitis", "Sepsis"), n, replace = TRUE, prob = c(0.6, 0.25, 0.15)) ) # Introdurre difetti raw$creatinine[sample(n, 25)] <- NA raw$wbc[sample(n, 15)] <- NA raw$systolic_bp[sample(n, 10)] <- NA raw$heart_rate[c(5, 77)] <- c(900, -20) # errori di inserimento raw$weight_kg[12] <- 750 # virgola decimale mancante write.csv(raw, "pazienti_grezzi.csv", row.names = FALSE) </syntaxhighlight> == 2.1 Caricamento dei dati == === CSV === <syntaxhighlight lang="r"> dati <- read.csv("pazienti_grezzi.csv", stringsAsFactors = FALSE) # Alternativa tidyverse (più veloce, tipi più prevedibili) dati <- read_csv("pazienti_grezzi.csv") # CSV europeo: separatore ";" e virgola decimale # dati <- read.csv2("file_europeo.csv") # dati <- read_csv2("file_europeo.csv") </syntaxhighlight> === Excel === <syntaxhighlight lang="r"> # Elencare i fogli e leggerne uno excel_sheets("pazienti.xlsx") dati <- read_excel("pazienti.xlsx", sheet = 1) # Saltare righe di intestazione e specificare i valori mancanti dati <- read_excel("pazienti.xlsx", skip = 2, na = c("", "NA", "N/D", "-")) </syntaxhighlight> === RDS === <syntaxhighlight lang="r"> saveRDS(dati, "pazienti.rds") dati <- readRDS("pazienti.rds") </syntaxhighlight> '''Buona pratica''': non modificare mai il file originale. Conserva i dati grezzi in una cartella separata e salva i dati puliti in un nuovo file. == 2.2 Ispezione iniziale == <syntaxhighlight lang="r"> dim(dati) # righe e colonne str(dati) # tipi di variabili head(dati) summary(dati) # statistiche e conteggio NA # Valori mancanti per colonna colSums(is.na(dati)) # Percentuale di mancanti round(colMeans(is.na(dati)) * 100, 1) # Righe duplicate sum(duplicated(dati)) sum(duplicated(dati$patient_id)) # Valori distinti delle variabili categoriche table(dati$sex, useNA = "ifany") table(dati$diagnosis, useNA = "ifany") </syntaxhighlight> '''Domande''': * Quali colonne hanno valori mancanti e in che percentuale? * La variabile <code>sex</code> è coerente? == 2.3 Pulizia delle variabili categoriche == <syntaxhighlight lang="r"> dati <- dati %>% mutate( sex = case_when( sex %in% c("M", "m", "Male") ~ "M", sex %in% c("F", "f", "Female") ~ "F", TRUE ~ NA_character_ ), sex = factor(sex, levels = c("F", "M")), diagnosis = factor(diagnosis, levels = c("Healthy", "Pancreatitis", "Sepsis")) ) table(dati$sex) levels(dati$diagnosis) </syntaxhighlight> == 2.4 Valori anomali (outlier) == === Valori fisiologicamente impossibili === Prima di usare metodi statistici, applica i limiti clinici: un battito di 900 al minuto è un errore, non un outlier da "tenere". <syntaxhighlight lang="r"> limiti <- list( age = c(0, 110), weight_kg = c(20, 250), height_cm = c(100, 220), systolic_bp = c(50, 260), heart_rate = c(20, 220), creatinine = c(0.1, 15), wbc = c(0.5, 100) ) for (v in names(limiti)) { fuori <- which(dati[[v]] < limiti[[v]][1] | dati[[v]] > limiti[[v]][2]) if (length(fuori) > 0) { cat(v, ": ", length(fuori), " valori fuori intervallo (righe ", paste(fuori, collapse = ", "), ")\n", sep = "") dati[[v]][fuori] <- NA # trasformare in mancanti } } </syntaxhighlight> === Metodo dell'IQR === <syntaxhighlight lang="r"> rileva_outlier_iqr <- function(x, k = 1.5) { q <- quantile(x, c(0.25, 0.75), na.rm = TRUE) iqr <- q[2] - q[1] x < (q[1] - k * iqr) | x > (q[2] + k * iqr) } out_creat <- rileva_outlier_iqr(dati$creatinine) sum(out_creat, na.rm = TRUE) boxplot(dati$creatinine, main = "Creatinina", horizontal = TRUE) </syntaxhighlight> '''Attenzione''': in medicina un valore estremo può essere clinicamente reale (per esempio creatinina molto alta in insufficienza renale). Non eliminare automaticamente gli outlier statistici: verifica sempre se sono errori o casi veri. == 2.5 Valori mancanti == === Esplorare lo schema dei mancanti === <syntaxhighlight lang="r"> vis_miss(dati) # mappa dei mancanti gg_miss_var(dati) # mancanti per variabile miss_var_summary(dati) </syntaxhighlight> Tipi di dati mancanti: * '''MCAR''': mancano in modo completamente casuale * '''MAR''': la mancanza dipende da altre variabili osservate * '''MNAR''': la mancanza dipende dal valore stesso (per esempio un esame non richiesto perché il paziente sembrava sano) === Strategie === <syntaxhighlight lang="r"> # 1) Eliminare le righe con mancanti (solo se poche) dati_completi <- na.omit(dati) nrow(dati) - nrow(dati_completi) # 2) Imputazione con la mediana (robusta agli outlier) imputa_mediana <- function(x) { x[is.na(x)] <- median(x, na.rm = TRUE) x } dati_imp <- dati %>% mutate(across(where(is.numeric), imputa_mediana)) # 3) Aggiungere un indicatore di "mancante" prima di imputare dati_ind <- dati %>% mutate(creatinine_mancante = as.integer(is.na(creatinine))) # 4) Imputazione k-nearest neighbors con caret pre <- preProcess(dati %>% select(where(is.numeric), -patient_id), method = "knnImpute") dati_knn <- predict(pre, dati %>% select(where(is.numeric), -patient_id)) </syntaxhighlight> '''Nota importante''': <code>knnImpute</code> centra e scala le variabili. Inoltre, ogni parametro di imputazione (mediane, medie) va calcolato '''solo sul training set''' e poi applicato al test set, per evitare la fuga di informazioni (data leakage). == 2.6 Feature engineering == <syntaxhighlight lang="r"> dati_imp <- dati_imp %>% mutate( # Indice di massa corporea bmi = weight_kg / (height_cm / 100)^2, # Categoria BMI bmi_cat = cut(bmi, breaks = c(0, 18.5, 25, 30, Inf), labels = c("Sottopeso", "Normale", "Sovrappeso", "Obeso"), right = FALSE), # Fasce d'età age_group = cut(age, breaks = c(0, 40, 65, Inf), labels = c("<40", "40-64", "65+"), right = FALSE), # Creatinina elevata high_creatinine = creatinine > 1.3, # Rapporto utile in clinica: shock index = FC / PAS shock_index = heart_rate / systolic_bp ) summary(dati_imp %>% select(bmi, shock_index)) table(dati_imp$bmi_cat) </syntaxhighlight> == 2.7 Codifica delle variabili categoriche == <syntaxhighlight lang="r"> # One-hot encoding con caret dummy <- dummyVars(~ sex + age_group, data = dati_imp) codificate <- predict(dummy, newdata = dati_imp) head(codificate) # Combinare con le variabili numeriche dati_modello <- cbind( dati_imp %>% select(where(is.numeric)), as.data.frame(codificate), diagnosis = dati_imp$diagnosis ) # Per un esito binario (sepsi sì/no) dati_modello$sepsis <- factor(ifelse(dati_modello$diagnosis == "Sepsis", "Si", "No"), levels = c("No", "Si")) </syntaxhighlight> '''Suggerimento''': molte funzioni di R (<code>glm</code>, <code>randomForest</code>, <code>train</code>) accettano direttamente i fattori e creano da sole le variabili dummy. == 2.8 Normalizzazione e standardizzazione == <syntaxhighlight lang="r"> numeriche <- c("age", "weight_kg", "systolic_bp", "heart_rate", "creatinine", "wbc", "bmi") # Standardizzazione (z-score): media 0, deviazione standard 1 z <- scale(dati_imp[, numeriche]) # Normalizzazione min-max: valori in [0, 1] min_max <- function(x) (x - min(x)) / (max(x) - min(x)) mm <- as.data.frame(lapply(dati_imp[, numeriche], min_max)) # Con caret (apprende i parametri dal training e li riapplica al test) idx <- createDataPartition(dati_imp$diagnosis, p = 0.7, list = FALSE) train <- dati_imp[idx, ] test <- dati_imp[-idx, ] pp <- preProcess(train[, numeriche], method = c("center", "scale")) train_scalato <- predict(pp, train[, numeriche]) test_scalato <- predict(pp, test[, numeriche]) # usa media e sd del training </syntaxhighlight> '''Quando serve''': kNN, SVM, k-means, regressione penalizzata e reti neurali sono sensibili alla scala. Alberi e Random Forest no. == 2.9 Rapporto sulla qualità dei dati == <syntaxhighlight lang="r"> rapporto_qualita <- function(df) { data.frame( variabile = names(df), tipo = sapply(df, function(x) class(x)[1]), mancanti = sapply(df, function(x) sum(is.na(x))), pct_manc = round(sapply(df, function(x) mean(is.na(x))) * 100, 1), distinti = sapply(df, function(x) length(unique(x))), row.names = NULL ) } rapporto_qualita(dati) rapporto_qualita(dati_imp) </syntaxhighlight> == 2.10 Esercizi pratici == === Esercizio 1: Ispezione === Carica <code>pazienti_grezzi.csv</code> e rispondi: * Quante righe e colonne ha? * Quale colonna ha più valori mancanti? * Quali valori distinti contiene <code>sex</code>? <syntaxhighlight lang="r"> dati <- read.csv("pazienti_grezzi.csv", stringsAsFactors = FALSE) dim(dati) colSums(is.na(dati)) table(dati$sex) </syntaxhighlight> === Esercizio 2: Pulizia === Uniforma <code>sex</code> in "F"/"M" e trasforma in <code>NA</code> la frequenza cardiaca fuori dall'intervallo 20-220. === Esercizio 3: Imputazione === Imputa la creatinina con la mediana '''per diagnosi''' (non con la mediana globale) e confronta il risultato con l'imputazione globale. <syntaxhighlight lang="r"> dati <- dati %>% group_by(diagnosis) %>% mutate(creatinine = ifelse(is.na(creatinine), median(creatinine, na.rm = TRUE), creatinine)) %>% ungroup() </syntaxhighlight> === Esercizio 4: Nuove variabili === Crea BMI, shock index e una variabile binaria <code>tachicardia</code> (frequenza cardiaca &gt; 100). === Esercizio 5: Divisione senza fuga di informazioni === Dividi i dati in training (70%) e test (30%). Calcola media e deviazione standard '''solo sul training''', standardizza entrambi i set e verifica che la media del test '''non''' sia esattamente 0. == 2.11 Soluzioni == === Esercizio 1 === Il dataset ha 300 righe e 10 colonne. La creatinina ha 25 valori mancanti (la più alta), seguita da <code>wbc</code> (15) e <code>systolic_bp</code> (10). La colonna <code>sex</code> contiene sei varianti: M, F, m, f, Male, Female. === Esercizio 2 === <syntaxhighlight lang="r"> dati$sex <- ifelse(toupper(substr(dati$sex, 1, 1)) == "M", "M", "F") dati$heart_rate[dati$heart_rate < 20 | dati$heart_rate > 220] <- NA sum(is.na(dati$heart_rate)) # 2 (i valori 900 e -20) </syntaxhighlight> === Esercizio 3 === L'imputazione per gruppo conserva meglio le differenze tra diagnosi. Con dati reali la creatinina è tipicamente più alta nei pazienti con sepsi, quindi la mediana globale la sottostimerebbe in quel gruppo. Attenzione: l'esito (diagnosi) non deve essere usato per imputare quando il modello dovrà predirlo su nuovi pazienti, perché in produzione la diagnosi non è nota. Questo esercizio serve solo a mostrare l'effetto; nel flusso predittivo si imputa con variabili disponibili al momento della predizione. === Esercizio 4 === <syntaxhighlight lang="r"> dati <- dati %>% mutate(bmi = weight_kg / (height_cm / 100)^2, shock_index = heart_rate / systolic_bp, tachicardia = heart_rate > 100) </syntaxhighlight> === Esercizio 5 === <syntaxhighlight lang="r"> idx <- createDataPartition(dati$diagnosis, p = 0.7, list = FALSE) train <- dati[idx, ] test <- dati[-idx, ] mu <- mean(train$wbc, na.rm = TRUE) s <- sd(train$wbc, na.rm = TRUE) train$wbc_z <- (train$wbc - mu) / s test$wbc_z <- (test$wbc - mu) / s mean(train$wbc_z, na.rm = TRUE) # 0 mean(test$wbc_z, na.rm = TRUE) # vicino a 0, ma non esattamente 0 </syntaxhighlight> La media del test non è 0 perché usa i parametri del training: è il comportamento corretto, perché in produzione i nuovi pazienti verranno standardizzati con i parametri appresi in fase di addestramento. == 2.12 Verifica della comprensione == * Perché non si deve modificare il file dei dati grezzi? * Qual è la differenza tra un valore impossibile e un outlier statistico? * Quando l'eliminazione delle righe con valori mancanti è rischiosa? * Che cos'è la fuga di informazioni (data leakage) e come si evita nella preparazione dei dati? * Perché Random Forest non richiede la standardizzazione, mentre kNN sì? * Che differenza c'è tra MCAR, MAR e MNAR? == Avvertenza == I dati di questa unità sono sintetici e a scopo didattico. Con dati clinici reali rispetta sempre le norme sulla privacy (anonimizzazione e GDPR) e consulta un esperto clinico per decidere come trattare valori anomali e mancanti. == Riepilogo dell'Unità 2 == Abbiamo trattato: * Caricamento da CSV, Excel e RDS * Ispezione di struttura e qualità * Pulizia delle variabili categoriche * Valori impossibili e outlier * Strategie per i valori mancanti * Feature engineering clinico (BMI, shock index) * Codifica, normalizzazione e standardizzazione * Prevenzione della fuga di informazioni * Rapporto sulla qualità dei dati == Letture Consigliate == * [https://r4ds.hadley.nz/ R for Data Science] * [https://topepo.github.io/caret/pre-processing.html Pre-processing con caret] * [https://naniar.njtierney.com/ Pacchetto naniar per i valori mancanti] == Prosegui da Qui == Ora i dati sono puliti: passa all'Unità 3, Analisi Esplorativa dei Dati. == Il progetto PenuX == Repository PenuX: https://github.com/netanelcyber/penux Sito PenuX: https://penux.uk == Quiz == [[PenuX in R/Quiz Unità 2|Fai il quiz dell'Unità 2]] [[Categoria:PenuX in R|Unità 2 - Preparazione e Caricamento dei Dati]] 7oz0ii3d7xkr4z7oj61httqp73xqke9 502135 502120 2026-10-04T18:33:53Z Gian BOT 27470 Bot: aggiunge l'indice 502135 wikitext text/x-wiki {{PenuX in R}} = PenuX in R: Unità 2 - Preparazione e Caricamento dei Dati = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Caricare dati clinici da file CSV, Excel e RDS * Ispezionare la struttura e la qualità di un dataset * Individuare e gestire i valori mancanti * Individuare e trattare i valori anomali (outlier) * Creare nuove variabili (feature engineering) * Codificare le variabili categoriche * Normalizzare e standardizzare le variabili numeriche * Produrre un breve rapporto sulla qualità dei dati '''Prerequisiti''': Unità 1 (Fondamenti del Linguaggio R). == 2.0 Preparazione == <syntaxhighlight lang="r"> install.packages(c("tidyverse", "readxl", "naniar", "caret")) library(tidyverse) library(readxl) library(naniar) library(caret) set.seed(42) </syntaxhighlight> === Dataset di esempio (sintetico) === Per gli esercizi creiamo un dataset clinico sintetico con difetti realistici: valori mancanti, outlier e categorie scritte in modi diversi. Non contiene dati di pazienti reali. <syntaxhighlight lang="r"> n <- 300 raw <- data.frame( patient_id = 1:n, age = round(rnorm(n, 58, 16)), sex = sample(c("M", "F", "m", "f", "Male", "Female"), n, replace = TRUE), weight_kg = round(rnorm(n, 75, 14), 1), height_cm = round(rnorm(n, 170, 10)), systolic_bp = round(rnorm(n, 128, 18)), heart_rate = round(rnorm(n, 84, 14)), creatinine = round(rlnorm(n, log(1.0), 0.35), 2), wbc = round(rnorm(n, 9, 3), 1), diagnosis = sample(c("Healthy", "Pancreatitis", "Sepsis"), n, replace = TRUE, prob = c(0.6, 0.25, 0.15)) ) # Introdurre difetti raw$creatinine[sample(n, 25)] <- NA raw$wbc[sample(n, 15)] <- NA raw$systolic_bp[sample(n, 10)] <- NA raw$heart_rate[c(5, 77)] <- c(900, -20) # errori di inserimento raw$weight_kg[12] <- 750 # virgola decimale mancante write.csv(raw, "pazienti_grezzi.csv", row.names = FALSE) </syntaxhighlight> == 2.1 Caricamento dei dati == === CSV === <syntaxhighlight lang="r"> dati <- read.csv("pazienti_grezzi.csv", stringsAsFactors = FALSE) # Alternativa tidyverse (più veloce, tipi più prevedibili) dati <- read_csv("pazienti_grezzi.csv") # CSV europeo: separatore ";" e virgola decimale # dati <- read.csv2("file_europeo.csv") # dati <- read_csv2("file_europeo.csv") </syntaxhighlight> === Excel === <syntaxhighlight lang="r"> # Elencare i fogli e leggerne uno excel_sheets("pazienti.xlsx") dati <- read_excel("pazienti.xlsx", sheet = 1) # Saltare righe di intestazione e specificare i valori mancanti dati <- read_excel("pazienti.xlsx", skip = 2, na = c("", "NA", "N/D", "-")) </syntaxhighlight> === RDS === <syntaxhighlight lang="r"> saveRDS(dati, "pazienti.rds") dati <- readRDS("pazienti.rds") </syntaxhighlight> '''Buona pratica''': non modificare mai il file originale. Conserva i dati grezzi in una cartella separata e salva i dati puliti in un nuovo file. == 2.2 Ispezione iniziale == <syntaxhighlight lang="r"> dim(dati) # righe e colonne str(dati) # tipi di variabili head(dati) summary(dati) # statistiche e conteggio NA # Valori mancanti per colonna colSums(is.na(dati)) # Percentuale di mancanti round(colMeans(is.na(dati)) * 100, 1) # Righe duplicate sum(duplicated(dati)) sum(duplicated(dati$patient_id)) # Valori distinti delle variabili categoriche table(dati$sex, useNA = "ifany") table(dati$diagnosis, useNA = "ifany") </syntaxhighlight> '''Domande''': * Quali colonne hanno valori mancanti e in che percentuale? * La variabile <code>sex</code> è coerente? == 2.3 Pulizia delle variabili categoriche == <syntaxhighlight lang="r"> dati <- dati %>% mutate( sex = case_when( sex %in% c("M", "m", "Male") ~ "M", sex %in% c("F", "f", "Female") ~ "F", TRUE ~ NA_character_ ), sex = factor(sex, levels = c("F", "M")), diagnosis = factor(diagnosis, levels = c("Healthy", "Pancreatitis", "Sepsis")) ) table(dati$sex) levels(dati$diagnosis) </syntaxhighlight> == 2.4 Valori anomali (outlier) == === Valori fisiologicamente impossibili === Prima di usare metodi statistici, applica i limiti clinici: un battito di 900 al minuto è un errore, non un outlier da "tenere". <syntaxhighlight lang="r"> limiti <- list( age = c(0, 110), weight_kg = c(20, 250), height_cm = c(100, 220), systolic_bp = c(50, 260), heart_rate = c(20, 220), creatinine = c(0.1, 15), wbc = c(0.5, 100) ) for (v in names(limiti)) { fuori <- which(dati[[v]] < limiti[[v]][1] | dati[[v]] > limiti[[v]][2]) if (length(fuori) > 0) { cat(v, ": ", length(fuori), " valori fuori intervallo (righe ", paste(fuori, collapse = ", "), ")\n", sep = "") dati[[v]][fuori] <- NA # trasformare in mancanti } } </syntaxhighlight> === Metodo dell'IQR === <syntaxhighlight lang="r"> rileva_outlier_iqr <- function(x, k = 1.5) { q <- quantile(x, c(0.25, 0.75), na.rm = TRUE) iqr <- q[2] - q[1] x < (q[1] - k * iqr) | x > (q[2] + k * iqr) } out_creat <- rileva_outlier_iqr(dati$creatinine) sum(out_creat, na.rm = TRUE) boxplot(dati$creatinine, main = "Creatinina", horizontal = TRUE) </syntaxhighlight> '''Attenzione''': in medicina un valore estremo può essere clinicamente reale (per esempio creatinina molto alta in insufficienza renale). Non eliminare automaticamente gli outlier statistici: verifica sempre se sono errori o casi veri. == 2.5 Valori mancanti == === Esplorare lo schema dei mancanti === <syntaxhighlight lang="r"> vis_miss(dati) # mappa dei mancanti gg_miss_var(dati) # mancanti per variabile miss_var_summary(dati) </syntaxhighlight> Tipi di dati mancanti: * '''MCAR''': mancano in modo completamente casuale * '''MAR''': la mancanza dipende da altre variabili osservate * '''MNAR''': la mancanza dipende dal valore stesso (per esempio un esame non richiesto perché il paziente sembrava sano) === Strategie === <syntaxhighlight lang="r"> # 1) Eliminare le righe con mancanti (solo se poche) dati_completi <- na.omit(dati) nrow(dati) - nrow(dati_completi) # 2) Imputazione con la mediana (robusta agli outlier) imputa_mediana <- function(x) { x[is.na(x)] <- median(x, na.rm = TRUE) x } dati_imp <- dati %>% mutate(across(where(is.numeric), imputa_mediana)) # 3) Aggiungere un indicatore di "mancante" prima di imputare dati_ind <- dati %>% mutate(creatinine_mancante = as.integer(is.na(creatinine))) # 4) Imputazione k-nearest neighbors con caret pre <- preProcess(dati %>% select(where(is.numeric), -patient_id), method = "knnImpute") dati_knn <- predict(pre, dati %>% select(where(is.numeric), -patient_id)) </syntaxhighlight> '''Nota importante''': <code>knnImpute</code> centra e scala le variabili. Inoltre, ogni parametro di imputazione (mediane, medie) va calcolato '''solo sul training set''' e poi applicato al test set, per evitare la fuga di informazioni (data leakage). == 2.6 Feature engineering == <syntaxhighlight lang="r"> dati_imp <- dati_imp %>% mutate( # Indice di massa corporea bmi = weight_kg / (height_cm / 100)^2, # Categoria BMI bmi_cat = cut(bmi, breaks = c(0, 18.5, 25, 30, Inf), labels = c("Sottopeso", "Normale", "Sovrappeso", "Obeso"), right = FALSE), # Fasce d'età age_group = cut(age, breaks = c(0, 40, 65, Inf), labels = c("<40", "40-64", "65+"), right = FALSE), # Creatinina elevata high_creatinine = creatinine > 1.3, # Rapporto utile in clinica: shock index = FC / PAS shock_index = heart_rate / systolic_bp ) summary(dati_imp %>% select(bmi, shock_index)) table(dati_imp$bmi_cat) </syntaxhighlight> == 2.7 Codifica delle variabili categoriche == <syntaxhighlight lang="r"> # One-hot encoding con caret dummy <- dummyVars(~ sex + age_group, data = dati_imp) codificate <- predict(dummy, newdata = dati_imp) head(codificate) # Combinare con le variabili numeriche dati_modello <- cbind( dati_imp %>% select(where(is.numeric)), as.data.frame(codificate), diagnosis = dati_imp$diagnosis ) # Per un esito binario (sepsi sì/no) dati_modello$sepsis <- factor(ifelse(dati_modello$diagnosis == "Sepsis", "Si", "No"), levels = c("No", "Si")) </syntaxhighlight> '''Suggerimento''': molte funzioni di R (<code>glm</code>, <code>randomForest</code>, <code>train</code>) accettano direttamente i fattori e creano da sole le variabili dummy. == 2.8 Normalizzazione e standardizzazione == <syntaxhighlight lang="r"> numeriche <- c("age", "weight_kg", "systolic_bp", "heart_rate", "creatinine", "wbc", "bmi") # Standardizzazione (z-score): media 0, deviazione standard 1 z <- scale(dati_imp[, numeriche]) # Normalizzazione min-max: valori in [0, 1] min_max <- function(x) (x - min(x)) / (max(x) - min(x)) mm <- as.data.frame(lapply(dati_imp[, numeriche], min_max)) # Con caret (apprende i parametri dal training e li riapplica al test) idx <- createDataPartition(dati_imp$diagnosis, p = 0.7, list = FALSE) train <- dati_imp[idx, ] test <- dati_imp[-idx, ] pp <- preProcess(train[, numeriche], method = c("center", "scale")) train_scalato <- predict(pp, train[, numeriche]) test_scalato <- predict(pp, test[, numeriche]) # usa media e sd del training </syntaxhighlight> '''Quando serve''': kNN, SVM, k-means, regressione penalizzata e reti neurali sono sensibili alla scala. Alberi e Random Forest no. == 2.9 Rapporto sulla qualità dei dati == <syntaxhighlight lang="r"> rapporto_qualita <- function(df) { data.frame( variabile = names(df), tipo = sapply(df, function(x) class(x)[1]), mancanti = sapply(df, function(x) sum(is.na(x))), pct_manc = round(sapply(df, function(x) mean(is.na(x))) * 100, 1), distinti = sapply(df, function(x) length(unique(x))), row.names = NULL ) } rapporto_qualita(dati) rapporto_qualita(dati_imp) </syntaxhighlight> == 2.10 Esercizi pratici == === Esercizio 1: Ispezione === Carica <code>pazienti_grezzi.csv</code> e rispondi: * Quante righe e colonne ha? * Quale colonna ha più valori mancanti? * Quali valori distinti contiene <code>sex</code>? <syntaxhighlight lang="r"> dati <- read.csv("pazienti_grezzi.csv", stringsAsFactors = FALSE) dim(dati) colSums(is.na(dati)) table(dati$sex) </syntaxhighlight> === Esercizio 2: Pulizia === Uniforma <code>sex</code> in "F"/"M" e trasforma in <code>NA</code> la frequenza cardiaca fuori dall'intervallo 20-220. === Esercizio 3: Imputazione === Imputa la creatinina con la mediana '''per diagnosi''' (non con la mediana globale) e confronta il risultato con l'imputazione globale. <syntaxhighlight lang="r"> dati <- dati %>% group_by(diagnosis) %>% mutate(creatinine = ifelse(is.na(creatinine), median(creatinine, na.rm = TRUE), creatinine)) %>% ungroup() </syntaxhighlight> === Esercizio 4: Nuove variabili === Crea BMI, shock index e una variabile binaria <code>tachicardia</code> (frequenza cardiaca &gt; 100). === Esercizio 5: Divisione senza fuga di informazioni === Dividi i dati in training (70%) e test (30%). Calcola media e deviazione standard '''solo sul training''', standardizza entrambi i set e verifica che la media del test '''non''' sia esattamente 0. == 2.11 Soluzioni == === Esercizio 1 === Il dataset ha 300 righe e 10 colonne. La creatinina ha 25 valori mancanti (la più alta), seguita da <code>wbc</code> (15) e <code>systolic_bp</code> (10). La colonna <code>sex</code> contiene sei varianti: M, F, m, f, Male, Female. === Esercizio 2 === <syntaxhighlight lang="r"> dati$sex <- ifelse(toupper(substr(dati$sex, 1, 1)) == "M", "M", "F") dati$heart_rate[dati$heart_rate < 20 | dati$heart_rate > 220] <- NA sum(is.na(dati$heart_rate)) # 2 (i valori 900 e -20) </syntaxhighlight> === Esercizio 3 === L'imputazione per gruppo conserva meglio le differenze tra diagnosi. Con dati reali la creatinina è tipicamente più alta nei pazienti con sepsi, quindi la mediana globale la sottostimerebbe in quel gruppo. Attenzione: l'esito (diagnosi) non deve essere usato per imputare quando il modello dovrà predirlo su nuovi pazienti, perché in produzione la diagnosi non è nota. Questo esercizio serve solo a mostrare l'effetto; nel flusso predittivo si imputa con variabili disponibili al momento della predizione. === Esercizio 4 === <syntaxhighlight lang="r"> dati <- dati %>% mutate(bmi = weight_kg / (height_cm / 100)^2, shock_index = heart_rate / systolic_bp, tachicardia = heart_rate > 100) </syntaxhighlight> === Esercizio 5 === <syntaxhighlight lang="r"> idx <- createDataPartition(dati$diagnosis, p = 0.7, list = FALSE) train <- dati[idx, ] test <- dati[-idx, ] mu <- mean(train$wbc, na.rm = TRUE) s <- sd(train$wbc, na.rm = TRUE) train$wbc_z <- (train$wbc - mu) / s test$wbc_z <- (test$wbc - mu) / s mean(train$wbc_z, na.rm = TRUE) # 0 mean(test$wbc_z, na.rm = TRUE) # vicino a 0, ma non esattamente 0 </syntaxhighlight> La media del test non è 0 perché usa i parametri del training: è il comportamento corretto, perché in produzione i nuovi pazienti verranno standardizzati con i parametri appresi in fase di addestramento. == 2.12 Verifica della comprensione == * Perché non si deve modificare il file dei dati grezzi? * Qual è la differenza tra un valore impossibile e un outlier statistico? * Quando l'eliminazione delle righe con valori mancanti è rischiosa? * Che cos'è la fuga di informazioni (data leakage) e come si evita nella preparazione dei dati? * Perché Random Forest non richiede la standardizzazione, mentre kNN sì? * Che differenza c'è tra MCAR, MAR e MNAR? == Avvertenza == I dati di questa unità sono sintetici e a scopo didattico. Con dati clinici reali rispetta sempre le norme sulla privacy (anonimizzazione e GDPR) e consulta un esperto clinico per decidere come trattare valori anomali e mancanti. == Riepilogo dell'Unità 2 == Abbiamo trattato: * Caricamento da CSV, Excel e RDS * Ispezione di struttura e qualità * Pulizia delle variabili categoriche * Valori impossibili e outlier * Strategie per i valori mancanti * Feature engineering clinico (BMI, shock index) * Codifica, normalizzazione e standardizzazione * Prevenzione della fuga di informazioni * Rapporto sulla qualità dei dati == Letture Consigliate == * [https://r4ds.hadley.nz/ R for Data Science] * [https://topepo.github.io/caret/pre-processing.html Pre-processing con caret] * [https://naniar.njtierney.com/ Pacchetto naniar per i valori mancanti] == Prosegui da Qui == Ora i dati sono puliti: passa all'Unità 3, Analisi Esplorativa dei Dati. == Il progetto PenuX == Repository PenuX: https://github.com/netanelcyber/penux Sito PenuX: https://penux.uk == Quiz == [[PenuX in R/Quiz Unità 2|Fai il quiz dell'Unità 2]] [[Categoria:PenuX in R|Unità 2 - Preparazione e Caricamento dei Dati]] t6a95xdrnb9433x85pf2riw11slrewm PenuX in R/Quiz Unità 2 0 61180 502065 502012 2026-10-04T14:54:36Z Hippias 18281 Hippias ha spostato la pagina [[PenuX in R: Quiz Unità 2]] a [[PenuX in R/Quiz Unità 2]] senza lasciare redirect: [[Aiuto:Convenzioni di nomenclatura|Convenzioni di nomenclatura]]: sottopagino correttamente 502012 wikitext text/x-wiki = PenuX in R: Quiz Unità 2 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Una frequenza cardiaca di 900 bpm in un dataset è: * A) Un outlier da conservare sempre * B) Un valore normale nella sepsi * C) Un valore da standardizzare * D) Un valore impossibile da trattare come errore (mancante) <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Valori fisiologicamente impossibili sono errori di inserimento e vanno trattati come mancanti. </div> == Domanda 2 == Perché spesso si imputa con la mediana anziché con la media? * A) La mediana è robusta agli outlier * B) La mediana è sempre più grande * C) La media non si può calcolare in R * D) La mediana crea nuove variabili <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. La mediana non è influenzata dai valori estremi. </div> == Domanda 3 == Che cos'è la fuga di informazioni (data leakage)? * A) Perdere righe del dataset * B) Usare informazioni del test set durante la preparazione o l'addestramento * C) Salvare i dati in un file RDS * D) Rimuovere le colonne duplicate <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Per esempio, calcolare media e sd su tutto il dataset prima della divisione rende la valutazione ottimistica. </div> == Domanda 4 == Quale algoritmo richiede in genere la standardizzazione delle variabili? * A) Random Forest * B) Albero decisionale * C) kNN * D) Nessuno <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. kNN usa le distanze, quindi le variabili con scala maggiore dominerebbero. </div> == Torna all'unità == [[PenuX in R: Unità 2 - Preparazione e Caricamento dei Dati|Torna all'Unità 2]] etcmuvl7u4t1e0cz3s6r8w91n1vcfx7 502097 502065 2026-10-04T18:20:13Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502097 wikitext text/x-wiki = PenuX in R: Quiz Unità 2 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Una frequenza cardiaca di 900 bpm in un dataset è: * A) Un outlier da conservare sempre * B) Un valore normale nella sepsi * C) Un valore da standardizzare * D) Un valore impossibile da trattare come errore (mancante) <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Valori fisiologicamente impossibili sono errori di inserimento e vanno trattati come mancanti. </div> == Domanda 2 == Perché spesso si imputa con la mediana anziché con la media? * A) La mediana è robusta agli outlier * B) La mediana è sempre più grande * C) La media non si può calcolare in R * D) La mediana crea nuove variabili <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. La mediana non è influenzata dai valori estremi. </div> == Domanda 3 == Che cos'è la fuga di informazioni (data leakage)? * A) Perdere righe del dataset * B) Usare informazioni del test set durante la preparazione o l'addestramento * C) Salvare i dati in un file RDS * D) Rimuovere le colonne duplicate <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Per esempio, calcolare media e sd su tutto il dataset prima della divisione rende la valutazione ottimistica. </div> == Domanda 4 == Quale algoritmo richiede in genere la standardizzazione delle variabili? * A) Random Forest * B) Albero decisionale * C) kNN * D) Nessuno <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. kNN usa le distanze, quindi le variabili con scala maggiore dominerebbero. </div> == Torna all'unità == [[PenuX in R: Unità 2 - Preparazione e Caricamento dei Dati|Torna all'Unità 2]] [[Categoria:PenuX in R|Quiz Unità 2]] 42ohcib9p54b3eepi20j3ct04cm7si6 502113 502097 2026-10-04T18:24:18Z Gian BOT 27470 bot: fix link 502113 wikitext text/x-wiki = PenuX in R: Quiz Unità 2 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Una frequenza cardiaca di 900 bpm in un dataset è: * A) Un outlier da conservare sempre * B) Un valore normale nella sepsi * C) Un valore da standardizzare * D) Un valore impossibile da trattare come errore (mancante) <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Valori fisiologicamente impossibili sono errori di inserimento e vanno trattati come mancanti. </div> == Domanda 2 == Perché spesso si imputa con la mediana anziché con la media? * A) La mediana è robusta agli outlier * B) La mediana è sempre più grande * C) La media non si può calcolare in R * D) La mediana crea nuove variabili <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. La mediana non è influenzata dai valori estremi. </div> == Domanda 3 == Che cos'è la fuga di informazioni (data leakage)? * A) Perdere righe del dataset * B) Usare informazioni del test set durante la preparazione o l'addestramento * C) Salvare i dati in un file RDS * D) Rimuovere le colonne duplicate <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Per esempio, calcolare media e sd su tutto il dataset prima della divisione rende la valutazione ottimistica. </div> == Domanda 4 == Quale algoritmo richiede in genere la standardizzazione delle variabili? * A) Random Forest * B) Albero decisionale * C) kNN * D) Nessuno <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. kNN usa le distanze, quindi le variabili con scala maggiore dominerebbero. </div> == Torna all'unità == [[PenuX in R/Unità 2 - Preparazione e Caricamento dei Dati|Torna all'Unità 2]] [[Categoria:PenuX in R|Quiz Unità 2]] ohy1s4lt6tt3su71zwjfwd9ueehxdhg 502128 502113 2026-10-04T18:32:10Z Gian BOT 27470 Bot: aggiunge l'indice 502128 wikitext text/x-wiki {{PenuX in R}} = PenuX in R: Quiz Unità 2 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Una frequenza cardiaca di 900 bpm in un dataset è: * A) Un outlier da conservare sempre * B) Un valore normale nella sepsi * C) Un valore da standardizzare * D) Un valore impossibile da trattare come errore (mancante) <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Valori fisiologicamente impossibili sono errori di inserimento e vanno trattati come mancanti. </div> == Domanda 2 == Perché spesso si imputa con la mediana anziché con la media? * A) La mediana è robusta agli outlier * B) La mediana è sempre più grande * C) La media non si può calcolare in R * D) La mediana crea nuove variabili <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. La mediana non è influenzata dai valori estremi. </div> == Domanda 3 == Che cos'è la fuga di informazioni (data leakage)? * A) Perdere righe del dataset * B) Usare informazioni del test set durante la preparazione o l'addestramento * C) Salvare i dati in un file RDS * D) Rimuovere le colonne duplicate <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Per esempio, calcolare media e sd su tutto il dataset prima della divisione rende la valutazione ottimistica. </div> == Domanda 4 == Quale algoritmo richiede in genere la standardizzazione delle variabili? * A) Random Forest * B) Albero decisionale * C) kNN * D) Nessuno <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. kNN usa le distanze, quindi le variabili con scala maggiore dominerebbero. </div> == Torna all'unità == [[PenuX in R/Unità 2 - Preparazione e Caricamento dei Dati|Torna all'Unità 2]] [[Categoria:PenuX in R|Quiz Unità 2]] eqhqdlwpreurisy9fepjwysno2ovqbe PenuX in R/Unità 3 - Analisi Esplorativa dei Dati 0 61181 502057 502013 2026-10-04T14:45:36Z Hippias 18281 Hippias ha spostato la pagina [[PenuX in R: Unità 3 - Analisi Esplorativa dei Dati]] a [[PenuX in R/Unità 3 - Analisi Esplorativa dei Dati]] senza lasciare redirect: [[Aiuto:Convenzioni di nomenclatura|Convenzioni di nomenclatura]]: sottopagino correttamente 502013 wikitext text/x-wiki = PenuX in R: Unità 3 - Analisi Esplorativa dei Dati (EDA) = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Eseguire analisi statistiche descrittive * Creare visualizzazioni di dati univariate e bivariate * Identificare relazioni e dipendenze tra variabili * Rilevare anomalie e pattern nei dati * Generare ipotesi basate sull'esplorazione * Documentare e comunicare i risultati == 3.1 Analisi Statistica Descrittiva == === Statistiche di base === <syntaxhighlight lang="r"> # Statistiche descrittive complessive summary(clinical_data) # Statistiche per singola variabile mean(clinical_data$age, na.rm = TRUE) median(clinical_data$age, na.rm = TRUE) sd(clinical_data$age, na.rm = TRUE) var(clinical_data$age, na.rm = TRUE) min(clinical_data$age, na.rm = TRUE) max(clinical_data$age, na.rm = TRUE) range(clinical_data$age, na.rm = TRUE) # Percentili quantile(clinical_data$age, probs = c(0.25, 0.5, 0.75, 0.95), na.rm = TRUE) </syntaxhighlight> === Statistiche per gruppo === <syntaxhighlight lang="r"> # Usare dplyr per statistiche raggruppate library(dplyr) clinical_data %>% group_by(diagnosis) %>% summarise( n = n(), mean_age = mean(age, na.rm = TRUE), sd_age = sd(age, na.rm = TRUE), mean_systolic = mean(systolic_bp, na.rm = TRUE), mean_diastolic = mean(diastolic_bp, na.rm = TRUE), .groups = 'drop' ) # Statistiche più dettagliate clinical_data %>% group_by(diagnosis, gender) %>% summarise( count = n(), age_mean = mean(age, na.rm = TRUE), age_sd = sd(age, na.rm = TRUE), wbc_mean = mean(white_blood_cells, na.rm = TRUE), creatinine_mean = mean(creatinine, na.rm = TRUE), .groups = 'drop' ) </syntaxhighlight> == 3.2 Visualizzazioni Univariate == === Istogrammi === <syntaxhighlight lang="r"> library(ggplot2) # Istogramma semplice ggplot(clinical_data, aes(x = age)) + geom_histogram(binwidth = 5, fill = "steelblue", color = "black", alpha = 0.7) + labs(title = "Distribuzione dell'età", x = "Età (anni)", y = "Frequenza") + theme_minimal() # Istogrammi per gruppo ggplot(clinical_data, aes(x = age, fill = diagnosis)) + geom_histogram(binwidth = 5, alpha = 0.6, position = "dodge") + labs(title = "Distribuzione dell'età per diagnosi", x = "Età (anni)", y = "Frequenza") + theme_minimal() + theme(legend.position = "bottom") # Densità overlay ggplot(clinical_data, aes(x = systolic_bp)) + geom_histogram(aes(y = after_stat(density)), binwidth = 10, fill = "steelblue", alpha = 0.5) + geom_density(color = "red", linewidth = 1) + labs(title = "Distribuzione della pressione sistolica", x = "Pressione Sistolica (mmHg)", y = "Densità") + theme_minimal() </syntaxhighlight> === Box Plot e Violin Plot === <syntaxhighlight lang="r"> # Box plot semplice ggplot(clinical_data, aes(x = diagnosis, y = age)) + geom_boxplot(fill = "lightblue", color = "darkblue") + geom_jitter(width = 0.2, alpha = 0.3) + labs(title = "Distribuzione dell'età per diagnosi", x = "Diagnosi", y = "Età (anni)") + theme_minimal() # Violin plot ggplot(clinical_data, aes(x = diagnosis, y = white_blood_cells, fill = diagnosis)) + geom_violin(alpha = 0.6) + geom_boxplot(width = 0.2, alpha = 0.8) + labs(title = "Distribuzione dei leucociti per diagnosi", x = "Diagnosi", y = "Leucociti (WBC)") + theme_minimal() + theme(legend.position = "none") # Facet plot ggplot(clinical_data, aes(x = age)) + geom_histogram(binwidth = 5, fill = "steelblue", alpha = 0.7) + facet_wrap(~ diagnosis) + labs(title = "Distribuzione dell'età per diagnosi", x = "Età (anni)", y = "Frequenza") + theme_minimal() </syntaxhighlight> == 3.3 Visualizzazioni Bivariate == === Scatter Plot === <syntaxhighlight lang="r"> # Scatter plot semplice ggplot(clinical_data, aes(x = age, y = systolic_bp)) + geom_point(alpha = 0.6, size = 2) + geom_smooth(method = "lm", se = TRUE, color = "red") + labs(title = "Relazione tra età e pressione sistolica", x = "Età (anni)", y = "Pressione Sistolica (mmHg)") + theme_minimal() # Scatter plot per gruppo ggplot(clinical_data, aes(x = age, y = white_blood_cells, color = diagnosis)) + geom_point(alpha = 0.6, size = 2) + geom_smooth(method = "lm", se = FALSE, linewidth = 1) + labs(title = "Relazione tra età e leucociti per diagnosi", x = "Età (anni)", y = "Leucociti (WBC)") + theme_minimal() + theme(legend.position = "bottom") </syntaxhighlight> === Matrice di Correlazione === <syntaxhighlight lang="r"> # Calcolare la matrice di correlazione numeric_data <- clinical_data %>% select_if(is.numeric) correlation_matrix <- cor(numeric_data, use = "complete.obs") print(correlation_matrix) # Visualizzare con ggplot library(reshape2) melted_corr <- melt(correlation_matrix) ggplot(melted_corr, aes(x = Var1, y = Var2, fill = value)) + geom_tile(color = "white") + geom_text(aes(label = round(value, 2)), size = 3) + scale_fill_gradient2(low = "blue", mid = "white", high = "red", limits = c(-1, 1)) + labs(title = "Matrice di Correlazione", x = "", y = "", fill = "Correlazione") + theme_minimal() + theme(axis.text.x = element_text(angle = 45, hjust = 1)) # Usare corrplot library(corrplot) corrplot(correlation_matrix, method = "circle", type = "upper", addCoef.col = "black", diag = FALSE, title = "Matrice di Correlazione - PenuX") </syntaxhighlight> == 3.4 Analisi Multivariata == === Analisi delle Componenti Principali (PCA) === <syntaxhighlight lang="r"> # Preparare i dati per PCA pca_data <- clinical_data %>% select_if(is.numeric) %>% scale() # Standardizzare # Eseguire PCA pca_result <- prcomp(pca_data, center = FALSE) # Riepilogo summary(pca_result) # Visualizzare la varianza spiegata scree_plot <- tibble( PC = 1:length(pca_result$sdev), Variance = (pca_result$sdev^2 / sum(pca_result$sdev^2)) * 100 ) ggplot(scree_plot, aes(x = PC, y = Variance)) + geom_col(fill = "steelblue", alpha = 0.7) + geom_line(color = "red", linewidth = 1) + labs(title = "Varianza Spiegata per Componente Principale", x = "Componente Principale", y = "Varianza Spiegata (%)") + theme_minimal() # Biplot biplot(pca_result, main = "PCA Biplot") </syntaxhighlight> === Clustering Analisi === <syntaxhighlight lang="r"> # K-means clustering kmeans_result <- kmeans(pca_data, centers = 3, nstart = 25) # Aggiungere i cluster ai dati clinical_data_clustered <- clinical_data %>% mutate(cluster = as.factor(kmeans_result$cluster)) # Visualizzare i cluster ggplot(clinical_data_clustered, aes(x = age, y = white_blood_cells, color = cluster)) + geom_point(size = 3, alpha = 0.6) + labs(title = "K-means Clustering (k=3)", x = "Età (anni)", y = "Leucociti (WBC)", color = "Cluster") + theme_minimal() # Hierarchical clustering library(dendextend) hc_result <- hclust(dist(pca_data), method = "ward.D2") # Dendrogram plot(hc_result, main = "Dendrogramma - Clustering Gerarchico", xlab = "Osservazioni", ylab = "Distanza") </syntaxhighlight> == 3.5 Analisi Diagnostica == === Test di Normalità === <syntaxhighlight lang="r"> # Test di Shapiro-Wilk shapiro_test <- shapiro.test(clinical_data$age) print(shapiro_test) # Test di Kolmogorov-Smirnov ks_test <- ks.test(clinical_data$age, "pnorm", mean = mean(clinical_data$age, na.rm = TRUE), sd = sd(clinical_data$age, na.rm = TRUE)) print(ks_test) # Q-Q plot ggplot(clinical_data, aes(sample = age)) + geom_qq() + geom_qq_line(color = "red") + labs(title = "Q-Q Plot - Età", x = "Quantili teorici", y = "Quantili osservati") + theme_minimal() </syntaxhighlight> === Test di Omoschedasticità === <syntaxhighlight lang="r"> # Test di Levene library(car) levene_test <- leveneTest(age ~ diagnosis, data = clinical_data) print(levene_test) # Test di Bartlett bartlett_test <- bartlett.test(age ~ diagnosis, data = clinical_data) print(bartlett_test) </syntaxhighlight> == 3.6 Generazione di Rapporti == === Rapporto EDA Automatico === <syntaxhighlight lang="r"> # Usare DataExplorer library(DataExplorer) # Creare un rapporto HTML automatico create_report(clinical_data, output_file = "eda_report.html", output_dir = "results/", y = "diagnosis") # Analisi di singole variabili plot_str(clinical_data) plot_missing(clinical_data) plot_histogram(clinical_data) plot_density(clinical_data) plot_boxplot(clinical_data, by = "diagnosis") plot_correlation(clinical_data, type = "continuous") </syntaxhighlight> === Rapporto Personalizzato === <syntaxhighlight lang="r"> # Creare un rapporto con R Markdown rmd_content <- " --- title: 'Analisi Esplorativa - PenuX' date: '`r Sys.Date()`' output: html_document --- ## Sommario dei Dati ```{r} summary(clinical_data) ``` ## Distribuzioni Univariate ```{r fig.width=12} # Istogrammi per tutte le variabili numeriche clinical_data %>% select_if(is.numeric) %>% pivot_longer(everything(), names_to = 'Variable', values_to = 'Value') %>% ggplot(aes(x = Value)) + geom_histogram(bins = 30, fill = 'steelblue') + facet_wrap(~Variable, scales = 'free') + theme_minimal() ``` ## Correlazioni ```{r} correlation_matrix <- cor(clinical_data %>% select_if(is.numeric), use = 'complete.obs') corrplot(correlation_matrix, method = 'circle', type = 'upper') ``` " # Scrivere il file R Markdown writeLines(rmd_content, "eda_report.Rmd") # Renderizzare il report library(rmarkdown) render("eda_report.Rmd", output_format = "html_document") </syntaxhighlight> == 3.7 Esercizi Pratici == # Caricare il dataset pulito da Unit 2 # Eseguire analisi statistiche descrittive # Creare almeno 10 visualizzazioni diverse # Identificare le principali relazioni tra variabili # Eseguire PCA e interpretare i risultati # Applicare clustering e valutarne la qualità # Generare un rapporto EDA completo # Documentare le ipotesi generate dall'esplorazione == 3.8 Verifica della Comprensione == * Quali test statistici usi per verificare la normalità dei dati? * Come interpreti una matrice di correlazione? * Quando e perché usi PCA? * Quali sono le differenze tra clustering k-means e gerarchico? * Come comunichi i risultati dell'EDA agli stakeholder clinici? == Riepilogo dell'unità 3 == Abbiamo trattato: * Analisi statistica descrittiva e raggruppata * Visualizzazioni univariate (istogrammi, box plot, violin plot) * Visualizzazioni bivariate e matrici di correlazione * Analisi multivariata (PCA, clustering) * Test diagnostici di normalità e omoschedasticità * Generazione automatica di rapporti EDA * Comunicazione efficace dei risultati == Letture Consigliate == * [https://ggplot2.tidyverse.org/ ggplot2 Documentation] * [https://cran.r-project.org/web/packages/DataExplorer/index.html DataExplorer Package] == Il progetto PenuX == Il codice sorgente, i modelli e la documentazione della piattaforma PenuX sono disponibili pubblicamente con licenza libera: * [https://github.com/netanelcyber/penux Repository PenuX su GitHub] * [https://penux.uk Sito del progetto PenuX] == Quiz == [[PenuX in R: Quiz Unità 3|Fai il quiz dell'Unità 3]] ptjqjeeakdp1wdlgj10pzyc5gbelqkx 502106 502057 2026-10-04T18:21:55Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502106 wikitext text/x-wiki = PenuX in R: Unità 3 - Analisi Esplorativa dei Dati (EDA) = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Eseguire analisi statistiche descrittive * Creare visualizzazioni di dati univariate e bivariate * Identificare relazioni e dipendenze tra variabili * Rilevare anomalie e pattern nei dati * Generare ipotesi basate sull'esplorazione * Documentare e comunicare i risultati == 3.1 Analisi Statistica Descrittiva == === Statistiche di base === <syntaxhighlight lang="r"> # Statistiche descrittive complessive summary(clinical_data) # Statistiche per singola variabile mean(clinical_data$age, na.rm = TRUE) median(clinical_data$age, na.rm = TRUE) sd(clinical_data$age, na.rm = TRUE) var(clinical_data$age, na.rm = TRUE) min(clinical_data$age, na.rm = TRUE) max(clinical_data$age, na.rm = TRUE) range(clinical_data$age, na.rm = TRUE) # Percentili quantile(clinical_data$age, probs = c(0.25, 0.5, 0.75, 0.95), na.rm = TRUE) </syntaxhighlight> === Statistiche per gruppo === <syntaxhighlight lang="r"> # Usare dplyr per statistiche raggruppate library(dplyr) clinical_data %>% group_by(diagnosis) %>% summarise( n = n(), mean_age = mean(age, na.rm = TRUE), sd_age = sd(age, na.rm = TRUE), mean_systolic = mean(systolic_bp, na.rm = TRUE), mean_diastolic = mean(diastolic_bp, na.rm = TRUE), .groups = 'drop' ) # Statistiche più dettagliate clinical_data %>% group_by(diagnosis, gender) %>% summarise( count = n(), age_mean = mean(age, na.rm = TRUE), age_sd = sd(age, na.rm = TRUE), wbc_mean = mean(white_blood_cells, na.rm = TRUE), creatinine_mean = mean(creatinine, na.rm = TRUE), .groups = 'drop' ) </syntaxhighlight> == 3.2 Visualizzazioni Univariate == === Istogrammi === <syntaxhighlight lang="r"> library(ggplot2) # Istogramma semplice ggplot(clinical_data, aes(x = age)) + geom_histogram(binwidth = 5, fill = "steelblue", color = "black", alpha = 0.7) + labs(title = "Distribuzione dell'età", x = "Età (anni)", y = "Frequenza") + theme_minimal() # Istogrammi per gruppo ggplot(clinical_data, aes(x = age, fill = diagnosis)) + geom_histogram(binwidth = 5, alpha = 0.6, position = "dodge") + labs(title = "Distribuzione dell'età per diagnosi", x = "Età (anni)", y = "Frequenza") + theme_minimal() + theme(legend.position = "bottom") # Densità overlay ggplot(clinical_data, aes(x = systolic_bp)) + geom_histogram(aes(y = after_stat(density)), binwidth = 10, fill = "steelblue", alpha = 0.5) + geom_density(color = "red", linewidth = 1) + labs(title = "Distribuzione della pressione sistolica", x = "Pressione Sistolica (mmHg)", y = "Densità") + theme_minimal() </syntaxhighlight> === Box Plot e Violin Plot === <syntaxhighlight lang="r"> # Box plot semplice ggplot(clinical_data, aes(x = diagnosis, y = age)) + geom_boxplot(fill = "lightblue", color = "darkblue") + geom_jitter(width = 0.2, alpha = 0.3) + labs(title = "Distribuzione dell'età per diagnosi", x = "Diagnosi", y = "Età (anni)") + theme_minimal() # Violin plot ggplot(clinical_data, aes(x = diagnosis, y = white_blood_cells, fill = diagnosis)) + geom_violin(alpha = 0.6) + geom_boxplot(width = 0.2, alpha = 0.8) + labs(title = "Distribuzione dei leucociti per diagnosi", x = "Diagnosi", y = "Leucociti (WBC)") + theme_minimal() + theme(legend.position = "none") # Facet plot ggplot(clinical_data, aes(x = age)) + geom_histogram(binwidth = 5, fill = "steelblue", alpha = 0.7) + facet_wrap(~ diagnosis) + labs(title = "Distribuzione dell'età per diagnosi", x = "Età (anni)", y = "Frequenza") + theme_minimal() </syntaxhighlight> == 3.3 Visualizzazioni Bivariate == === Scatter Plot === <syntaxhighlight lang="r"> # Scatter plot semplice ggplot(clinical_data, aes(x = age, y = systolic_bp)) + geom_point(alpha = 0.6, size = 2) + geom_smooth(method = "lm", se = TRUE, color = "red") + labs(title = "Relazione tra età e pressione sistolica", x = "Età (anni)", y = "Pressione Sistolica (mmHg)") + theme_minimal() # Scatter plot per gruppo ggplot(clinical_data, aes(x = age, y = white_blood_cells, color = diagnosis)) + geom_point(alpha = 0.6, size = 2) + geom_smooth(method = "lm", se = FALSE, linewidth = 1) + labs(title = "Relazione tra età e leucociti per diagnosi", x = "Età (anni)", y = "Leucociti (WBC)") + theme_minimal() + theme(legend.position = "bottom") </syntaxhighlight> === Matrice di Correlazione === <syntaxhighlight lang="r"> # Calcolare la matrice di correlazione numeric_data <- clinical_data %>% select_if(is.numeric) correlation_matrix <- cor(numeric_data, use = "complete.obs") print(correlation_matrix) # Visualizzare con ggplot library(reshape2) melted_corr <- melt(correlation_matrix) ggplot(melted_corr, aes(x = Var1, y = Var2, fill = value)) + geom_tile(color = "white") + geom_text(aes(label = round(value, 2)), size = 3) + scale_fill_gradient2(low = "blue", mid = "white", high = "red", limits = c(-1, 1)) + labs(title = "Matrice di Correlazione", x = "", y = "", fill = "Correlazione") + theme_minimal() + theme(axis.text.x = element_text(angle = 45, hjust = 1)) # Usare corrplot library(corrplot) corrplot(correlation_matrix, method = "circle", type = "upper", addCoef.col = "black", diag = FALSE, title = "Matrice di Correlazione - PenuX") </syntaxhighlight> == 3.4 Analisi Multivariata == === Analisi delle Componenti Principali (PCA) === <syntaxhighlight lang="r"> # Preparare i dati per PCA pca_data <- clinical_data %>% select_if(is.numeric) %>% scale() # Standardizzare # Eseguire PCA pca_result <- prcomp(pca_data, center = FALSE) # Riepilogo summary(pca_result) # Visualizzare la varianza spiegata scree_plot <- tibble( PC = 1:length(pca_result$sdev), Variance = (pca_result$sdev^2 / sum(pca_result$sdev^2)) * 100 ) ggplot(scree_plot, aes(x = PC, y = Variance)) + geom_col(fill = "steelblue", alpha = 0.7) + geom_line(color = "red", linewidth = 1) + labs(title = "Varianza Spiegata per Componente Principale", x = "Componente Principale", y = "Varianza Spiegata (%)") + theme_minimal() # Biplot biplot(pca_result, main = "PCA Biplot") </syntaxhighlight> === Clustering Analisi === <syntaxhighlight lang="r"> # K-means clustering kmeans_result <- kmeans(pca_data, centers = 3, nstart = 25) # Aggiungere i cluster ai dati clinical_data_clustered <- clinical_data %>% mutate(cluster = as.factor(kmeans_result$cluster)) # Visualizzare i cluster ggplot(clinical_data_clustered, aes(x = age, y = white_blood_cells, color = cluster)) + geom_point(size = 3, alpha = 0.6) + labs(title = "K-means Clustering (k=3)", x = "Età (anni)", y = "Leucociti (WBC)", color = "Cluster") + theme_minimal() # Hierarchical clustering library(dendextend) hc_result <- hclust(dist(pca_data), method = "ward.D2") # Dendrogram plot(hc_result, main = "Dendrogramma - Clustering Gerarchico", xlab = "Osservazioni", ylab = "Distanza") </syntaxhighlight> == 3.5 Analisi Diagnostica == === Test di Normalità === <syntaxhighlight lang="r"> # Test di Shapiro-Wilk shapiro_test <- shapiro.test(clinical_data$age) print(shapiro_test) # Test di Kolmogorov-Smirnov ks_test <- ks.test(clinical_data$age, "pnorm", mean = mean(clinical_data$age, na.rm = TRUE), sd = sd(clinical_data$age, na.rm = TRUE)) print(ks_test) # Q-Q plot ggplot(clinical_data, aes(sample = age)) + geom_qq() + geom_qq_line(color = "red") + labs(title = "Q-Q Plot - Età", x = "Quantili teorici", y = "Quantili osservati") + theme_minimal() </syntaxhighlight> === Test di Omoschedasticità === <syntaxhighlight lang="r"> # Test di Levene library(car) levene_test <- leveneTest(age ~ diagnosis, data = clinical_data) print(levene_test) # Test di Bartlett bartlett_test <- bartlett.test(age ~ diagnosis, data = clinical_data) print(bartlett_test) </syntaxhighlight> == 3.6 Generazione di Rapporti == === Rapporto EDA Automatico === <syntaxhighlight lang="r"> # Usare DataExplorer library(DataExplorer) # Creare un rapporto HTML automatico create_report(clinical_data, output_file = "eda_report.html", output_dir = "results/", y = "diagnosis") # Analisi di singole variabili plot_str(clinical_data) plot_missing(clinical_data) plot_histogram(clinical_data) plot_density(clinical_data) plot_boxplot(clinical_data, by = "diagnosis") plot_correlation(clinical_data, type = "continuous") </syntaxhighlight> === Rapporto Personalizzato === <syntaxhighlight lang="r"> # Creare un rapporto con R Markdown rmd_content <- " --- title: 'Analisi Esplorativa - PenuX' date: '`r Sys.Date()`' output: html_document --- ## Sommario dei Dati ```{r} summary(clinical_data) ``` ## Distribuzioni Univariate ```{r fig.width=12} # Istogrammi per tutte le variabili numeriche clinical_data %>% select_if(is.numeric) %>% pivot_longer(everything(), names_to = 'Variable', values_to = 'Value') %>% ggplot(aes(x = Value)) + geom_histogram(bins = 30, fill = 'steelblue') + facet_wrap(~Variable, scales = 'free') + theme_minimal() ``` ## Correlazioni ```{r} correlation_matrix <- cor(clinical_data %>% select_if(is.numeric), use = 'complete.obs') corrplot(correlation_matrix, method = 'circle', type = 'upper') ``` " # Scrivere il file R Markdown writeLines(rmd_content, "eda_report.Rmd") # Renderizzare il report library(rmarkdown) render("eda_report.Rmd", output_format = "html_document") </syntaxhighlight> == 3.7 Esercizi Pratici == # Caricare il dataset pulito da Unit 2 # Eseguire analisi statistiche descrittive # Creare almeno 10 visualizzazioni diverse # Identificare le principali relazioni tra variabili # Eseguire PCA e interpretare i risultati # Applicare clustering e valutarne la qualità # Generare un rapporto EDA completo # Documentare le ipotesi generate dall'esplorazione == 3.8 Verifica della Comprensione == * Quali test statistici usi per verificare la normalità dei dati? * Come interpreti una matrice di correlazione? * Quando e perché usi PCA? * Quali sono le differenze tra clustering k-means e gerarchico? * Come comunichi i risultati dell'EDA agli stakeholder clinici? == Riepilogo dell'unità 3 == Abbiamo trattato: * Analisi statistica descrittiva e raggruppata * Visualizzazioni univariate (istogrammi, box plot, violin plot) * Visualizzazioni bivariate e matrici di correlazione * Analisi multivariata (PCA, clustering) * Test diagnostici di normalità e omoschedasticità * Generazione automatica di rapporti EDA * Comunicazione efficace dei risultati == Letture Consigliate == * [https://ggplot2.tidyverse.org/ ggplot2 Documentation] * [https://cran.r-project.org/web/packages/DataExplorer/index.html DataExplorer Package] == Il progetto PenuX == Il codice sorgente, i modelli e la documentazione della piattaforma PenuX sono disponibili pubblicamente con licenza libera: * [https://github.com/netanelcyber/penux Repository PenuX su GitHub] * [https://penux.uk Sito del progetto PenuX] == Quiz == [[PenuX in R: Quiz Unità 3|Fai il quiz dell'Unità 3]] [[Categoria:PenuX in R|Unità 3 - Analisi Esplorativa dei Dati]] ajaxcaczf8suljomc4odaevsktox5yq 502121 502106 2026-10-04T18:25:38Z Gian BOT 27470 bot: fix link 502121 wikitext text/x-wiki = PenuX in R: Unità 3 - Analisi Esplorativa dei Dati (EDA) = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Eseguire analisi statistiche descrittive * Creare visualizzazioni di dati univariate e bivariate * Identificare relazioni e dipendenze tra variabili * Rilevare anomalie e pattern nei dati * Generare ipotesi basate sull'esplorazione * Documentare e comunicare i risultati == 3.1 Analisi Statistica Descrittiva == === Statistiche di base === <syntaxhighlight lang="r"> # Statistiche descrittive complessive summary(clinical_data) # Statistiche per singola variabile mean(clinical_data$age, na.rm = TRUE) median(clinical_data$age, na.rm = TRUE) sd(clinical_data$age, na.rm = TRUE) var(clinical_data$age, na.rm = TRUE) min(clinical_data$age, na.rm = TRUE) max(clinical_data$age, na.rm = TRUE) range(clinical_data$age, na.rm = TRUE) # Percentili quantile(clinical_data$age, probs = c(0.25, 0.5, 0.75, 0.95), na.rm = TRUE) </syntaxhighlight> === Statistiche per gruppo === <syntaxhighlight lang="r"> # Usare dplyr per statistiche raggruppate library(dplyr) clinical_data %>% group_by(diagnosis) %>% summarise( n = n(), mean_age = mean(age, na.rm = TRUE), sd_age = sd(age, na.rm = TRUE), mean_systolic = mean(systolic_bp, na.rm = TRUE), mean_diastolic = mean(diastolic_bp, na.rm = TRUE), .groups = 'drop' ) # Statistiche più dettagliate clinical_data %>% group_by(diagnosis, gender) %>% summarise( count = n(), age_mean = mean(age, na.rm = TRUE), age_sd = sd(age, na.rm = TRUE), wbc_mean = mean(white_blood_cells, na.rm = TRUE), creatinine_mean = mean(creatinine, na.rm = TRUE), .groups = 'drop' ) </syntaxhighlight> == 3.2 Visualizzazioni Univariate == === Istogrammi === <syntaxhighlight lang="r"> library(ggplot2) # Istogramma semplice ggplot(clinical_data, aes(x = age)) + geom_histogram(binwidth = 5, fill = "steelblue", color = "black", alpha = 0.7) + labs(title = "Distribuzione dell'età", x = "Età (anni)", y = "Frequenza") + theme_minimal() # Istogrammi per gruppo ggplot(clinical_data, aes(x = age, fill = diagnosis)) + geom_histogram(binwidth = 5, alpha = 0.6, position = "dodge") + labs(title = "Distribuzione dell'età per diagnosi", x = "Età (anni)", y = "Frequenza") + theme_minimal() + theme(legend.position = "bottom") # Densità overlay ggplot(clinical_data, aes(x = systolic_bp)) + geom_histogram(aes(y = after_stat(density)), binwidth = 10, fill = "steelblue", alpha = 0.5) + geom_density(color = "red", linewidth = 1) + labs(title = "Distribuzione della pressione sistolica", x = "Pressione Sistolica (mmHg)", y = "Densità") + theme_minimal() </syntaxhighlight> === Box Plot e Violin Plot === <syntaxhighlight lang="r"> # Box plot semplice ggplot(clinical_data, aes(x = diagnosis, y = age)) + geom_boxplot(fill = "lightblue", color = "darkblue") + geom_jitter(width = 0.2, alpha = 0.3) + labs(title = "Distribuzione dell'età per diagnosi", x = "Diagnosi", y = "Età (anni)") + theme_minimal() # Violin plot ggplot(clinical_data, aes(x = diagnosis, y = white_blood_cells, fill = diagnosis)) + geom_violin(alpha = 0.6) + geom_boxplot(width = 0.2, alpha = 0.8) + labs(title = "Distribuzione dei leucociti per diagnosi", x = "Diagnosi", y = "Leucociti (WBC)") + theme_minimal() + theme(legend.position = "none") # Facet plot ggplot(clinical_data, aes(x = age)) + geom_histogram(binwidth = 5, fill = "steelblue", alpha = 0.7) + facet_wrap(~ diagnosis) + labs(title = "Distribuzione dell'età per diagnosi", x = "Età (anni)", y = "Frequenza") + theme_minimal() </syntaxhighlight> == 3.3 Visualizzazioni Bivariate == === Scatter Plot === <syntaxhighlight lang="r"> # Scatter plot semplice ggplot(clinical_data, aes(x = age, y = systolic_bp)) + geom_point(alpha = 0.6, size = 2) + geom_smooth(method = "lm", se = TRUE, color = "red") + labs(title = "Relazione tra età e pressione sistolica", x = "Età (anni)", y = "Pressione Sistolica (mmHg)") + theme_minimal() # Scatter plot per gruppo ggplot(clinical_data, aes(x = age, y = white_blood_cells, color = diagnosis)) + geom_point(alpha = 0.6, size = 2) + geom_smooth(method = "lm", se = FALSE, linewidth = 1) + labs(title = "Relazione tra età e leucociti per diagnosi", x = "Età (anni)", y = "Leucociti (WBC)") + theme_minimal() + theme(legend.position = "bottom") </syntaxhighlight> === Matrice di Correlazione === <syntaxhighlight lang="r"> # Calcolare la matrice di correlazione numeric_data <- clinical_data %>% select_if(is.numeric) correlation_matrix <- cor(numeric_data, use = "complete.obs") print(correlation_matrix) # Visualizzare con ggplot library(reshape2) melted_corr <- melt(correlation_matrix) ggplot(melted_corr, aes(x = Var1, y = Var2, fill = value)) + geom_tile(color = "white") + geom_text(aes(label = round(value, 2)), size = 3) + scale_fill_gradient2(low = "blue", mid = "white", high = "red", limits = c(-1, 1)) + labs(title = "Matrice di Correlazione", x = "", y = "", fill = "Correlazione") + theme_minimal() + theme(axis.text.x = element_text(angle = 45, hjust = 1)) # Usare corrplot library(corrplot) corrplot(correlation_matrix, method = "circle", type = "upper", addCoef.col = "black", diag = FALSE, title = "Matrice di Correlazione - PenuX") </syntaxhighlight> == 3.4 Analisi Multivariata == === Analisi delle Componenti Principali (PCA) === <syntaxhighlight lang="r"> # Preparare i dati per PCA pca_data <- clinical_data %>% select_if(is.numeric) %>% scale() # Standardizzare # Eseguire PCA pca_result <- prcomp(pca_data, center = FALSE) # Riepilogo summary(pca_result) # Visualizzare la varianza spiegata scree_plot <- tibble( PC = 1:length(pca_result$sdev), Variance = (pca_result$sdev^2 / sum(pca_result$sdev^2)) * 100 ) ggplot(scree_plot, aes(x = PC, y = Variance)) + geom_col(fill = "steelblue", alpha = 0.7) + geom_line(color = "red", linewidth = 1) + labs(title = "Varianza Spiegata per Componente Principale", x = "Componente Principale", y = "Varianza Spiegata (%)") + theme_minimal() # Biplot biplot(pca_result, main = "PCA Biplot") </syntaxhighlight> === Clustering Analisi === <syntaxhighlight lang="r"> # K-means clustering kmeans_result <- kmeans(pca_data, centers = 3, nstart = 25) # Aggiungere i cluster ai dati clinical_data_clustered <- clinical_data %>% mutate(cluster = as.factor(kmeans_result$cluster)) # Visualizzare i cluster ggplot(clinical_data_clustered, aes(x = age, y = white_blood_cells, color = cluster)) + geom_point(size = 3, alpha = 0.6) + labs(title = "K-means Clustering (k=3)", x = "Età (anni)", y = "Leucociti (WBC)", color = "Cluster") + theme_minimal() # Hierarchical clustering library(dendextend) hc_result <- hclust(dist(pca_data), method = "ward.D2") # Dendrogram plot(hc_result, main = "Dendrogramma - Clustering Gerarchico", xlab = "Osservazioni", ylab = "Distanza") </syntaxhighlight> == 3.5 Analisi Diagnostica == === Test di Normalità === <syntaxhighlight lang="r"> # Test di Shapiro-Wilk shapiro_test <- shapiro.test(clinical_data$age) print(shapiro_test) # Test di Kolmogorov-Smirnov ks_test <- ks.test(clinical_data$age, "pnorm", mean = mean(clinical_data$age, na.rm = TRUE), sd = sd(clinical_data$age, na.rm = TRUE)) print(ks_test) # Q-Q plot ggplot(clinical_data, aes(sample = age)) + geom_qq() + geom_qq_line(color = "red") + labs(title = "Q-Q Plot - Età", x = "Quantili teorici", y = "Quantili osservati") + theme_minimal() </syntaxhighlight> === Test di Omoschedasticità === <syntaxhighlight lang="r"> # Test di Levene library(car) levene_test <- leveneTest(age ~ diagnosis, data = clinical_data) print(levene_test) # Test di Bartlett bartlett_test <- bartlett.test(age ~ diagnosis, data = clinical_data) print(bartlett_test) </syntaxhighlight> == 3.6 Generazione di Rapporti == === Rapporto EDA Automatico === <syntaxhighlight lang="r"> # Usare DataExplorer library(DataExplorer) # Creare un rapporto HTML automatico create_report(clinical_data, output_file = "eda_report.html", output_dir = "results/", y = "diagnosis") # Analisi di singole variabili plot_str(clinical_data) plot_missing(clinical_data) plot_histogram(clinical_data) plot_density(clinical_data) plot_boxplot(clinical_data, by = "diagnosis") plot_correlation(clinical_data, type = "continuous") </syntaxhighlight> === Rapporto Personalizzato === <syntaxhighlight lang="r"> # Creare un rapporto con R Markdown rmd_content <- " --- title: 'Analisi Esplorativa - PenuX' date: '`r Sys.Date()`' output: html_document --- ## Sommario dei Dati ```{r} summary(clinical_data) ``` ## Distribuzioni Univariate ```{r fig.width=12} # Istogrammi per tutte le variabili numeriche clinical_data %>% select_if(is.numeric) %>% pivot_longer(everything(), names_to = 'Variable', values_to = 'Value') %>% ggplot(aes(x = Value)) + geom_histogram(bins = 30, fill = 'steelblue') + facet_wrap(~Variable, scales = 'free') + theme_minimal() ``` ## Correlazioni ```{r} correlation_matrix <- cor(clinical_data %>% select_if(is.numeric), use = 'complete.obs') corrplot(correlation_matrix, method = 'circle', type = 'upper') ``` " # Scrivere il file R Markdown writeLines(rmd_content, "eda_report.Rmd") # Renderizzare il report library(rmarkdown) render("eda_report.Rmd", output_format = "html_document") </syntaxhighlight> == 3.7 Esercizi Pratici == # Caricare il dataset pulito da Unit 2 # Eseguire analisi statistiche descrittive # Creare almeno 10 visualizzazioni diverse # Identificare le principali relazioni tra variabili # Eseguire PCA e interpretare i risultati # Applicare clustering e valutarne la qualità # Generare un rapporto EDA completo # Documentare le ipotesi generate dall'esplorazione == 3.8 Verifica della Comprensione == * Quali test statistici usi per verificare la normalità dei dati? * Come interpreti una matrice di correlazione? * Quando e perché usi PCA? * Quali sono le differenze tra clustering k-means e gerarchico? * Come comunichi i risultati dell'EDA agli stakeholder clinici? == Riepilogo dell'unità 3 == Abbiamo trattato: * Analisi statistica descrittiva e raggruppata * Visualizzazioni univariate (istogrammi, box plot, violin plot) * Visualizzazioni bivariate e matrici di correlazione * Analisi multivariata (PCA, clustering) * Test diagnostici di normalità e omoschedasticità * Generazione automatica di rapporti EDA * Comunicazione efficace dei risultati == Letture Consigliate == * [https://ggplot2.tidyverse.org/ ggplot2 Documentation] * [https://cran.r-project.org/web/packages/DataExplorer/index.html DataExplorer Package] == Il progetto PenuX == Il codice sorgente, i modelli e la documentazione della piattaforma PenuX sono disponibili pubblicamente con licenza libera: * [https://github.com/netanelcyber/penux Repository PenuX su GitHub] * [https://penux.uk Sito del progetto PenuX] == Quiz == [[PenuX in R/Quiz Unità 3|Fai il quiz dell'Unità 3]] [[Categoria:PenuX in R|Unità 3 - Analisi Esplorativa dei Dati]] m7e6x18gg0sukohu8k7uqg5j1ngugij 502136 502121 2026-10-04T18:34:03Z Gian BOT 27470 Bot: aggiunge l'indice 502136 wikitext text/x-wiki {{PenuX in R}} = PenuX in R: Unità 3 - Analisi Esplorativa dei Dati (EDA) = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Eseguire analisi statistiche descrittive * Creare visualizzazioni di dati univariate e bivariate * Identificare relazioni e dipendenze tra variabili * Rilevare anomalie e pattern nei dati * Generare ipotesi basate sull'esplorazione * Documentare e comunicare i risultati == 3.1 Analisi Statistica Descrittiva == === Statistiche di base === <syntaxhighlight lang="r"> # Statistiche descrittive complessive summary(clinical_data) # Statistiche per singola variabile mean(clinical_data$age, na.rm = TRUE) median(clinical_data$age, na.rm = TRUE) sd(clinical_data$age, na.rm = TRUE) var(clinical_data$age, na.rm = TRUE) min(clinical_data$age, na.rm = TRUE) max(clinical_data$age, na.rm = TRUE) range(clinical_data$age, na.rm = TRUE) # Percentili quantile(clinical_data$age, probs = c(0.25, 0.5, 0.75, 0.95), na.rm = TRUE) </syntaxhighlight> === Statistiche per gruppo === <syntaxhighlight lang="r"> # Usare dplyr per statistiche raggruppate library(dplyr) clinical_data %>% group_by(diagnosis) %>% summarise( n = n(), mean_age = mean(age, na.rm = TRUE), sd_age = sd(age, na.rm = TRUE), mean_systolic = mean(systolic_bp, na.rm = TRUE), mean_diastolic = mean(diastolic_bp, na.rm = TRUE), .groups = 'drop' ) # Statistiche più dettagliate clinical_data %>% group_by(diagnosis, gender) %>% summarise( count = n(), age_mean = mean(age, na.rm = TRUE), age_sd = sd(age, na.rm = TRUE), wbc_mean = mean(white_blood_cells, na.rm = TRUE), creatinine_mean = mean(creatinine, na.rm = TRUE), .groups = 'drop' ) </syntaxhighlight> == 3.2 Visualizzazioni Univariate == === Istogrammi === <syntaxhighlight lang="r"> library(ggplot2) # Istogramma semplice ggplot(clinical_data, aes(x = age)) + geom_histogram(binwidth = 5, fill = "steelblue", color = "black", alpha = 0.7) + labs(title = "Distribuzione dell'età", x = "Età (anni)", y = "Frequenza") + theme_minimal() # Istogrammi per gruppo ggplot(clinical_data, aes(x = age, fill = diagnosis)) + geom_histogram(binwidth = 5, alpha = 0.6, position = "dodge") + labs(title = "Distribuzione dell'età per diagnosi", x = "Età (anni)", y = "Frequenza") + theme_minimal() + theme(legend.position = "bottom") # Densità overlay ggplot(clinical_data, aes(x = systolic_bp)) + geom_histogram(aes(y = after_stat(density)), binwidth = 10, fill = "steelblue", alpha = 0.5) + geom_density(color = "red", linewidth = 1) + labs(title = "Distribuzione della pressione sistolica", x = "Pressione Sistolica (mmHg)", y = "Densità") + theme_minimal() </syntaxhighlight> === Box Plot e Violin Plot === <syntaxhighlight lang="r"> # Box plot semplice ggplot(clinical_data, aes(x = diagnosis, y = age)) + geom_boxplot(fill = "lightblue", color = "darkblue") + geom_jitter(width = 0.2, alpha = 0.3) + labs(title = "Distribuzione dell'età per diagnosi", x = "Diagnosi", y = "Età (anni)") + theme_minimal() # Violin plot ggplot(clinical_data, aes(x = diagnosis, y = white_blood_cells, fill = diagnosis)) + geom_violin(alpha = 0.6) + geom_boxplot(width = 0.2, alpha = 0.8) + labs(title = "Distribuzione dei leucociti per diagnosi", x = "Diagnosi", y = "Leucociti (WBC)") + theme_minimal() + theme(legend.position = "none") # Facet plot ggplot(clinical_data, aes(x = age)) + geom_histogram(binwidth = 5, fill = "steelblue", alpha = 0.7) + facet_wrap(~ diagnosis) + labs(title = "Distribuzione dell'età per diagnosi", x = "Età (anni)", y = "Frequenza") + theme_minimal() </syntaxhighlight> == 3.3 Visualizzazioni Bivariate == === Scatter Plot === <syntaxhighlight lang="r"> # Scatter plot semplice ggplot(clinical_data, aes(x = age, y = systolic_bp)) + geom_point(alpha = 0.6, size = 2) + geom_smooth(method = "lm", se = TRUE, color = "red") + labs(title = "Relazione tra età e pressione sistolica", x = "Età (anni)", y = "Pressione Sistolica (mmHg)") + theme_minimal() # Scatter plot per gruppo ggplot(clinical_data, aes(x = age, y = white_blood_cells, color = diagnosis)) + geom_point(alpha = 0.6, size = 2) + geom_smooth(method = "lm", se = FALSE, linewidth = 1) + labs(title = "Relazione tra età e leucociti per diagnosi", x = "Età (anni)", y = "Leucociti (WBC)") + theme_minimal() + theme(legend.position = "bottom") </syntaxhighlight> === Matrice di Correlazione === <syntaxhighlight lang="r"> # Calcolare la matrice di correlazione numeric_data <- clinical_data %>% select_if(is.numeric) correlation_matrix <- cor(numeric_data, use = "complete.obs") print(correlation_matrix) # Visualizzare con ggplot library(reshape2) melted_corr <- melt(correlation_matrix) ggplot(melted_corr, aes(x = Var1, y = Var2, fill = value)) + geom_tile(color = "white") + geom_text(aes(label = round(value, 2)), size = 3) + scale_fill_gradient2(low = "blue", mid = "white", high = "red", limits = c(-1, 1)) + labs(title = "Matrice di Correlazione", x = "", y = "", fill = "Correlazione") + theme_minimal() + theme(axis.text.x = element_text(angle = 45, hjust = 1)) # Usare corrplot library(corrplot) corrplot(correlation_matrix, method = "circle", type = "upper", addCoef.col = "black", diag = FALSE, title = "Matrice di Correlazione - PenuX") </syntaxhighlight> == 3.4 Analisi Multivariata == === Analisi delle Componenti Principali (PCA) === <syntaxhighlight lang="r"> # Preparare i dati per PCA pca_data <- clinical_data %>% select_if(is.numeric) %>% scale() # Standardizzare # Eseguire PCA pca_result <- prcomp(pca_data, center = FALSE) # Riepilogo summary(pca_result) # Visualizzare la varianza spiegata scree_plot <- tibble( PC = 1:length(pca_result$sdev), Variance = (pca_result$sdev^2 / sum(pca_result$sdev^2)) * 100 ) ggplot(scree_plot, aes(x = PC, y = Variance)) + geom_col(fill = "steelblue", alpha = 0.7) + geom_line(color = "red", linewidth = 1) + labs(title = "Varianza Spiegata per Componente Principale", x = "Componente Principale", y = "Varianza Spiegata (%)") + theme_minimal() # Biplot biplot(pca_result, main = "PCA Biplot") </syntaxhighlight> === Clustering Analisi === <syntaxhighlight lang="r"> # K-means clustering kmeans_result <- kmeans(pca_data, centers = 3, nstart = 25) # Aggiungere i cluster ai dati clinical_data_clustered <- clinical_data %>% mutate(cluster = as.factor(kmeans_result$cluster)) # Visualizzare i cluster ggplot(clinical_data_clustered, aes(x = age, y = white_blood_cells, color = cluster)) + geom_point(size = 3, alpha = 0.6) + labs(title = "K-means Clustering (k=3)", x = "Età (anni)", y = "Leucociti (WBC)", color = "Cluster") + theme_minimal() # Hierarchical clustering library(dendextend) hc_result <- hclust(dist(pca_data), method = "ward.D2") # Dendrogram plot(hc_result, main = "Dendrogramma - Clustering Gerarchico", xlab = "Osservazioni", ylab = "Distanza") </syntaxhighlight> == 3.5 Analisi Diagnostica == === Test di Normalità === <syntaxhighlight lang="r"> # Test di Shapiro-Wilk shapiro_test <- shapiro.test(clinical_data$age) print(shapiro_test) # Test di Kolmogorov-Smirnov ks_test <- ks.test(clinical_data$age, "pnorm", mean = mean(clinical_data$age, na.rm = TRUE), sd = sd(clinical_data$age, na.rm = TRUE)) print(ks_test) # Q-Q plot ggplot(clinical_data, aes(sample = age)) + geom_qq() + geom_qq_line(color = "red") + labs(title = "Q-Q Plot - Età", x = "Quantili teorici", y = "Quantili osservati") + theme_minimal() </syntaxhighlight> === Test di Omoschedasticità === <syntaxhighlight lang="r"> # Test di Levene library(car) levene_test <- leveneTest(age ~ diagnosis, data = clinical_data) print(levene_test) # Test di Bartlett bartlett_test <- bartlett.test(age ~ diagnosis, data = clinical_data) print(bartlett_test) </syntaxhighlight> == 3.6 Generazione di Rapporti == === Rapporto EDA Automatico === <syntaxhighlight lang="r"> # Usare DataExplorer library(DataExplorer) # Creare un rapporto HTML automatico create_report(clinical_data, output_file = "eda_report.html", output_dir = "results/", y = "diagnosis") # Analisi di singole variabili plot_str(clinical_data) plot_missing(clinical_data) plot_histogram(clinical_data) plot_density(clinical_data) plot_boxplot(clinical_data, by = "diagnosis") plot_correlation(clinical_data, type = "continuous") </syntaxhighlight> === Rapporto Personalizzato === <syntaxhighlight lang="r"> # Creare un rapporto con R Markdown rmd_content <- " --- title: 'Analisi Esplorativa - PenuX' date: '`r Sys.Date()`' output: html_document --- ## Sommario dei Dati ```{r} summary(clinical_data) ``` ## Distribuzioni Univariate ```{r fig.width=12} # Istogrammi per tutte le variabili numeriche clinical_data %>% select_if(is.numeric) %>% pivot_longer(everything(), names_to = 'Variable', values_to = 'Value') %>% ggplot(aes(x = Value)) + geom_histogram(bins = 30, fill = 'steelblue') + facet_wrap(~Variable, scales = 'free') + theme_minimal() ``` ## Correlazioni ```{r} correlation_matrix <- cor(clinical_data %>% select_if(is.numeric), use = 'complete.obs') corrplot(correlation_matrix, method = 'circle', type = 'upper') ``` " # Scrivere il file R Markdown writeLines(rmd_content, "eda_report.Rmd") # Renderizzare il report library(rmarkdown) render("eda_report.Rmd", output_format = "html_document") </syntaxhighlight> == 3.7 Esercizi Pratici == # Caricare il dataset pulito da Unit 2 # Eseguire analisi statistiche descrittive # Creare almeno 10 visualizzazioni diverse # Identificare le principali relazioni tra variabili # Eseguire PCA e interpretare i risultati # Applicare clustering e valutarne la qualità # Generare un rapporto EDA completo # Documentare le ipotesi generate dall'esplorazione == 3.8 Verifica della Comprensione == * Quali test statistici usi per verificare la normalità dei dati? * Come interpreti una matrice di correlazione? * Quando e perché usi PCA? * Quali sono le differenze tra clustering k-means e gerarchico? * Come comunichi i risultati dell'EDA agli stakeholder clinici? == Riepilogo dell'unità 3 == Abbiamo trattato: * Analisi statistica descrittiva e raggruppata * Visualizzazioni univariate (istogrammi, box plot, violin plot) * Visualizzazioni bivariate e matrici di correlazione * Analisi multivariata (PCA, clustering) * Test diagnostici di normalità e omoschedasticità * Generazione automatica di rapporti EDA * Comunicazione efficace dei risultati == Letture Consigliate == * [https://ggplot2.tidyverse.org/ ggplot2 Documentation] * [https://cran.r-project.org/web/packages/DataExplorer/index.html DataExplorer Package] == Il progetto PenuX == Il codice sorgente, i modelli e la documentazione della piattaforma PenuX sono disponibili pubblicamente con licenza libera: * [https://github.com/netanelcyber/penux Repository PenuX su GitHub] * [https://penux.uk Sito del progetto PenuX] == Quiz == [[PenuX in R/Quiz Unità 3|Fai il quiz dell'Unità 3]] [[Categoria:PenuX in R|Unità 3 - Analisi Esplorativa dei Dati]] 73gib4wyusay6uh20uu9dj1ufmnfoz4 PenuX in R/Quiz Unità 3 0 61182 502066 502014 2026-10-04T14:54:44Z Hippias 18281 Hippias ha spostato la pagina [[PenuX in R: Quiz Unità 3]] a [[PenuX in R/Quiz Unità 3]] senza lasciare redirect: [[Aiuto:Convenzioni di nomenclatura|Convenzioni di nomenclatura]]: sottopagino correttamente 502014 wikitext text/x-wiki = PenuX in R: Quiz Unità 3 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Quale grafico mostra mediana e quartili? * A) Boxplot * B) Grafico a torta * C) Grafico a dispersione * D) Mappa di calore <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Il boxplot riassume mediana, quartili e valori estremi. </div> == Domanda 2 == Un coefficiente di correlazione r = -0,8 indica: * A) Nessuna correlazione * B) Una forte correlazione negativa * C) Una debole correlazione positiva * D) Un errore di calcolo <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Quando una variabile aumenta, l'altra tende a diminuire in modo marcato. </div> == Domanda 3 == A cosa serve l'analisi delle componenti principali (PCA)? * A) A imputare i valori mancanti * B) A dividere i dati in training e test * C) A ridurre la dimensionalità conservando la maggior parte della varianza * D) A calcolare l'AUC <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. La PCA riassume molte variabili correlate in poche componenti. </div> == Domanda 4 == Una correlazione elevata tra due variabili dimostra un nesso causale? * A) Sì, sempre * B) Sì, se r > 0,5 * C) Solo nei dati clinici * D) No, la correlazione da sola non prova la causalità <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Possono esserci variabili confondenti o coincidenze. </div> == Torna all'unità == [[PenuX in R: Unità 3 - Analisi Esplorativa dei Dati|Torna all'Unità 3]] 4i2as7plt0ctger8jkhg1fdd1eyau0n 502098 502066 2026-10-04T18:20:23Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502098 wikitext text/x-wiki = PenuX in R: Quiz Unità 3 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Quale grafico mostra mediana e quartili? * A) Boxplot * B) Grafico a torta * C) Grafico a dispersione * D) Mappa di calore <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Il boxplot riassume mediana, quartili e valori estremi. </div> == Domanda 2 == Un coefficiente di correlazione r = -0,8 indica: * A) Nessuna correlazione * B) Una forte correlazione negativa * C) Una debole correlazione positiva * D) Un errore di calcolo <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Quando una variabile aumenta, l'altra tende a diminuire in modo marcato. </div> == Domanda 3 == A cosa serve l'analisi delle componenti principali (PCA)? * A) A imputare i valori mancanti * B) A dividere i dati in training e test * C) A ridurre la dimensionalità conservando la maggior parte della varianza * D) A calcolare l'AUC <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. La PCA riassume molte variabili correlate in poche componenti. </div> == Domanda 4 == Una correlazione elevata tra due variabili dimostra un nesso causale? * A) Sì, sempre * B) Sì, se r > 0,5 * C) Solo nei dati clinici * D) No, la correlazione da sola non prova la causalità <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Possono esserci variabili confondenti o coincidenze. </div> == Torna all'unità == [[PenuX in R: Unità 3 - Analisi Esplorativa dei Dati|Torna all'Unità 3]] [[Categoria:PenuX in R|Quiz Unità 3]] 6aljzattbahf6kwesavjiawyibduy6n 502114 502098 2026-10-04T18:24:28Z Gian BOT 27470 bot: fix link 502114 wikitext text/x-wiki = PenuX in R: Quiz Unità 3 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Quale grafico mostra mediana e quartili? * A) Boxplot * B) Grafico a torta * C) Grafico a dispersione * D) Mappa di calore <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Il boxplot riassume mediana, quartili e valori estremi. </div> == Domanda 2 == Un coefficiente di correlazione r = -0,8 indica: * A) Nessuna correlazione * B) Una forte correlazione negativa * C) Una debole correlazione positiva * D) Un errore di calcolo <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Quando una variabile aumenta, l'altra tende a diminuire in modo marcato. </div> == Domanda 3 == A cosa serve l'analisi delle componenti principali (PCA)? * A) A imputare i valori mancanti * B) A dividere i dati in training e test * C) A ridurre la dimensionalità conservando la maggior parte della varianza * D) A calcolare l'AUC <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. La PCA riassume molte variabili correlate in poche componenti. </div> == Domanda 4 == Una correlazione elevata tra due variabili dimostra un nesso causale? * A) Sì, sempre * B) Sì, se r > 0,5 * C) Solo nei dati clinici * D) No, la correlazione da sola non prova la causalità <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Possono esserci variabili confondenti o coincidenze. </div> == Torna all'unità == [[PenuX in R/Unità 3 - Analisi Esplorativa dei Dati|Torna all'Unità 3]] [[Categoria:PenuX in R|Quiz Unità 3]] t2un0ulbmdpyyow5uvu3wvqv45e4n13 502129 502114 2026-10-04T18:32:39Z Gian BOT 27470 Bot: aggiunge l'indice 502129 wikitext text/x-wiki {{PenuX in R}} = PenuX in R: Quiz Unità 3 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Quale grafico mostra mediana e quartili? * A) Boxplot * B) Grafico a torta * C) Grafico a dispersione * D) Mappa di calore <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Il boxplot riassume mediana, quartili e valori estremi. </div> == Domanda 2 == Un coefficiente di correlazione r = -0,8 indica: * A) Nessuna correlazione * B) Una forte correlazione negativa * C) Una debole correlazione positiva * D) Un errore di calcolo <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Quando una variabile aumenta, l'altra tende a diminuire in modo marcato. </div> == Domanda 3 == A cosa serve l'analisi delle componenti principali (PCA)? * A) A imputare i valori mancanti * B) A dividere i dati in training e test * C) A ridurre la dimensionalità conservando la maggior parte della varianza * D) A calcolare l'AUC <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. La PCA riassume molte variabili correlate in poche componenti. </div> == Domanda 4 == Una correlazione elevata tra due variabili dimostra un nesso causale? * A) Sì, sempre * B) Sì, se r > 0,5 * C) Solo nei dati clinici * D) No, la correlazione da sola non prova la causalità <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Possono esserci variabili confondenti o coincidenze. </div> == Torna all'unità == [[PenuX in R/Unità 3 - Analisi Esplorativa dei Dati|Torna all'Unità 3]] [[Categoria:PenuX in R|Quiz Unità 3]] 33fydpissx28mb0kbm8rkzrln5tpplr PenuX in R/Unità 4 - Costruzione dei Modelli Predittivi 0 61183 502058 502015 2026-10-04T14:45:52Z Hippias 18281 Hippias ha spostato la pagina [[PenuX in R: Unità 4 - Costruzione dei Modelli Predittivi]] a [[PenuX in R/Unità 4 - Costruzione dei Modelli Predittivi]] senza lasciare redirect: [[Aiuto:Convenzioni di nomenclatura|Convenzioni di nomenclatura]]: sottopagino correttamente 502015 wikitext text/x-wiki = PenuX in R: Unità 4 - Costruzione dei Modelli Predittivi = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Suddividere i dati in training e test * Costruire modelli di regressione logistica * Implementare algoritmi di machine learning (Random Forest, SVM, XGBoost) * Ottimizzare gli iperparametri * Confrontare le prestazioni di diversi modelli * Gestire il class imbalance == 4.1 Preparazione dei Dati == === Train-Test Split === <syntaxhighlight lang="r"> library(caret) library(tidyverse) # Impostare il seed per riproducibilità set.seed(42) # Creare indici di training (80%) e test (20%) train_index <- createDataPartition(clinical_data$diagnosis, p = 0.8, list = FALSE) train_data <- clinical_data[train_index, ] test_data <- clinical_data[-train_index, ] cat("Training set:", nrow(train_data), "righe\n") cat("Test set:", nrow(test_data), "righe\n") cat("Proporzione diagnosi nel training:\n") print(table(train_data$diagnosis) / nrow(train_data)) </syntaxhighlight> === Cross-Validation === <syntaxhighlight lang="r"> # Configurare k-fold cross-validation train_control <- trainControl( method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary ) # Alternativa: Stratified k-fold per dataset sbilanciai train_control_stratified <- trainControl( method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary, sampling = "smote" # SMOTE per gestire imbalance ) </syntaxhighlight> == 4.2 Regressione Logistica == === Modello Base === <syntaxhighlight lang="r"> # Modello di regressione logistica logistic_model <- glm(diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, family = binomial(link = "logit"), data = train_data) # Riepilogo del modello summary(logistic_model) # Coefficienti e odds ratio coefficients(logistic_model) exp(coefficients(logistic_model)) </syntaxhighlight> === Previsioni e Valutazione === <syntaxhighlight lang="r"> # Previsioni sul test set predictions <- predict(logistic_model, newdata = test_data, type = "response") # Convertire in classi (soglia = 0.5) predicted_class <- ifelse(predictions > 0.5, "Disease", "Healthy") # Matrice di confusione conf_matrix <- confusionMatrix( factor(predicted_class), factor(test_data$diagnosis) ) print(conf_matrix) </syntaxhighlight> == 4.3 Random Forest == === Addestramento === <syntaxhighlight lang="r"> library(randomForest) # Random Forest basic rf_model <- randomForest( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = train_data, ntree = 500, mtry = sqrt(ncol(train_data) - 1), importance = TRUE ) print(rf_model) # Importanza delle variabili importance(rf_model) varImpPlot(rf_model, main = "Variable Importance - Random Forest") </syntaxhighlight> === Ottimizzazione Iperparametri === <syntaxhighlight lang="r"> # Tuning con caret rf_grid <- expand.grid( mtry = c(2, 3, 4, 5) ) rf_tuned <- train( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = train_data, method = "rf", trControl = train_control, tuneGrid = rf_grid, ntree = 500, metric = "ROC" ) plot(rf_tuned) print(rf_tuned$bestTune) </syntaxhighlight> == 4.4 Support Vector Machines (SVM) == <syntaxhighlight lang="r"> library(kernlab) # SVM con kernel radiale svm_model <- ksvm( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = train_data, kernel = "rbfdot", C = 1, prob.model = TRUE ) # Previsioni svm_pred <- predict(svm_model, newdata = test_data) confusionMatrix(svm_pred, test_data$diagnosis) </syntaxhighlight> == 4.5 XGBoost == === Addestramento === <syntaxhighlight lang="r"> library(xgboost) # Preparare i dati per XGBoost train_matrix <- xgb.DMatrix( data = as.matrix(train_data %>% select(age, systolic_bp, diastolic_bp, white_blood_cells, creatinine)), label = as.numeric(train_data$diagnosis) - 1 ) test_matrix <- xgb.DMatrix( data = as.matrix(test_data %>% select(age, systolic_bp, diastolic_bp, white_blood_cells, creatinine)), label = as.numeric(test_data$diagnosis) - 1 ) # Parametri params <- list( objective = "binary:logistic", max_depth = 6, eta = 0.1, gamma = 1, subsample = 0.8, colsample_bytree = 0.8 ) # Addestramento xgb_model <- xgb.train( params = params, data = train_matrix, nrounds = 100, watchlist = list(train = train_matrix, test = test_matrix), print_every_n = 10, early_stopping_rounds = 10 ) </syntaxhighlight> === Feature Importance === <syntaxhighlight lang="r"> # Feature importance importance_matrix <- xgb.importance( feature_names = c("age", "systolic_bp", "diastolic_bp", "white_blood_cells", "creatinine"), model = xgb_model ) xgb.plot.importance(importance_matrix) print(importance_matrix) </syntaxhighlight> == 4.6 Gestione del Class Imbalance == === SMOTE (Synthetic Minority Over-sampling) === <syntaxhighlight lang="r"> library(DMwR) # Applicare SMOTE balanced_data <- SMOTE(diagnosis ~ ., data = train_data, perc.over = 200, perc.under = 150) # Controllare il bilanciamento cat("Before SMOTE:\n") print(table(train_data$diagnosis)) cat("After SMOTE:\n") print(table(balanced_data$diagnosis)) # Addestrare il modello su dati bilanciati rf_balanced <- randomForest( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = balanced_data, ntree = 500 ) </syntaxhighlight> === Class Weights === <syntaxhighlight lang="r"> # Calcolare i pesi delle classi class_weights <- table(train_data$diagnosis) / nrow(train_data) scale_pos_weight <- class_weights["Healthy"] / class_weights["Disease"] # XGBoost con class weights xgb_weighted <- xgb.train( params = list( objective = "binary:logistic", max_depth = 6, eta = 0.1, scale_pos_weight = scale_pos_weight ), data = train_matrix, nrounds = 100 ) </syntaxhighlight> == 4.7 Salvataggio dei Modelli == === Serializzazione === <syntaxhighlight lang="r"> # Salvare il modello Random Forest saveRDS(rf_model, "models/rf_model.rds") # Salvare il modello XGBoost xgb.save(xgb_model, "models/xgb_model.model") # Caricare i modelli rf_loaded <- readRDS("models/rf_model.rds") xgb_loaded <- xgb.load("models/xgb_model.model") # Previsioni con modello caricato pred_loaded <- predict(rf_loaded, newdata = test_data) </syntaxhighlight> == 4.8 Esercizi Pratici == # Dividere i dati in training (80%) e test (20%) # Addestrare una regressione logistica # Addestrare un Random Forest con tuning # Addestrare un modello SVM # Addestrare un modello XGBoost # Confrontare le prestazioni dei tre modelli # Gestire il class imbalance con SMOTE # Salvare i modelli migliori == Riepilogo dell'unità 4 == Abbiamo trattato: * Preparazione e suddivisione dei dati * Regressione logistica * Random Forest con ottimizzazione iperparametri * Support Vector Machines * XGBoost * Gestione del class imbalance * Salvataggio e caricamento dei modelli == Il progetto PenuX == Il codice sorgente è disponibile su GitHub: https://github.com/netanelcyber/penux == Quiz == [[PenuX in R: Quiz Unità 4|Fai il quiz dell'Unità 4]] kw6chom36v2itv936n6yehazoq34jiz 502107 502058 2026-10-04T18:22:05Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502107 wikitext text/x-wiki = PenuX in R: Unità 4 - Costruzione dei Modelli Predittivi = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Suddividere i dati in training e test * Costruire modelli di regressione logistica * Implementare algoritmi di machine learning (Random Forest, SVM, XGBoost) * Ottimizzare gli iperparametri * Confrontare le prestazioni di diversi modelli * Gestire il class imbalance == 4.1 Preparazione dei Dati == === Train-Test Split === <syntaxhighlight lang="r"> library(caret) library(tidyverse) # Impostare il seed per riproducibilità set.seed(42) # Creare indici di training (80%) e test (20%) train_index <- createDataPartition(clinical_data$diagnosis, p = 0.8, list = FALSE) train_data <- clinical_data[train_index, ] test_data <- clinical_data[-train_index, ] cat("Training set:", nrow(train_data), "righe\n") cat("Test set:", nrow(test_data), "righe\n") cat("Proporzione diagnosi nel training:\n") print(table(train_data$diagnosis) / nrow(train_data)) </syntaxhighlight> === Cross-Validation === <syntaxhighlight lang="r"> # Configurare k-fold cross-validation train_control <- trainControl( method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary ) # Alternativa: Stratified k-fold per dataset sbilanciai train_control_stratified <- trainControl( method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary, sampling = "smote" # SMOTE per gestire imbalance ) </syntaxhighlight> == 4.2 Regressione Logistica == === Modello Base === <syntaxhighlight lang="r"> # Modello di regressione logistica logistic_model <- glm(diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, family = binomial(link = "logit"), data = train_data) # Riepilogo del modello summary(logistic_model) # Coefficienti e odds ratio coefficients(logistic_model) exp(coefficients(logistic_model)) </syntaxhighlight> === Previsioni e Valutazione === <syntaxhighlight lang="r"> # Previsioni sul test set predictions <- predict(logistic_model, newdata = test_data, type = "response") # Convertire in classi (soglia = 0.5) predicted_class <- ifelse(predictions > 0.5, "Disease", "Healthy") # Matrice di confusione conf_matrix <- confusionMatrix( factor(predicted_class), factor(test_data$diagnosis) ) print(conf_matrix) </syntaxhighlight> == 4.3 Random Forest == === Addestramento === <syntaxhighlight lang="r"> library(randomForest) # Random Forest basic rf_model <- randomForest( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = train_data, ntree = 500, mtry = sqrt(ncol(train_data) - 1), importance = TRUE ) print(rf_model) # Importanza delle variabili importance(rf_model) varImpPlot(rf_model, main = "Variable Importance - Random Forest") </syntaxhighlight> === Ottimizzazione Iperparametri === <syntaxhighlight lang="r"> # Tuning con caret rf_grid <- expand.grid( mtry = c(2, 3, 4, 5) ) rf_tuned <- train( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = train_data, method = "rf", trControl = train_control, tuneGrid = rf_grid, ntree = 500, metric = "ROC" ) plot(rf_tuned) print(rf_tuned$bestTune) </syntaxhighlight> == 4.4 Support Vector Machines (SVM) == <syntaxhighlight lang="r"> library(kernlab) # SVM con kernel radiale svm_model <- ksvm( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = train_data, kernel = "rbfdot", C = 1, prob.model = TRUE ) # Previsioni svm_pred <- predict(svm_model, newdata = test_data) confusionMatrix(svm_pred, test_data$diagnosis) </syntaxhighlight> == 4.5 XGBoost == === Addestramento === <syntaxhighlight lang="r"> library(xgboost) # Preparare i dati per XGBoost train_matrix <- xgb.DMatrix( data = as.matrix(train_data %>% select(age, systolic_bp, diastolic_bp, white_blood_cells, creatinine)), label = as.numeric(train_data$diagnosis) - 1 ) test_matrix <- xgb.DMatrix( data = as.matrix(test_data %>% select(age, systolic_bp, diastolic_bp, white_blood_cells, creatinine)), label = as.numeric(test_data$diagnosis) - 1 ) # Parametri params <- list( objective = "binary:logistic", max_depth = 6, eta = 0.1, gamma = 1, subsample = 0.8, colsample_bytree = 0.8 ) # Addestramento xgb_model <- xgb.train( params = params, data = train_matrix, nrounds = 100, watchlist = list(train = train_matrix, test = test_matrix), print_every_n = 10, early_stopping_rounds = 10 ) </syntaxhighlight> === Feature Importance === <syntaxhighlight lang="r"> # Feature importance importance_matrix <- xgb.importance( feature_names = c("age", "systolic_bp", "diastolic_bp", "white_blood_cells", "creatinine"), model = xgb_model ) xgb.plot.importance(importance_matrix) print(importance_matrix) </syntaxhighlight> == 4.6 Gestione del Class Imbalance == === SMOTE (Synthetic Minority Over-sampling) === <syntaxhighlight lang="r"> library(DMwR) # Applicare SMOTE balanced_data <- SMOTE(diagnosis ~ ., data = train_data, perc.over = 200, perc.under = 150) # Controllare il bilanciamento cat("Before SMOTE:\n") print(table(train_data$diagnosis)) cat("After SMOTE:\n") print(table(balanced_data$diagnosis)) # Addestrare il modello su dati bilanciati rf_balanced <- randomForest( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = balanced_data, ntree = 500 ) </syntaxhighlight> === Class Weights === <syntaxhighlight lang="r"> # Calcolare i pesi delle classi class_weights <- table(train_data$diagnosis) / nrow(train_data) scale_pos_weight <- class_weights["Healthy"] / class_weights["Disease"] # XGBoost con class weights xgb_weighted <- xgb.train( params = list( objective = "binary:logistic", max_depth = 6, eta = 0.1, scale_pos_weight = scale_pos_weight ), data = train_matrix, nrounds = 100 ) </syntaxhighlight> == 4.7 Salvataggio dei Modelli == === Serializzazione === <syntaxhighlight lang="r"> # Salvare il modello Random Forest saveRDS(rf_model, "models/rf_model.rds") # Salvare il modello XGBoost xgb.save(xgb_model, "models/xgb_model.model") # Caricare i modelli rf_loaded <- readRDS("models/rf_model.rds") xgb_loaded <- xgb.load("models/xgb_model.model") # Previsioni con modello caricato pred_loaded <- predict(rf_loaded, newdata = test_data) </syntaxhighlight> == 4.8 Esercizi Pratici == # Dividere i dati in training (80%) e test (20%) # Addestrare una regressione logistica # Addestrare un Random Forest con tuning # Addestrare un modello SVM # Addestrare un modello XGBoost # Confrontare le prestazioni dei tre modelli # Gestire il class imbalance con SMOTE # Salvare i modelli migliori == Riepilogo dell'unità 4 == Abbiamo trattato: * Preparazione e suddivisione dei dati * Regressione logistica * Random Forest con ottimizzazione iperparametri * Support Vector Machines * XGBoost * Gestione del class imbalance * Salvataggio e caricamento dei modelli == Il progetto PenuX == Il codice sorgente è disponibile su GitHub: https://github.com/netanelcyber/penux == Quiz == [[PenuX in R: Quiz Unità 4|Fai il quiz dell'Unità 4]] [[Categoria:PenuX in R|Unità 4 - Costruzione dei Modelli Predittivi]] q5p941ftpoot80sa57vdgze2hu3as85 502122 502107 2026-10-04T18:25:48Z Gian BOT 27470 bot: fix link 502122 wikitext text/x-wiki = PenuX in R: Unità 4 - Costruzione dei Modelli Predittivi = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Suddividere i dati in training e test * Costruire modelli di regressione logistica * Implementare algoritmi di machine learning (Random Forest, SVM, XGBoost) * Ottimizzare gli iperparametri * Confrontare le prestazioni di diversi modelli * Gestire il class imbalance == 4.1 Preparazione dei Dati == === Train-Test Split === <syntaxhighlight lang="r"> library(caret) library(tidyverse) # Impostare il seed per riproducibilità set.seed(42) # Creare indici di training (80%) e test (20%) train_index <- createDataPartition(clinical_data$diagnosis, p = 0.8, list = FALSE) train_data <- clinical_data[train_index, ] test_data <- clinical_data[-train_index, ] cat("Training set:", nrow(train_data), "righe\n") cat("Test set:", nrow(test_data), "righe\n") cat("Proporzione diagnosi nel training:\n") print(table(train_data$diagnosis) / nrow(train_data)) </syntaxhighlight> === Cross-Validation === <syntaxhighlight lang="r"> # Configurare k-fold cross-validation train_control <- trainControl( method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary ) # Alternativa: Stratified k-fold per dataset sbilanciai train_control_stratified <- trainControl( method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary, sampling = "smote" # SMOTE per gestire imbalance ) </syntaxhighlight> == 4.2 Regressione Logistica == === Modello Base === <syntaxhighlight lang="r"> # Modello di regressione logistica logistic_model <- glm(diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, family = binomial(link = "logit"), data = train_data) # Riepilogo del modello summary(logistic_model) # Coefficienti e odds ratio coefficients(logistic_model) exp(coefficients(logistic_model)) </syntaxhighlight> === Previsioni e Valutazione === <syntaxhighlight lang="r"> # Previsioni sul test set predictions <- predict(logistic_model, newdata = test_data, type = "response") # Convertire in classi (soglia = 0.5) predicted_class <- ifelse(predictions > 0.5, "Disease", "Healthy") # Matrice di confusione conf_matrix <- confusionMatrix( factor(predicted_class), factor(test_data$diagnosis) ) print(conf_matrix) </syntaxhighlight> == 4.3 Random Forest == === Addestramento === <syntaxhighlight lang="r"> library(randomForest) # Random Forest basic rf_model <- randomForest( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = train_data, ntree = 500, mtry = sqrt(ncol(train_data) - 1), importance = TRUE ) print(rf_model) # Importanza delle variabili importance(rf_model) varImpPlot(rf_model, main = "Variable Importance - Random Forest") </syntaxhighlight> === Ottimizzazione Iperparametri === <syntaxhighlight lang="r"> # Tuning con caret rf_grid <- expand.grid( mtry = c(2, 3, 4, 5) ) rf_tuned <- train( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = train_data, method = "rf", trControl = train_control, tuneGrid = rf_grid, ntree = 500, metric = "ROC" ) plot(rf_tuned) print(rf_tuned$bestTune) </syntaxhighlight> == 4.4 Support Vector Machines (SVM) == <syntaxhighlight lang="r"> library(kernlab) # SVM con kernel radiale svm_model <- ksvm( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = train_data, kernel = "rbfdot", C = 1, prob.model = TRUE ) # Previsioni svm_pred <- predict(svm_model, newdata = test_data) confusionMatrix(svm_pred, test_data$diagnosis) </syntaxhighlight> == 4.5 XGBoost == === Addestramento === <syntaxhighlight lang="r"> library(xgboost) # Preparare i dati per XGBoost train_matrix <- xgb.DMatrix( data = as.matrix(train_data %>% select(age, systolic_bp, diastolic_bp, white_blood_cells, creatinine)), label = as.numeric(train_data$diagnosis) - 1 ) test_matrix <- xgb.DMatrix( data = as.matrix(test_data %>% select(age, systolic_bp, diastolic_bp, white_blood_cells, creatinine)), label = as.numeric(test_data$diagnosis) - 1 ) # Parametri params <- list( objective = "binary:logistic", max_depth = 6, eta = 0.1, gamma = 1, subsample = 0.8, colsample_bytree = 0.8 ) # Addestramento xgb_model <- xgb.train( params = params, data = train_matrix, nrounds = 100, watchlist = list(train = train_matrix, test = test_matrix), print_every_n = 10, early_stopping_rounds = 10 ) </syntaxhighlight> === Feature Importance === <syntaxhighlight lang="r"> # Feature importance importance_matrix <- xgb.importance( feature_names = c("age", "systolic_bp", "diastolic_bp", "white_blood_cells", "creatinine"), model = xgb_model ) xgb.plot.importance(importance_matrix) print(importance_matrix) </syntaxhighlight> == 4.6 Gestione del Class Imbalance == === SMOTE (Synthetic Minority Over-sampling) === <syntaxhighlight lang="r"> library(DMwR) # Applicare SMOTE balanced_data <- SMOTE(diagnosis ~ ., data = train_data, perc.over = 200, perc.under = 150) # Controllare il bilanciamento cat("Before SMOTE:\n") print(table(train_data$diagnosis)) cat("After SMOTE:\n") print(table(balanced_data$diagnosis)) # Addestrare il modello su dati bilanciati rf_balanced <- randomForest( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = balanced_data, ntree = 500 ) </syntaxhighlight> === Class Weights === <syntaxhighlight lang="r"> # Calcolare i pesi delle classi class_weights <- table(train_data$diagnosis) / nrow(train_data) scale_pos_weight <- class_weights["Healthy"] / class_weights["Disease"] # XGBoost con class weights xgb_weighted <- xgb.train( params = list( objective = "binary:logistic", max_depth = 6, eta = 0.1, scale_pos_weight = scale_pos_weight ), data = train_matrix, nrounds = 100 ) </syntaxhighlight> == 4.7 Salvataggio dei Modelli == === Serializzazione === <syntaxhighlight lang="r"> # Salvare il modello Random Forest saveRDS(rf_model, "models/rf_model.rds") # Salvare il modello XGBoost xgb.save(xgb_model, "models/xgb_model.model") # Caricare i modelli rf_loaded <- readRDS("models/rf_model.rds") xgb_loaded <- xgb.load("models/xgb_model.model") # Previsioni con modello caricato pred_loaded <- predict(rf_loaded, newdata = test_data) </syntaxhighlight> == 4.8 Esercizi Pratici == # Dividere i dati in training (80%) e test (20%) # Addestrare una regressione logistica # Addestrare un Random Forest con tuning # Addestrare un modello SVM # Addestrare un modello XGBoost # Confrontare le prestazioni dei tre modelli # Gestire il class imbalance con SMOTE # Salvare i modelli migliori == Riepilogo dell'unità 4 == Abbiamo trattato: * Preparazione e suddivisione dei dati * Regressione logistica * Random Forest con ottimizzazione iperparametri * Support Vector Machines * XGBoost * Gestione del class imbalance * Salvataggio e caricamento dei modelli == Il progetto PenuX == Il codice sorgente è disponibile su GitHub: https://github.com/netanelcyber/penux == Quiz == [[PenuX in R/Quiz Unità 4|Fai il quiz dell'Unità 4]] [[Categoria:PenuX in R|Unità 4 - Costruzione dei Modelli Predittivi]] 39oq9jd4altn050zs10prkma4eytxr8 502137 502122 2026-10-04T18:34:13Z Gian BOT 27470 Bot: aggiunge l'indice 502137 wikitext text/x-wiki {{PenuX in R}} = PenuX in R: Unità 4 - Costruzione dei Modelli Predittivi = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Suddividere i dati in training e test * Costruire modelli di regressione logistica * Implementare algoritmi di machine learning (Random Forest, SVM, XGBoost) * Ottimizzare gli iperparametri * Confrontare le prestazioni di diversi modelli * Gestire il class imbalance == 4.1 Preparazione dei Dati == === Train-Test Split === <syntaxhighlight lang="r"> library(caret) library(tidyverse) # Impostare il seed per riproducibilità set.seed(42) # Creare indici di training (80%) e test (20%) train_index <- createDataPartition(clinical_data$diagnosis, p = 0.8, list = FALSE) train_data <- clinical_data[train_index, ] test_data <- clinical_data[-train_index, ] cat("Training set:", nrow(train_data), "righe\n") cat("Test set:", nrow(test_data), "righe\n") cat("Proporzione diagnosi nel training:\n") print(table(train_data$diagnosis) / nrow(train_data)) </syntaxhighlight> === Cross-Validation === <syntaxhighlight lang="r"> # Configurare k-fold cross-validation train_control <- trainControl( method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary ) # Alternativa: Stratified k-fold per dataset sbilanciai train_control_stratified <- trainControl( method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary, sampling = "smote" # SMOTE per gestire imbalance ) </syntaxhighlight> == 4.2 Regressione Logistica == === Modello Base === <syntaxhighlight lang="r"> # Modello di regressione logistica logistic_model <- glm(diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, family = binomial(link = "logit"), data = train_data) # Riepilogo del modello summary(logistic_model) # Coefficienti e odds ratio coefficients(logistic_model) exp(coefficients(logistic_model)) </syntaxhighlight> === Previsioni e Valutazione === <syntaxhighlight lang="r"> # Previsioni sul test set predictions <- predict(logistic_model, newdata = test_data, type = "response") # Convertire in classi (soglia = 0.5) predicted_class <- ifelse(predictions > 0.5, "Disease", "Healthy") # Matrice di confusione conf_matrix <- confusionMatrix( factor(predicted_class), factor(test_data$diagnosis) ) print(conf_matrix) </syntaxhighlight> == 4.3 Random Forest == === Addestramento === <syntaxhighlight lang="r"> library(randomForest) # Random Forest basic rf_model <- randomForest( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = train_data, ntree = 500, mtry = sqrt(ncol(train_data) - 1), importance = TRUE ) print(rf_model) # Importanza delle variabili importance(rf_model) varImpPlot(rf_model, main = "Variable Importance - Random Forest") </syntaxhighlight> === Ottimizzazione Iperparametri === <syntaxhighlight lang="r"> # Tuning con caret rf_grid <- expand.grid( mtry = c(2, 3, 4, 5) ) rf_tuned <- train( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = train_data, method = "rf", trControl = train_control, tuneGrid = rf_grid, ntree = 500, metric = "ROC" ) plot(rf_tuned) print(rf_tuned$bestTune) </syntaxhighlight> == 4.4 Support Vector Machines (SVM) == <syntaxhighlight lang="r"> library(kernlab) # SVM con kernel radiale svm_model <- ksvm( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = train_data, kernel = "rbfdot", C = 1, prob.model = TRUE ) # Previsioni svm_pred <- predict(svm_model, newdata = test_data) confusionMatrix(svm_pred, test_data$diagnosis) </syntaxhighlight> == 4.5 XGBoost == === Addestramento === <syntaxhighlight lang="r"> library(xgboost) # Preparare i dati per XGBoost train_matrix <- xgb.DMatrix( data = as.matrix(train_data %>% select(age, systolic_bp, diastolic_bp, white_blood_cells, creatinine)), label = as.numeric(train_data$diagnosis) - 1 ) test_matrix <- xgb.DMatrix( data = as.matrix(test_data %>% select(age, systolic_bp, diastolic_bp, white_blood_cells, creatinine)), label = as.numeric(test_data$diagnosis) - 1 ) # Parametri params <- list( objective = "binary:logistic", max_depth = 6, eta = 0.1, gamma = 1, subsample = 0.8, colsample_bytree = 0.8 ) # Addestramento xgb_model <- xgb.train( params = params, data = train_matrix, nrounds = 100, watchlist = list(train = train_matrix, test = test_matrix), print_every_n = 10, early_stopping_rounds = 10 ) </syntaxhighlight> === Feature Importance === <syntaxhighlight lang="r"> # Feature importance importance_matrix <- xgb.importance( feature_names = c("age", "systolic_bp", "diastolic_bp", "white_blood_cells", "creatinine"), model = xgb_model ) xgb.plot.importance(importance_matrix) print(importance_matrix) </syntaxhighlight> == 4.6 Gestione del Class Imbalance == === SMOTE (Synthetic Minority Over-sampling) === <syntaxhighlight lang="r"> library(DMwR) # Applicare SMOTE balanced_data <- SMOTE(diagnosis ~ ., data = train_data, perc.over = 200, perc.under = 150) # Controllare il bilanciamento cat("Before SMOTE:\n") print(table(train_data$diagnosis)) cat("After SMOTE:\n") print(table(balanced_data$diagnosis)) # Addestrare il modello su dati bilanciati rf_balanced <- randomForest( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = balanced_data, ntree = 500 ) </syntaxhighlight> === Class Weights === <syntaxhighlight lang="r"> # Calcolare i pesi delle classi class_weights <- table(train_data$diagnosis) / nrow(train_data) scale_pos_weight <- class_weights["Healthy"] / class_weights["Disease"] # XGBoost con class weights xgb_weighted <- xgb.train( params = list( objective = "binary:logistic", max_depth = 6, eta = 0.1, scale_pos_weight = scale_pos_weight ), data = train_matrix, nrounds = 100 ) </syntaxhighlight> == 4.7 Salvataggio dei Modelli == === Serializzazione === <syntaxhighlight lang="r"> # Salvare il modello Random Forest saveRDS(rf_model, "models/rf_model.rds") # Salvare il modello XGBoost xgb.save(xgb_model, "models/xgb_model.model") # Caricare i modelli rf_loaded <- readRDS("models/rf_model.rds") xgb_loaded <- xgb.load("models/xgb_model.model") # Previsioni con modello caricato pred_loaded <- predict(rf_loaded, newdata = test_data) </syntaxhighlight> == 4.8 Esercizi Pratici == # Dividere i dati in training (80%) e test (20%) # Addestrare una regressione logistica # Addestrare un Random Forest con tuning # Addestrare un modello SVM # Addestrare un modello XGBoost # Confrontare le prestazioni dei tre modelli # Gestire il class imbalance con SMOTE # Salvare i modelli migliori == Riepilogo dell'unità 4 == Abbiamo trattato: * Preparazione e suddivisione dei dati * Regressione logistica * Random Forest con ottimizzazione iperparametri * Support Vector Machines * XGBoost * Gestione del class imbalance * Salvataggio e caricamento dei modelli == Il progetto PenuX == Il codice sorgente è disponibile su GitHub: https://github.com/netanelcyber/penux == Quiz == [[PenuX in R/Quiz Unità 4|Fai il quiz dell'Unità 4]] [[Categoria:PenuX in R|Unità 4 - Costruzione dei Modelli Predittivi]] 3wx54bpmmujcdhk1o3wvowpydpc23p7 PenuX in R/Quiz Unità 4 0 61184 502067 502016 2026-10-04T14:54:53Z Hippias 18281 Hippias ha spostato la pagina [[PenuX in R: Quiz Unità 4]] a [[PenuX in R/Quiz Unità 4]] senza lasciare redirect: [[Aiuto:Convenzioni di nomenclatura|Convenzioni di nomenclatura]]: sottopagino correttamente 502016 wikitext text/x-wiki = PenuX in R: Quiz Unità 4 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Perché si divide il dataset in training e test set? * A) Per ridurre il numero di variabili * B) Per valutare il modello su dati che non ha mai visto * C) Per eliminare i valori mancanti * D) Per velocizzare la lettura del file <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. La valutazione sui dati di addestramento è troppo ottimistica. </div> == Domanda 2 == Come funziona una Random Forest? * A) Usa un solo albero molto profondo * B) Calcola la media di tutte le variabili * C) Combina molti alberi addestrati su campioni bootstrap e variabili casuali * D) Applica una regressione lineare <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. L'aggregazione di molti alberi riduce la varianza. </div> == Domanda 3 == Che cos'è l'overfitting? * A) Prestazioni scarse ovunque * B) Un errore di sintassi in R * C) Un metodo di imputazione * D) Ottime prestazioni sul training ma scarse su dati nuovi <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Il modello memorizza il rumore invece di apprendere il segnale. </div> == Domanda 4 == Quale tecnica aiuta con classi molto sbilanciate? * A) Pesi di classe o SMOTE * B) Eliminare la classe minoritaria * C) Usare solo l'accuratezza * D) Standardizzare l'esito <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Con classi sbilanciate l'accuratezza da sola può ingannare. </div> == Torna all'unità == [[PenuX in R: Unità 4 - Costruzione dei Modelli Predittivi|Torna all'Unità 4]] ljigbwebu1jktjjarmw4v38sjhios84 502099 502067 2026-10-04T18:20:37Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502099 wikitext text/x-wiki = PenuX in R: Quiz Unità 4 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Perché si divide il dataset in training e test set? * A) Per ridurre il numero di variabili * B) Per valutare il modello su dati che non ha mai visto * C) Per eliminare i valori mancanti * D) Per velocizzare la lettura del file <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. La valutazione sui dati di addestramento è troppo ottimistica. </div> == Domanda 2 == Come funziona una Random Forest? * A) Usa un solo albero molto profondo * B) Calcola la media di tutte le variabili * C) Combina molti alberi addestrati su campioni bootstrap e variabili casuali * D) Applica una regressione lineare <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. L'aggregazione di molti alberi riduce la varianza. </div> == Domanda 3 == Che cos'è l'overfitting? * A) Prestazioni scarse ovunque * B) Un errore di sintassi in R * C) Un metodo di imputazione * D) Ottime prestazioni sul training ma scarse su dati nuovi <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Il modello memorizza il rumore invece di apprendere il segnale. </div> == Domanda 4 == Quale tecnica aiuta con classi molto sbilanciate? * A) Pesi di classe o SMOTE * B) Eliminare la classe minoritaria * C) Usare solo l'accuratezza * D) Standardizzare l'esito <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Con classi sbilanciate l'accuratezza da sola può ingannare. </div> == Torna all'unità == [[PenuX in R: Unità 4 - Costruzione dei Modelli Predittivi|Torna all'Unità 4]] [[Categoria:PenuX in R|Quiz Unità 4]] d0uztv3lapedxs2uo8biyfo6dnp67ze 502115 502099 2026-10-04T18:24:38Z Gian BOT 27470 bot: fix link 502115 wikitext text/x-wiki = PenuX in R: Quiz Unità 4 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Perché si divide il dataset in training e test set? * A) Per ridurre il numero di variabili * B) Per valutare il modello su dati che non ha mai visto * C) Per eliminare i valori mancanti * D) Per velocizzare la lettura del file <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. La valutazione sui dati di addestramento è troppo ottimistica. </div> == Domanda 2 == Come funziona una Random Forest? * A) Usa un solo albero molto profondo * B) Calcola la media di tutte le variabili * C) Combina molti alberi addestrati su campioni bootstrap e variabili casuali * D) Applica una regressione lineare <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. L'aggregazione di molti alberi riduce la varianza. </div> == Domanda 3 == Che cos'è l'overfitting? * A) Prestazioni scarse ovunque * B) Un errore di sintassi in R * C) Un metodo di imputazione * D) Ottime prestazioni sul training ma scarse su dati nuovi <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Il modello memorizza il rumore invece di apprendere il segnale. </div> == Domanda 4 == Quale tecnica aiuta con classi molto sbilanciate? * A) Pesi di classe o SMOTE * B) Eliminare la classe minoritaria * C) Usare solo l'accuratezza * D) Standardizzare l'esito <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Con classi sbilanciate l'accuratezza da sola può ingannare. </div> == Torna all'unità == [[PenuX in R/Unità 4 - Costruzione dei Modelli Predittivi|Torna all'Unità 4]] [[Categoria:PenuX in R|Quiz Unità 4]] orayl7ohlken6omf71lngv37titnq68 502130 502115 2026-10-04T18:32:49Z Gian BOT 27470 Bot: aggiunge l'indice 502130 wikitext text/x-wiki {{PenuX in R}} = PenuX in R: Quiz Unità 4 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Perché si divide il dataset in training e test set? * A) Per ridurre il numero di variabili * B) Per valutare il modello su dati che non ha mai visto * C) Per eliminare i valori mancanti * D) Per velocizzare la lettura del file <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. La valutazione sui dati di addestramento è troppo ottimistica. </div> == Domanda 2 == Come funziona una Random Forest? * A) Usa un solo albero molto profondo * B) Calcola la media di tutte le variabili * C) Combina molti alberi addestrati su campioni bootstrap e variabili casuali * D) Applica una regressione lineare <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. L'aggregazione di molti alberi riduce la varianza. </div> == Domanda 3 == Che cos'è l'overfitting? * A) Prestazioni scarse ovunque * B) Un errore di sintassi in R * C) Un metodo di imputazione * D) Ottime prestazioni sul training ma scarse su dati nuovi <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Il modello memorizza il rumore invece di apprendere il segnale. </div> == Domanda 4 == Quale tecnica aiuta con classi molto sbilanciate? * A) Pesi di classe o SMOTE * B) Eliminare la classe minoritaria * C) Usare solo l'accuratezza * D) Standardizzare l'esito <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Con classi sbilanciate l'accuratezza da sola può ingannare. </div> == Torna all'unità == [[PenuX in R/Unità 4 - Costruzione dei Modelli Predittivi|Torna all'Unità 4]] [[Categoria:PenuX in R|Quiz Unità 4]] pgnnxthvc0erwxsn29b27ko6332jjzu PenuX in R/Unità 5 - Valutazione e Validazione dei Modelli 0 61185 502059 502017 2026-10-04T14:46:09Z Hippias 18281 Hippias ha spostato la pagina [[PenuX in R: Unità 5 - Valutazione e Validazione dei Modelli]] a [[PenuX in R:/Unità 5 - Valutazione e Validazione dei Modelli]] senza lasciare redirect: [[Aiuto:Convenzioni di nomenclatura|Convenzioni di nomenclatura]]: sottopagino correttamente 502017 wikitext text/x-wiki = PenuX in R: Unità 5 - Valutazione e Validazione dei Modelli = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Calcolare metriche di valutazione (accuracy, sensitivity, specificity) * Costruire curve ROC e calcolare AUC * Valutare le prestazioni su dati clinici * Eseguire validazione esterna * Confrontare modelli statisticamente * Documentare le prestazioni == 5.1 Metriche di Valutazione == === Matrice di Confusione e Metriche Derivate === <syntaxhighlight lang="r"> library(caret) library(ggplot2) # Previsioni predictions <- predict(rf_model, newdata = test_data, type = "class") # Matrice di confusione conf_matrix <- confusionMatrix(predictions, test_data$diagnosis) print(conf_matrix) # Estrarre metriche accuracy <- conf_matrix$overall['Accuracy'] sensitivity <- conf_matrix$byClass['Sensitivity'] specificity <- conf_matrix$byClass['Specificity'] ppv <- conf_matrix$byClass['Pos Pred Value'] npv <- conf_matrix$byClass['Neg Pred Value'] metrics_df <- data.frame( Metric = c("Accuracy", "Sensitivity (TPR)", "Specificity (TNR)", "PPV", "NPV"), Value = c(accuracy, sensitivity, specificity, ppv, npv) ) print(metrics_df) </syntaxhighlight> === Visualizzare la Matrice di Confusione === <syntaxhighlight lang="r"> # Creare una visualizzazione della matrice di confusione cm_table <- as.data.frame(table( Predicted = predictions, Actual = test_data$diagnosis )) ggplot(cm_table, aes(x = Predicted, y = Actual, fill = Freq)) + geom_tile() + geom_text(aes(label = Freq), color = "white", size = 8) + scale_fill_gradient(low = "lightblue", high = "darkblue") + labs(title = "Matrice di Confusione", x = "Predetto", y = "Reale", fill = "Frequenza") + theme_minimal() </syntaxhighlight> == 5.2 Curve ROC e AUC == === Calcolo di ROC e AUC === <syntaxhighlight lang="r"> library(pROC) # Previsioni probabilistiche prob_predictions <- predict(rf_model, newdata = test_data, type = "prob") # Calcolare ROC roc_curve <- roc(response = test_data$diagnosis, predictor = prob_predictions[, "Disease"]) # AUC auc_value <- auc(roc_curve) print(paste("AUC:", round(auc_value, 3))) # Plottare la curva ROC plot(roc_curve, main = "Curva ROC - Random Forest", xlab = "1 - Specificity", ylab = "Sensitivity") text(0.5, 0.2, paste("AUC =", round(auc_value, 3)), cex = 2) </syntaxhighlight> === Confronto di Modelli con ROC === <syntaxhighlight lang="r"> # ROC per più modelli roc_rf <- roc(test_data$diagnosis, predict(rf_model, test_data, type = "prob")[, "Disease"]) roc_xgb <- roc(test_data$diagnosis, predict(xgb_model, test_matrix, type = "prob")) roc_svm <- roc(test_data$diagnosis, predict(svm_model, test_data, type = "prob")[, "Disease"]) # Plot comparativo ggroc(list(RandomForest = roc_rf, XGBoost = roc_xgb, SVM = roc_svm)) + ggtitle("Confronto delle curve ROC") + theme_minimal() # AUC per ogni modello data.frame( Model = c("Random Forest", "XGBoost", "SVM"), AUC = c(auc(roc_rf), auc(roc_xgb), auc(roc_svm)) ) </syntaxhighlight> == 5.3 Validazione Esterna == === Cross-Validation === <syntaxhighlight lang="r"> # K-fold cross-validation train_control <- trainControl( method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary ) # Addestrare con CV cv_model <- train( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = clinical_data, method = "rf", trControl = train_control, metric = "ROC" ) # Risultati cross-validation print(cv_model$results) print(cv_model$resample) </syntaxhighlight> === Validazione su Dataset Esterno === <syntaxhighlight lang="r"> # Simulare un dataset esterno external_data <- clinical_data %>% sample_frac(0.2) # Previsioni external_predictions <- predict(rf_model, newdata = external_data) # Valutazione external_cm <- confusionMatrix(external_predictions, external_data$diagnosis) print(external_cm) # Confrontare con test set cat("Accuracy - Test Set:", accuracy, "\n") cat("Accuracy - External Set:", external_cm$overall['Accuracy'], "\n") </syntaxhighlight> == 5.4 Calibrazione del Modello == === Verifica della Calibrazione === <syntaxhighlight lang="r"> library(MASS) # Previsioni probabilistiche prob_preds <- predict(rf_model, newdata = test_data, type = "prob")[, "Disease"] # Creare gruppi di decile deciles <- cut(prob_preds, breaks = quantile(prob_preds, probs = seq(0, 1, 0.1)), include.lowest = TRUE) # Calcolare expected vs observed calibration_data <- data.frame( decile = deciles, predicted_prob = prob_preds, actual = as.numeric(test_data$diagnosis) - 1 ) calibration_summary <- calibration_data %>% group_by(decile) %>% summarise( mean_predicted = mean(predicted_prob), mean_observed = mean(actual), n = n(), .groups = 'drop' ) # Plottare la calibrazione ggplot(calibration_summary, aes(x = mean_predicted, y = mean_observed)) + geom_point(aes(size = n)) + geom_smooth(method = "loess", se = FALSE) + geom_abline(intercept = 0, slope = 1, linetype = "dashed", color = "red") + labs(title = "Diagramma di Calibrazione", x = "Probabilità Predetta", y = "Probabilità Osservata") + theme_minimal() </syntaxhighlight> == 5.5 Analisi di Sensibilità == === Threshold Optimization === <syntaxhighlight lang="r"> # Analizzare performance a diversi soglie thresholds <- seq(0.3, 0.7, by = 0.05) threshold_performance <- lapply(thresholds, function(t) { pred_class <- ifelse(prob_preds > t, "Disease", "Healthy") cm <- confusionMatrix(factor(pred_class), test_data$diagnosis) data.frame( Threshold = t, Accuracy = cm$overall['Accuracy'], Sensitivity = cm$byClass['Sensitivity'], Specificity = cm$byClass['Specificity'] ) }) %>% bind_rows() # Visualizzare threshold_performance %>% pivot_longer(-Threshold) %>% ggplot(aes(x = Threshold, y = value, color = name)) + geom_line(linewidth = 1) + labs(title = "Performance vs Threshold", x = "Soglia di Classificazione", y = "Valore Metrica") + theme_minimal() + theme(legend.position = "bottom") </syntaxhighlight> == 5.6 Rapporto di Valutazione == === Generare Rapporto Automatico === <syntaxhighlight lang="r"> # Creare un rapporto completo report_content <- paste(" # Rapporto di Valutazione del Modello PenuX ## Dataset - Training set: ", nrow(train_data), " pazienti - Test set: ", nrow(test_data), " pazienti - Variabili predittive: age, systolic_bp, diastolic_bp, white_blood_cells, creatinine ## Performance Complessiva - Accuracy: ", round(accuracy, 3), " - Sensitivity: ", round(sensitivity, 3), " - Specificity: ", round(specificity, 3), " - AUC: ", round(auc_value, 3), " ## Conclusioni Il modello mostra buone performance predittive per la diagnosi di pancreatite acuta grave e sepsi nel contesto PenuX. ") writeLines(report_content, "results/model_evaluation_report.txt") </syntaxhighlight> == 5.7 Esercizi Pratici == # Calcolare tutte le metriche di valutazione # Costruire e interpretare la curva ROC # Eseguire validazione incrociata # Testare su un dataset esterno simulato # Verificare la calibrazione del modello # Ottimizzare la soglia di classificazione # Generare un rapporto completo == Riepilogo dell'unità 5 == Abbiamo trattato: * Metriche di valutazione (accuracy, sensitivity, specificity) * Curve ROC e AUC * Validazione incrociata ed esterna * Calibrazione dei modelli * Ottimizzazione della soglia * Documentazione delle prestazioni == Il progetto PenuX == Repository: https://github.com/netanelcyber/penux Sito: https://penux.uk == Quiz == [[PenuX in R: Quiz Unità 5|Fai il quiz dell'Unità 5]] se8mxolivc99y559pc26ir7sk0grcoy 502062 502059 2026-10-04T14:47:24Z Hippias 18281 Hippias ha spostato la pagina [[PenuX in R:/Unità 5 - Valutazione e Validazione dei Modelli]] a [[PenuX in R/Unità 5 - Valutazione e Validazione dei Modelli]] senza lasciare redirect: [[Aiuto:Sposta|Il titolo contiene errori di ortografia o di battitura]]: fix 502017 wikitext text/x-wiki = PenuX in R: Unità 5 - Valutazione e Validazione dei Modelli = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Calcolare metriche di valutazione (accuracy, sensitivity, specificity) * Costruire curve ROC e calcolare AUC * Valutare le prestazioni su dati clinici * Eseguire validazione esterna * Confrontare modelli statisticamente * Documentare le prestazioni == 5.1 Metriche di Valutazione == === Matrice di Confusione e Metriche Derivate === <syntaxhighlight lang="r"> library(caret) library(ggplot2) # Previsioni predictions <- predict(rf_model, newdata = test_data, type = "class") # Matrice di confusione conf_matrix <- confusionMatrix(predictions, test_data$diagnosis) print(conf_matrix) # Estrarre metriche accuracy <- conf_matrix$overall['Accuracy'] sensitivity <- conf_matrix$byClass['Sensitivity'] specificity <- conf_matrix$byClass['Specificity'] ppv <- conf_matrix$byClass['Pos Pred Value'] npv <- conf_matrix$byClass['Neg Pred Value'] metrics_df <- data.frame( Metric = c("Accuracy", "Sensitivity (TPR)", "Specificity (TNR)", "PPV", "NPV"), Value = c(accuracy, sensitivity, specificity, ppv, npv) ) print(metrics_df) </syntaxhighlight> === Visualizzare la Matrice di Confusione === <syntaxhighlight lang="r"> # Creare una visualizzazione della matrice di confusione cm_table <- as.data.frame(table( Predicted = predictions, Actual = test_data$diagnosis )) ggplot(cm_table, aes(x = Predicted, y = Actual, fill = Freq)) + geom_tile() + geom_text(aes(label = Freq), color = "white", size = 8) + scale_fill_gradient(low = "lightblue", high = "darkblue") + labs(title = "Matrice di Confusione", x = "Predetto", y = "Reale", fill = "Frequenza") + theme_minimal() </syntaxhighlight> == 5.2 Curve ROC e AUC == === Calcolo di ROC e AUC === <syntaxhighlight lang="r"> library(pROC) # Previsioni probabilistiche prob_predictions <- predict(rf_model, newdata = test_data, type = "prob") # Calcolare ROC roc_curve <- roc(response = test_data$diagnosis, predictor = prob_predictions[, "Disease"]) # AUC auc_value <- auc(roc_curve) print(paste("AUC:", round(auc_value, 3))) # Plottare la curva ROC plot(roc_curve, main = "Curva ROC - Random Forest", xlab = "1 - Specificity", ylab = "Sensitivity") text(0.5, 0.2, paste("AUC =", round(auc_value, 3)), cex = 2) </syntaxhighlight> === Confronto di Modelli con ROC === <syntaxhighlight lang="r"> # ROC per più modelli roc_rf <- roc(test_data$diagnosis, predict(rf_model, test_data, type = "prob")[, "Disease"]) roc_xgb <- roc(test_data$diagnosis, predict(xgb_model, test_matrix, type = "prob")) roc_svm <- roc(test_data$diagnosis, predict(svm_model, test_data, type = "prob")[, "Disease"]) # Plot comparativo ggroc(list(RandomForest = roc_rf, XGBoost = roc_xgb, SVM = roc_svm)) + ggtitle("Confronto delle curve ROC") + theme_minimal() # AUC per ogni modello data.frame( Model = c("Random Forest", "XGBoost", "SVM"), AUC = c(auc(roc_rf), auc(roc_xgb), auc(roc_svm)) ) </syntaxhighlight> == 5.3 Validazione Esterna == === Cross-Validation === <syntaxhighlight lang="r"> # K-fold cross-validation train_control <- trainControl( method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary ) # Addestrare con CV cv_model <- train( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = clinical_data, method = "rf", trControl = train_control, metric = "ROC" ) # Risultati cross-validation print(cv_model$results) print(cv_model$resample) </syntaxhighlight> === Validazione su Dataset Esterno === <syntaxhighlight lang="r"> # Simulare un dataset esterno external_data <- clinical_data %>% sample_frac(0.2) # Previsioni external_predictions <- predict(rf_model, newdata = external_data) # Valutazione external_cm <- confusionMatrix(external_predictions, external_data$diagnosis) print(external_cm) # Confrontare con test set cat("Accuracy - Test Set:", accuracy, "\n") cat("Accuracy - External Set:", external_cm$overall['Accuracy'], "\n") </syntaxhighlight> == 5.4 Calibrazione del Modello == === Verifica della Calibrazione === <syntaxhighlight lang="r"> library(MASS) # Previsioni probabilistiche prob_preds <- predict(rf_model, newdata = test_data, type = "prob")[, "Disease"] # Creare gruppi di decile deciles <- cut(prob_preds, breaks = quantile(prob_preds, probs = seq(0, 1, 0.1)), include.lowest = TRUE) # Calcolare expected vs observed calibration_data <- data.frame( decile = deciles, predicted_prob = prob_preds, actual = as.numeric(test_data$diagnosis) - 1 ) calibration_summary <- calibration_data %>% group_by(decile) %>% summarise( mean_predicted = mean(predicted_prob), mean_observed = mean(actual), n = n(), .groups = 'drop' ) # Plottare la calibrazione ggplot(calibration_summary, aes(x = mean_predicted, y = mean_observed)) + geom_point(aes(size = n)) + geom_smooth(method = "loess", se = FALSE) + geom_abline(intercept = 0, slope = 1, linetype = "dashed", color = "red") + labs(title = "Diagramma di Calibrazione", x = "Probabilità Predetta", y = "Probabilità Osservata") + theme_minimal() </syntaxhighlight> == 5.5 Analisi di Sensibilità == === Threshold Optimization === <syntaxhighlight lang="r"> # Analizzare performance a diversi soglie thresholds <- seq(0.3, 0.7, by = 0.05) threshold_performance <- lapply(thresholds, function(t) { pred_class <- ifelse(prob_preds > t, "Disease", "Healthy") cm <- confusionMatrix(factor(pred_class), test_data$diagnosis) data.frame( Threshold = t, Accuracy = cm$overall['Accuracy'], Sensitivity = cm$byClass['Sensitivity'], Specificity = cm$byClass['Specificity'] ) }) %>% bind_rows() # Visualizzare threshold_performance %>% pivot_longer(-Threshold) %>% ggplot(aes(x = Threshold, y = value, color = name)) + geom_line(linewidth = 1) + labs(title = "Performance vs Threshold", x = "Soglia di Classificazione", y = "Valore Metrica") + theme_minimal() + theme(legend.position = "bottom") </syntaxhighlight> == 5.6 Rapporto di Valutazione == === Generare Rapporto Automatico === <syntaxhighlight lang="r"> # Creare un rapporto completo report_content <- paste(" # Rapporto di Valutazione del Modello PenuX ## Dataset - Training set: ", nrow(train_data), " pazienti - Test set: ", nrow(test_data), " pazienti - Variabili predittive: age, systolic_bp, diastolic_bp, white_blood_cells, creatinine ## Performance Complessiva - Accuracy: ", round(accuracy, 3), " - Sensitivity: ", round(sensitivity, 3), " - Specificity: ", round(specificity, 3), " - AUC: ", round(auc_value, 3), " ## Conclusioni Il modello mostra buone performance predittive per la diagnosi di pancreatite acuta grave e sepsi nel contesto PenuX. ") writeLines(report_content, "results/model_evaluation_report.txt") </syntaxhighlight> == 5.7 Esercizi Pratici == # Calcolare tutte le metriche di valutazione # Costruire e interpretare la curva ROC # Eseguire validazione incrociata # Testare su un dataset esterno simulato # Verificare la calibrazione del modello # Ottimizzare la soglia di classificazione # Generare un rapporto completo == Riepilogo dell'unità 5 == Abbiamo trattato: * Metriche di valutazione (accuracy, sensitivity, specificity) * Curve ROC e AUC * Validazione incrociata ed esterna * Calibrazione dei modelli * Ottimizzazione della soglia * Documentazione delle prestazioni == Il progetto PenuX == Repository: https://github.com/netanelcyber/penux Sito: https://penux.uk == Quiz == [[PenuX in R: Quiz Unità 5|Fai il quiz dell'Unità 5]] se8mxolivc99y559pc26ir7sk0grcoy 502108 502062 2026-10-04T18:22:15Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502108 wikitext text/x-wiki = PenuX in R: Unità 5 - Valutazione e Validazione dei Modelli = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Calcolare metriche di valutazione (accuracy, sensitivity, specificity) * Costruire curve ROC e calcolare AUC * Valutare le prestazioni su dati clinici * Eseguire validazione esterna * Confrontare modelli statisticamente * Documentare le prestazioni == 5.1 Metriche di Valutazione == === Matrice di Confusione e Metriche Derivate === <syntaxhighlight lang="r"> library(caret) library(ggplot2) # Previsioni predictions <- predict(rf_model, newdata = test_data, type = "class") # Matrice di confusione conf_matrix <- confusionMatrix(predictions, test_data$diagnosis) print(conf_matrix) # Estrarre metriche accuracy <- conf_matrix$overall['Accuracy'] sensitivity <- conf_matrix$byClass['Sensitivity'] specificity <- conf_matrix$byClass['Specificity'] ppv <- conf_matrix$byClass['Pos Pred Value'] npv <- conf_matrix$byClass['Neg Pred Value'] metrics_df <- data.frame( Metric = c("Accuracy", "Sensitivity (TPR)", "Specificity (TNR)", "PPV", "NPV"), Value = c(accuracy, sensitivity, specificity, ppv, npv) ) print(metrics_df) </syntaxhighlight> === Visualizzare la Matrice di Confusione === <syntaxhighlight lang="r"> # Creare una visualizzazione della matrice di confusione cm_table <- as.data.frame(table( Predicted = predictions, Actual = test_data$diagnosis )) ggplot(cm_table, aes(x = Predicted, y = Actual, fill = Freq)) + geom_tile() + geom_text(aes(label = Freq), color = "white", size = 8) + scale_fill_gradient(low = "lightblue", high = "darkblue") + labs(title = "Matrice di Confusione", x = "Predetto", y = "Reale", fill = "Frequenza") + theme_minimal() </syntaxhighlight> == 5.2 Curve ROC e AUC == === Calcolo di ROC e AUC === <syntaxhighlight lang="r"> library(pROC) # Previsioni probabilistiche prob_predictions <- predict(rf_model, newdata = test_data, type = "prob") # Calcolare ROC roc_curve <- roc(response = test_data$diagnosis, predictor = prob_predictions[, "Disease"]) # AUC auc_value <- auc(roc_curve) print(paste("AUC:", round(auc_value, 3))) # Plottare la curva ROC plot(roc_curve, main = "Curva ROC - Random Forest", xlab = "1 - Specificity", ylab = "Sensitivity") text(0.5, 0.2, paste("AUC =", round(auc_value, 3)), cex = 2) </syntaxhighlight> === Confronto di Modelli con ROC === <syntaxhighlight lang="r"> # ROC per più modelli roc_rf <- roc(test_data$diagnosis, predict(rf_model, test_data, type = "prob")[, "Disease"]) roc_xgb <- roc(test_data$diagnosis, predict(xgb_model, test_matrix, type = "prob")) roc_svm <- roc(test_data$diagnosis, predict(svm_model, test_data, type = "prob")[, "Disease"]) # Plot comparativo ggroc(list(RandomForest = roc_rf, XGBoost = roc_xgb, SVM = roc_svm)) + ggtitle("Confronto delle curve ROC") + theme_minimal() # AUC per ogni modello data.frame( Model = c("Random Forest", "XGBoost", "SVM"), AUC = c(auc(roc_rf), auc(roc_xgb), auc(roc_svm)) ) </syntaxhighlight> == 5.3 Validazione Esterna == === Cross-Validation === <syntaxhighlight lang="r"> # K-fold cross-validation train_control <- trainControl( method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary ) # Addestrare con CV cv_model <- train( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = clinical_data, method = "rf", trControl = train_control, metric = "ROC" ) # Risultati cross-validation print(cv_model$results) print(cv_model$resample) </syntaxhighlight> === Validazione su Dataset Esterno === <syntaxhighlight lang="r"> # Simulare un dataset esterno external_data <- clinical_data %>% sample_frac(0.2) # Previsioni external_predictions <- predict(rf_model, newdata = external_data) # Valutazione external_cm <- confusionMatrix(external_predictions, external_data$diagnosis) print(external_cm) # Confrontare con test set cat("Accuracy - Test Set:", accuracy, "\n") cat("Accuracy - External Set:", external_cm$overall['Accuracy'], "\n") </syntaxhighlight> == 5.4 Calibrazione del Modello == === Verifica della Calibrazione === <syntaxhighlight lang="r"> library(MASS) # Previsioni probabilistiche prob_preds <- predict(rf_model, newdata = test_data, type = "prob")[, "Disease"] # Creare gruppi di decile deciles <- cut(prob_preds, breaks = quantile(prob_preds, probs = seq(0, 1, 0.1)), include.lowest = TRUE) # Calcolare expected vs observed calibration_data <- data.frame( decile = deciles, predicted_prob = prob_preds, actual = as.numeric(test_data$diagnosis) - 1 ) calibration_summary <- calibration_data %>% group_by(decile) %>% summarise( mean_predicted = mean(predicted_prob), mean_observed = mean(actual), n = n(), .groups = 'drop' ) # Plottare la calibrazione ggplot(calibration_summary, aes(x = mean_predicted, y = mean_observed)) + geom_point(aes(size = n)) + geom_smooth(method = "loess", se = FALSE) + geom_abline(intercept = 0, slope = 1, linetype = "dashed", color = "red") + labs(title = "Diagramma di Calibrazione", x = "Probabilità Predetta", y = "Probabilità Osservata") + theme_minimal() </syntaxhighlight> == 5.5 Analisi di Sensibilità == === Threshold Optimization === <syntaxhighlight lang="r"> # Analizzare performance a diversi soglie thresholds <- seq(0.3, 0.7, by = 0.05) threshold_performance <- lapply(thresholds, function(t) { pred_class <- ifelse(prob_preds > t, "Disease", "Healthy") cm <- confusionMatrix(factor(pred_class), test_data$diagnosis) data.frame( Threshold = t, Accuracy = cm$overall['Accuracy'], Sensitivity = cm$byClass['Sensitivity'], Specificity = cm$byClass['Specificity'] ) }) %>% bind_rows() # Visualizzare threshold_performance %>% pivot_longer(-Threshold) %>% ggplot(aes(x = Threshold, y = value, color = name)) + geom_line(linewidth = 1) + labs(title = "Performance vs Threshold", x = "Soglia di Classificazione", y = "Valore Metrica") + theme_minimal() + theme(legend.position = "bottom") </syntaxhighlight> == 5.6 Rapporto di Valutazione == === Generare Rapporto Automatico === <syntaxhighlight lang="r"> # Creare un rapporto completo report_content <- paste(" # Rapporto di Valutazione del Modello PenuX ## Dataset - Training set: ", nrow(train_data), " pazienti - Test set: ", nrow(test_data), " pazienti - Variabili predittive: age, systolic_bp, diastolic_bp, white_blood_cells, creatinine ## Performance Complessiva - Accuracy: ", round(accuracy, 3), " - Sensitivity: ", round(sensitivity, 3), " - Specificity: ", round(specificity, 3), " - AUC: ", round(auc_value, 3), " ## Conclusioni Il modello mostra buone performance predittive per la diagnosi di pancreatite acuta grave e sepsi nel contesto PenuX. ") writeLines(report_content, "results/model_evaluation_report.txt") </syntaxhighlight> == 5.7 Esercizi Pratici == # Calcolare tutte le metriche di valutazione # Costruire e interpretare la curva ROC # Eseguire validazione incrociata # Testare su un dataset esterno simulato # Verificare la calibrazione del modello # Ottimizzare la soglia di classificazione # Generare un rapporto completo == Riepilogo dell'unità 5 == Abbiamo trattato: * Metriche di valutazione (accuracy, sensitivity, specificity) * Curve ROC e AUC * Validazione incrociata ed esterna * Calibrazione dei modelli * Ottimizzazione della soglia * Documentazione delle prestazioni == Il progetto PenuX == Repository: https://github.com/netanelcyber/penux Sito: https://penux.uk == Quiz == [[PenuX in R: Quiz Unità 5|Fai il quiz dell'Unità 5]] [[Categoria:PenuX in R|Unità 5 - Valutazione e Validazione dei Modelli]] 4jrqlcpj0ixs00btxx0bg04olt42r1v 502123 502108 2026-10-04T18:25:58Z Gian BOT 27470 bot: fix link 502123 wikitext text/x-wiki = PenuX in R: Unità 5 - Valutazione e Validazione dei Modelli = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Calcolare metriche di valutazione (accuracy, sensitivity, specificity) * Costruire curve ROC e calcolare AUC * Valutare le prestazioni su dati clinici * Eseguire validazione esterna * Confrontare modelli statisticamente * Documentare le prestazioni == 5.1 Metriche di Valutazione == === Matrice di Confusione e Metriche Derivate === <syntaxhighlight lang="r"> library(caret) library(ggplot2) # Previsioni predictions <- predict(rf_model, newdata = test_data, type = "class") # Matrice di confusione conf_matrix <- confusionMatrix(predictions, test_data$diagnosis) print(conf_matrix) # Estrarre metriche accuracy <- conf_matrix$overall['Accuracy'] sensitivity <- conf_matrix$byClass['Sensitivity'] specificity <- conf_matrix$byClass['Specificity'] ppv <- conf_matrix$byClass['Pos Pred Value'] npv <- conf_matrix$byClass['Neg Pred Value'] metrics_df <- data.frame( Metric = c("Accuracy", "Sensitivity (TPR)", "Specificity (TNR)", "PPV", "NPV"), Value = c(accuracy, sensitivity, specificity, ppv, npv) ) print(metrics_df) </syntaxhighlight> === Visualizzare la Matrice di Confusione === <syntaxhighlight lang="r"> # Creare una visualizzazione della matrice di confusione cm_table <- as.data.frame(table( Predicted = predictions, Actual = test_data$diagnosis )) ggplot(cm_table, aes(x = Predicted, y = Actual, fill = Freq)) + geom_tile() + geom_text(aes(label = Freq), color = "white", size = 8) + scale_fill_gradient(low = "lightblue", high = "darkblue") + labs(title = "Matrice di Confusione", x = "Predetto", y = "Reale", fill = "Frequenza") + theme_minimal() </syntaxhighlight> == 5.2 Curve ROC e AUC == === Calcolo di ROC e AUC === <syntaxhighlight lang="r"> library(pROC) # Previsioni probabilistiche prob_predictions <- predict(rf_model, newdata = test_data, type = "prob") # Calcolare ROC roc_curve <- roc(response = test_data$diagnosis, predictor = prob_predictions[, "Disease"]) # AUC auc_value <- auc(roc_curve) print(paste("AUC:", round(auc_value, 3))) # Plottare la curva ROC plot(roc_curve, main = "Curva ROC - Random Forest", xlab = "1 - Specificity", ylab = "Sensitivity") text(0.5, 0.2, paste("AUC =", round(auc_value, 3)), cex = 2) </syntaxhighlight> === Confronto di Modelli con ROC === <syntaxhighlight lang="r"> # ROC per più modelli roc_rf <- roc(test_data$diagnosis, predict(rf_model, test_data, type = "prob")[, "Disease"]) roc_xgb <- roc(test_data$diagnosis, predict(xgb_model, test_matrix, type = "prob")) roc_svm <- roc(test_data$diagnosis, predict(svm_model, test_data, type = "prob")[, "Disease"]) # Plot comparativo ggroc(list(RandomForest = roc_rf, XGBoost = roc_xgb, SVM = roc_svm)) + ggtitle("Confronto delle curve ROC") + theme_minimal() # AUC per ogni modello data.frame( Model = c("Random Forest", "XGBoost", "SVM"), AUC = c(auc(roc_rf), auc(roc_xgb), auc(roc_svm)) ) </syntaxhighlight> == 5.3 Validazione Esterna == === Cross-Validation === <syntaxhighlight lang="r"> # K-fold cross-validation train_control <- trainControl( method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary ) # Addestrare con CV cv_model <- train( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = clinical_data, method = "rf", trControl = train_control, metric = "ROC" ) # Risultati cross-validation print(cv_model$results) print(cv_model$resample) </syntaxhighlight> === Validazione su Dataset Esterno === <syntaxhighlight lang="r"> # Simulare un dataset esterno external_data <- clinical_data %>% sample_frac(0.2) # Previsioni external_predictions <- predict(rf_model, newdata = external_data) # Valutazione external_cm <- confusionMatrix(external_predictions, external_data$diagnosis) print(external_cm) # Confrontare con test set cat("Accuracy - Test Set:", accuracy, "\n") cat("Accuracy - External Set:", external_cm$overall['Accuracy'], "\n") </syntaxhighlight> == 5.4 Calibrazione del Modello == === Verifica della Calibrazione === <syntaxhighlight lang="r"> library(MASS) # Previsioni probabilistiche prob_preds <- predict(rf_model, newdata = test_data, type = "prob")[, "Disease"] # Creare gruppi di decile deciles <- cut(prob_preds, breaks = quantile(prob_preds, probs = seq(0, 1, 0.1)), include.lowest = TRUE) # Calcolare expected vs observed calibration_data <- data.frame( decile = deciles, predicted_prob = prob_preds, actual = as.numeric(test_data$diagnosis) - 1 ) calibration_summary <- calibration_data %>% group_by(decile) %>% summarise( mean_predicted = mean(predicted_prob), mean_observed = mean(actual), n = n(), .groups = 'drop' ) # Plottare la calibrazione ggplot(calibration_summary, aes(x = mean_predicted, y = mean_observed)) + geom_point(aes(size = n)) + geom_smooth(method = "loess", se = FALSE) + geom_abline(intercept = 0, slope = 1, linetype = "dashed", color = "red") + labs(title = "Diagramma di Calibrazione", x = "Probabilità Predetta", y = "Probabilità Osservata") + theme_minimal() </syntaxhighlight> == 5.5 Analisi di Sensibilità == === Threshold Optimization === <syntaxhighlight lang="r"> # Analizzare performance a diversi soglie thresholds <- seq(0.3, 0.7, by = 0.05) threshold_performance <- lapply(thresholds, function(t) { pred_class <- ifelse(prob_preds > t, "Disease", "Healthy") cm <- confusionMatrix(factor(pred_class), test_data$diagnosis) data.frame( Threshold = t, Accuracy = cm$overall['Accuracy'], Sensitivity = cm$byClass['Sensitivity'], Specificity = cm$byClass['Specificity'] ) }) %>% bind_rows() # Visualizzare threshold_performance %>% pivot_longer(-Threshold) %>% ggplot(aes(x = Threshold, y = value, color = name)) + geom_line(linewidth = 1) + labs(title = "Performance vs Threshold", x = "Soglia di Classificazione", y = "Valore Metrica") + theme_minimal() + theme(legend.position = "bottom") </syntaxhighlight> == 5.6 Rapporto di Valutazione == === Generare Rapporto Automatico === <syntaxhighlight lang="r"> # Creare un rapporto completo report_content <- paste(" # Rapporto di Valutazione del Modello PenuX ## Dataset - Training set: ", nrow(train_data), " pazienti - Test set: ", nrow(test_data), " pazienti - Variabili predittive: age, systolic_bp, diastolic_bp, white_blood_cells, creatinine ## Performance Complessiva - Accuracy: ", round(accuracy, 3), " - Sensitivity: ", round(sensitivity, 3), " - Specificity: ", round(specificity, 3), " - AUC: ", round(auc_value, 3), " ## Conclusioni Il modello mostra buone performance predittive per la diagnosi di pancreatite acuta grave e sepsi nel contesto PenuX. ") writeLines(report_content, "results/model_evaluation_report.txt") </syntaxhighlight> == 5.7 Esercizi Pratici == # Calcolare tutte le metriche di valutazione # Costruire e interpretare la curva ROC # Eseguire validazione incrociata # Testare su un dataset esterno simulato # Verificare la calibrazione del modello # Ottimizzare la soglia di classificazione # Generare un rapporto completo == Riepilogo dell'unità 5 == Abbiamo trattato: * Metriche di valutazione (accuracy, sensitivity, specificity) * Curve ROC e AUC * Validazione incrociata ed esterna * Calibrazione dei modelli * Ottimizzazione della soglia * Documentazione delle prestazioni == Il progetto PenuX == Repository: https://github.com/netanelcyber/penux Sito: https://penux.uk == Quiz == [[PenuX in R/Quiz Unità 5|Fai il quiz dell'Unità 5]] [[Categoria:PenuX in R|Unità 5 - Valutazione e Validazione dei Modelli]] 63tfgm98ayc88u018tmsniw2tr7ve85 502138 502123 2026-10-04T18:34:23Z Gian BOT 27470 Bot: aggiunge l'indice 502138 wikitext text/x-wiki {{PenuX in R}} = PenuX in R: Unità 5 - Valutazione e Validazione dei Modelli = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Calcolare metriche di valutazione (accuracy, sensitivity, specificity) * Costruire curve ROC e calcolare AUC * Valutare le prestazioni su dati clinici * Eseguire validazione esterna * Confrontare modelli statisticamente * Documentare le prestazioni == 5.1 Metriche di Valutazione == === Matrice di Confusione e Metriche Derivate === <syntaxhighlight lang="r"> library(caret) library(ggplot2) # Previsioni predictions <- predict(rf_model, newdata = test_data, type = "class") # Matrice di confusione conf_matrix <- confusionMatrix(predictions, test_data$diagnosis) print(conf_matrix) # Estrarre metriche accuracy <- conf_matrix$overall['Accuracy'] sensitivity <- conf_matrix$byClass['Sensitivity'] specificity <- conf_matrix$byClass['Specificity'] ppv <- conf_matrix$byClass['Pos Pred Value'] npv <- conf_matrix$byClass['Neg Pred Value'] metrics_df <- data.frame( Metric = c("Accuracy", "Sensitivity (TPR)", "Specificity (TNR)", "PPV", "NPV"), Value = c(accuracy, sensitivity, specificity, ppv, npv) ) print(metrics_df) </syntaxhighlight> === Visualizzare la Matrice di Confusione === <syntaxhighlight lang="r"> # Creare una visualizzazione della matrice di confusione cm_table <- as.data.frame(table( Predicted = predictions, Actual = test_data$diagnosis )) ggplot(cm_table, aes(x = Predicted, y = Actual, fill = Freq)) + geom_tile() + geom_text(aes(label = Freq), color = "white", size = 8) + scale_fill_gradient(low = "lightblue", high = "darkblue") + labs(title = "Matrice di Confusione", x = "Predetto", y = "Reale", fill = "Frequenza") + theme_minimal() </syntaxhighlight> == 5.2 Curve ROC e AUC == === Calcolo di ROC e AUC === <syntaxhighlight lang="r"> library(pROC) # Previsioni probabilistiche prob_predictions <- predict(rf_model, newdata = test_data, type = "prob") # Calcolare ROC roc_curve <- roc(response = test_data$diagnosis, predictor = prob_predictions[, "Disease"]) # AUC auc_value <- auc(roc_curve) print(paste("AUC:", round(auc_value, 3))) # Plottare la curva ROC plot(roc_curve, main = "Curva ROC - Random Forest", xlab = "1 - Specificity", ylab = "Sensitivity") text(0.5, 0.2, paste("AUC =", round(auc_value, 3)), cex = 2) </syntaxhighlight> === Confronto di Modelli con ROC === <syntaxhighlight lang="r"> # ROC per più modelli roc_rf <- roc(test_data$diagnosis, predict(rf_model, test_data, type = "prob")[, "Disease"]) roc_xgb <- roc(test_data$diagnosis, predict(xgb_model, test_matrix, type = "prob")) roc_svm <- roc(test_data$diagnosis, predict(svm_model, test_data, type = "prob")[, "Disease"]) # Plot comparativo ggroc(list(RandomForest = roc_rf, XGBoost = roc_xgb, SVM = roc_svm)) + ggtitle("Confronto delle curve ROC") + theme_minimal() # AUC per ogni modello data.frame( Model = c("Random Forest", "XGBoost", "SVM"), AUC = c(auc(roc_rf), auc(roc_xgb), auc(roc_svm)) ) </syntaxhighlight> == 5.3 Validazione Esterna == === Cross-Validation === <syntaxhighlight lang="r"> # K-fold cross-validation train_control <- trainControl( method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary ) # Addestrare con CV cv_model <- train( diagnosis ~ age + systolic_bp + diastolic_bp + white_blood_cells + creatinine, data = clinical_data, method = "rf", trControl = train_control, metric = "ROC" ) # Risultati cross-validation print(cv_model$results) print(cv_model$resample) </syntaxhighlight> === Validazione su Dataset Esterno === <syntaxhighlight lang="r"> # Simulare un dataset esterno external_data <- clinical_data %>% sample_frac(0.2) # Previsioni external_predictions <- predict(rf_model, newdata = external_data) # Valutazione external_cm <- confusionMatrix(external_predictions, external_data$diagnosis) print(external_cm) # Confrontare con test set cat("Accuracy - Test Set:", accuracy, "\n") cat("Accuracy - External Set:", external_cm$overall['Accuracy'], "\n") </syntaxhighlight> == 5.4 Calibrazione del Modello == === Verifica della Calibrazione === <syntaxhighlight lang="r"> library(MASS) # Previsioni probabilistiche prob_preds <- predict(rf_model, newdata = test_data, type = "prob")[, "Disease"] # Creare gruppi di decile deciles <- cut(prob_preds, breaks = quantile(prob_preds, probs = seq(0, 1, 0.1)), include.lowest = TRUE) # Calcolare expected vs observed calibration_data <- data.frame( decile = deciles, predicted_prob = prob_preds, actual = as.numeric(test_data$diagnosis) - 1 ) calibration_summary <- calibration_data %>% group_by(decile) %>% summarise( mean_predicted = mean(predicted_prob), mean_observed = mean(actual), n = n(), .groups = 'drop' ) # Plottare la calibrazione ggplot(calibration_summary, aes(x = mean_predicted, y = mean_observed)) + geom_point(aes(size = n)) + geom_smooth(method = "loess", se = FALSE) + geom_abline(intercept = 0, slope = 1, linetype = "dashed", color = "red") + labs(title = "Diagramma di Calibrazione", x = "Probabilità Predetta", y = "Probabilità Osservata") + theme_minimal() </syntaxhighlight> == 5.5 Analisi di Sensibilità == === Threshold Optimization === <syntaxhighlight lang="r"> # Analizzare performance a diversi soglie thresholds <- seq(0.3, 0.7, by = 0.05) threshold_performance <- lapply(thresholds, function(t) { pred_class <- ifelse(prob_preds > t, "Disease", "Healthy") cm <- confusionMatrix(factor(pred_class), test_data$diagnosis) data.frame( Threshold = t, Accuracy = cm$overall['Accuracy'], Sensitivity = cm$byClass['Sensitivity'], Specificity = cm$byClass['Specificity'] ) }) %>% bind_rows() # Visualizzare threshold_performance %>% pivot_longer(-Threshold) %>% ggplot(aes(x = Threshold, y = value, color = name)) + geom_line(linewidth = 1) + labs(title = "Performance vs Threshold", x = "Soglia di Classificazione", y = "Valore Metrica") + theme_minimal() + theme(legend.position = "bottom") </syntaxhighlight> == 5.6 Rapporto di Valutazione == === Generare Rapporto Automatico === <syntaxhighlight lang="r"> # Creare un rapporto completo report_content <- paste(" # Rapporto di Valutazione del Modello PenuX ## Dataset - Training set: ", nrow(train_data), " pazienti - Test set: ", nrow(test_data), " pazienti - Variabili predittive: age, systolic_bp, diastolic_bp, white_blood_cells, creatinine ## Performance Complessiva - Accuracy: ", round(accuracy, 3), " - Sensitivity: ", round(sensitivity, 3), " - Specificity: ", round(specificity, 3), " - AUC: ", round(auc_value, 3), " ## Conclusioni Il modello mostra buone performance predittive per la diagnosi di pancreatite acuta grave e sepsi nel contesto PenuX. ") writeLines(report_content, "results/model_evaluation_report.txt") </syntaxhighlight> == 5.7 Esercizi Pratici == # Calcolare tutte le metriche di valutazione # Costruire e interpretare la curva ROC # Eseguire validazione incrociata # Testare su un dataset esterno simulato # Verificare la calibrazione del modello # Ottimizzare la soglia di classificazione # Generare un rapporto completo == Riepilogo dell'unità 5 == Abbiamo trattato: * Metriche di valutazione (accuracy, sensitivity, specificity) * Curve ROC e AUC * Validazione incrociata ed esterna * Calibrazione dei modelli * Ottimizzazione della soglia * Documentazione delle prestazioni == Il progetto PenuX == Repository: https://github.com/netanelcyber/penux Sito: https://penux.uk == Quiz == [[PenuX in R/Quiz Unità 5|Fai il quiz dell'Unità 5]] [[Categoria:PenuX in R|Unità 5 - Valutazione e Validazione dei Modelli]] o3kfimcv6m35t1p91r3b3i5wdgxr06j PenuX in R/Quiz Unità 5 0 61186 502068 502018 2026-10-04T14:55:02Z Hippias 18281 Hippias ha spostato la pagina [[PenuX in R: Quiz Unità 5]] a [[PenuX in R/Quiz Unità 5]] senza lasciare redirect: [[Aiuto:Convenzioni di nomenclatura|Convenzioni di nomenclatura]]: sottopagino correttamente 502018 wikitext text/x-wiki = PenuX in R: Quiz Unità 5 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Come si calcola la sensibilità? * A) VN / (VN + FP) * B) VP / (VP + FP) * C) VP / (VP + FN) * D) (VP + VN) / totale <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. La sensibilità è la quota di malati correttamente riconosciuti. </div> == Domanda 2 == Un'AUC pari a 0,5 significa: * A) Un modello perfetto * B) Un modello molto accurato * C) Un errore di calibrazione * D) Nessuna capacità discriminante (come il caso) <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Il modello non distingue meglio di un lancio di moneta. </div> == Domanda 3 == Che cos'è la validazione esterna? * A) Valutare il modello su dati di un altro centro o periodo * B) Ripetere la divisione train/test * C) Aumentare il numero di alberi * D) Standardizzare i dati <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Verifica la generalizzabilità oltre il dataset di sviluppo. </div> == Domanda 4 == Che cosa misura la calibrazione di un modello? * A) La velocità di calcolo * B) La concordanza tra probabilità previste e frequenze osservate * C) Il numero di variabili * D) La percentuale di valori mancanti <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Se il modello dice 20%, circa 20 pazienti su 100 dovrebbero avere l'evento. </div> == Torna all'unità == [[PenuX in R: Unità 5 - Valutazione e Validazione dei Modelli|Torna all'Unità 5]] atgnqlampuyuw20mnemyg6u91uuu3z3 502100 502068 2026-10-04T18:20:49Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502100 wikitext text/x-wiki = PenuX in R: Quiz Unità 5 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Come si calcola la sensibilità? * A) VN / (VN + FP) * B) VP / (VP + FP) * C) VP / (VP + FN) * D) (VP + VN) / totale <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. La sensibilità è la quota di malati correttamente riconosciuti. </div> == Domanda 2 == Un'AUC pari a 0,5 significa: * A) Un modello perfetto * B) Un modello molto accurato * C) Un errore di calibrazione * D) Nessuna capacità discriminante (come il caso) <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Il modello non distingue meglio di un lancio di moneta. </div> == Domanda 3 == Che cos'è la validazione esterna? * A) Valutare il modello su dati di un altro centro o periodo * B) Ripetere la divisione train/test * C) Aumentare il numero di alberi * D) Standardizzare i dati <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Verifica la generalizzabilità oltre il dataset di sviluppo. </div> == Domanda 4 == Che cosa misura la calibrazione di un modello? * A) La velocità di calcolo * B) La concordanza tra probabilità previste e frequenze osservate * C) Il numero di variabili * D) La percentuale di valori mancanti <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Se il modello dice 20%, circa 20 pazienti su 100 dovrebbero avere l'evento. </div> == Torna all'unità == [[PenuX in R: Unità 5 - Valutazione e Validazione dei Modelli|Torna all'Unità 5]] [[Categoria:PenuX in R|Quiz Unità 5]] fxtm3nki52uuii5fzxkcqdwahtfdspf 502116 502100 2026-10-04T18:24:48Z Gian BOT 27470 bot: fix link 502116 wikitext text/x-wiki = PenuX in R: Quiz Unità 5 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Come si calcola la sensibilità? * A) VN / (VN + FP) * B) VP / (VP + FP) * C) VP / (VP + FN) * D) (VP + VN) / totale <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. La sensibilità è la quota di malati correttamente riconosciuti. </div> == Domanda 2 == Un'AUC pari a 0,5 significa: * A) Un modello perfetto * B) Un modello molto accurato * C) Un errore di calibrazione * D) Nessuna capacità discriminante (come il caso) <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Il modello non distingue meglio di un lancio di moneta. </div> == Domanda 3 == Che cos'è la validazione esterna? * A) Valutare il modello su dati di un altro centro o periodo * B) Ripetere la divisione train/test * C) Aumentare il numero di alberi * D) Standardizzare i dati <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Verifica la generalizzabilità oltre il dataset di sviluppo. </div> == Domanda 4 == Che cosa misura la calibrazione di un modello? * A) La velocità di calcolo * B) La concordanza tra probabilità previste e frequenze osservate * C) Il numero di variabili * D) La percentuale di valori mancanti <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Se il modello dice 20%, circa 20 pazienti su 100 dovrebbero avere l'evento. </div> == Torna all'unità == [[PenuX in R/Unità 5 - Valutazione e Validazione dei Modelli|Torna all'Unità 5]] [[Categoria:PenuX in R|Quiz Unità 5]] 4owfxxv9jcrcmz898g00yv8bmzhbrjx 502131 502116 2026-10-04T18:33:10Z Gian BOT 27470 Bot: aggiunge l'indice 502131 wikitext text/x-wiki {{PenuX in R}} = PenuX in R: Quiz Unità 5 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Come si calcola la sensibilità? * A) VN / (VN + FP) * B) VP / (VP + FP) * C) VP / (VP + FN) * D) (VP + VN) / totale <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. La sensibilità è la quota di malati correttamente riconosciuti. </div> == Domanda 2 == Un'AUC pari a 0,5 significa: * A) Un modello perfetto * B) Un modello molto accurato * C) Un errore di calibrazione * D) Nessuna capacità discriminante (come il caso) <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Il modello non distingue meglio di un lancio di moneta. </div> == Domanda 3 == Che cos'è la validazione esterna? * A) Valutare il modello su dati di un altro centro o periodo * B) Ripetere la divisione train/test * C) Aumentare il numero di alberi * D) Standardizzare i dati <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Verifica la generalizzabilità oltre il dataset di sviluppo. </div> == Domanda 4 == Che cosa misura la calibrazione di un modello? * A) La velocità di calcolo * B) La concordanza tra probabilità previste e frequenze osservate * C) Il numero di variabili * D) La percentuale di valori mancanti <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Se il modello dice 20%, circa 20 pazienti su 100 dovrebbero avere l'evento. </div> == Torna all'unità == [[PenuX in R/Unità 5 - Valutazione e Validazione dei Modelli|Torna all'Unità 5]] [[Categoria:PenuX in R|Quiz Unità 5]] 0tk84l0cjpmq7r6e47mcm9orbmy08p8 PenuX in R/Unità 6 - Deployment e Implementazione Clinica 0 61187 502060 502019 2026-10-04T14:46:25Z Hippias 18281 Hippias ha spostato la pagina [[PenuX in R: Unità 6 - Deployment e Implementazione Clinica]] a [[PenuX in R/Unità 6 - Deployment e Implementazione Clinica]] senza lasciare redirect: [[Aiuto:Convenzioni di nomenclatura|Convenzioni di nomenclatura]]: sottopagino correttamente 502019 wikitext text/x-wiki = PenuX in R: Unità 6 - Deployment e Implementazione Clinica = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Containerizzare il modello con Docker * Creare API REST per le previsioni * Integrare il modello con sistemi clinici * Gestire il monitoraggio del modello * Implementare controlli di qualità * Documentare la soluzione == 6.1 Creazione di una Funzione di Previsione == === Funzione Wrapper === <syntaxhighlight lang="r"> # Creare una funzione per fare previsioni standardizzate predict_penux <- function(model, new_patient_data, threshold = 0.5) { # Validare l'input required_cols <- c("age", "systolic_bp", "diastolic_bp", "white_blood_cells", "creatinine") if (!all(required_cols %in% colnames(new_patient_data))) { stop("Colonne mancanti:", paste(setdiff(required_cols, colnames(new_patient_data)), collapse = ", ")) } # Fare previsioni probabilistiche prob_predictions <- predict(model, newdata = new_patient_data, type = "prob") # Convertire in classi predicted_class <- ifelse(prob_predictions[, "Disease"] > threshold, "Disease", "Healthy") # Ritornare risultati strutturati results <- data.frame( patient_id = 1:nrow(new_patient_data), predicted_probability = prob_predictions[, "Disease"], predicted_class = predicted_class, confidence = pmax(prob_predictions[, "Disease"], prob_predictions[, "Healthy"]), risk_level = ifelse(prob_predictions[, "Disease"] > 0.7, "High", ifelse(prob_predictions[, "Disease"] > 0.4, "Medium", "Low")) ) return(results) } # Testare la funzione test_prediction <- predict_penux(rf_model, test_data[1:5, ]) print(test_prediction) </syntaxhighlight> == 6.2 API REST con Plumber == === Creare un'API === <syntaxhighlight lang="r"> # Installare plumber # install.packages("plumber") library(plumber) # Creare il file API (plumber.R) api_code <- " #' PenuX Model Prediction API #' @post /predict #' @param age:int Età del paziente #' @param systolic_bp:numeric Pressione sistolica #' @param diastolic_bp:numeric Pressione diastolica #' @param white_blood_cells:numeric Conta leucocitaria #' @param creatinine:numeric Livello di creatinina predict_disease <- function(age, systolic_bp, diastolic_bp, white_blood_cells, creatinine) { patient_data <- data.frame( age = age, systolic_bp = systolic_bp, diastolic_bp = diastolic_bp, white_blood_cells = white_blood_cells, creatinine = creatinine ) prediction <- predict_penux(rf_model, patient_data) return(prediction) } #' Health Check #' @get /health health_check <- function() { return(list(status = 'OK', model = 'PenuX v1.0')) } " writeLines(api_code, "api/plumber.R") # Lanciare l'API # pr <- plumb("api/plumber.R") # pr$run(host = "0.0.0.0", port = 8000) </syntaxhighlight> == 6.3 Containerizzazione con Docker == === Dockerfile === <syntaxhighlight lang="dockerfile"> FROM rocker/tidyverse:latest # Installare dipendenze RUN install2.r \ randomForest \ xgboost \ caret \ pROC \ plumber # Copiare il modello e l'API COPY models/rf_model.rds /app/models/ COPY api/plumber.R /app/api/ WORKDIR /app # Esporre la porta EXPOSE 8000 # Comando di avvio CMD ["R", "-e", "library(plumber); pr <- plumb('api/plumber.R'); pr$run(host = '0.0.0.0', port = 8000)"] </syntaxhighlight> === Docker Compose === <syntaxhighlight lang="yaml"> version: '3' services: penux-model: build: . ports: - "8000:8000" environment: - MODEL_PATH=/app/models/rf_model.rds volumes: - ./logs:/app/logs healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3 </syntaxhighlight> == 6.4 Monitoraggio del Modello == === Performance Tracking === <syntaxhighlight lang="r"> # Creare un sistema di tracking delle performance create_model_monitor <- function(model_id, model_version) { list( model_id = model_id, model_version = model_version, deployment_date = Sys.Date(), metrics = list(), predictions_log = NULL ) } # Registrare una previsione log_prediction <- function(monitor, prediction_result, actual_outcome = NA) { log_entry <- data.frame( timestamp = Sys.time(), prediction_probability = prediction_result$predicted_probability, prediction_class = prediction_result$predicted_class, actual_outcome = actual_outcome ) monitor$predictions_log <- rbind(monitor$predictions_log, log_entry) return(monitor) } # Calcolare data drift calculate_data_drift <- function(training_stats, new_data) { drift_metrics <- list() for (col in names(training_stats)) { new_mean <- mean(new_data[[col]], na.rm = TRUE) new_sd <- sd(new_data[[col]], na.rm = TRUE) drift_metrics[[col]] <- list( training_mean = training_stats[[col]]$mean, new_mean = new_mean, mean_shift = abs(new_mean - training_stats[[col]]$mean) / training_stats[[col]]$sd, training_sd = training_stats[[col]]$sd, new_sd = new_sd ) } return(drift_metrics) } </syntaxhighlight> == 6.5 Integrazione Clinica == === Validazione Clinica === <syntaxhighlight lang="r"> # Workflow di validazione clinica clinical_validation <- function(model, clinical_test_data, acceptance_criteria) { # Generare previsioni predictions <- predict_penux(model, clinical_test_data) # Valutare rispetto ai criteri di accettazione results <- list( total_samples = nrow(clinical_test_data), min_auc = acceptance_criteria$min_auc, min_sensitivity = acceptance_criteria$min_sensitivity, min_specificity = acceptance_criteria$min_specificity, passed = FALSE ) # Implementare ulteriori controlli if (all(unlist(results) >= unlist(acceptance_criteria))) { results$passed <- TRUE } return(results) } # Criteri di accettazione PenuX penux_criteria <- list( min_auc = 0.85, min_sensitivity = 0.85, min_specificity = 0.80, max_false_positive_rate = 0.10 ) # Eseguire validazione validation_result <- clinical_validation(rf_model, test_data, penux_criteria) print(validation_result) </syntaxhighlight> == 6.6 Documentazione e Compliance == === Regulatory Documentation === <syntaxhighlight lang="r"> # Generare rapporto di conformità generate_regulatory_report <- function(model, validation_results, training_data, deployment_date) { report <- list( model_information = list( name = "PenuX Prediction Model", version = "1.0.0", deployment_date = deployment_date, intended_use = "Early prediction of severe acute pancreatitis and sepsis" ), training_data = list( sample_size = nrow(training_data), variables = names(training_data), date_range = paste(min(training_data$date), "to", max(training_data$date)) ), performance_metrics = validation_results, limitations = list( "Model trained on specific patient population", "Regular revalidation recommended", "Clinician judgment should not be replaced" ), maintenance_plan = list( monitoring_frequency = "Monthly", retraining_frequency = "Quarterly", data_drift_threshold = 0.2 ) ) return(report) } </syntaxhighlight> == 6.7 Ciclo di Vita Continuo == === Retraining Pipeline === <syntaxhighlight lang="r"> # Creare una pipeline di retraining automatico create_retraining_pipeline <- function(data, model_path, performance_threshold = 0.80) { # 1. Verificare la performance current_model <- readRDS(model_path) current_performance <- evaluate_model(current_model) # 2. Se la performance degrada, ritirare if (current_performance$auc < performance_threshold) { # 2a. Ritirare il modello su dati aggiornati new_model <- train_model(data) # 2b. Confrontare le performance new_performance <- evaluate_model(new_model) # 2c. Se il nuovo è migliore, salvare if (new_performance$auc > current_performance$auc) { saveRDS(new_model, paste0(model_path, ".backup")) saveRDS(new_model, model_path) return(list(status = "Retrained", new_auc = new_performance$auc)) } } return(list(status = "No Retrain Needed")) } </syntaxhighlight> == 6.8 Esercizi Pratici == # Creare una funzione di previsione robusta # Costruire un'API REST con plumber # Creare un Dockerfile funzionante # Implementare un sistema di monitoraggio # Generare un rapporto di conformità normativa # Testare il deployment in ambiente locale # Documentare il ciclo di vita del modello == Riepilogo dell'unità 6 == Abbiamo trattato: * Creazione di funzioni di previsione robust * API REST con plumber * Containerizzazione con Docker * Monitoraggio continuo del modello * Validazione clinica e compliance * Documentazione normativa * Ciclo di vita continuo e retraining == Prossimi Passi == * Distribuire su cloud (AWS, Google Cloud, Azure) * Integrare con sistemi EHR * Implementare feedback loops clinici * Stabilire partnership cliniche per validazione * Preparare per regulatory approval == Il progetto PenuX == Repository: https://github.com/netanelcyber/penux Sito: https://penux.uk == Quiz == [[PenuX in R: Quiz Unità 6|Fai il quiz dell'Unità 6]] qi4qv6kasqvf5282tlsseoya24nyupc 502109 502060 2026-10-04T18:22:29Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502109 wikitext text/x-wiki = PenuX in R: Unità 6 - Deployment e Implementazione Clinica = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Containerizzare il modello con Docker * Creare API REST per le previsioni * Integrare il modello con sistemi clinici * Gestire il monitoraggio del modello * Implementare controlli di qualità * Documentare la soluzione == 6.1 Creazione di una Funzione di Previsione == === Funzione Wrapper === <syntaxhighlight lang="r"> # Creare una funzione per fare previsioni standardizzate predict_penux <- function(model, new_patient_data, threshold = 0.5) { # Validare l'input required_cols <- c("age", "systolic_bp", "diastolic_bp", "white_blood_cells", "creatinine") if (!all(required_cols %in% colnames(new_patient_data))) { stop("Colonne mancanti:", paste(setdiff(required_cols, colnames(new_patient_data)), collapse = ", ")) } # Fare previsioni probabilistiche prob_predictions <- predict(model, newdata = new_patient_data, type = "prob") # Convertire in classi predicted_class <- ifelse(prob_predictions[, "Disease"] > threshold, "Disease", "Healthy") # Ritornare risultati strutturati results <- data.frame( patient_id = 1:nrow(new_patient_data), predicted_probability = prob_predictions[, "Disease"], predicted_class = predicted_class, confidence = pmax(prob_predictions[, "Disease"], prob_predictions[, "Healthy"]), risk_level = ifelse(prob_predictions[, "Disease"] > 0.7, "High", ifelse(prob_predictions[, "Disease"] > 0.4, "Medium", "Low")) ) return(results) } # Testare la funzione test_prediction <- predict_penux(rf_model, test_data[1:5, ]) print(test_prediction) </syntaxhighlight> == 6.2 API REST con Plumber == === Creare un'API === <syntaxhighlight lang="r"> # Installare plumber # install.packages("plumber") library(plumber) # Creare il file API (plumber.R) api_code <- " #' PenuX Model Prediction API #' @post /predict #' @param age:int Età del paziente #' @param systolic_bp:numeric Pressione sistolica #' @param diastolic_bp:numeric Pressione diastolica #' @param white_blood_cells:numeric Conta leucocitaria #' @param creatinine:numeric Livello di creatinina predict_disease <- function(age, systolic_bp, diastolic_bp, white_blood_cells, creatinine) { patient_data <- data.frame( age = age, systolic_bp = systolic_bp, diastolic_bp = diastolic_bp, white_blood_cells = white_blood_cells, creatinine = creatinine ) prediction <- predict_penux(rf_model, patient_data) return(prediction) } #' Health Check #' @get /health health_check <- function() { return(list(status = 'OK', model = 'PenuX v1.0')) } " writeLines(api_code, "api/plumber.R") # Lanciare l'API # pr <- plumb("api/plumber.R") # pr$run(host = "0.0.0.0", port = 8000) </syntaxhighlight> == 6.3 Containerizzazione con Docker == === Dockerfile === <syntaxhighlight lang="dockerfile"> FROM rocker/tidyverse:latest # Installare dipendenze RUN install2.r \ randomForest \ xgboost \ caret \ pROC \ plumber # Copiare il modello e l'API COPY models/rf_model.rds /app/models/ COPY api/plumber.R /app/api/ WORKDIR /app # Esporre la porta EXPOSE 8000 # Comando di avvio CMD ["R", "-e", "library(plumber); pr <- plumb('api/plumber.R'); pr$run(host = '0.0.0.0', port = 8000)"] </syntaxhighlight> === Docker Compose === <syntaxhighlight lang="yaml"> version: '3' services: penux-model: build: . ports: - "8000:8000" environment: - MODEL_PATH=/app/models/rf_model.rds volumes: - ./logs:/app/logs healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3 </syntaxhighlight> == 6.4 Monitoraggio del Modello == === Performance Tracking === <syntaxhighlight lang="r"> # Creare un sistema di tracking delle performance create_model_monitor <- function(model_id, model_version) { list( model_id = model_id, model_version = model_version, deployment_date = Sys.Date(), metrics = list(), predictions_log = NULL ) } # Registrare una previsione log_prediction <- function(monitor, prediction_result, actual_outcome = NA) { log_entry <- data.frame( timestamp = Sys.time(), prediction_probability = prediction_result$predicted_probability, prediction_class = prediction_result$predicted_class, actual_outcome = actual_outcome ) monitor$predictions_log <- rbind(monitor$predictions_log, log_entry) return(monitor) } # Calcolare data drift calculate_data_drift <- function(training_stats, new_data) { drift_metrics <- list() for (col in names(training_stats)) { new_mean <- mean(new_data[[col]], na.rm = TRUE) new_sd <- sd(new_data[[col]], na.rm = TRUE) drift_metrics[[col]] <- list( training_mean = training_stats[[col]]$mean, new_mean = new_mean, mean_shift = abs(new_mean - training_stats[[col]]$mean) / training_stats[[col]]$sd, training_sd = training_stats[[col]]$sd, new_sd = new_sd ) } return(drift_metrics) } </syntaxhighlight> == 6.5 Integrazione Clinica == === Validazione Clinica === <syntaxhighlight lang="r"> # Workflow di validazione clinica clinical_validation <- function(model, clinical_test_data, acceptance_criteria) { # Generare previsioni predictions <- predict_penux(model, clinical_test_data) # Valutare rispetto ai criteri di accettazione results <- list( total_samples = nrow(clinical_test_data), min_auc = acceptance_criteria$min_auc, min_sensitivity = acceptance_criteria$min_sensitivity, min_specificity = acceptance_criteria$min_specificity, passed = FALSE ) # Implementare ulteriori controlli if (all(unlist(results) >= unlist(acceptance_criteria))) { results$passed <- TRUE } return(results) } # Criteri di accettazione PenuX penux_criteria <- list( min_auc = 0.85, min_sensitivity = 0.85, min_specificity = 0.80, max_false_positive_rate = 0.10 ) # Eseguire validazione validation_result <- clinical_validation(rf_model, test_data, penux_criteria) print(validation_result) </syntaxhighlight> == 6.6 Documentazione e Compliance == === Regulatory Documentation === <syntaxhighlight lang="r"> # Generare rapporto di conformità generate_regulatory_report <- function(model, validation_results, training_data, deployment_date) { report <- list( model_information = list( name = "PenuX Prediction Model", version = "1.0.0", deployment_date = deployment_date, intended_use = "Early prediction of severe acute pancreatitis and sepsis" ), training_data = list( sample_size = nrow(training_data), variables = names(training_data), date_range = paste(min(training_data$date), "to", max(training_data$date)) ), performance_metrics = validation_results, limitations = list( "Model trained on specific patient population", "Regular revalidation recommended", "Clinician judgment should not be replaced" ), maintenance_plan = list( monitoring_frequency = "Monthly", retraining_frequency = "Quarterly", data_drift_threshold = 0.2 ) ) return(report) } </syntaxhighlight> == 6.7 Ciclo di Vita Continuo == === Retraining Pipeline === <syntaxhighlight lang="r"> # Creare una pipeline di retraining automatico create_retraining_pipeline <- function(data, model_path, performance_threshold = 0.80) { # 1. Verificare la performance current_model <- readRDS(model_path) current_performance <- evaluate_model(current_model) # 2. Se la performance degrada, ritirare if (current_performance$auc < performance_threshold) { # 2a. Ritirare il modello su dati aggiornati new_model <- train_model(data) # 2b. Confrontare le performance new_performance <- evaluate_model(new_model) # 2c. Se il nuovo è migliore, salvare if (new_performance$auc > current_performance$auc) { saveRDS(new_model, paste0(model_path, ".backup")) saveRDS(new_model, model_path) return(list(status = "Retrained", new_auc = new_performance$auc)) } } return(list(status = "No Retrain Needed")) } </syntaxhighlight> == 6.8 Esercizi Pratici == # Creare una funzione di previsione robusta # Costruire un'API REST con plumber # Creare un Dockerfile funzionante # Implementare un sistema di monitoraggio # Generare un rapporto di conformità normativa # Testare il deployment in ambiente locale # Documentare il ciclo di vita del modello == Riepilogo dell'unità 6 == Abbiamo trattato: * Creazione di funzioni di previsione robust * API REST con plumber * Containerizzazione con Docker * Monitoraggio continuo del modello * Validazione clinica e compliance * Documentazione normativa * Ciclo di vita continuo e retraining == Prossimi Passi == * Distribuire su cloud (AWS, Google Cloud, Azure) * Integrare con sistemi EHR * Implementare feedback loops clinici * Stabilire partnership cliniche per validazione * Preparare per regulatory approval == Il progetto PenuX == Repository: https://github.com/netanelcyber/penux Sito: https://penux.uk == Quiz == [[PenuX in R: Quiz Unità 6|Fai il quiz dell'Unità 6]] [[Categoria:PenuX in R|Unità 6 - Deployment e Implementazione Clinica]] o92jlph33ng2ey9ds63bym5ioiusen7 502124 502109 2026-10-04T18:26:08Z Gian BOT 27470 bot: fix link 502124 wikitext text/x-wiki = PenuX in R: Unità 6 - Deployment e Implementazione Clinica = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Containerizzare il modello con Docker * Creare API REST per le previsioni * Integrare il modello con sistemi clinici * Gestire il monitoraggio del modello * Implementare controlli di qualità * Documentare la soluzione == 6.1 Creazione di una Funzione di Previsione == === Funzione Wrapper === <syntaxhighlight lang="r"> # Creare una funzione per fare previsioni standardizzate predict_penux <- function(model, new_patient_data, threshold = 0.5) { # Validare l'input required_cols <- c("age", "systolic_bp", "diastolic_bp", "white_blood_cells", "creatinine") if (!all(required_cols %in% colnames(new_patient_data))) { stop("Colonne mancanti:", paste(setdiff(required_cols, colnames(new_patient_data)), collapse = ", ")) } # Fare previsioni probabilistiche prob_predictions <- predict(model, newdata = new_patient_data, type = "prob") # Convertire in classi predicted_class <- ifelse(prob_predictions[, "Disease"] > threshold, "Disease", "Healthy") # Ritornare risultati strutturati results <- data.frame( patient_id = 1:nrow(new_patient_data), predicted_probability = prob_predictions[, "Disease"], predicted_class = predicted_class, confidence = pmax(prob_predictions[, "Disease"], prob_predictions[, "Healthy"]), risk_level = ifelse(prob_predictions[, "Disease"] > 0.7, "High", ifelse(prob_predictions[, "Disease"] > 0.4, "Medium", "Low")) ) return(results) } # Testare la funzione test_prediction <- predict_penux(rf_model, test_data[1:5, ]) print(test_prediction) </syntaxhighlight> == 6.2 API REST con Plumber == === Creare un'API === <syntaxhighlight lang="r"> # Installare plumber # install.packages("plumber") library(plumber) # Creare il file API (plumber.R) api_code <- " #' PenuX Model Prediction API #' @post /predict #' @param age:int Età del paziente #' @param systolic_bp:numeric Pressione sistolica #' @param diastolic_bp:numeric Pressione diastolica #' @param white_blood_cells:numeric Conta leucocitaria #' @param creatinine:numeric Livello di creatinina predict_disease <- function(age, systolic_bp, diastolic_bp, white_blood_cells, creatinine) { patient_data <- data.frame( age = age, systolic_bp = systolic_bp, diastolic_bp = diastolic_bp, white_blood_cells = white_blood_cells, creatinine = creatinine ) prediction <- predict_penux(rf_model, patient_data) return(prediction) } #' Health Check #' @get /health health_check <- function() { return(list(status = 'OK', model = 'PenuX v1.0')) } " writeLines(api_code, "api/plumber.R") # Lanciare l'API # pr <- plumb("api/plumber.R") # pr$run(host = "0.0.0.0", port = 8000) </syntaxhighlight> == 6.3 Containerizzazione con Docker == === Dockerfile === <syntaxhighlight lang="dockerfile"> FROM rocker/tidyverse:latest # Installare dipendenze RUN install2.r \ randomForest \ xgboost \ caret \ pROC \ plumber # Copiare il modello e l'API COPY models/rf_model.rds /app/models/ COPY api/plumber.R /app/api/ WORKDIR /app # Esporre la porta EXPOSE 8000 # Comando di avvio CMD ["R", "-e", "library(plumber); pr <- plumb('api/plumber.R'); pr$run(host = '0.0.0.0', port = 8000)"] </syntaxhighlight> === Docker Compose === <syntaxhighlight lang="yaml"> version: '3' services: penux-model: build: . ports: - "8000:8000" environment: - MODEL_PATH=/app/models/rf_model.rds volumes: - ./logs:/app/logs healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3 </syntaxhighlight> == 6.4 Monitoraggio del Modello == === Performance Tracking === <syntaxhighlight lang="r"> # Creare un sistema di tracking delle performance create_model_monitor <- function(model_id, model_version) { list( model_id = model_id, model_version = model_version, deployment_date = Sys.Date(), metrics = list(), predictions_log = NULL ) } # Registrare una previsione log_prediction <- function(monitor, prediction_result, actual_outcome = NA) { log_entry <- data.frame( timestamp = Sys.time(), prediction_probability = prediction_result$predicted_probability, prediction_class = prediction_result$predicted_class, actual_outcome = actual_outcome ) monitor$predictions_log <- rbind(monitor$predictions_log, log_entry) return(monitor) } # Calcolare data drift calculate_data_drift <- function(training_stats, new_data) { drift_metrics <- list() for (col in names(training_stats)) { new_mean <- mean(new_data[[col]], na.rm = TRUE) new_sd <- sd(new_data[[col]], na.rm = TRUE) drift_metrics[[col]] <- list( training_mean = training_stats[[col]]$mean, new_mean = new_mean, mean_shift = abs(new_mean - training_stats[[col]]$mean) / training_stats[[col]]$sd, training_sd = training_stats[[col]]$sd, new_sd = new_sd ) } return(drift_metrics) } </syntaxhighlight> == 6.5 Integrazione Clinica == === Validazione Clinica === <syntaxhighlight lang="r"> # Workflow di validazione clinica clinical_validation <- function(model, clinical_test_data, acceptance_criteria) { # Generare previsioni predictions <- predict_penux(model, clinical_test_data) # Valutare rispetto ai criteri di accettazione results <- list( total_samples = nrow(clinical_test_data), min_auc = acceptance_criteria$min_auc, min_sensitivity = acceptance_criteria$min_sensitivity, min_specificity = acceptance_criteria$min_specificity, passed = FALSE ) # Implementare ulteriori controlli if (all(unlist(results) >= unlist(acceptance_criteria))) { results$passed <- TRUE } return(results) } # Criteri di accettazione PenuX penux_criteria <- list( min_auc = 0.85, min_sensitivity = 0.85, min_specificity = 0.80, max_false_positive_rate = 0.10 ) # Eseguire validazione validation_result <- clinical_validation(rf_model, test_data, penux_criteria) print(validation_result) </syntaxhighlight> == 6.6 Documentazione e Compliance == === Regulatory Documentation === <syntaxhighlight lang="r"> # Generare rapporto di conformità generate_regulatory_report <- function(model, validation_results, training_data, deployment_date) { report <- list( model_information = list( name = "PenuX Prediction Model", version = "1.0.0", deployment_date = deployment_date, intended_use = "Early prediction of severe acute pancreatitis and sepsis" ), training_data = list( sample_size = nrow(training_data), variables = names(training_data), date_range = paste(min(training_data$date), "to", max(training_data$date)) ), performance_metrics = validation_results, limitations = list( "Model trained on specific patient population", "Regular revalidation recommended", "Clinician judgment should not be replaced" ), maintenance_plan = list( monitoring_frequency = "Monthly", retraining_frequency = "Quarterly", data_drift_threshold = 0.2 ) ) return(report) } </syntaxhighlight> == 6.7 Ciclo di Vita Continuo == === Retraining Pipeline === <syntaxhighlight lang="r"> # Creare una pipeline di retraining automatico create_retraining_pipeline <- function(data, model_path, performance_threshold = 0.80) { # 1. Verificare la performance current_model <- readRDS(model_path) current_performance <- evaluate_model(current_model) # 2. Se la performance degrada, ritirare if (current_performance$auc < performance_threshold) { # 2a. Ritirare il modello su dati aggiornati new_model <- train_model(data) # 2b. Confrontare le performance new_performance <- evaluate_model(new_model) # 2c. Se il nuovo è migliore, salvare if (new_performance$auc > current_performance$auc) { saveRDS(new_model, paste0(model_path, ".backup")) saveRDS(new_model, model_path) return(list(status = "Retrained", new_auc = new_performance$auc)) } } return(list(status = "No Retrain Needed")) } </syntaxhighlight> == 6.8 Esercizi Pratici == # Creare una funzione di previsione robusta # Costruire un'API REST con plumber # Creare un Dockerfile funzionante # Implementare un sistema di monitoraggio # Generare un rapporto di conformità normativa # Testare il deployment in ambiente locale # Documentare il ciclo di vita del modello == Riepilogo dell'unità 6 == Abbiamo trattato: * Creazione di funzioni di previsione robust * API REST con plumber * Containerizzazione con Docker * Monitoraggio continuo del modello * Validazione clinica e compliance * Documentazione normativa * Ciclo di vita continuo e retraining == Prossimi Passi == * Distribuire su cloud (AWS, Google Cloud, Azure) * Integrare con sistemi EHR * Implementare feedback loops clinici * Stabilire partnership cliniche per validazione * Preparare per regulatory approval == Il progetto PenuX == Repository: https://github.com/netanelcyber/penux Sito: https://penux.uk == Quiz == [[PenuX in R/Quiz Unità 6|Fai il quiz dell'Unità 6]] [[Categoria:PenuX in R|Unità 6 - Deployment e Implementazione Clinica]] 50x3sl4oqfxc021rw2pqakw8bpg4p62 502139 502124 2026-10-04T18:34:33Z Gian BOT 27470 Bot: aggiunge l'indice 502139 wikitext text/x-wiki {{PenuX in R}} = PenuX in R: Unità 6 - Deployment e Implementazione Clinica = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Containerizzare il modello con Docker * Creare API REST per le previsioni * Integrare il modello con sistemi clinici * Gestire il monitoraggio del modello * Implementare controlli di qualità * Documentare la soluzione == 6.1 Creazione di una Funzione di Previsione == === Funzione Wrapper === <syntaxhighlight lang="r"> # Creare una funzione per fare previsioni standardizzate predict_penux <- function(model, new_patient_data, threshold = 0.5) { # Validare l'input required_cols <- c("age", "systolic_bp", "diastolic_bp", "white_blood_cells", "creatinine") if (!all(required_cols %in% colnames(new_patient_data))) { stop("Colonne mancanti:", paste(setdiff(required_cols, colnames(new_patient_data)), collapse = ", ")) } # Fare previsioni probabilistiche prob_predictions <- predict(model, newdata = new_patient_data, type = "prob") # Convertire in classi predicted_class <- ifelse(prob_predictions[, "Disease"] > threshold, "Disease", "Healthy") # Ritornare risultati strutturati results <- data.frame( patient_id = 1:nrow(new_patient_data), predicted_probability = prob_predictions[, "Disease"], predicted_class = predicted_class, confidence = pmax(prob_predictions[, "Disease"], prob_predictions[, "Healthy"]), risk_level = ifelse(prob_predictions[, "Disease"] > 0.7, "High", ifelse(prob_predictions[, "Disease"] > 0.4, "Medium", "Low")) ) return(results) } # Testare la funzione test_prediction <- predict_penux(rf_model, test_data[1:5, ]) print(test_prediction) </syntaxhighlight> == 6.2 API REST con Plumber == === Creare un'API === <syntaxhighlight lang="r"> # Installare plumber # install.packages("plumber") library(plumber) # Creare il file API (plumber.R) api_code <- " #' PenuX Model Prediction API #' @post /predict #' @param age:int Età del paziente #' @param systolic_bp:numeric Pressione sistolica #' @param diastolic_bp:numeric Pressione diastolica #' @param white_blood_cells:numeric Conta leucocitaria #' @param creatinine:numeric Livello di creatinina predict_disease <- function(age, systolic_bp, diastolic_bp, white_blood_cells, creatinine) { patient_data <- data.frame( age = age, systolic_bp = systolic_bp, diastolic_bp = diastolic_bp, white_blood_cells = white_blood_cells, creatinine = creatinine ) prediction <- predict_penux(rf_model, patient_data) return(prediction) } #' Health Check #' @get /health health_check <- function() { return(list(status = 'OK', model = 'PenuX v1.0')) } " writeLines(api_code, "api/plumber.R") # Lanciare l'API # pr <- plumb("api/plumber.R") # pr$run(host = "0.0.0.0", port = 8000) </syntaxhighlight> == 6.3 Containerizzazione con Docker == === Dockerfile === <syntaxhighlight lang="dockerfile"> FROM rocker/tidyverse:latest # Installare dipendenze RUN install2.r \ randomForest \ xgboost \ caret \ pROC \ plumber # Copiare il modello e l'API COPY models/rf_model.rds /app/models/ COPY api/plumber.R /app/api/ WORKDIR /app # Esporre la porta EXPOSE 8000 # Comando di avvio CMD ["R", "-e", "library(plumber); pr <- plumb('api/plumber.R'); pr$run(host = '0.0.0.0', port = 8000)"] </syntaxhighlight> === Docker Compose === <syntaxhighlight lang="yaml"> version: '3' services: penux-model: build: . ports: - "8000:8000" environment: - MODEL_PATH=/app/models/rf_model.rds volumes: - ./logs:/app/logs healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3 </syntaxhighlight> == 6.4 Monitoraggio del Modello == === Performance Tracking === <syntaxhighlight lang="r"> # Creare un sistema di tracking delle performance create_model_monitor <- function(model_id, model_version) { list( model_id = model_id, model_version = model_version, deployment_date = Sys.Date(), metrics = list(), predictions_log = NULL ) } # Registrare una previsione log_prediction <- function(monitor, prediction_result, actual_outcome = NA) { log_entry <- data.frame( timestamp = Sys.time(), prediction_probability = prediction_result$predicted_probability, prediction_class = prediction_result$predicted_class, actual_outcome = actual_outcome ) monitor$predictions_log <- rbind(monitor$predictions_log, log_entry) return(monitor) } # Calcolare data drift calculate_data_drift <- function(training_stats, new_data) { drift_metrics <- list() for (col in names(training_stats)) { new_mean <- mean(new_data[[col]], na.rm = TRUE) new_sd <- sd(new_data[[col]], na.rm = TRUE) drift_metrics[[col]] <- list( training_mean = training_stats[[col]]$mean, new_mean = new_mean, mean_shift = abs(new_mean - training_stats[[col]]$mean) / training_stats[[col]]$sd, training_sd = training_stats[[col]]$sd, new_sd = new_sd ) } return(drift_metrics) } </syntaxhighlight> == 6.5 Integrazione Clinica == === Validazione Clinica === <syntaxhighlight lang="r"> # Workflow di validazione clinica clinical_validation <- function(model, clinical_test_data, acceptance_criteria) { # Generare previsioni predictions <- predict_penux(model, clinical_test_data) # Valutare rispetto ai criteri di accettazione results <- list( total_samples = nrow(clinical_test_data), min_auc = acceptance_criteria$min_auc, min_sensitivity = acceptance_criteria$min_sensitivity, min_specificity = acceptance_criteria$min_specificity, passed = FALSE ) # Implementare ulteriori controlli if (all(unlist(results) >= unlist(acceptance_criteria))) { results$passed <- TRUE } return(results) } # Criteri di accettazione PenuX penux_criteria <- list( min_auc = 0.85, min_sensitivity = 0.85, min_specificity = 0.80, max_false_positive_rate = 0.10 ) # Eseguire validazione validation_result <- clinical_validation(rf_model, test_data, penux_criteria) print(validation_result) </syntaxhighlight> == 6.6 Documentazione e Compliance == === Regulatory Documentation === <syntaxhighlight lang="r"> # Generare rapporto di conformità generate_regulatory_report <- function(model, validation_results, training_data, deployment_date) { report <- list( model_information = list( name = "PenuX Prediction Model", version = "1.0.0", deployment_date = deployment_date, intended_use = "Early prediction of severe acute pancreatitis and sepsis" ), training_data = list( sample_size = nrow(training_data), variables = names(training_data), date_range = paste(min(training_data$date), "to", max(training_data$date)) ), performance_metrics = validation_results, limitations = list( "Model trained on specific patient population", "Regular revalidation recommended", "Clinician judgment should not be replaced" ), maintenance_plan = list( monitoring_frequency = "Monthly", retraining_frequency = "Quarterly", data_drift_threshold = 0.2 ) ) return(report) } </syntaxhighlight> == 6.7 Ciclo di Vita Continuo == === Retraining Pipeline === <syntaxhighlight lang="r"> # Creare una pipeline di retraining automatico create_retraining_pipeline <- function(data, model_path, performance_threshold = 0.80) { # 1. Verificare la performance current_model <- readRDS(model_path) current_performance <- evaluate_model(current_model) # 2. Se la performance degrada, ritirare if (current_performance$auc < performance_threshold) { # 2a. Ritirare il modello su dati aggiornati new_model <- train_model(data) # 2b. Confrontare le performance new_performance <- evaluate_model(new_model) # 2c. Se il nuovo è migliore, salvare if (new_performance$auc > current_performance$auc) { saveRDS(new_model, paste0(model_path, ".backup")) saveRDS(new_model, model_path) return(list(status = "Retrained", new_auc = new_performance$auc)) } } return(list(status = "No Retrain Needed")) } </syntaxhighlight> == 6.8 Esercizi Pratici == # Creare una funzione di previsione robusta # Costruire un'API REST con plumber # Creare un Dockerfile funzionante # Implementare un sistema di monitoraggio # Generare un rapporto di conformità normativa # Testare il deployment in ambiente locale # Documentare il ciclo di vita del modello == Riepilogo dell'unità 6 == Abbiamo trattato: * Creazione di funzioni di previsione robust * API REST con plumber * Containerizzazione con Docker * Monitoraggio continuo del modello * Validazione clinica e compliance * Documentazione normativa * Ciclo di vita continuo e retraining == Prossimi Passi == * Distribuire su cloud (AWS, Google Cloud, Azure) * Integrare con sistemi EHR * Implementare feedback loops clinici * Stabilire partnership cliniche per validazione * Preparare per regulatory approval == Il progetto PenuX == Repository: https://github.com/netanelcyber/penux Sito: https://penux.uk == Quiz == [[PenuX in R/Quiz Unità 6|Fai il quiz dell'Unità 6]] [[Categoria:PenuX in R|Unità 6 - Deployment e Implementazione Clinica]] sgn2gbpwwahfetubfhgdf55gv26bgkn PenuX in R/Quiz Unità 6 0 61188 502069 502020 2026-10-04T14:55:12Z Hippias 18281 Hippias ha spostato la pagina [[PenuX in R: Quiz Unità 6]] a [[PenuX in R/Quiz Unità 6]] senza lasciare redirect: [[Aiuto:Convenzioni di nomenclatura|Convenzioni di nomenclatura]]: sottopagino correttamente 502020 wikitext text/x-wiki = PenuX in R: Quiz Unità 6 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == A cosa serve il pacchetto Plumber? * A) A creare grafici * B) A pulire i dati * C) A calcolare l'AUC * D) A esporre funzioni R come API REST <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Permette di servire un modello tramite richieste HTTP. </div> == Domanda 2 == Qual è il vantaggio principale di Docker? * A) Impacchetta applicazione e dipendenze in un ambiente riproducibile * B) Rende il modello più accurato * C) Sostituisce R * D) Elimina la necessità di test <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Lo stesso container funziona allo stesso modo su macchine diverse. </div> == Domanda 3 == Che cos'è il data drift? * A) Un errore di sintassi * B) Un cambiamento nella distribuzione dei dati in produzione rispetto al training * C) La perdita di connessione all'API * D) Un metodo di imputazione <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Può degradare le prestazioni nel tempo e richiede monitoraggio. </div> == Domanda 4 == Che cosa serve prima di un uso clinico di un modello predittivo? * A) Solo un'AUC alta sul training * B) Solo una buona documentazione del codice * C) Validazione clinica e conformità normativa * D) Nulla, se il modello è accurato <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. Un'accuratezza elevata non basta: servono validazione prospettica, sicurezza e norme applicabili. </div> == Torna all'unità == [[PenuX in R: Unità 6 - Deployment e Implementazione Clinica|Torna all'Unità 6]] 8hab7zlildwax2xuib6jslm7mkd67h0 502101 502069 2026-10-04T18:20:59Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502101 wikitext text/x-wiki = PenuX in R: Quiz Unità 6 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == A cosa serve il pacchetto Plumber? * A) A creare grafici * B) A pulire i dati * C) A calcolare l'AUC * D) A esporre funzioni R come API REST <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Permette di servire un modello tramite richieste HTTP. </div> == Domanda 2 == Qual è il vantaggio principale di Docker? * A) Impacchetta applicazione e dipendenze in un ambiente riproducibile * B) Rende il modello più accurato * C) Sostituisce R * D) Elimina la necessità di test <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Lo stesso container funziona allo stesso modo su macchine diverse. </div> == Domanda 3 == Che cos'è il data drift? * A) Un errore di sintassi * B) Un cambiamento nella distribuzione dei dati in produzione rispetto al training * C) La perdita di connessione all'API * D) Un metodo di imputazione <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Può degradare le prestazioni nel tempo e richiede monitoraggio. </div> == Domanda 4 == Che cosa serve prima di un uso clinico di un modello predittivo? * A) Solo un'AUC alta sul training * B) Solo una buona documentazione del codice * C) Validazione clinica e conformità normativa * D) Nulla, se il modello è accurato <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. Un'accuratezza elevata non basta: servono validazione prospettica, sicurezza e norme applicabili. </div> == Torna all'unità == [[PenuX in R: Unità 6 - Deployment e Implementazione Clinica|Torna all'Unità 6]] [[Categoria:PenuX in R|Quiz Unità 6]] 8r08nm6birzbslwll0r0talevkx0pty 502117 502101 2026-10-04T18:24:58Z Gian BOT 27470 bot: fix link 502117 wikitext text/x-wiki = PenuX in R: Quiz Unità 6 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == A cosa serve il pacchetto Plumber? * A) A creare grafici * B) A pulire i dati * C) A calcolare l'AUC * D) A esporre funzioni R come API REST <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Permette di servire un modello tramite richieste HTTP. </div> == Domanda 2 == Qual è il vantaggio principale di Docker? * A) Impacchetta applicazione e dipendenze in un ambiente riproducibile * B) Rende il modello più accurato * C) Sostituisce R * D) Elimina la necessità di test <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Lo stesso container funziona allo stesso modo su macchine diverse. </div> == Domanda 3 == Che cos'è il data drift? * A) Un errore di sintassi * B) Un cambiamento nella distribuzione dei dati in produzione rispetto al training * C) La perdita di connessione all'API * D) Un metodo di imputazione <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Può degradare le prestazioni nel tempo e richiede monitoraggio. </div> == Domanda 4 == Che cosa serve prima di un uso clinico di un modello predittivo? * A) Solo un'AUC alta sul training * B) Solo una buona documentazione del codice * C) Validazione clinica e conformità normativa * D) Nulla, se il modello è accurato <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. Un'accuratezza elevata non basta: servono validazione prospettica, sicurezza e norme applicabili. </div> == Torna all'unità == [[PenuX in R/Unità 6 - Deployment e Implementazione Clinica|Torna all'Unità 6]] [[Categoria:PenuX in R|Quiz Unità 6]] k67ilxeyuzg0ovqhxmk90c37gampd98 502132 502117 2026-10-04T18:33:20Z Gian BOT 27470 Bot: aggiunge l'indice 502132 wikitext text/x-wiki {{PenuX in R}} = PenuX in R: Quiz Unità 6 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == A cosa serve il pacchetto Plumber? * A) A creare grafici * B) A pulire i dati * C) A calcolare l'AUC * D) A esporre funzioni R come API REST <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Permette di servire un modello tramite richieste HTTP. </div> == Domanda 2 == Qual è il vantaggio principale di Docker? * A) Impacchetta applicazione e dipendenze in un ambiente riproducibile * B) Rende il modello più accurato * C) Sostituisce R * D) Elimina la necessità di test <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Lo stesso container funziona allo stesso modo su macchine diverse. </div> == Domanda 3 == Che cos'è il data drift? * A) Un errore di sintassi * B) Un cambiamento nella distribuzione dei dati in produzione rispetto al training * C) La perdita di connessione all'API * D) Un metodo di imputazione <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Può degradare le prestazioni nel tempo e richiede monitoraggio. </div> == Domanda 4 == Che cosa serve prima di un uso clinico di un modello predittivo? * A) Solo un'AUC alta sul training * B) Solo una buona documentazione del codice * C) Validazione clinica e conformità normativa * D) Nulla, se il modello è accurato <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. Un'accuratezza elevata non basta: servono validazione prospettica, sicurezza e norme applicabili. </div> == Torna all'unità == [[PenuX in R/Unità 6 - Deployment e Implementazione Clinica|Torna all'Unità 6]] [[Categoria:PenuX in R|Quiz Unità 6]] 29ckvqzjdl7txsr02y40m0dl7lmj19q PenuX in R/Unità 7 - Esercitazioni di Machine Learning in R 0 61189 502061 502021 2026-10-04T14:46:43Z Hippias 18281 Hippias ha spostato la pagina [[PenuX in R: Unità 7 - Esercitazioni di Machine Learning in R]] a [[PenuX in R/Unità 7 - Esercitazioni di Machine Learning in R]] senza lasciare redirect: [[Aiuto:Convenzioni di nomenclatura|Convenzioni di nomenclatura]]: sottopagino correttamente 502021 wikitext text/x-wiki = PenuX in R: Unità 7 - Esercitazioni di Machine Learning in R = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Preparare i dati e dividerli in training e test set * Addestrare modelli di classificazione (regressione logistica, albero decisionale, Random Forest, kNN) * Valutare i modelli con matrice di confusione, ROC e AUC * Confrontare più modelli con la validazione incrociata * Costruire un modello di regressione e interpretarne l'errore (RMSE) * Applicare un metodo non supervisionato (k-means) * Completare un mini-progetto clinico di predizione della sepsi '''Prerequisiti''': Unità 1 (Fondamenti di R) e conoscenza di base delle Unità 2-5. == 7.0 Preparazione == <syntaxhighlight lang="r"> # Installare i pacchetti (una sola volta) install.packages(c("caret", "randomForest", "rpart", "pROC", "e1071")) # Caricare i pacchetti library(caret) library(randomForest) library(rpart) library(pROC) set.seed(42) # Riproducibilità </syntaxhighlight> === Dati clinici sintetici === In tutti gli esercizi useremo un dataset sintetico (non contiene dati di pazienti reali) per la predizione della sepsi. <syntaxhighlight lang="r"> n <- 500 clinical <- data.frame( age = round(rnorm(n, 55, 15)), heart_rate = round(rnorm(n, 85, 15)), temperature = round(rnorm(n, 37.2, 0.8), 1), wbc = round(rnorm(n, 9, 3), 1), lactate = round(rlnorm(n, log(1.5), 0.4), 2) ) # Rischio reale (logit) usato per generare l'esito risk <- -7.5 + 0.02 * clinical$age + 0.03 * clinical$heart_rate + 0.5 * (clinical$temperature - 37) + 0.1 * clinical$wbc + 0.9 * clinical$lactate clinical$sepsis <- factor( rbinom(n, 1, plogis(risk)), levels = c(0, 1), labels = c("No", "Si") ) table(clinical$sepsis) prop.table(table(clinical$sepsis)) str(clinical) </syntaxhighlight> == 7.1 Esercizio 1: Divisione dei dati == '''Obiettivo''': dividere il dataset in 70% training e 30% test mantenendo la proporzione delle classi. <syntaxhighlight lang="r"> # Completa il codice: train_idx <- createDataPartition(clinical$sepsis, p = 0.70, list = FALSE) train_data <- clinical[train_idx, ] test_data <- clinical[-train_idx, ] # Verifica: nrow(train_data) nrow(test_data) prop.table(table(train_data$sepsis)) prop.table(table(test_data$sepsis)) </syntaxhighlight> '''Domande''': * Perché è importante stratificare la divisione per la variabile esito? * Cosa succede se valutiamo il modello sugli stessi dati usati per l'addestramento? == 7.2 Esercizio 2: Regressione logistica == <syntaxhighlight lang="r"> # Addestrare il modello logit_model <- glm(sepsis ~ ., data = train_data, family = binomial) summary(logit_model) # Odds ratio con intervalli di confidenza exp(cbind(OR = coef(logit_model), confint.default(logit_model))) # Predizioni sul test set prob_logit <- predict(logit_model, newdata = test_data, type = "response") pred_logit <- factor(ifelse(prob_logit > 0.5, "Si", "No"), levels = c("No", "Si")) # Matrice di confusione confusionMatrix(pred_logit, test_data$sepsis, positive = "Si") </syntaxhighlight> '''Compito''': quale variabile ha l'odds ratio più alto? Come interpreti il valore per il lattato? == 7.3 Esercizio 3: Curva ROC e AUC == <syntaxhighlight lang="r"> roc_logit <- roc(response = test_data$sepsis, predictor = prob_logit, levels = c("No", "Si")) auc(roc_logit) plot(roc_logit, main = "Curva ROC - Regressione logistica", col = "steelblue", lwd = 2) # Soglia ottimale (indice di Youden) coords(roc_logit, "best", ret = c("threshold", "sensitivity", "specificity")) </syntaxhighlight> '''Compito''': ripeti la matrice di confusione usando la soglia ottimale al posto di 0.5. Come cambiano sensibilità e specificità? == 7.4 Esercizio 4: Albero decisionale == <syntaxhighlight lang="r"> tree_model <- rpart(sepsis ~ ., data = train_data, method = "class", control = rpart.control(cp = 0.01)) # Visualizzare l'albero plot(tree_model, margin = 0.1) text(tree_model, use.n = TRUE, cex = 0.8) # Predizioni pred_tree <- predict(tree_model, newdata = test_data, type = "class") confusionMatrix(pred_tree, test_data$sepsis, positive = "Si") </syntaxhighlight> '''Compito''': modifica il parametro <code>cp</code> (0.001, 0.05) e osserva come cambia la complessità dell'albero (overfitting vs underfitting). == 7.5 Esercizio 5: Random Forest == <syntaxhighlight lang="r"> rf_model <- randomForest(sepsis ~ ., data = train_data, ntree = 500, importance = TRUE) print(rf_model) # Importanza delle variabili importance(rf_model) varImpPlot(rf_model, main = "Importanza delle variabili") # Valutazione sul test set pred_rf <- predict(rf_model, newdata = test_data) prob_rf <- predict(rf_model, newdata = test_data, type = "prob")[, "Si"] confusionMatrix(pred_rf, test_data$sepsis, positive = "Si") auc(roc(test_data$sepsis, prob_rf, levels = c("No", "Si"))) </syntaxhighlight> '''Domande''': * Quali sono le tre variabili più importanti? * Corrispondono ai coefficienti più alti della regressione logistica? == 7.6 Esercizio 6: Validazione incrociata e confronto modelli == <syntaxhighlight lang="r"> ctrl <- trainControl( method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary, savePredictions = "final" ) set.seed(42) cv_logit <- train(sepsis ~ ., data = train_data, method = "glm", family = "binomial", metric = "ROC", trControl = ctrl) set.seed(42) cv_rf <- train(sepsis ~ ., data = train_data, method = "rf", metric = "ROC", trControl = ctrl, tuneLength = 3) set.seed(42) cv_knn <- train(sepsis ~ ., data = train_data, method = "knn", metric = "ROC", trControl = ctrl, preProcess = c("center", "scale"), tuneLength = 5) # Confronto risultati <- resamples(list(Logistica = cv_logit, RandomForest = cv_rf, kNN = cv_knn)) summary(risultati) bwplot(risultati, metric = "ROC") </syntaxhighlight> '''Compito''': quale modello ha l'AUC media più alta? La differenza è rilevante rispetto alla variabilità tra i fold? '''Nota''': per il kNN la standardizzazione (<code>center</code>, <code>scale</code>) è fondamentale perché l'algoritmo usa le distanze. == 7.7 Esercizio 7: Dati sbilanciati == <syntaxhighlight lang="r"> # Pesi per le classi pesi <- ifelse(train_data$sepsis == "Si", sum(train_data$sepsis == "No") / sum(train_data$sepsis == "Si"), 1) logit_pesata <- glm(sepsis ~ ., data = train_data, family = binomial, weights = pesi) prob_pesata <- predict(logit_pesata, newdata = test_data, type = "response") pred_pesata <- factor(ifelse(prob_pesata > 0.5, "Si", "No"), levels = c("No", "Si")) confusionMatrix(pred_pesata, test_data$sepsis, positive = "Si") </syntaxhighlight> '''Compito''': confronta la sensibilità con il modello non pesato dell'Esercizio 2. In un contesto clinico (sepsi), è peggio un falso negativo o un falso positivo? == 7.8 Esercizio 8: Regressione (variabile continua) == Predire il consumo di carburante (<code>mpg</code>) dal dataset integrato <code>mtcars</code>. <syntaxhighlight lang="r"> data(mtcars) set.seed(42) idx <- createDataPartition(mtcars$mpg, p = 0.75, list = FALSE) train <- mtcars[idx, ] test <- mtcars[-idx, ] lm_model <- lm(mpg ~ wt + hp + cyl, data = train) summary(lm_model) pred <- predict(lm_model, newdata = test) # Metriche di regressione rmse <- sqrt(mean((test$mpg - pred)^2)) mae <- mean(abs(test$mpg - pred)) r2 <- cor(test$mpg, pred)^2 cat("RMSE:", round(rmse, 2), "| MAE:", round(mae, 2), "| R2:", round(r2, 2), "\n") # Valori osservati vs predetti plot(test$mpg, pred, xlab = "Osservato", ylab = "Predetto", main = "Osservato vs Predetto", pch = 19) abline(0, 1, col = "red", lty = 2) </syntaxhighlight> '''Compito''': aggiungi altre variabili al modello (per esempio <code>disp</code>, <code>qsec</code>) e verifica se l'RMSE sul test set migliora. == 7.9 Esercizio 9: Apprendimento non supervisionato (k-means) == <syntaxhighlight lang="r"> # Usare solo le variabili cliniche (senza l'esito) X <- scale(clinical[, c("age", "heart_rate", "temperature", "wbc", "lactate")]) # Metodo del gomito wss <- sapply(1:8, function(k) kmeans(X, centers = k, nstart = 20)$tot.withinss) plot(1:8, wss, type = "b", xlab = "Numero di cluster", ylab = "Somma dei quadrati intra-cluster", main = "Metodo del gomito") # Clustering con k = 3 set.seed(42) km <- kmeans(X, centers = 3, nstart = 25) table(Cluster = km$cluster, Sepsi = clinical$sepsis) # Visualizzazione con PCA pca <- prcomp(X) plot(pca$x[, 1:2], col = km$cluster, pch = 19, main = "Cluster nello spazio delle prime due componenti principali") </syntaxhighlight> '''Domande''': * I cluster trovati corrispondono alla presenza di sepsi? * Perché è necessario standardizzare le variabili prima di k-means? == 7.10 Mini-progetto finale == Completa il flusso di lavoro, dall'inizio alla fine: # Genera un nuovo dataset con <code>set.seed(2026)</code> e <code>n = 800</code> # Dividi i dati in training (70%) e test (30%) # Addestra almeno tre modelli (per esempio logistica, Random Forest, SVM) # Confrontali con 5-fold CV usando l'AUC # Scegli il modello migliore e valutalo sul test set (matrice di confusione, ROC, soglia ottimale) # Salva il modello con <code>saveRDS()</code> e ricaricalo per fare una predizione su un nuovo paziente # Scrivi un breve paragrafo (5 righe) che spiega i limiti del modello <syntaxhighlight lang="r"> # Suggerimento per il punto 6: saveRDS(rf_model, "modello_sepsi.rds") modello <- readRDS("modello_sepsi.rds") nuovo_paziente <- data.frame(age = 72, heart_rate = 112, temperature = 38.6, wbc = 15.2, lactate = 3.4) predict(modello, nuovo_paziente, type = "prob") </syntaxhighlight> == 7.11 Soluzioni e Risposte == === Esercizio 1 === La stratificazione mantiene la stessa proporzione di casi positivi in training e test; senza di essa, con classi sbilanciate, il test set potrebbe contenere pochissimi casi positivi. Valutare sui dati di addestramento sovrastima le prestazioni (overfitting): il modello ha già "visto" quelle risposte. === Esercizio 2 === Il lattato ha di solito l'odds ratio più alto perché nel processo generatore ha il coefficiente maggiore (0.9, cioè OR ≈ 2.5 per ogni unità di aumento, a parità delle altre variabili). Con dati simulati i valori stimati varieranno leggermente. === Esercizio 3 === Abbassare la soglia sotto 0.5 aumenta di solito la sensibilità a scapito della specificità. In ambito clinico, per una condizione grave come la sepsi si preferisce spesso una sensibilità maggiore. === Esercizio 4 === Un <code>cp</code> basso produce un albero profondo (rischio di overfitting); un <code>cp</code> alto produce un albero troppo semplice (underfitting). === Esercizio 5 === Le variabili più importanti sono tipicamente lattato, frequenza cardiaca ed età. L'importanza nella Random Forest e i coefficienti della regressione logistica tendono a concordare, ma non sono la stessa misura (non lineare vs lineare). === Esercizio 6 === Poiché i dati sono generati da un modello logistico, la regressione logistica è spesso competitiva o migliore della Random Forest. Se le differenze di AUC sono minori della deviazione standard tra i fold, i modelli sono statisticamente indistinguibili. === Esercizio 7 === I pesi aumentano la sensibilità e riducono la specificità. Nella sepsi un falso negativo (paziente malato non riconosciuto) è generalmente più grave di un falso positivo. === Esercizio 8 === Aggiungere variabili può ridurre l'RMSE sul training, ma con pochi dati (<code>mtcars</code> ha 32 righe) il test set è molto piccolo e il risultato è instabile: valutare con validazione incrociata. === Esercizio 9 === K-means non usa l'esito, quindi i cluster non coincidono necessariamente con la sepsi. La standardizzazione evita che variabili con scala maggiore (es. frequenza cardiaca) dominino la distanza. == Verifica della comprensione == * Qual è la differenza tra apprendimento supervisionato e non supervisionato? * Perché si usa un test set separato? * Cosa misura l'AUC? Quando può essere fuorviante? * Qual è la differenza tra sensibilità e valore predittivo positivo? * Perché il kNN richiede la standardizzazione? * Cos'è l'overfitting e come lo si individua? == Avvertenza == I dati di questa unità sono sintetici e a scopo didattico. I modelli non sono validati clinicamente e non devono essere usati per decisioni su pazienti reali. == Riepilogo dell'Unità 7 == Abbiamo praticato: * Divisione stratificata dei dati * Regressione logistica, albero decisionale, Random Forest, kNN * Matrice di confusione, ROC, AUC e scelta della soglia * Validazione incrociata e confronto tra modelli * Gestione dello sbilanciamento delle classi * Regressione con RMSE, MAE e R² * Clustering con k-means * Un mini-progetto completo == Letture Consigliate == * [https://topepo.github.io/caret/ Manuale del pacchetto caret] * [https://www.statlearning.com/ An Introduction to Statistical Learning (con applicazioni in R)] * [https://r4ds.hadley.nz/ R for Data Science] == Il progetto PenuX == Repository PenuX: https://github.com/netanelcyber/penux Sito PenuX: https://penux.uk == Quiz == [[PenuX in R: Quiz Unità 7|Fai il quiz dell'Unità 7]] 9b34a4dfkkeerwajghw02x68gddwpqh 502110 502061 2026-10-04T18:22:39Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502110 wikitext text/x-wiki = PenuX in R: Unità 7 - Esercitazioni di Machine Learning in R = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Preparare i dati e dividerli in training e test set * Addestrare modelli di classificazione (regressione logistica, albero decisionale, Random Forest, kNN) * Valutare i modelli con matrice di confusione, ROC e AUC * Confrontare più modelli con la validazione incrociata * Costruire un modello di regressione e interpretarne l'errore (RMSE) * Applicare un metodo non supervisionato (k-means) * Completare un mini-progetto clinico di predizione della sepsi '''Prerequisiti''': Unità 1 (Fondamenti di R) e conoscenza di base delle Unità 2-5. == 7.0 Preparazione == <syntaxhighlight lang="r"> # Installare i pacchetti (una sola volta) install.packages(c("caret", "randomForest", "rpart", "pROC", "e1071")) # Caricare i pacchetti library(caret) library(randomForest) library(rpart) library(pROC) set.seed(42) # Riproducibilità </syntaxhighlight> === Dati clinici sintetici === In tutti gli esercizi useremo un dataset sintetico (non contiene dati di pazienti reali) per la predizione della sepsi. <syntaxhighlight lang="r"> n <- 500 clinical <- data.frame( age = round(rnorm(n, 55, 15)), heart_rate = round(rnorm(n, 85, 15)), temperature = round(rnorm(n, 37.2, 0.8), 1), wbc = round(rnorm(n, 9, 3), 1), lactate = round(rlnorm(n, log(1.5), 0.4), 2) ) # Rischio reale (logit) usato per generare l'esito risk <- -7.5 + 0.02 * clinical$age + 0.03 * clinical$heart_rate + 0.5 * (clinical$temperature - 37) + 0.1 * clinical$wbc + 0.9 * clinical$lactate clinical$sepsis <- factor( rbinom(n, 1, plogis(risk)), levels = c(0, 1), labels = c("No", "Si") ) table(clinical$sepsis) prop.table(table(clinical$sepsis)) str(clinical) </syntaxhighlight> == 7.1 Esercizio 1: Divisione dei dati == '''Obiettivo''': dividere il dataset in 70% training e 30% test mantenendo la proporzione delle classi. <syntaxhighlight lang="r"> # Completa il codice: train_idx <- createDataPartition(clinical$sepsis, p = 0.70, list = FALSE) train_data <- clinical[train_idx, ] test_data <- clinical[-train_idx, ] # Verifica: nrow(train_data) nrow(test_data) prop.table(table(train_data$sepsis)) prop.table(table(test_data$sepsis)) </syntaxhighlight> '''Domande''': * Perché è importante stratificare la divisione per la variabile esito? * Cosa succede se valutiamo il modello sugli stessi dati usati per l'addestramento? == 7.2 Esercizio 2: Regressione logistica == <syntaxhighlight lang="r"> # Addestrare il modello logit_model <- glm(sepsis ~ ., data = train_data, family = binomial) summary(logit_model) # Odds ratio con intervalli di confidenza exp(cbind(OR = coef(logit_model), confint.default(logit_model))) # Predizioni sul test set prob_logit <- predict(logit_model, newdata = test_data, type = "response") pred_logit <- factor(ifelse(prob_logit > 0.5, "Si", "No"), levels = c("No", "Si")) # Matrice di confusione confusionMatrix(pred_logit, test_data$sepsis, positive = "Si") </syntaxhighlight> '''Compito''': quale variabile ha l'odds ratio più alto? Come interpreti il valore per il lattato? == 7.3 Esercizio 3: Curva ROC e AUC == <syntaxhighlight lang="r"> roc_logit <- roc(response = test_data$sepsis, predictor = prob_logit, levels = c("No", "Si")) auc(roc_logit) plot(roc_logit, main = "Curva ROC - Regressione logistica", col = "steelblue", lwd = 2) # Soglia ottimale (indice di Youden) coords(roc_logit, "best", ret = c("threshold", "sensitivity", "specificity")) </syntaxhighlight> '''Compito''': ripeti la matrice di confusione usando la soglia ottimale al posto di 0.5. Come cambiano sensibilità e specificità? == 7.4 Esercizio 4: Albero decisionale == <syntaxhighlight lang="r"> tree_model <- rpart(sepsis ~ ., data = train_data, method = "class", control = rpart.control(cp = 0.01)) # Visualizzare l'albero plot(tree_model, margin = 0.1) text(tree_model, use.n = TRUE, cex = 0.8) # Predizioni pred_tree <- predict(tree_model, newdata = test_data, type = "class") confusionMatrix(pred_tree, test_data$sepsis, positive = "Si") </syntaxhighlight> '''Compito''': modifica il parametro <code>cp</code> (0.001, 0.05) e osserva come cambia la complessità dell'albero (overfitting vs underfitting). == 7.5 Esercizio 5: Random Forest == <syntaxhighlight lang="r"> rf_model <- randomForest(sepsis ~ ., data = train_data, ntree = 500, importance = TRUE) print(rf_model) # Importanza delle variabili importance(rf_model) varImpPlot(rf_model, main = "Importanza delle variabili") # Valutazione sul test set pred_rf <- predict(rf_model, newdata = test_data) prob_rf <- predict(rf_model, newdata = test_data, type = "prob")[, "Si"] confusionMatrix(pred_rf, test_data$sepsis, positive = "Si") auc(roc(test_data$sepsis, prob_rf, levels = c("No", "Si"))) </syntaxhighlight> '''Domande''': * Quali sono le tre variabili più importanti? * Corrispondono ai coefficienti più alti della regressione logistica? == 7.6 Esercizio 6: Validazione incrociata e confronto modelli == <syntaxhighlight lang="r"> ctrl <- trainControl( method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary, savePredictions = "final" ) set.seed(42) cv_logit <- train(sepsis ~ ., data = train_data, method = "glm", family = "binomial", metric = "ROC", trControl = ctrl) set.seed(42) cv_rf <- train(sepsis ~ ., data = train_data, method = "rf", metric = "ROC", trControl = ctrl, tuneLength = 3) set.seed(42) cv_knn <- train(sepsis ~ ., data = train_data, method = "knn", metric = "ROC", trControl = ctrl, preProcess = c("center", "scale"), tuneLength = 5) # Confronto risultati <- resamples(list(Logistica = cv_logit, RandomForest = cv_rf, kNN = cv_knn)) summary(risultati) bwplot(risultati, metric = "ROC") </syntaxhighlight> '''Compito''': quale modello ha l'AUC media più alta? La differenza è rilevante rispetto alla variabilità tra i fold? '''Nota''': per il kNN la standardizzazione (<code>center</code>, <code>scale</code>) è fondamentale perché l'algoritmo usa le distanze. == 7.7 Esercizio 7: Dati sbilanciati == <syntaxhighlight lang="r"> # Pesi per le classi pesi <- ifelse(train_data$sepsis == "Si", sum(train_data$sepsis == "No") / sum(train_data$sepsis == "Si"), 1) logit_pesata <- glm(sepsis ~ ., data = train_data, family = binomial, weights = pesi) prob_pesata <- predict(logit_pesata, newdata = test_data, type = "response") pred_pesata <- factor(ifelse(prob_pesata > 0.5, "Si", "No"), levels = c("No", "Si")) confusionMatrix(pred_pesata, test_data$sepsis, positive = "Si") </syntaxhighlight> '''Compito''': confronta la sensibilità con il modello non pesato dell'Esercizio 2. In un contesto clinico (sepsi), è peggio un falso negativo o un falso positivo? == 7.8 Esercizio 8: Regressione (variabile continua) == Predire il consumo di carburante (<code>mpg</code>) dal dataset integrato <code>mtcars</code>. <syntaxhighlight lang="r"> data(mtcars) set.seed(42) idx <- createDataPartition(mtcars$mpg, p = 0.75, list = FALSE) train <- mtcars[idx, ] test <- mtcars[-idx, ] lm_model <- lm(mpg ~ wt + hp + cyl, data = train) summary(lm_model) pred <- predict(lm_model, newdata = test) # Metriche di regressione rmse <- sqrt(mean((test$mpg - pred)^2)) mae <- mean(abs(test$mpg - pred)) r2 <- cor(test$mpg, pred)^2 cat("RMSE:", round(rmse, 2), "| MAE:", round(mae, 2), "| R2:", round(r2, 2), "\n") # Valori osservati vs predetti plot(test$mpg, pred, xlab = "Osservato", ylab = "Predetto", main = "Osservato vs Predetto", pch = 19) abline(0, 1, col = "red", lty = 2) </syntaxhighlight> '''Compito''': aggiungi altre variabili al modello (per esempio <code>disp</code>, <code>qsec</code>) e verifica se l'RMSE sul test set migliora. == 7.9 Esercizio 9: Apprendimento non supervisionato (k-means) == <syntaxhighlight lang="r"> # Usare solo le variabili cliniche (senza l'esito) X <- scale(clinical[, c("age", "heart_rate", "temperature", "wbc", "lactate")]) # Metodo del gomito wss <- sapply(1:8, function(k) kmeans(X, centers = k, nstart = 20)$tot.withinss) plot(1:8, wss, type = "b", xlab = "Numero di cluster", ylab = "Somma dei quadrati intra-cluster", main = "Metodo del gomito") # Clustering con k = 3 set.seed(42) km <- kmeans(X, centers = 3, nstart = 25) table(Cluster = km$cluster, Sepsi = clinical$sepsis) # Visualizzazione con PCA pca <- prcomp(X) plot(pca$x[, 1:2], col = km$cluster, pch = 19, main = "Cluster nello spazio delle prime due componenti principali") </syntaxhighlight> '''Domande''': * I cluster trovati corrispondono alla presenza di sepsi? * Perché è necessario standardizzare le variabili prima di k-means? == 7.10 Mini-progetto finale == Completa il flusso di lavoro, dall'inizio alla fine: # Genera un nuovo dataset con <code>set.seed(2026)</code> e <code>n = 800</code> # Dividi i dati in training (70%) e test (30%) # Addestra almeno tre modelli (per esempio logistica, Random Forest, SVM) # Confrontali con 5-fold CV usando l'AUC # Scegli il modello migliore e valutalo sul test set (matrice di confusione, ROC, soglia ottimale) # Salva il modello con <code>saveRDS()</code> e ricaricalo per fare una predizione su un nuovo paziente # Scrivi un breve paragrafo (5 righe) che spiega i limiti del modello <syntaxhighlight lang="r"> # Suggerimento per il punto 6: saveRDS(rf_model, "modello_sepsi.rds") modello <- readRDS("modello_sepsi.rds") nuovo_paziente <- data.frame(age = 72, heart_rate = 112, temperature = 38.6, wbc = 15.2, lactate = 3.4) predict(modello, nuovo_paziente, type = "prob") </syntaxhighlight> == 7.11 Soluzioni e Risposte == === Esercizio 1 === La stratificazione mantiene la stessa proporzione di casi positivi in training e test; senza di essa, con classi sbilanciate, il test set potrebbe contenere pochissimi casi positivi. Valutare sui dati di addestramento sovrastima le prestazioni (overfitting): il modello ha già "visto" quelle risposte. === Esercizio 2 === Il lattato ha di solito l'odds ratio più alto perché nel processo generatore ha il coefficiente maggiore (0.9, cioè OR ≈ 2.5 per ogni unità di aumento, a parità delle altre variabili). Con dati simulati i valori stimati varieranno leggermente. === Esercizio 3 === Abbassare la soglia sotto 0.5 aumenta di solito la sensibilità a scapito della specificità. In ambito clinico, per una condizione grave come la sepsi si preferisce spesso una sensibilità maggiore. === Esercizio 4 === Un <code>cp</code> basso produce un albero profondo (rischio di overfitting); un <code>cp</code> alto produce un albero troppo semplice (underfitting). === Esercizio 5 === Le variabili più importanti sono tipicamente lattato, frequenza cardiaca ed età. L'importanza nella Random Forest e i coefficienti della regressione logistica tendono a concordare, ma non sono la stessa misura (non lineare vs lineare). === Esercizio 6 === Poiché i dati sono generati da un modello logistico, la regressione logistica è spesso competitiva o migliore della Random Forest. Se le differenze di AUC sono minori della deviazione standard tra i fold, i modelli sono statisticamente indistinguibili. === Esercizio 7 === I pesi aumentano la sensibilità e riducono la specificità. Nella sepsi un falso negativo (paziente malato non riconosciuto) è generalmente più grave di un falso positivo. === Esercizio 8 === Aggiungere variabili può ridurre l'RMSE sul training, ma con pochi dati (<code>mtcars</code> ha 32 righe) il test set è molto piccolo e il risultato è instabile: valutare con validazione incrociata. === Esercizio 9 === K-means non usa l'esito, quindi i cluster non coincidono necessariamente con la sepsi. La standardizzazione evita che variabili con scala maggiore (es. frequenza cardiaca) dominino la distanza. == Verifica della comprensione == * Qual è la differenza tra apprendimento supervisionato e non supervisionato? * Perché si usa un test set separato? * Cosa misura l'AUC? Quando può essere fuorviante? * Qual è la differenza tra sensibilità e valore predittivo positivo? * Perché il kNN richiede la standardizzazione? * Cos'è l'overfitting e come lo si individua? == Avvertenza == I dati di questa unità sono sintetici e a scopo didattico. I modelli non sono validati clinicamente e non devono essere usati per decisioni su pazienti reali. == Riepilogo dell'Unità 7 == Abbiamo praticato: * Divisione stratificata dei dati * Regressione logistica, albero decisionale, Random Forest, kNN * Matrice di confusione, ROC, AUC e scelta della soglia * Validazione incrociata e confronto tra modelli * Gestione dello sbilanciamento delle classi * Regressione con RMSE, MAE e R² * Clustering con k-means * Un mini-progetto completo == Letture Consigliate == * [https://topepo.github.io/caret/ Manuale del pacchetto caret] * [https://www.statlearning.com/ An Introduction to Statistical Learning (con applicazioni in R)] * [https://r4ds.hadley.nz/ R for Data Science] == Il progetto PenuX == Repository PenuX: https://github.com/netanelcyber/penux Sito PenuX: https://penux.uk == Quiz == [[PenuX in R: Quiz Unità 7|Fai il quiz dell'Unità 7]] [[Categoria:PenuX in R|Unità 7 - Esercitazioni di Machine Learning in R]] k96sgnl9vhgthh821ytsaaam8zfxf4a 502125 502110 2026-10-04T18:26:18Z Gian BOT 27470 bot: fix link 502125 wikitext text/x-wiki = PenuX in R: Unità 7 - Esercitazioni di Machine Learning in R = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Preparare i dati e dividerli in training e test set * Addestrare modelli di classificazione (regressione logistica, albero decisionale, Random Forest, kNN) * Valutare i modelli con matrice di confusione, ROC e AUC * Confrontare più modelli con la validazione incrociata * Costruire un modello di regressione e interpretarne l'errore (RMSE) * Applicare un metodo non supervisionato (k-means) * Completare un mini-progetto clinico di predizione della sepsi '''Prerequisiti''': Unità 1 (Fondamenti di R) e conoscenza di base delle Unità 2-5. == 7.0 Preparazione == <syntaxhighlight lang="r"> # Installare i pacchetti (una sola volta) install.packages(c("caret", "randomForest", "rpart", "pROC", "e1071")) # Caricare i pacchetti library(caret) library(randomForest) library(rpart) library(pROC) set.seed(42) # Riproducibilità </syntaxhighlight> === Dati clinici sintetici === In tutti gli esercizi useremo un dataset sintetico (non contiene dati di pazienti reali) per la predizione della sepsi. <syntaxhighlight lang="r"> n <- 500 clinical <- data.frame( age = round(rnorm(n, 55, 15)), heart_rate = round(rnorm(n, 85, 15)), temperature = round(rnorm(n, 37.2, 0.8), 1), wbc = round(rnorm(n, 9, 3), 1), lactate = round(rlnorm(n, log(1.5), 0.4), 2) ) # Rischio reale (logit) usato per generare l'esito risk <- -7.5 + 0.02 * clinical$age + 0.03 * clinical$heart_rate + 0.5 * (clinical$temperature - 37) + 0.1 * clinical$wbc + 0.9 * clinical$lactate clinical$sepsis <- factor( rbinom(n, 1, plogis(risk)), levels = c(0, 1), labels = c("No", "Si") ) table(clinical$sepsis) prop.table(table(clinical$sepsis)) str(clinical) </syntaxhighlight> == 7.1 Esercizio 1: Divisione dei dati == '''Obiettivo''': dividere il dataset in 70% training e 30% test mantenendo la proporzione delle classi. <syntaxhighlight lang="r"> # Completa il codice: train_idx <- createDataPartition(clinical$sepsis, p = 0.70, list = FALSE) train_data <- clinical[train_idx, ] test_data <- clinical[-train_idx, ] # Verifica: nrow(train_data) nrow(test_data) prop.table(table(train_data$sepsis)) prop.table(table(test_data$sepsis)) </syntaxhighlight> '''Domande''': * Perché è importante stratificare la divisione per la variabile esito? * Cosa succede se valutiamo il modello sugli stessi dati usati per l'addestramento? == 7.2 Esercizio 2: Regressione logistica == <syntaxhighlight lang="r"> # Addestrare il modello logit_model <- glm(sepsis ~ ., data = train_data, family = binomial) summary(logit_model) # Odds ratio con intervalli di confidenza exp(cbind(OR = coef(logit_model), confint.default(logit_model))) # Predizioni sul test set prob_logit <- predict(logit_model, newdata = test_data, type = "response") pred_logit <- factor(ifelse(prob_logit > 0.5, "Si", "No"), levels = c("No", "Si")) # Matrice di confusione confusionMatrix(pred_logit, test_data$sepsis, positive = "Si") </syntaxhighlight> '''Compito''': quale variabile ha l'odds ratio più alto? Come interpreti il valore per il lattato? == 7.3 Esercizio 3: Curva ROC e AUC == <syntaxhighlight lang="r"> roc_logit <- roc(response = test_data$sepsis, predictor = prob_logit, levels = c("No", "Si")) auc(roc_logit) plot(roc_logit, main = "Curva ROC - Regressione logistica", col = "steelblue", lwd = 2) # Soglia ottimale (indice di Youden) coords(roc_logit, "best", ret = c("threshold", "sensitivity", "specificity")) </syntaxhighlight> '''Compito''': ripeti la matrice di confusione usando la soglia ottimale al posto di 0.5. Come cambiano sensibilità e specificità? == 7.4 Esercizio 4: Albero decisionale == <syntaxhighlight lang="r"> tree_model <- rpart(sepsis ~ ., data = train_data, method = "class", control = rpart.control(cp = 0.01)) # Visualizzare l'albero plot(tree_model, margin = 0.1) text(tree_model, use.n = TRUE, cex = 0.8) # Predizioni pred_tree <- predict(tree_model, newdata = test_data, type = "class") confusionMatrix(pred_tree, test_data$sepsis, positive = "Si") </syntaxhighlight> '''Compito''': modifica il parametro <code>cp</code> (0.001, 0.05) e osserva come cambia la complessità dell'albero (overfitting vs underfitting). == 7.5 Esercizio 5: Random Forest == <syntaxhighlight lang="r"> rf_model <- randomForest(sepsis ~ ., data = train_data, ntree = 500, importance = TRUE) print(rf_model) # Importanza delle variabili importance(rf_model) varImpPlot(rf_model, main = "Importanza delle variabili") # Valutazione sul test set pred_rf <- predict(rf_model, newdata = test_data) prob_rf <- predict(rf_model, newdata = test_data, type = "prob")[, "Si"] confusionMatrix(pred_rf, test_data$sepsis, positive = "Si") auc(roc(test_data$sepsis, prob_rf, levels = c("No", "Si"))) </syntaxhighlight> '''Domande''': * Quali sono le tre variabili più importanti? * Corrispondono ai coefficienti più alti della regressione logistica? == 7.6 Esercizio 6: Validazione incrociata e confronto modelli == <syntaxhighlight lang="r"> ctrl <- trainControl( method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary, savePredictions = "final" ) set.seed(42) cv_logit <- train(sepsis ~ ., data = train_data, method = "glm", family = "binomial", metric = "ROC", trControl = ctrl) set.seed(42) cv_rf <- train(sepsis ~ ., data = train_data, method = "rf", metric = "ROC", trControl = ctrl, tuneLength = 3) set.seed(42) cv_knn <- train(sepsis ~ ., data = train_data, method = "knn", metric = "ROC", trControl = ctrl, preProcess = c("center", "scale"), tuneLength = 5) # Confronto risultati <- resamples(list(Logistica = cv_logit, RandomForest = cv_rf, kNN = cv_knn)) summary(risultati) bwplot(risultati, metric = "ROC") </syntaxhighlight> '''Compito''': quale modello ha l'AUC media più alta? La differenza è rilevante rispetto alla variabilità tra i fold? '''Nota''': per il kNN la standardizzazione (<code>center</code>, <code>scale</code>) è fondamentale perché l'algoritmo usa le distanze. == 7.7 Esercizio 7: Dati sbilanciati == <syntaxhighlight lang="r"> # Pesi per le classi pesi <- ifelse(train_data$sepsis == "Si", sum(train_data$sepsis == "No") / sum(train_data$sepsis == "Si"), 1) logit_pesata <- glm(sepsis ~ ., data = train_data, family = binomial, weights = pesi) prob_pesata <- predict(logit_pesata, newdata = test_data, type = "response") pred_pesata <- factor(ifelse(prob_pesata > 0.5, "Si", "No"), levels = c("No", "Si")) confusionMatrix(pred_pesata, test_data$sepsis, positive = "Si") </syntaxhighlight> '''Compito''': confronta la sensibilità con il modello non pesato dell'Esercizio 2. In un contesto clinico (sepsi), è peggio un falso negativo o un falso positivo? == 7.8 Esercizio 8: Regressione (variabile continua) == Predire il consumo di carburante (<code>mpg</code>) dal dataset integrato <code>mtcars</code>. <syntaxhighlight lang="r"> data(mtcars) set.seed(42) idx <- createDataPartition(mtcars$mpg, p = 0.75, list = FALSE) train <- mtcars[idx, ] test <- mtcars[-idx, ] lm_model <- lm(mpg ~ wt + hp + cyl, data = train) summary(lm_model) pred <- predict(lm_model, newdata = test) # Metriche di regressione rmse <- sqrt(mean((test$mpg - pred)^2)) mae <- mean(abs(test$mpg - pred)) r2 <- cor(test$mpg, pred)^2 cat("RMSE:", round(rmse, 2), "| MAE:", round(mae, 2), "| R2:", round(r2, 2), "\n") # Valori osservati vs predetti plot(test$mpg, pred, xlab = "Osservato", ylab = "Predetto", main = "Osservato vs Predetto", pch = 19) abline(0, 1, col = "red", lty = 2) </syntaxhighlight> '''Compito''': aggiungi altre variabili al modello (per esempio <code>disp</code>, <code>qsec</code>) e verifica se l'RMSE sul test set migliora. == 7.9 Esercizio 9: Apprendimento non supervisionato (k-means) == <syntaxhighlight lang="r"> # Usare solo le variabili cliniche (senza l'esito) X <- scale(clinical[, c("age", "heart_rate", "temperature", "wbc", "lactate")]) # Metodo del gomito wss <- sapply(1:8, function(k) kmeans(X, centers = k, nstart = 20)$tot.withinss) plot(1:8, wss, type = "b", xlab = "Numero di cluster", ylab = "Somma dei quadrati intra-cluster", main = "Metodo del gomito") # Clustering con k = 3 set.seed(42) km <- kmeans(X, centers = 3, nstart = 25) table(Cluster = km$cluster, Sepsi = clinical$sepsis) # Visualizzazione con PCA pca <- prcomp(X) plot(pca$x[, 1:2], col = km$cluster, pch = 19, main = "Cluster nello spazio delle prime due componenti principali") </syntaxhighlight> '''Domande''': * I cluster trovati corrispondono alla presenza di sepsi? * Perché è necessario standardizzare le variabili prima di k-means? == 7.10 Mini-progetto finale == Completa il flusso di lavoro, dall'inizio alla fine: # Genera un nuovo dataset con <code>set.seed(2026)</code> e <code>n = 800</code> # Dividi i dati in training (70%) e test (30%) # Addestra almeno tre modelli (per esempio logistica, Random Forest, SVM) # Confrontali con 5-fold CV usando l'AUC # Scegli il modello migliore e valutalo sul test set (matrice di confusione, ROC, soglia ottimale) # Salva il modello con <code>saveRDS()</code> e ricaricalo per fare una predizione su un nuovo paziente # Scrivi un breve paragrafo (5 righe) che spiega i limiti del modello <syntaxhighlight lang="r"> # Suggerimento per il punto 6: saveRDS(rf_model, "modello_sepsi.rds") modello <- readRDS("modello_sepsi.rds") nuovo_paziente <- data.frame(age = 72, heart_rate = 112, temperature = 38.6, wbc = 15.2, lactate = 3.4) predict(modello, nuovo_paziente, type = "prob") </syntaxhighlight> == 7.11 Soluzioni e Risposte == === Esercizio 1 === La stratificazione mantiene la stessa proporzione di casi positivi in training e test; senza di essa, con classi sbilanciate, il test set potrebbe contenere pochissimi casi positivi. Valutare sui dati di addestramento sovrastima le prestazioni (overfitting): il modello ha già "visto" quelle risposte. === Esercizio 2 === Il lattato ha di solito l'odds ratio più alto perché nel processo generatore ha il coefficiente maggiore (0.9, cioè OR ≈ 2.5 per ogni unità di aumento, a parità delle altre variabili). Con dati simulati i valori stimati varieranno leggermente. === Esercizio 3 === Abbassare la soglia sotto 0.5 aumenta di solito la sensibilità a scapito della specificità. In ambito clinico, per una condizione grave come la sepsi si preferisce spesso una sensibilità maggiore. === Esercizio 4 === Un <code>cp</code> basso produce un albero profondo (rischio di overfitting); un <code>cp</code> alto produce un albero troppo semplice (underfitting). === Esercizio 5 === Le variabili più importanti sono tipicamente lattato, frequenza cardiaca ed età. L'importanza nella Random Forest e i coefficienti della regressione logistica tendono a concordare, ma non sono la stessa misura (non lineare vs lineare). === Esercizio 6 === Poiché i dati sono generati da un modello logistico, la regressione logistica è spesso competitiva o migliore della Random Forest. Se le differenze di AUC sono minori della deviazione standard tra i fold, i modelli sono statisticamente indistinguibili. === Esercizio 7 === I pesi aumentano la sensibilità e riducono la specificità. Nella sepsi un falso negativo (paziente malato non riconosciuto) è generalmente più grave di un falso positivo. === Esercizio 8 === Aggiungere variabili può ridurre l'RMSE sul training, ma con pochi dati (<code>mtcars</code> ha 32 righe) il test set è molto piccolo e il risultato è instabile: valutare con validazione incrociata. === Esercizio 9 === K-means non usa l'esito, quindi i cluster non coincidono necessariamente con la sepsi. La standardizzazione evita che variabili con scala maggiore (es. frequenza cardiaca) dominino la distanza. == Verifica della comprensione == * Qual è la differenza tra apprendimento supervisionato e non supervisionato? * Perché si usa un test set separato? * Cosa misura l'AUC? Quando può essere fuorviante? * Qual è la differenza tra sensibilità e valore predittivo positivo? * Perché il kNN richiede la standardizzazione? * Cos'è l'overfitting e come lo si individua? == Avvertenza == I dati di questa unità sono sintetici e a scopo didattico. I modelli non sono validati clinicamente e non devono essere usati per decisioni su pazienti reali. == Riepilogo dell'Unità 7 == Abbiamo praticato: * Divisione stratificata dei dati * Regressione logistica, albero decisionale, Random Forest, kNN * Matrice di confusione, ROC, AUC e scelta della soglia * Validazione incrociata e confronto tra modelli * Gestione dello sbilanciamento delle classi * Regressione con RMSE, MAE e R² * Clustering con k-means * Un mini-progetto completo == Letture Consigliate == * [https://topepo.github.io/caret/ Manuale del pacchetto caret] * [https://www.statlearning.com/ An Introduction to Statistical Learning (con applicazioni in R)] * [https://r4ds.hadley.nz/ R for Data Science] == Il progetto PenuX == Repository PenuX: https://github.com/netanelcyber/penux Sito PenuX: https://penux.uk == Quiz == [[PenuX in R/Quiz Unità 7|Fai il quiz dell'Unità 7]] [[Categoria:PenuX in R|Unità 7 - Esercitazioni di Machine Learning in R]] hsu24jriwnkwd5cec4uaznjpqwlc5b1 502140 502125 2026-10-04T18:34:43Z Gian BOT 27470 Bot: aggiunge l'indice 502140 wikitext text/x-wiki {{PenuX in R}} = PenuX in R: Unità 7 - Esercitazioni di Machine Learning in R = == Obiettivi dell'unità == Al termine di questa unità sarai in grado di: * Preparare i dati e dividerli in training e test set * Addestrare modelli di classificazione (regressione logistica, albero decisionale, Random Forest, kNN) * Valutare i modelli con matrice di confusione, ROC e AUC * Confrontare più modelli con la validazione incrociata * Costruire un modello di regressione e interpretarne l'errore (RMSE) * Applicare un metodo non supervisionato (k-means) * Completare un mini-progetto clinico di predizione della sepsi '''Prerequisiti''': Unità 1 (Fondamenti di R) e conoscenza di base delle Unità 2-5. == 7.0 Preparazione == <syntaxhighlight lang="r"> # Installare i pacchetti (una sola volta) install.packages(c("caret", "randomForest", "rpart", "pROC", "e1071")) # Caricare i pacchetti library(caret) library(randomForest) library(rpart) library(pROC) set.seed(42) # Riproducibilità </syntaxhighlight> === Dati clinici sintetici === In tutti gli esercizi useremo un dataset sintetico (non contiene dati di pazienti reali) per la predizione della sepsi. <syntaxhighlight lang="r"> n <- 500 clinical <- data.frame( age = round(rnorm(n, 55, 15)), heart_rate = round(rnorm(n, 85, 15)), temperature = round(rnorm(n, 37.2, 0.8), 1), wbc = round(rnorm(n, 9, 3), 1), lactate = round(rlnorm(n, log(1.5), 0.4), 2) ) # Rischio reale (logit) usato per generare l'esito risk <- -7.5 + 0.02 * clinical$age + 0.03 * clinical$heart_rate + 0.5 * (clinical$temperature - 37) + 0.1 * clinical$wbc + 0.9 * clinical$lactate clinical$sepsis <- factor( rbinom(n, 1, plogis(risk)), levels = c(0, 1), labels = c("No", "Si") ) table(clinical$sepsis) prop.table(table(clinical$sepsis)) str(clinical) </syntaxhighlight> == 7.1 Esercizio 1: Divisione dei dati == '''Obiettivo''': dividere il dataset in 70% training e 30% test mantenendo la proporzione delle classi. <syntaxhighlight lang="r"> # Completa il codice: train_idx <- createDataPartition(clinical$sepsis, p = 0.70, list = FALSE) train_data <- clinical[train_idx, ] test_data <- clinical[-train_idx, ] # Verifica: nrow(train_data) nrow(test_data) prop.table(table(train_data$sepsis)) prop.table(table(test_data$sepsis)) </syntaxhighlight> '''Domande''': * Perché è importante stratificare la divisione per la variabile esito? * Cosa succede se valutiamo il modello sugli stessi dati usati per l'addestramento? == 7.2 Esercizio 2: Regressione logistica == <syntaxhighlight lang="r"> # Addestrare il modello logit_model <- glm(sepsis ~ ., data = train_data, family = binomial) summary(logit_model) # Odds ratio con intervalli di confidenza exp(cbind(OR = coef(logit_model), confint.default(logit_model))) # Predizioni sul test set prob_logit <- predict(logit_model, newdata = test_data, type = "response") pred_logit <- factor(ifelse(prob_logit > 0.5, "Si", "No"), levels = c("No", "Si")) # Matrice di confusione confusionMatrix(pred_logit, test_data$sepsis, positive = "Si") </syntaxhighlight> '''Compito''': quale variabile ha l'odds ratio più alto? Come interpreti il valore per il lattato? == 7.3 Esercizio 3: Curva ROC e AUC == <syntaxhighlight lang="r"> roc_logit <- roc(response = test_data$sepsis, predictor = prob_logit, levels = c("No", "Si")) auc(roc_logit) plot(roc_logit, main = "Curva ROC - Regressione logistica", col = "steelblue", lwd = 2) # Soglia ottimale (indice di Youden) coords(roc_logit, "best", ret = c("threshold", "sensitivity", "specificity")) </syntaxhighlight> '''Compito''': ripeti la matrice di confusione usando la soglia ottimale al posto di 0.5. Come cambiano sensibilità e specificità? == 7.4 Esercizio 4: Albero decisionale == <syntaxhighlight lang="r"> tree_model <- rpart(sepsis ~ ., data = train_data, method = "class", control = rpart.control(cp = 0.01)) # Visualizzare l'albero plot(tree_model, margin = 0.1) text(tree_model, use.n = TRUE, cex = 0.8) # Predizioni pred_tree <- predict(tree_model, newdata = test_data, type = "class") confusionMatrix(pred_tree, test_data$sepsis, positive = "Si") </syntaxhighlight> '''Compito''': modifica il parametro <code>cp</code> (0.001, 0.05) e osserva come cambia la complessità dell'albero (overfitting vs underfitting). == 7.5 Esercizio 5: Random Forest == <syntaxhighlight lang="r"> rf_model <- randomForest(sepsis ~ ., data = train_data, ntree = 500, importance = TRUE) print(rf_model) # Importanza delle variabili importance(rf_model) varImpPlot(rf_model, main = "Importanza delle variabili") # Valutazione sul test set pred_rf <- predict(rf_model, newdata = test_data) prob_rf <- predict(rf_model, newdata = test_data, type = "prob")[, "Si"] confusionMatrix(pred_rf, test_data$sepsis, positive = "Si") auc(roc(test_data$sepsis, prob_rf, levels = c("No", "Si"))) </syntaxhighlight> '''Domande''': * Quali sono le tre variabili più importanti? * Corrispondono ai coefficienti più alti della regressione logistica? == 7.6 Esercizio 6: Validazione incrociata e confronto modelli == <syntaxhighlight lang="r"> ctrl <- trainControl( method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary, savePredictions = "final" ) set.seed(42) cv_logit <- train(sepsis ~ ., data = train_data, method = "glm", family = "binomial", metric = "ROC", trControl = ctrl) set.seed(42) cv_rf <- train(sepsis ~ ., data = train_data, method = "rf", metric = "ROC", trControl = ctrl, tuneLength = 3) set.seed(42) cv_knn <- train(sepsis ~ ., data = train_data, method = "knn", metric = "ROC", trControl = ctrl, preProcess = c("center", "scale"), tuneLength = 5) # Confronto risultati <- resamples(list(Logistica = cv_logit, RandomForest = cv_rf, kNN = cv_knn)) summary(risultati) bwplot(risultati, metric = "ROC") </syntaxhighlight> '''Compito''': quale modello ha l'AUC media più alta? La differenza è rilevante rispetto alla variabilità tra i fold? '''Nota''': per il kNN la standardizzazione (<code>center</code>, <code>scale</code>) è fondamentale perché l'algoritmo usa le distanze. == 7.7 Esercizio 7: Dati sbilanciati == <syntaxhighlight lang="r"> # Pesi per le classi pesi <- ifelse(train_data$sepsis == "Si", sum(train_data$sepsis == "No") / sum(train_data$sepsis == "Si"), 1) logit_pesata <- glm(sepsis ~ ., data = train_data, family = binomial, weights = pesi) prob_pesata <- predict(logit_pesata, newdata = test_data, type = "response") pred_pesata <- factor(ifelse(prob_pesata > 0.5, "Si", "No"), levels = c("No", "Si")) confusionMatrix(pred_pesata, test_data$sepsis, positive = "Si") </syntaxhighlight> '''Compito''': confronta la sensibilità con il modello non pesato dell'Esercizio 2. In un contesto clinico (sepsi), è peggio un falso negativo o un falso positivo? == 7.8 Esercizio 8: Regressione (variabile continua) == Predire il consumo di carburante (<code>mpg</code>) dal dataset integrato <code>mtcars</code>. <syntaxhighlight lang="r"> data(mtcars) set.seed(42) idx <- createDataPartition(mtcars$mpg, p = 0.75, list = FALSE) train <- mtcars[idx, ] test <- mtcars[-idx, ] lm_model <- lm(mpg ~ wt + hp + cyl, data = train) summary(lm_model) pred <- predict(lm_model, newdata = test) # Metriche di regressione rmse <- sqrt(mean((test$mpg - pred)^2)) mae <- mean(abs(test$mpg - pred)) r2 <- cor(test$mpg, pred)^2 cat("RMSE:", round(rmse, 2), "| MAE:", round(mae, 2), "| R2:", round(r2, 2), "\n") # Valori osservati vs predetti plot(test$mpg, pred, xlab = "Osservato", ylab = "Predetto", main = "Osservato vs Predetto", pch = 19) abline(0, 1, col = "red", lty = 2) </syntaxhighlight> '''Compito''': aggiungi altre variabili al modello (per esempio <code>disp</code>, <code>qsec</code>) e verifica se l'RMSE sul test set migliora. == 7.9 Esercizio 9: Apprendimento non supervisionato (k-means) == <syntaxhighlight lang="r"> # Usare solo le variabili cliniche (senza l'esito) X <- scale(clinical[, c("age", "heart_rate", "temperature", "wbc", "lactate")]) # Metodo del gomito wss <- sapply(1:8, function(k) kmeans(X, centers = k, nstart = 20)$tot.withinss) plot(1:8, wss, type = "b", xlab = "Numero di cluster", ylab = "Somma dei quadrati intra-cluster", main = "Metodo del gomito") # Clustering con k = 3 set.seed(42) km <- kmeans(X, centers = 3, nstart = 25) table(Cluster = km$cluster, Sepsi = clinical$sepsis) # Visualizzazione con PCA pca <- prcomp(X) plot(pca$x[, 1:2], col = km$cluster, pch = 19, main = "Cluster nello spazio delle prime due componenti principali") </syntaxhighlight> '''Domande''': * I cluster trovati corrispondono alla presenza di sepsi? * Perché è necessario standardizzare le variabili prima di k-means? == 7.10 Mini-progetto finale == Completa il flusso di lavoro, dall'inizio alla fine: # Genera un nuovo dataset con <code>set.seed(2026)</code> e <code>n = 800</code> # Dividi i dati in training (70%) e test (30%) # Addestra almeno tre modelli (per esempio logistica, Random Forest, SVM) # Confrontali con 5-fold CV usando l'AUC # Scegli il modello migliore e valutalo sul test set (matrice di confusione, ROC, soglia ottimale) # Salva il modello con <code>saveRDS()</code> e ricaricalo per fare una predizione su un nuovo paziente # Scrivi un breve paragrafo (5 righe) che spiega i limiti del modello <syntaxhighlight lang="r"> # Suggerimento per il punto 6: saveRDS(rf_model, "modello_sepsi.rds") modello <- readRDS("modello_sepsi.rds") nuovo_paziente <- data.frame(age = 72, heart_rate = 112, temperature = 38.6, wbc = 15.2, lactate = 3.4) predict(modello, nuovo_paziente, type = "prob") </syntaxhighlight> == 7.11 Soluzioni e Risposte == === Esercizio 1 === La stratificazione mantiene la stessa proporzione di casi positivi in training e test; senza di essa, con classi sbilanciate, il test set potrebbe contenere pochissimi casi positivi. Valutare sui dati di addestramento sovrastima le prestazioni (overfitting): il modello ha già "visto" quelle risposte. === Esercizio 2 === Il lattato ha di solito l'odds ratio più alto perché nel processo generatore ha il coefficiente maggiore (0.9, cioè OR ≈ 2.5 per ogni unità di aumento, a parità delle altre variabili). Con dati simulati i valori stimati varieranno leggermente. === Esercizio 3 === Abbassare la soglia sotto 0.5 aumenta di solito la sensibilità a scapito della specificità. In ambito clinico, per una condizione grave come la sepsi si preferisce spesso una sensibilità maggiore. === Esercizio 4 === Un <code>cp</code> basso produce un albero profondo (rischio di overfitting); un <code>cp</code> alto produce un albero troppo semplice (underfitting). === Esercizio 5 === Le variabili più importanti sono tipicamente lattato, frequenza cardiaca ed età. L'importanza nella Random Forest e i coefficienti della regressione logistica tendono a concordare, ma non sono la stessa misura (non lineare vs lineare). === Esercizio 6 === Poiché i dati sono generati da un modello logistico, la regressione logistica è spesso competitiva o migliore della Random Forest. Se le differenze di AUC sono minori della deviazione standard tra i fold, i modelli sono statisticamente indistinguibili. === Esercizio 7 === I pesi aumentano la sensibilità e riducono la specificità. Nella sepsi un falso negativo (paziente malato non riconosciuto) è generalmente più grave di un falso positivo. === Esercizio 8 === Aggiungere variabili può ridurre l'RMSE sul training, ma con pochi dati (<code>mtcars</code> ha 32 righe) il test set è molto piccolo e il risultato è instabile: valutare con validazione incrociata. === Esercizio 9 === K-means non usa l'esito, quindi i cluster non coincidono necessariamente con la sepsi. La standardizzazione evita che variabili con scala maggiore (es. frequenza cardiaca) dominino la distanza. == Verifica della comprensione == * Qual è la differenza tra apprendimento supervisionato e non supervisionato? * Perché si usa un test set separato? * Cosa misura l'AUC? Quando può essere fuorviante? * Qual è la differenza tra sensibilità e valore predittivo positivo? * Perché il kNN richiede la standardizzazione? * Cos'è l'overfitting e come lo si individua? == Avvertenza == I dati di questa unità sono sintetici e a scopo didattico. I modelli non sono validati clinicamente e non devono essere usati per decisioni su pazienti reali. == Riepilogo dell'Unità 7 == Abbiamo praticato: * Divisione stratificata dei dati * Regressione logistica, albero decisionale, Random Forest, kNN * Matrice di confusione, ROC, AUC e scelta della soglia * Validazione incrociata e confronto tra modelli * Gestione dello sbilanciamento delle classi * Regressione con RMSE, MAE e R² * Clustering con k-means * Un mini-progetto completo == Letture Consigliate == * [https://topepo.github.io/caret/ Manuale del pacchetto caret] * [https://www.statlearning.com/ An Introduction to Statistical Learning (con applicazioni in R)] * [https://r4ds.hadley.nz/ R for Data Science] == Il progetto PenuX == Repository PenuX: https://github.com/netanelcyber/penux Sito PenuX: https://penux.uk == Quiz == [[PenuX in R/Quiz Unità 7|Fai il quiz dell'Unità 7]] [[Categoria:PenuX in R|Unità 7 - Esercitazioni di Machine Learning in R]] beh7uk9zpnndm02l53ijkxsxdr4x5ea PenuX in R/Quiz Unità 7 0 61190 502070 502022 2026-10-04T14:55:20Z Hippias 18281 Hippias ha spostato la pagina [[PenuX in R: Quiz Unità 7]] a [[PenuX in R/Quiz Unità 7]] senza lasciare redirect: [[Aiuto:Convenzioni di nomenclatura|Convenzioni di nomenclatura]]: sottopagino correttamente 502022 wikitext text/x-wiki = PenuX in R: Quiz Unità 7 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Quale funzione di caret esegue una divisione stratificata? * A) createDataPartition() * B) dummyVars() * C) varImp() * D) scale() <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Mantiene la stessa proporzione di classi in training e test. </div> == Domanda 2 == Perché nel kNN si usa <code>preProcess = c("center", "scale")</code>? * A) Per velocizzare il training * B) Perché l'algoritmo si basa sulle distanze * C) Per creare variabili dummy * D) Per imputare i mancanti <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Senza standardizzazione le variabili con scala maggiore dominano. </div> == Domanda 3 == Nella predizione della sepsi, quale errore è di solito più grave? * A) Il falso positivo * B) Sono sempre equivalenti * C) Il falso negativo (paziente malato non riconosciuto) * D) Nessuno dei due <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. Per questo spesso si privilegia una sensibilità alta. </div> == Domanda 4 == K-means è un esempio di: * A) Apprendimento supervisionato * B) Regressione logistica * C) Validazione esterna * D) Apprendimento non supervisionato <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Non usa la variabile esito per formare i cluster. </div> == Torna all'unità == [[PenuX in R: Unità 7 - Esercitazioni di Machine Learning in R|Torna all'Unità 7]] k7wa5yhjfumf61jf51gt46cfydqtyra 502102 502070 2026-10-04T18:21:09Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502102 wikitext text/x-wiki = PenuX in R: Quiz Unità 7 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Quale funzione di caret esegue una divisione stratificata? * A) createDataPartition() * B) dummyVars() * C) varImp() * D) scale() <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Mantiene la stessa proporzione di classi in training e test. </div> == Domanda 2 == Perché nel kNN si usa <code>preProcess = c("center", "scale")</code>? * A) Per velocizzare il training * B) Perché l'algoritmo si basa sulle distanze * C) Per creare variabili dummy * D) Per imputare i mancanti <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Senza standardizzazione le variabili con scala maggiore dominano. </div> == Domanda 3 == Nella predizione della sepsi, quale errore è di solito più grave? * A) Il falso positivo * B) Sono sempre equivalenti * C) Il falso negativo (paziente malato non riconosciuto) * D) Nessuno dei due <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. Per questo spesso si privilegia una sensibilità alta. </div> == Domanda 4 == K-means è un esempio di: * A) Apprendimento supervisionato * B) Regressione logistica * C) Validazione esterna * D) Apprendimento non supervisionato <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Non usa la variabile esito per formare i cluster. </div> == Torna all'unità == [[PenuX in R: Unità 7 - Esercitazioni di Machine Learning in R|Torna all'Unità 7]] [[Categoria:PenuX in R|Quiz Unità 7]] ooi2xvilqfb3bca7t447fca1nvpfoyu 502118 502102 2026-10-04T18:25:08Z Gian BOT 27470 bot: fix link 502118 wikitext text/x-wiki = PenuX in R: Quiz Unità 7 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Quale funzione di caret esegue una divisione stratificata? * A) createDataPartition() * B) dummyVars() * C) varImp() * D) scale() <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Mantiene la stessa proporzione di classi in training e test. </div> == Domanda 2 == Perché nel kNN si usa <code>preProcess = c("center", "scale")</code>? * A) Per velocizzare il training * B) Perché l'algoritmo si basa sulle distanze * C) Per creare variabili dummy * D) Per imputare i mancanti <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Senza standardizzazione le variabili con scala maggiore dominano. </div> == Domanda 3 == Nella predizione della sepsi, quale errore è di solito più grave? * A) Il falso positivo * B) Sono sempre equivalenti * C) Il falso negativo (paziente malato non riconosciuto) * D) Nessuno dei due <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. Per questo spesso si privilegia una sensibilità alta. </div> == Domanda 4 == K-means è un esempio di: * A) Apprendimento supervisionato * B) Regressione logistica * C) Validazione esterna * D) Apprendimento non supervisionato <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Non usa la variabile esito per formare i cluster. </div> == Torna all'unità == [[PenuX in R/Unità 7 - Esercitazioni di Machine Learning in R|Torna all'Unità 7]] [[Categoria:PenuX in R|Quiz Unità 7]] qk0hd4ccbdvuz470v36zbl51peashxv 502133 502118 2026-10-04T18:33:30Z Gian BOT 27470 Bot: aggiunge l'indice 502133 wikitext text/x-wiki {{PenuX in R}} = PenuX in R: Quiz Unità 7 = Rispondi alle domande, poi clicca su "Mostra risposta" per controllare. == Domanda 1 == Quale funzione di caret esegue una divisione stratificata? * A) createDataPartition() * B) dummyVars() * C) varImp() * D) scale() <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: A'''. Mantiene la stessa proporzione di classi in training e test. </div> == Domanda 2 == Perché nel kNN si usa <code>preProcess = c("center", "scale")</code>? * A) Per velocizzare il training * B) Perché l'algoritmo si basa sulle distanze * C) Per creare variabili dummy * D) Per imputare i mancanti <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: B'''. Senza standardizzazione le variabili con scala maggiore dominano. </div> == Domanda 3 == Nella predizione della sepsi, quale errore è di solito più grave? * A) Il falso positivo * B) Sono sempre equivalenti * C) Il falso negativo (paziente malato non riconosciuto) * D) Nessuno dei due <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: C'''. Per questo spesso si privilegia una sensibilità alta. </div> == Domanda 4 == K-means è un esempio di: * A) Apprendimento supervisionato * B) Regressione logistica * C) Validazione esterna * D) Apprendimento non supervisionato <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposta" data-collapsetext="Nascondi risposta"> '''Risposta: D'''. Non usa la variabile esito per formare i cluster. </div> == Torna all'unità == [[PenuX in R/Unità 7 - Esercitazioni di Machine Learning in R|Torna all'Unità 7]] [[Categoria:PenuX in R|Quiz Unità 7]] 853kk9tfqvtw9r4gv2bpzf8h47idu9k PenuX in R/Guida di base al Machine Learning in R 0 61191 502053 502026 2026-10-04T14:38:29Z Hippias 18281 Hippias ha spostato la pagina [[PenuX in R: Guida di base al Machine Learning in R]] a [[PenuX in R/Guida di base al Machine Learning in R]] senza lasciare redirect: [[Aiuto:Convenzioni di nomenclatura|Convenzioni di nomenclatura]]: sottopagino correttamente 502026 wikitext text/x-wiki = PenuX in R: Guida di base al Machine Learning in R = Questa guida introduce i concetti essenziali del machine learning (apprendimento automatico) e mostra, passo dopo passo, come applicarli in R con piccoli esempi che usano dataset già inclusi in R (<code>iris</code> e <code>mtcars</code>). Non servono dati clinici né conoscenze avanzate: è sufficiente aver letto l'[[PenuX in R: Unità 1 - Fondamenti del Linguaggio R|Unità 1]]. == Che cos'è il machine learning == Il machine learning è l'insieme dei metodi con cui un programma impara dai dati a fare previsioni o a trovare strutture, senza che le regole vengano scritte a mano. === Due famiglie principali === * '''Apprendimento supervisionato''': i dati contengono la risposta corretta (l'etichetta, o variabile target) e il modello impara a prevederla. ** ''Classificazione'': la risposta è una categoria (per esempio malato / sano, oppure la specie di un fiore). ** ''Regressione'': la risposta è un numero (per esempio il consumo di carburante). * '''Apprendimento non supervisionato''': non c'è una risposta nota; il modello cerca gruppi o pattern (per esempio il ''clustering'' con k-means). === Vocabolario di base === * '''Feature (variabile predittiva)''': una colonna usata per fare la previsione (età, pressione, lunghezza del petalo). * '''Target (esito)''': la colonna che vogliamo prevedere. * '''Training set''': i dati su cui il modello impara. * '''Test set''': dati tenuti da parte, mai visti dal modello, usati per valutarlo. * '''Overfitting''': il modello memorizza il rumore del training set e funziona male su dati nuovi. == Il flusso di lavoro in sei passi == # Definire il problema e la variabile target # Preparare e controllare i dati (valori mancanti, tipi, outlier) # Dividere i dati in training e test # Addestrare uno o più modelli # Valutare i modelli sul test set # Interpretare, confrontare e (se serve) migliorare == Preparazione == <syntaxhighlight lang="r"> install.packages(c("caret", "randomForest", "rpart", "e1071")) library(caret) set.seed(42) # rende i risultati riproducibili data(iris) str(iris) summary(iris) table(iris$Species) </syntaxhighlight> Il dataset <code>iris</code> contiene 150 fiori di tre specie, descritti da quattro misure (lunghezza e larghezza di sepalo e petalo). La variabile target è <code>Species</code>. == Passo 1: dividere i dati == <syntaxhighlight lang="r"> idx <- createDataPartition(iris$Species, p = 0.70, list = FALSE) train <- iris[idx, ] test <- iris[-idx, ] nrow(train) # circa 105 nrow(test) # circa 45 table(train$Species) </syntaxhighlight> <code>createDataPartition()</code> mantiene la stessa proporzione di classi nei due insiemi (divisione ''stratificata''). == Passo 2: addestrare un primo modello == <syntaxhighlight lang="r"> ctrl <- trainControl(method = "cv", number = 5) # validazione incrociata a 5 fold modello_albero <- train(Species ~ ., data = train, method = "rpart", trControl = ctrl) modello_albero </syntaxhighlight> La funzione <code>train()</code> di caret offre la stessa interfaccia per centinaia di algoritmi: basta cambiare l'argomento <code>method</code>. == Passo 3: valutare sul test set == <syntaxhighlight lang="r"> previsioni <- predict(modello_albero, newdata = test) confusionMatrix(previsioni, test$Species) </syntaxhighlight> La ''matrice di confusione'' confronta classi previste e classi reali. Da essa si ricavano: * '''Accuratezza''': quota di previsioni corrette * '''Sensibilità''': tra i casi positivi, quanti vengono riconosciuti * '''Specificità''': tra i casi negativi, quanti vengono riconosciuti Con classi molto sbilanciate (per esempio una malattia rara) l'accuratezza da sola può ingannare: valuta sempre anche sensibilità e specificità. == Passo 4: provare altri modelli e confrontarli == <syntaxhighlight lang="r"> set.seed(42) modello_rf <- train(Species ~ ., data = train, method = "rf", trControl = ctrl) set.seed(42) modello_knn <- train(Species ~ ., data = train, method = "knn", trControl = ctrl, preProcess = c("center", "scale")) confronto <- resamples(list(Albero = modello_albero, RandomForest = modello_rf, kNN = modello_knn)) summary(confronto) bwplot(confronto) </syntaxhighlight> Note utili: * Il '''kNN''' usa le distanze, quindi richiede la standardizzazione (<code>center</code> e <code>scale</code>). * Gli '''alberi''' e la '''Random Forest''' non richiedono standardizzazione. * Scegli il modello con le prestazioni migliori in validazione incrociata, poi verificalo '''una sola volta''' sul test set. == Passo 5: quali variabili contano? == <syntaxhighlight lang="r"> varImp(modello_rf) plot(varImp(modello_rf)) </syntaxhighlight> == Un esempio di regressione == Prevediamo il consumo (<code>mpg</code>) delle auto del dataset <code>mtcars</code>. <syntaxhighlight lang="r"> data(mtcars) set.seed(42) idx <- createDataPartition(mtcars$mpg, p = 0.75, list = FALSE) train <- mtcars[idx, ] test <- mtcars[-idx, ] modello_lm <- lm(mpg ~ wt + hp, data = train) summary(modello_lm) pred <- predict(modello_lm, newdata = test) # Errore medio di previsione rmse <- sqrt(mean((test$mpg - pred)^2)) mae <- mean(abs(test$mpg - pred)) c(RMSE = rmse, MAE = mae) </syntaxhighlight> In regressione si usano metriche di errore: '''RMSE''' (radice dell'errore quadratico medio, penalizza gli errori grandi) e '''MAE''' (errore assoluto medio). == Un esempio non supervisionato: k-means == <syntaxhighlight lang="r"> X <- scale(iris[, 1:4]) # usiamo solo le misure, senza la specie set.seed(42) km <- kmeans(X, centers = 3, nstart = 25) table(Cluster = km$cluster, Specie = iris$Species) </syntaxhighlight> Il modello non ha visto le specie, ma i cluster ne ricalcano in gran parte la divisione. Questo non succede sempre: i cluster non coincidono necessariamente con categorie reali. == Errori comuni da evitare == * '''Valutare sui dati di addestramento''': porta a sovrastimare le prestazioni. * '''Fuga di informazioni (data leakage)''': calcolare medie, scalature o imputazioni sull'intero dataset prima della divisione. Calcolale solo sul training e applicale al test. * '''Dimenticare il seme''' (<code>set.seed()</code>): senza, i risultati cambiano a ogni esecuzione. * '''Usare solo l'accuratezza''' con classi sbilanciate. * '''Confondere correlazione e causalità''': un buon modello predittivo non spiega il perché. * '''Usare il test set più volte''' per scegliere il modello: diventa di fatto un secondo training set. == Mini-quiz di autovalutazione == * Qual è la differenza tra classificazione e regressione? * Perché si tiene da parte un test set? * Che cosa indica una grande differenza tra accuratezza sul training e sul test? * Perché il kNN richiede la standardizzazione e la Random Forest no? * Perché k-means è un metodo non supervisionato? <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposte" data-collapsetext="Nascondi risposte"> # La classificazione prevede una categoria, la regressione un numero. # Per stimare le prestazioni su dati mai visti dal modello. # Overfitting: il modello ha memorizzato il training set. # Il kNN si basa sulle distanze, che dipendono dalla scala delle variabili; gli alberi dividono per soglie e non risentono della scala. # Perché non usa la variabile target per formare i gruppi. </div> == Esercizi == # Ripeti il flusso con il dataset <code>iris</code> usando <code>p = 0.8</code>. Cambiano i risultati? # Aggiungi un modello SVM (<code>method = "svmRadial"</code>) al confronto. # Sul dataset <code>mtcars</code> aggiungi la variabile <code>cyl</code> al modello lineare e confronta l'RMSE. # Prova k-means con <code>centers = 2</code> e <code>centers = 4</code>: come cambia la tabella rispetto alle specie? # Ripeti l'Esercizio 1 con <code>set.seed(1)</code> e <code>set.seed(2)</code> e confronta la variabilità delle prestazioni. == Avvertenza == I dataset usati qui sono didattici. Un modello predittivo in ambito sanitario richiede validazione clinica, controllo della qualità dei dati e conformità normativa prima di qualunque uso reale: vedi le Unità 5 e 6. == Prosegui da qui == * [[PenuX in R: Unità 2 - Preparazione e Caricamento dei Dati|Unità 2: preparazione dei dati]] * [[PenuX in R: Unità 7 - Esercitazioni di Machine Learning in R|Unità 7: esercitazioni di machine learning]] * [[PenuX in R]] == Il progetto PenuX == Repository PenuX: https://github.com/netanelcyber/penux Sito PenuX: https://penux.uk [[uk:PenuX в R: Базовий посібник з машинного навчання в R]] g3u8kf3wx0r3a8gyg127lvctny6i7hs 502095 502053 2026-10-04T18:19:53Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502095 wikitext text/x-wiki = PenuX in R: Guida di base al Machine Learning in R = Questa guida introduce i concetti essenziali del machine learning (apprendimento automatico) e mostra, passo dopo passo, come applicarli in R con piccoli esempi che usano dataset già inclusi in R (<code>iris</code> e <code>mtcars</code>). Non servono dati clinici né conoscenze avanzate: è sufficiente aver letto l'[[PenuX in R: Unità 1 - Fondamenti del Linguaggio R|Unità 1]]. == Che cos'è il machine learning == Il machine learning è l'insieme dei metodi con cui un programma impara dai dati a fare previsioni o a trovare strutture, senza che le regole vengano scritte a mano. === Due famiglie principali === * '''Apprendimento supervisionato''': i dati contengono la risposta corretta (l'etichetta, o variabile target) e il modello impara a prevederla. ** ''Classificazione'': la risposta è una categoria (per esempio malato / sano, oppure la specie di un fiore). ** ''Regressione'': la risposta è un numero (per esempio il consumo di carburante). * '''Apprendimento non supervisionato''': non c'è una risposta nota; il modello cerca gruppi o pattern (per esempio il ''clustering'' con k-means). === Vocabolario di base === * '''Feature (variabile predittiva)''': una colonna usata per fare la previsione (età, pressione, lunghezza del petalo). * '''Target (esito)''': la colonna che vogliamo prevedere. * '''Training set''': i dati su cui il modello impara. * '''Test set''': dati tenuti da parte, mai visti dal modello, usati per valutarlo. * '''Overfitting''': il modello memorizza il rumore del training set e funziona male su dati nuovi. == Il flusso di lavoro in sei passi == # Definire il problema e la variabile target # Preparare e controllare i dati (valori mancanti, tipi, outlier) # Dividere i dati in training e test # Addestrare uno o più modelli # Valutare i modelli sul test set # Interpretare, confrontare e (se serve) migliorare == Preparazione == <syntaxhighlight lang="r"> install.packages(c("caret", "randomForest", "rpart", "e1071")) library(caret) set.seed(42) # rende i risultati riproducibili data(iris) str(iris) summary(iris) table(iris$Species) </syntaxhighlight> Il dataset <code>iris</code> contiene 150 fiori di tre specie, descritti da quattro misure (lunghezza e larghezza di sepalo e petalo). La variabile target è <code>Species</code>. == Passo 1: dividere i dati == <syntaxhighlight lang="r"> idx <- createDataPartition(iris$Species, p = 0.70, list = FALSE) train <- iris[idx, ] test <- iris[-idx, ] nrow(train) # circa 105 nrow(test) # circa 45 table(train$Species) </syntaxhighlight> <code>createDataPartition()</code> mantiene la stessa proporzione di classi nei due insiemi (divisione ''stratificata''). == Passo 2: addestrare un primo modello == <syntaxhighlight lang="r"> ctrl <- trainControl(method = "cv", number = 5) # validazione incrociata a 5 fold modello_albero <- train(Species ~ ., data = train, method = "rpart", trControl = ctrl) modello_albero </syntaxhighlight> La funzione <code>train()</code> di caret offre la stessa interfaccia per centinaia di algoritmi: basta cambiare l'argomento <code>method</code>. == Passo 3: valutare sul test set == <syntaxhighlight lang="r"> previsioni <- predict(modello_albero, newdata = test) confusionMatrix(previsioni, test$Species) </syntaxhighlight> La ''matrice di confusione'' confronta classi previste e classi reali. Da essa si ricavano: * '''Accuratezza''': quota di previsioni corrette * '''Sensibilità''': tra i casi positivi, quanti vengono riconosciuti * '''Specificità''': tra i casi negativi, quanti vengono riconosciuti Con classi molto sbilanciate (per esempio una malattia rara) l'accuratezza da sola può ingannare: valuta sempre anche sensibilità e specificità. == Passo 4: provare altri modelli e confrontarli == <syntaxhighlight lang="r"> set.seed(42) modello_rf <- train(Species ~ ., data = train, method = "rf", trControl = ctrl) set.seed(42) modello_knn <- train(Species ~ ., data = train, method = "knn", trControl = ctrl, preProcess = c("center", "scale")) confronto <- resamples(list(Albero = modello_albero, RandomForest = modello_rf, kNN = modello_knn)) summary(confronto) bwplot(confronto) </syntaxhighlight> Note utili: * Il '''kNN''' usa le distanze, quindi richiede la standardizzazione (<code>center</code> e <code>scale</code>). * Gli '''alberi''' e la '''Random Forest''' non richiedono standardizzazione. * Scegli il modello con le prestazioni migliori in validazione incrociata, poi verificalo '''una sola volta''' sul test set. == Passo 5: quali variabili contano? == <syntaxhighlight lang="r"> varImp(modello_rf) plot(varImp(modello_rf)) </syntaxhighlight> == Un esempio di regressione == Prevediamo il consumo (<code>mpg</code>) delle auto del dataset <code>mtcars</code>. <syntaxhighlight lang="r"> data(mtcars) set.seed(42) idx <- createDataPartition(mtcars$mpg, p = 0.75, list = FALSE) train <- mtcars[idx, ] test <- mtcars[-idx, ] modello_lm <- lm(mpg ~ wt + hp, data = train) summary(modello_lm) pred <- predict(modello_lm, newdata = test) # Errore medio di previsione rmse <- sqrt(mean((test$mpg - pred)^2)) mae <- mean(abs(test$mpg - pred)) c(RMSE = rmse, MAE = mae) </syntaxhighlight> In regressione si usano metriche di errore: '''RMSE''' (radice dell'errore quadratico medio, penalizza gli errori grandi) e '''MAE''' (errore assoluto medio). == Un esempio non supervisionato: k-means == <syntaxhighlight lang="r"> X <- scale(iris[, 1:4]) # usiamo solo le misure, senza la specie set.seed(42) km <- kmeans(X, centers = 3, nstart = 25) table(Cluster = km$cluster, Specie = iris$Species) </syntaxhighlight> Il modello non ha visto le specie, ma i cluster ne ricalcano in gran parte la divisione. Questo non succede sempre: i cluster non coincidono necessariamente con categorie reali. == Errori comuni da evitare == * '''Valutare sui dati di addestramento''': porta a sovrastimare le prestazioni. * '''Fuga di informazioni (data leakage)''': calcolare medie, scalature o imputazioni sull'intero dataset prima della divisione. Calcolale solo sul training e applicale al test. * '''Dimenticare il seme''' (<code>set.seed()</code>): senza, i risultati cambiano a ogni esecuzione. * '''Usare solo l'accuratezza''' con classi sbilanciate. * '''Confondere correlazione e causalità''': un buon modello predittivo non spiega il perché. * '''Usare il test set più volte''' per scegliere il modello: diventa di fatto un secondo training set. == Mini-quiz di autovalutazione == * Qual è la differenza tra classificazione e regressione? * Perché si tiene da parte un test set? * Che cosa indica una grande differenza tra accuratezza sul training e sul test? * Perché il kNN richiede la standardizzazione e la Random Forest no? * Perché k-means è un metodo non supervisionato? <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposte" data-collapsetext="Nascondi risposte"> # La classificazione prevede una categoria, la regressione un numero. # Per stimare le prestazioni su dati mai visti dal modello. # Overfitting: il modello ha memorizzato il training set. # Il kNN si basa sulle distanze, che dipendono dalla scala delle variabili; gli alberi dividono per soglie e non risentono della scala. # Perché non usa la variabile target per formare i gruppi. </div> == Esercizi == # Ripeti il flusso con il dataset <code>iris</code> usando <code>p = 0.8</code>. Cambiano i risultati? # Aggiungi un modello SVM (<code>method = "svmRadial"</code>) al confronto. # Sul dataset <code>mtcars</code> aggiungi la variabile <code>cyl</code> al modello lineare e confronta l'RMSE. # Prova k-means con <code>centers = 2</code> e <code>centers = 4</code>: come cambia la tabella rispetto alle specie? # Ripeti l'Esercizio 1 con <code>set.seed(1)</code> e <code>set.seed(2)</code> e confronta la variabilità delle prestazioni. == Avvertenza == I dataset usati qui sono didattici. Un modello predittivo in ambito sanitario richiede validazione clinica, controllo della qualità dei dati e conformità normativa prima di qualunque uso reale: vedi le Unità 5 e 6. == Prosegui da qui == * [[PenuX in R: Unità 2 - Preparazione e Caricamento dei Dati|Unità 2: preparazione dei dati]] * [[PenuX in R: Unità 7 - Esercitazioni di Machine Learning in R|Unità 7: esercitazioni di machine learning]] * [[PenuX in R]] == Il progetto PenuX == Repository PenuX: https://github.com/netanelcyber/penux Sito PenuX: https://penux.uk [[Categoria:PenuX in R|Guida di base al Machine Learning in R]] [[uk:PenuX в R: Базовий посібник з машинного навчання в R]] 76skjm4qrog1jhc5myyrc0if5n0a05p 502111 502095 2026-10-04T18:23:57Z Gian BOT 27470 bot: fix link 502111 wikitext text/x-wiki = PenuX in R: Guida di base al Machine Learning in R = Questa guida introduce i concetti essenziali del machine learning (apprendimento automatico) e mostra, passo dopo passo, come applicarli in R con piccoli esempi che usano dataset già inclusi in R (<code>iris</code> e <code>mtcars</code>). Non servono dati clinici né conoscenze avanzate: è sufficiente aver letto l'[[PenuX in R/Unità 1 - Fondamenti del Linguaggio R|Unità 1]]. == Che cos'è il machine learning == Il machine learning è l'insieme dei metodi con cui un programma impara dai dati a fare previsioni o a trovare strutture, senza che le regole vengano scritte a mano. === Due famiglie principali === * '''Apprendimento supervisionato''': i dati contengono la risposta corretta (l'etichetta, o variabile target) e il modello impara a prevederla. ** ''Classificazione'': la risposta è una categoria (per esempio malato / sano, oppure la specie di un fiore). ** ''Regressione'': la risposta è un numero (per esempio il consumo di carburante). * '''Apprendimento non supervisionato''': non c'è una risposta nota; il modello cerca gruppi o pattern (per esempio il ''clustering'' con k-means). === Vocabolario di base === * '''Feature (variabile predittiva)''': una colonna usata per fare la previsione (età, pressione, lunghezza del petalo). * '''Target (esito)''': la colonna che vogliamo prevedere. * '''Training set''': i dati su cui il modello impara. * '''Test set''': dati tenuti da parte, mai visti dal modello, usati per valutarlo. * '''Overfitting''': il modello memorizza il rumore del training set e funziona male su dati nuovi. == Il flusso di lavoro in sei passi == # Definire il problema e la variabile target # Preparare e controllare i dati (valori mancanti, tipi, outlier) # Dividere i dati in training e test # Addestrare uno o più modelli # Valutare i modelli sul test set # Interpretare, confrontare e (se serve) migliorare == Preparazione == <syntaxhighlight lang="r"> install.packages(c("caret", "randomForest", "rpart", "e1071")) library(caret) set.seed(42) # rende i risultati riproducibili data(iris) str(iris) summary(iris) table(iris$Species) </syntaxhighlight> Il dataset <code>iris</code> contiene 150 fiori di tre specie, descritti da quattro misure (lunghezza e larghezza di sepalo e petalo). La variabile target è <code>Species</code>. == Passo 1: dividere i dati == <syntaxhighlight lang="r"> idx <- createDataPartition(iris$Species, p = 0.70, list = FALSE) train <- iris[idx, ] test <- iris[-idx, ] nrow(train) # circa 105 nrow(test) # circa 45 table(train$Species) </syntaxhighlight> <code>createDataPartition()</code> mantiene la stessa proporzione di classi nei due insiemi (divisione ''stratificata''). == Passo 2: addestrare un primo modello == <syntaxhighlight lang="r"> ctrl <- trainControl(method = "cv", number = 5) # validazione incrociata a 5 fold modello_albero <- train(Species ~ ., data = train, method = "rpart", trControl = ctrl) modello_albero </syntaxhighlight> La funzione <code>train()</code> di caret offre la stessa interfaccia per centinaia di algoritmi: basta cambiare l'argomento <code>method</code>. == Passo 3: valutare sul test set == <syntaxhighlight lang="r"> previsioni <- predict(modello_albero, newdata = test) confusionMatrix(previsioni, test$Species) </syntaxhighlight> La ''matrice di confusione'' confronta classi previste e classi reali. Da essa si ricavano: * '''Accuratezza''': quota di previsioni corrette * '''Sensibilità''': tra i casi positivi, quanti vengono riconosciuti * '''Specificità''': tra i casi negativi, quanti vengono riconosciuti Con classi molto sbilanciate (per esempio una malattia rara) l'accuratezza da sola può ingannare: valuta sempre anche sensibilità e specificità. == Passo 4: provare altri modelli e confrontarli == <syntaxhighlight lang="r"> set.seed(42) modello_rf <- train(Species ~ ., data = train, method = "rf", trControl = ctrl) set.seed(42) modello_knn <- train(Species ~ ., data = train, method = "knn", trControl = ctrl, preProcess = c("center", "scale")) confronto <- resamples(list(Albero = modello_albero, RandomForest = modello_rf, kNN = modello_knn)) summary(confronto) bwplot(confronto) </syntaxhighlight> Note utili: * Il '''kNN''' usa le distanze, quindi richiede la standardizzazione (<code>center</code> e <code>scale</code>). * Gli '''alberi''' e la '''Random Forest''' non richiedono standardizzazione. * Scegli il modello con le prestazioni migliori in validazione incrociata, poi verificalo '''una sola volta''' sul test set. == Passo 5: quali variabili contano? == <syntaxhighlight lang="r"> varImp(modello_rf) plot(varImp(modello_rf)) </syntaxhighlight> == Un esempio di regressione == Prevediamo il consumo (<code>mpg</code>) delle auto del dataset <code>mtcars</code>. <syntaxhighlight lang="r"> data(mtcars) set.seed(42) idx <- createDataPartition(mtcars$mpg, p = 0.75, list = FALSE) train <- mtcars[idx, ] test <- mtcars[-idx, ] modello_lm <- lm(mpg ~ wt + hp, data = train) summary(modello_lm) pred <- predict(modello_lm, newdata = test) # Errore medio di previsione rmse <- sqrt(mean((test$mpg - pred)^2)) mae <- mean(abs(test$mpg - pred)) c(RMSE = rmse, MAE = mae) </syntaxhighlight> In regressione si usano metriche di errore: '''RMSE''' (radice dell'errore quadratico medio, penalizza gli errori grandi) e '''MAE''' (errore assoluto medio). == Un esempio non supervisionato: k-means == <syntaxhighlight lang="r"> X <- scale(iris[, 1:4]) # usiamo solo le misure, senza la specie set.seed(42) km <- kmeans(X, centers = 3, nstart = 25) table(Cluster = km$cluster, Specie = iris$Species) </syntaxhighlight> Il modello non ha visto le specie, ma i cluster ne ricalcano in gran parte la divisione. Questo non succede sempre: i cluster non coincidono necessariamente con categorie reali. == Errori comuni da evitare == * '''Valutare sui dati di addestramento''': porta a sovrastimare le prestazioni. * '''Fuga di informazioni (data leakage)''': calcolare medie, scalature o imputazioni sull'intero dataset prima della divisione. Calcolale solo sul training e applicale al test. * '''Dimenticare il seme''' (<code>set.seed()</code>): senza, i risultati cambiano a ogni esecuzione. * '''Usare solo l'accuratezza''' con classi sbilanciate. * '''Confondere correlazione e causalità''': un buon modello predittivo non spiega il perché. * '''Usare il test set più volte''' per scegliere il modello: diventa di fatto un secondo training set. == Mini-quiz di autovalutazione == * Qual è la differenza tra classificazione e regressione? * Perché si tiene da parte un test set? * Che cosa indica una grande differenza tra accuratezza sul training e sul test? * Perché il kNN richiede la standardizzazione e la Random Forest no? * Perché k-means è un metodo non supervisionato? <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposte" data-collapsetext="Nascondi risposte"> # La classificazione prevede una categoria, la regressione un numero. # Per stimare le prestazioni su dati mai visti dal modello. # Overfitting: il modello ha memorizzato il training set. # Il kNN si basa sulle distanze, che dipendono dalla scala delle variabili; gli alberi dividono per soglie e non risentono della scala. # Perché non usa la variabile target per formare i gruppi. </div> == Esercizi == # Ripeti il flusso con il dataset <code>iris</code> usando <code>p = 0.8</code>. Cambiano i risultati? # Aggiungi un modello SVM (<code>method = "svmRadial"</code>) al confronto. # Sul dataset <code>mtcars</code> aggiungi la variabile <code>cyl</code> al modello lineare e confronta l'RMSE. # Prova k-means con <code>centers = 2</code> e <code>centers = 4</code>: come cambia la tabella rispetto alle specie? # Ripeti l'Esercizio 1 con <code>set.seed(1)</code> e <code>set.seed(2)</code> e confronta la variabilità delle prestazioni. == Avvertenza == I dataset usati qui sono didattici. Un modello predittivo in ambito sanitario richiede validazione clinica, controllo della qualità dei dati e conformità normativa prima di qualunque uso reale: vedi le Unità 5 e 6. == Prosegui da qui == * [[PenuX in R/Unità 2 - Preparazione e Caricamento dei Dati|Unità 2: preparazione dei dati]] * [[PenuX in R/Unità 7 - Esercitazioni di Machine Learning in R|Unità 7: esercitazioni di machine learning]] * [[PenuX in R]] == Il progetto PenuX == Repository PenuX: https://github.com/netanelcyber/penux Sito PenuX: https://penux.uk [[Categoria:PenuX in R|Guida di base al Machine Learning in R]] [[uk:PenuX в R: Базовий посібник з машинного навчання в R]] 224nduymulrtwdz6g60hvy1ddli5pu5 502126 502111 2026-10-04T18:31:50Z Gian BOT 27470 Bot: aggiunge l'indice 502126 wikitext text/x-wiki {{PenuX in R}} = PenuX in R: Guida di base al Machine Learning in R = Questa guida introduce i concetti essenziali del machine learning (apprendimento automatico) e mostra, passo dopo passo, come applicarli in R con piccoli esempi che usano dataset già inclusi in R (<code>iris</code> e <code>mtcars</code>). Non servono dati clinici né conoscenze avanzate: è sufficiente aver letto l'[[PenuX in R/Unità 1 - Fondamenti del Linguaggio R|Unità 1]]. == Che cos'è il machine learning == Il machine learning è l'insieme dei metodi con cui un programma impara dai dati a fare previsioni o a trovare strutture, senza che le regole vengano scritte a mano. === Due famiglie principali === * '''Apprendimento supervisionato''': i dati contengono la risposta corretta (l'etichetta, o variabile target) e il modello impara a prevederla. ** ''Classificazione'': la risposta è una categoria (per esempio malato / sano, oppure la specie di un fiore). ** ''Regressione'': la risposta è un numero (per esempio il consumo di carburante). * '''Apprendimento non supervisionato''': non c'è una risposta nota; il modello cerca gruppi o pattern (per esempio il ''clustering'' con k-means). === Vocabolario di base === * '''Feature (variabile predittiva)''': una colonna usata per fare la previsione (età, pressione, lunghezza del petalo). * '''Target (esito)''': la colonna che vogliamo prevedere. * '''Training set''': i dati su cui il modello impara. * '''Test set''': dati tenuti da parte, mai visti dal modello, usati per valutarlo. * '''Overfitting''': il modello memorizza il rumore del training set e funziona male su dati nuovi. == Il flusso di lavoro in sei passi == # Definire il problema e la variabile target # Preparare e controllare i dati (valori mancanti, tipi, outlier) # Dividere i dati in training e test # Addestrare uno o più modelli # Valutare i modelli sul test set # Interpretare, confrontare e (se serve) migliorare == Preparazione == <syntaxhighlight lang="r"> install.packages(c("caret", "randomForest", "rpart", "e1071")) library(caret) set.seed(42) # rende i risultati riproducibili data(iris) str(iris) summary(iris) table(iris$Species) </syntaxhighlight> Il dataset <code>iris</code> contiene 150 fiori di tre specie, descritti da quattro misure (lunghezza e larghezza di sepalo e petalo). La variabile target è <code>Species</code>. == Passo 1: dividere i dati == <syntaxhighlight lang="r"> idx <- createDataPartition(iris$Species, p = 0.70, list = FALSE) train <- iris[idx, ] test <- iris[-idx, ] nrow(train) # circa 105 nrow(test) # circa 45 table(train$Species) </syntaxhighlight> <code>createDataPartition()</code> mantiene la stessa proporzione di classi nei due insiemi (divisione ''stratificata''). == Passo 2: addestrare un primo modello == <syntaxhighlight lang="r"> ctrl <- trainControl(method = "cv", number = 5) # validazione incrociata a 5 fold modello_albero <- train(Species ~ ., data = train, method = "rpart", trControl = ctrl) modello_albero </syntaxhighlight> La funzione <code>train()</code> di caret offre la stessa interfaccia per centinaia di algoritmi: basta cambiare l'argomento <code>method</code>. == Passo 3: valutare sul test set == <syntaxhighlight lang="r"> previsioni <- predict(modello_albero, newdata = test) confusionMatrix(previsioni, test$Species) </syntaxhighlight> La ''matrice di confusione'' confronta classi previste e classi reali. Da essa si ricavano: * '''Accuratezza''': quota di previsioni corrette * '''Sensibilità''': tra i casi positivi, quanti vengono riconosciuti * '''Specificità''': tra i casi negativi, quanti vengono riconosciuti Con classi molto sbilanciate (per esempio una malattia rara) l'accuratezza da sola può ingannare: valuta sempre anche sensibilità e specificità. == Passo 4: provare altri modelli e confrontarli == <syntaxhighlight lang="r"> set.seed(42) modello_rf <- train(Species ~ ., data = train, method = "rf", trControl = ctrl) set.seed(42) modello_knn <- train(Species ~ ., data = train, method = "knn", trControl = ctrl, preProcess = c("center", "scale")) confronto <- resamples(list(Albero = modello_albero, RandomForest = modello_rf, kNN = modello_knn)) summary(confronto) bwplot(confronto) </syntaxhighlight> Note utili: * Il '''kNN''' usa le distanze, quindi richiede la standardizzazione (<code>center</code> e <code>scale</code>). * Gli '''alberi''' e la '''Random Forest''' non richiedono standardizzazione. * Scegli il modello con le prestazioni migliori in validazione incrociata, poi verificalo '''una sola volta''' sul test set. == Passo 5: quali variabili contano? == <syntaxhighlight lang="r"> varImp(modello_rf) plot(varImp(modello_rf)) </syntaxhighlight> == Un esempio di regressione == Prevediamo il consumo (<code>mpg</code>) delle auto del dataset <code>mtcars</code>. <syntaxhighlight lang="r"> data(mtcars) set.seed(42) idx <- createDataPartition(mtcars$mpg, p = 0.75, list = FALSE) train <- mtcars[idx, ] test <- mtcars[-idx, ] modello_lm <- lm(mpg ~ wt + hp, data = train) summary(modello_lm) pred <- predict(modello_lm, newdata = test) # Errore medio di previsione rmse <- sqrt(mean((test$mpg - pred)^2)) mae <- mean(abs(test$mpg - pred)) c(RMSE = rmse, MAE = mae) </syntaxhighlight> In regressione si usano metriche di errore: '''RMSE''' (radice dell'errore quadratico medio, penalizza gli errori grandi) e '''MAE''' (errore assoluto medio). == Un esempio non supervisionato: k-means == <syntaxhighlight lang="r"> X <- scale(iris[, 1:4]) # usiamo solo le misure, senza la specie set.seed(42) km <- kmeans(X, centers = 3, nstart = 25) table(Cluster = km$cluster, Specie = iris$Species) </syntaxhighlight> Il modello non ha visto le specie, ma i cluster ne ricalcano in gran parte la divisione. Questo non succede sempre: i cluster non coincidono necessariamente con categorie reali. == Errori comuni da evitare == * '''Valutare sui dati di addestramento''': porta a sovrastimare le prestazioni. * '''Fuga di informazioni (data leakage)''': calcolare medie, scalature o imputazioni sull'intero dataset prima della divisione. Calcolale solo sul training e applicale al test. * '''Dimenticare il seme''' (<code>set.seed()</code>): senza, i risultati cambiano a ogni esecuzione. * '''Usare solo l'accuratezza''' con classi sbilanciate. * '''Confondere correlazione e causalità''': un buon modello predittivo non spiega il perché. * '''Usare il test set più volte''' per scegliere il modello: diventa di fatto un secondo training set. == Mini-quiz di autovalutazione == * Qual è la differenza tra classificazione e regressione? * Perché si tiene da parte un test set? * Che cosa indica una grande differenza tra accuratezza sul training e sul test? * Perché il kNN richiede la standardizzazione e la Random Forest no? * Perché k-means è un metodo non supervisionato? <div class="mw-collapsible mw-collapsed" data-expandtext="Mostra risposte" data-collapsetext="Nascondi risposte"> # La classificazione prevede una categoria, la regressione un numero. # Per stimare le prestazioni su dati mai visti dal modello. # Overfitting: il modello ha memorizzato il training set. # Il kNN si basa sulle distanze, che dipendono dalla scala delle variabili; gli alberi dividono per soglie e non risentono della scala. # Perché non usa la variabile target per formare i gruppi. </div> == Esercizi == # Ripeti il flusso con il dataset <code>iris</code> usando <code>p = 0.8</code>. Cambiano i risultati? # Aggiungi un modello SVM (<code>method = "svmRadial"</code>) al confronto. # Sul dataset <code>mtcars</code> aggiungi la variabile <code>cyl</code> al modello lineare e confronta l'RMSE. # Prova k-means con <code>centers = 2</code> e <code>centers = 4</code>: come cambia la tabella rispetto alle specie? # Ripeti l'Esercizio 1 con <code>set.seed(1)</code> e <code>set.seed(2)</code> e confronta la variabilità delle prestazioni. == Avvertenza == I dataset usati qui sono didattici. Un modello predittivo in ambito sanitario richiede validazione clinica, controllo della qualità dei dati e conformità normativa prima di qualunque uso reale: vedi le Unità 5 e 6. == Prosegui da qui == * [[PenuX in R/Unità 2 - Preparazione e Caricamento dei Dati|Unità 2: preparazione dei dati]] * [[PenuX in R/Unità 7 - Esercitazioni di Machine Learning in R|Unità 7: esercitazioni di machine learning]] * [[PenuX in R]] == Il progetto PenuX == Repository PenuX: https://github.com/netanelcyber/penux Sito PenuX: https://penux.uk [[Categoria:PenuX in R|Guida di base al Machine Learning in R]] [[uk:PenuX в R: Базовий посібник з машинного навчання в R]] m1cs51iurdpmmma2ihls5p8lmnh41rn Disposizioni foniche di organi a canne/Italia/Umbria/Provincia di Perugia/Perugia/Colombella - Chiesa di Santa Maria Annunziata 0 61192 502086 502045 2026-10-04T18:01:12Z Gian BOT 27470 Bot: aggiunge la categoria del libro 502086 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} {{Doppia immagine|center|Organo Colombella.jpg|303|Consolle Colombella.jpg|300}} * '''Costruttore:''' Tamburini * '''Anno:''' 1925 * '''Restauri/modifiche:''' ? * '''Registri:''' 6 * '''Canne:''' ? * '''Trasmissione:''' pneumatica * '''Consolle:''' addossata al centro del corpo fonico * '''Tastiere:''' 1 di 58 note (''Do<sup>1</sup>''-''La<sup>5</sup>'') * '''Pedaliera:''' parallela piana di 30 note (''Do<sup>1</sup>''-''Fa<sup>3</sup>'') * '''Collocazione:''' in corpo unico, a terra, nel transetto destro {| border="0" cellspacing="24" cellpadding="18" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" |colspan="4"| '''''Manuale''''' ---- |- |Principale || 8' |- |Salicionale || 8' |- |Voce celeste || 8' |- |Ottava || 4' |- |Ripieno ||5 file |- |} | style="vertical-align:top" | {| border="0" | colspan=2 | '''Pedale''' ---- |- |Bordone || 16' |- |} |} {{Avanzamento|100%|3 ottobre 2026}} [[Categoria:Disposizioni foniche di organi a canne|Colombella - Chiesa di Santa Maria Annunziata]] lfz6u2vj0g6tfkmm2wz83rqkmcswhud Discussioni utente:נתנאל שטרן 3 61195 502050 2026-10-04T14:20:54Z Hippias 18281 Benvenuto/a su Wikibooks! 502050 wikitext text/x-wiki <div style="font-size:90%; text-align:right;">For other languages, consider using [[Wikibooks:Babel]] &middot; [[Wikibooks:Ambasciata|Embassy]]</div> {| width="100%" cellspacing="0" cellpadding="6" style="font-size:95%; line-height: 15px; background-color: var(--background-color-warning-subtle, #fef6e7); color: inherit; border: 1px solid #faecc8;" |- | colspan="4" style="background: #faecc8; color: #000;" |<span style="font-size:larger">'''[[Aiuto:Benvenuto|Benvenut{{GENDER:{{BASEPAGENAME}}|o|a|a/o}}]] {{PAGENAME}}''' in it.Wikibooks </span>, la biblioteca libera. |- | colspan="4" | Ciao, {{PAGENAME}}. Grazie per voler partecipare al progetto. Spero che la tua collaborazione ti risulti gradevole e che continuerai a contribuire. |- | colspan="4" | [[Aiuto:It.wb|Wikibooks]] è una raccolta di '''manuali e libri di testo''' '''[[Wikibooks:Copyright|gratuiti ed a contenuto aperto]]'''; questa comunità si è data delle regole per favore usa un po' del tuo tempo per leggere cosa [[Aiuto:Cosa mettere su Wikibooks|puoi]] o [[Wikibooks:Cosa Wikibooks non è|non puoi]] mettere su Wikibooks. |- | align="right" | [[Image:BluePillar.svg<!--Crystal Clear app lassist.png-->|30px]] | [[Wikibooks:cinque pilastri|'''I cinque pilastri di Wikibooks'''<br>linee guida generali per capire su cosa si fonda il progetto]] | align="right" |[[File:Cicero.PNG|30px]] | [[Aiuto:NPOV| '''Punto di vista neutrale'''.<br>Apprendi i fondamentali del punto di vista neutrale]] |- | align="right" | [[File:Kpdf bookish.svg|30px]] | [[Wikibooks:Tutti_i_libri|'''I ripiani'''<br>Fai un giro tra i ripiani per trovare l'argomento a cui ti interessa contribuire]] | align="right" |[[File:Nuvola_apps_khelpcenter.png‎‎|30px]] | [[Aiuto:Manuale|'''Manuale'''<br>Tutte le pagine di aiuto e le linee guida di Wikibooks]] |- | align="right" | [[File:Nuvola apps important yellow.svg|30px]] | [[Aiuto:Errori comuni nell'uso di Wikibooks|'''Cosa bisognerebbe evitare'''<br>Impara a non commettere gli errori più comuni]] | align="right" | [[File:Nuvola apps ksirc.png|30px]] | [[Aiuto:FAQ|'''Domande frequenti'''<br>Cerca qui le risposte a tutte le domande più frequenti]] |- | width="8%" align="right" | [[File:Crystal_Clear_app_korganizer.png<!--Crystal Clear action apply.png-->|30px]] | [[Aiuto:Modifica|'''Impara a modificare una pagina'''<br>Come scrivere in una pagina wiki]] | align="right" | [[File:Nuvola apps bookcase.svg|30px]] | [[Aiuto:Libro|'''Come scrivere un libro'''<br>Tutte le convenzioni di formattazione e organizzazione dei contenuti]] |- | align="right" | [[File:Crystal_128_three.png|30px]] | [[Wikibooks:Portale Comunità|'''Portale Comunità'''<br>Conosci meglio il progetto con le indicazioni del portale comunità]] | align="right" | [[File:Nuvola apps kteatime.png|30px]] | [[Wikibooks:bar|'''Bar'''<br>Incontra e discuti con altri Wikibookiani]] |- | align="right" | [[File:Wikipedia-logo.svg|30px]] | [[Aiuto:Wikibooks per Wikipediani|'''Wikibooks per Wikipediani'''<br/>Per capire le differenze tra Wikibooks e Wikipedia]] | align="right" | [[Image:Exquisite-kcontrol.png|30px]] | [[Utente:{{PAGENAME}}/Sandbox|'''Sandbox'''<br>Ricordati anche che hai una pagina personale per fare tutte le prove che vuoi e salvare le tue bozze]] |- | colspan="4" style="border-top:2px solid #faecc8;" | <br /> [[File:Signature_button.png|right|Per firmare i tuoi post usa il tasto indicato]] Questa è la tua [[Aiuto:Pagina di discussione|'''pagina delle discussioni''']], dove saranno raccolti tutti i messaggi degli altri [[Wikibooks:Wikibookiani|wikibookiani]]. Per lasciare un messaggio ad altri utenti devi scrivergli '''nella loro pagina di discussione''', altrimenti non verrà notificato loro la presenza di un nuovo messaggio. Ogni intervento nelle pagine di discussione deve essere [[Aiuto:Firma|firmato con quattro tilde (<span style="font-size:larger"><nowiki>~~~~</nowiki></span>)]] o premendo il pulsante in figura. {{Suggerimento casuale}} |} {{#if:--[[Utente:Hippias|<span style="font-family:Georgia, serif">Hippias</span>]] <sup>([[Discussioni utente:Hippias|msg]])</sup> 16:20, 4 ott 2026 (CEST)|Naturalmente, un benvenuto anche da parte mia.|Un saluto da parte di tutti i [[Wikibooks:Wikibookiani|Wikibookiani]]!}} Se hai bisogno di qualunque cosa, puoi lasciare un messaggio al bar ([https://it.wikibooks.org/w/index.php?title=Wikibooks:Bar&action=edit&section=new clicca qui]). Grazie per aver deciso di contribuire e buon lavoro! --[[Utente:Hippias|<span style="font-family:Georgia, serif">Hippias</span>]] <sup>([[Discussioni utente:Hippias|msg]])</sup> 16:20, 4 ott 2026 (CEST) 80khrx1yy16en1xdjvwh6fh7funl9ln 502055 502050 2026-10-04T14:44:41Z Hippias 18281 /* Consigli */ nuova sezione 502055 wikitext text/x-wiki <div style="font-size:90%; text-align:right;">For other languages, consider using [[Wikibooks:Babel]] &middot; [[Wikibooks:Ambasciata|Embassy]]</div> {| width="100%" cellspacing="0" cellpadding="6" style="font-size:95%; line-height: 15px; background-color: var(--background-color-warning-subtle, #fef6e7); color: inherit; border: 1px solid #faecc8;" |- | colspan="4" style="background: #faecc8; color: #000;" |<span style="font-size:larger">'''[[Aiuto:Benvenuto|Benvenut{{GENDER:{{BASEPAGENAME}}|o|a|a/o}}]] {{PAGENAME}}''' in it.Wikibooks </span>, la biblioteca libera. |- | colspan="4" | Ciao, {{PAGENAME}}. Grazie per voler partecipare al progetto. Spero che la tua collaborazione ti risulti gradevole e che continuerai a contribuire. |- | colspan="4" | [[Aiuto:It.wb|Wikibooks]] è una raccolta di '''manuali e libri di testo''' '''[[Wikibooks:Copyright|gratuiti ed a contenuto aperto]]'''; questa comunità si è data delle regole per favore usa un po' del tuo tempo per leggere cosa [[Aiuto:Cosa mettere su Wikibooks|puoi]] o [[Wikibooks:Cosa Wikibooks non è|non puoi]] mettere su Wikibooks. |- | align="right" | [[Image:BluePillar.svg<!--Crystal Clear app lassist.png-->|30px]] | [[Wikibooks:cinque pilastri|'''I cinque pilastri di Wikibooks'''<br>linee guida generali per capire su cosa si fonda il progetto]] | align="right" |[[File:Cicero.PNG|30px]] | [[Aiuto:NPOV| '''Punto di vista neutrale'''.<br>Apprendi i fondamentali del punto di vista neutrale]] |- | align="right" | [[File:Kpdf bookish.svg|30px]] | [[Wikibooks:Tutti_i_libri|'''I ripiani'''<br>Fai un giro tra i ripiani per trovare l'argomento a cui ti interessa contribuire]] | align="right" |[[File:Nuvola_apps_khelpcenter.png‎‎|30px]] | [[Aiuto:Manuale|'''Manuale'''<br>Tutte le pagine di aiuto e le linee guida di Wikibooks]] |- | align="right" | [[File:Nuvola apps important yellow.svg|30px]] | [[Aiuto:Errori comuni nell'uso di Wikibooks|'''Cosa bisognerebbe evitare'''<br>Impara a non commettere gli errori più comuni]] | align="right" | [[File:Nuvola apps ksirc.png|30px]] | [[Aiuto:FAQ|'''Domande frequenti'''<br>Cerca qui le risposte a tutte le domande più frequenti]] |- | width="8%" align="right" | [[File:Crystal_Clear_app_korganizer.png<!--Crystal Clear action apply.png-->|30px]] | [[Aiuto:Modifica|'''Impara a modificare una pagina'''<br>Come scrivere in una pagina wiki]] | align="right" | [[File:Nuvola apps bookcase.svg|30px]] | [[Aiuto:Libro|'''Come scrivere un libro'''<br>Tutte le convenzioni di formattazione e organizzazione dei contenuti]] |- | align="right" | [[File:Crystal_128_three.png|30px]] | [[Wikibooks:Portale Comunità|'''Portale Comunità'''<br>Conosci meglio il progetto con le indicazioni del portale comunità]] | align="right" | [[File:Nuvola apps kteatime.png|30px]] | [[Wikibooks:bar|'''Bar'''<br>Incontra e discuti con altri Wikibookiani]] |- | align="right" | [[File:Wikipedia-logo.svg|30px]] | [[Aiuto:Wikibooks per Wikipediani|'''Wikibooks per Wikipediani'''<br/>Per capire le differenze tra Wikibooks e Wikipedia]] | align="right" | [[Image:Exquisite-kcontrol.png|30px]] | [[Utente:{{PAGENAME}}/Sandbox|'''Sandbox'''<br>Ricordati anche che hai una pagina personale per fare tutte le prove che vuoi e salvare le tue bozze]] |- | colspan="4" style="border-top:2px solid #faecc8;" | <br /> [[File:Signature_button.png|right|Per firmare i tuoi post usa il tasto indicato]] Questa è la tua [[Aiuto:Pagina di discussione|'''pagina delle discussioni''']], dove saranno raccolti tutti i messaggi degli altri [[Wikibooks:Wikibookiani|wikibookiani]]. Per lasciare un messaggio ad altri utenti devi scrivergli '''nella loro pagina di discussione''', altrimenti non verrà notificato loro la presenza di un nuovo messaggio. Ogni intervento nelle pagine di discussione deve essere [[Aiuto:Firma|firmato con quattro tilde (<span style="font-size:larger"><nowiki>~~~~</nowiki></span>)]] o premendo il pulsante in figura. {{Suggerimento casuale}} |} {{#if:--[[Utente:Hippias|<span style="font-family:Georgia, serif">Hippias</span>]] <sup>([[Discussioni utente:Hippias|msg]])</sup> 16:20, 4 ott 2026 (CEST)|Naturalmente, un benvenuto anche da parte mia.|Un saluto da parte di tutti i [[Wikibooks:Wikibookiani|Wikibookiani]]!}} Se hai bisogno di qualunque cosa, puoi lasciare un messaggio al bar ([https://it.wikibooks.org/w/index.php?title=Wikibooks:Bar&action=edit&section=new clicca qui]). Grazie per aver deciso di contribuire e buon lavoro! --[[Utente:Hippias|<span style="font-family:Georgia, serif">Hippias</span>]] <sup>([[Discussioni utente:Hippias|msg]])</sup> 16:20, 4 ott 2026 (CEST) == Consigli == {{Aiuto nuovo libro}} -- [[Utente:Hippias|<span style="font-family:Georgia, serif">Hippias</span>]] <sup>([[Discussioni utente:Hippias|msg]])</sup> 16:44, 4 ott 2026 (CEST) g9aml75krn1me4ydc68zuta1d6bmeh6 Template:PenuX in R 10 61196 502051 2026-10-04T14:35:38Z Hippias 18281 nuovo indice 502051 wikitext text/x-wiki {{Sommario V | titolo = PenuX in R | contenuto = * {{modulo|PenuX in R/Guida di base al Machine Learning in R}} * {{modulo|PenuX in R/Unità 1 - Fondamenti del Linguaggio R|Unità 1: Fondamenti di R}} * {{modulo|PenuX in R/Unità 2 - Preparazione e Caricamento dei Dati|Unità 2: Preparazione Dati}} * {{modulo|PenuX in R/Unità 3 - Analisi Esplorativa dei Dati|Unità 3: Analisi Esplorativa}} * {{modulo|PenuX in R/Unità 4 - Costruzione dei Modelli Predittivi|Unità 4: Modelli Predittivi}} * {{modulo|PenuX in R/Unità 5 - Valutazione e Validazione dei Modelli|Unità 5: Valutazione}} * {{modulo|PenuX in R/Unità 6 - Deployment e Implementazione Clinica|Unità 6: Deployment}} * {{modulo|PenuX in R/Unità 7 - Esercitazioni di Machine Learning in R|Unità 7: Esercitazioni di Machine Learning}} }}<noinclude>[[Categoria:PenuX in R| ]] [[Categoria:Template sommario]]</noinclude> ia7eqhyl5npp7s0yskkjp3n0qee8ojw 502071 502051 2026-10-04T14:55:44Z Hippias 18281 502071 wikitext text/x-wiki {{Sommario V | titolo = PenuX in R | contenuto = * {{modulo|PenuX in R/Guida di base al Machine Learning in R}} * {{modulo|PenuX in R/Unità 1 - Fondamenti del Linguaggio R|Unità 1: Fondamenti di R}} ({{modulo|PenuX in R/Quiz Unità 1|quiz}}) * {{modulo|PenuX in R/Unità 2 - Preparazione e Caricamento dei Dati|Unità 2: Preparazione Dati}} ({{modulo|PenuX in R/Quiz Unità 2|quiz}}) * {{modulo|PenuX in R/Unità 3 - Analisi Esplorativa dei Dati|Unità 3: Analisi Esplorativa}} ({{modulo|PenuX in R/Quiz Unità 3|quiz}}) * {{modulo|PenuX in R/Unità 4 - Costruzione dei Modelli Predittivi|Unità 4: Modelli Predittivi}} ({{modulo|PenuX in R/Quiz Unità 4|quiz}}) * {{modulo|PenuX in R/Unità 5 - Valutazione e Validazione dei Modelli|Unità 5: Valutazione}} ({{modulo|PenuX in R/Quiz Unità 5|quiz}}) * {{modulo|PenuX in R/Unità 6 - Deployment e Implementazione Clinica|Unità 6: Deployment}} ({{modulo|PenuX in R/Quiz Unità 6|quiz}}) * {{modulo|PenuX in R/Unità 7 - Esercitazioni di Machine Learning in R|Unità 7: Esercitazioni di Machine Learning}} ({{modulo|PenuX in R/Quiz Unità 7|quiz}}) }}<noinclude>[[Categoria:PenuX in R| ]] [[Categoria:Template sommario]]</noinclude> g0o4bkjop8zaou36xa7fno8gsv4z1ja Categoria:PenuX in R 14 61197 502052 2026-10-04T14:36:55Z Hippias 18281 categoria 502052 wikitext text/x-wiki Questa categoria raccoglie le pagine del libro ''[[{{PAGENAME}}]]''. [[Categoria:Categorie dei libri]] h6c7lljonxpajmm5za0mxp205oh60uz Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Crespiatica 0 61198 502144 2026-10-04T21:54:03Z ~2026-46067-79 54720 Nuova pagina: == Capoluogo == == Frazioni == 502144 wikitext text/x-wiki == Capoluogo == == Frazioni == ozkx25izds8x08imhet1f6ypivzsd7y 502145 502144 2026-10-04T22:08:25Z ~2026-46067-79 54720 /* Frazioni */ 502145 wikitext text/x-wiki == Capoluogo == == Frazioni == * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Crespiatica/Tormo - Chiesa della Beata Vergine Addolorata e Sant'Ambrogio|Tormo - Chiesa della Beata Vergine Addolorata e Sant'Ambrogio]] n2k01pebxxvhhwh3jvn85a59cw4nz2t 502146 502145 2026-10-04T22:17:44Z ~2026-46067-79 54720 /* Capoluogo */ 502146 wikitext text/x-wiki == Capoluogo == * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Crespiatica/Crespiatica - Chiesa di Sant'Andrea apostolo|Chiesa di Sant'Andrea apostolo]] == Frazioni == * [[Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Crespiatica/Tormo - Chiesa della Beata Vergine Addolorata e Sant'Ambrogio|Tormo - Chiesa della Beata Vergine Addolorata e Sant'Ambrogio]] a9p68z02htmx5uoxp1achgwwcvz9kog Disposizioni foniche di organi a canne/Italia/Lombardia/Provincia di Lodi/Crespiatica/Crespiatica - Chiesa di Sant'Andrea apostolo 0 61199 502147 2026-10-04T22:51:39Z ~2026-46067-79 54720 Nuova pagina: {{Disposizioni foniche di organi a canne}} * '''Costruttore:''' Giuseppe Bossi * '''Anno:''' 1799 * '''Restauri/modifiche:''' Angelo Cavalli (seconda metà del XIX° secolo, restauro e ampliamento) * '''Registri:''' 39 * '''Canne:''' * '''Trasmissione:''' meccanica * '''Tastiere:''' 2 di 54 note (''Do<sup>1</sup>''-''Fa<sup>5</sup>'', divisione Bassi/Soprani ''Si<sup>2</sup>''/''Do<sup>3</sup>'') * '''Pedaliera:''' piana - parallela di 18 note (''Do<sup>1</sup>''-''Fa<sup>2</... 502147 wikitext text/x-wiki {{Disposizioni foniche di organi a canne}} * '''Costruttore:''' Giuseppe Bossi * '''Anno:''' 1799 * '''Restauri/modifiche:''' Angelo Cavalli (seconda metà del XIX° secolo, restauro e ampliamento) * '''Registri:''' 39 * '''Canne:''' * '''Trasmissione:''' meccanica * '''Tastiere:''' 2 di 54 note (''Do<sup>1</sup>''-''Fa<sup>5</sup>'', divisione Bassi/Soprani ''Si<sup>2</sup>''/''Do<sup>3</sup>'') * '''Pedaliera:''' piana - parallela di 18 note (''Do<sup>1</sup>''-''Fa<sup>2</sup>'') * '''Collocazione:''' in corpo unico sulla cantoria in cornu evangelii * '''Accessori:''' Tremolo - Espressione corale - Campanelli * '''Note:''' strumento non funzionante, in stato di completo abbandono {| border="0" cellspacing="0" cellpadding="20" style="border-collapse:collapse;" | style="vertical-align:top" | {| border="0" | colspan=2 | '''II - Espressivo''' ---- |- |Violoncello || 8' Soprani |- |Violoncello || 8' Bassi |- |Flauto || 8' Soprani |- |Voce umana || 8' |- |Principale || 8' Bassi |- |Principale || 8' Soprani |- |Ottava || 4' Bassi |- |Ottava || 4' Soprani |- |Decima quinta || 2' |- |Decima nona || 1.1/3 |- |Vigesima seconda || 1' |- |Due di Ripieno || 2/3' |- |} | style="vertical-align:top" | {| border="0" | colspan=2 | '''I - Grand'organo – ''Concerto''''' ---- |- |Terza mano |- |Unione tastiere |- |Cornetto II (XV - XVII) || 2' |- |Voce umana || 8' |- |Fagotto || 8' Bassi |- |Tromba || 8' Soprani |- |Clarino || 4' Bassi |- |Clarone || 4' Soprani |- |Viola|| 4' Bassi |- |Corni dolci || 16' Soprani |- |Flauto || 4' |- |Ottavino || 2' |- |Basso || 8' al pedale |- |Bombardino pedale || 8' al pedale |- |''feritoia vuota'' |- |} | style="vertical-align:top" | {| border="0" | colspan=2 | '''I - Grand' organo – ''Ripieno''''' ---- |- |Principale || 8' Bassi |- |Principale || 8' Soprani |- |Principale || 16' Bassi |- |Principale || 16' Soprani |- |Ottava || 4' Bassi |- |Ottava || 4' Soprani |- |Duodecima || 2.2/3' |- |Decima quinta || 2' |- |Decima nona || 1.1/3' |- |Vigesima seconda || 1' |- |Vigesima sesta || 2/3' |- |Vigesima nona || 1/2' |- |Trentatreesima || 1/3' |- |Trigesima sesta || 1/4' |- |Contrabbassi || 16' al pedale |- |} 5ufr25z0u074t0q71ik81sk5i9lhzh0