Questa guida raccoglie appunti sul corso di sistemi informativi in

Sistemi informativi
Questa guida raccoglie appunti sul corso di sistemi informativi in preparazione
all'esame. Sono presenti alcune annotazioni per agevolare l'apprendimento o
rendere più esplicito alcune parti.
Attenzione: Indica un concetto particolarmente importante o che presenta determinate criticità.
Nota: Focalizza l'attenzione su un aspetto che richiede un approfondimanto.
Problema: Definisce un problema da risolvere.
Soluzione: Propone una soluzione ad un problema.
Davide Mottin
Indice
Sistemi informativi
Indice
Argomenti trattati
Dati strutturati
Object oriented model
Tipi di dato
Chiavi
Esercizi possibili
Object-relational model
User defined types (UDT)
References (puntatori)
Dereferenziare puntatori
Inserimento e ordinamento
Introduzione ai dati semistrutturati
XML
Principali caratteristiche di XML
La sintassi
Namespace
DTD
Sintassi DTD
Attributi
Definizioni ricorsive
Usare i DTD nei documenti XML
Esercizi possibili
Query su documenti XML
XPath
Espressioni XPath
Condizioni nelle espressioni XPath
XPath (esteso)
XQuery
Sintassi di XQuery
Join
Eliminazione dei duplicati
Test su insiemi di nodi
Aggregazione
Condizioni if
Ordinamento
XML Schema
Sintassi di XML Schema
Tipi semplici
Tipi complessi
Sequenze
Attributi
Altri tipi e restrizioni
Chiavi e chiavi esportate
Estensioni ai tipi
Substitutions groups
XQuery con tipi
XSLT
value-of
apply-templates
for-each
if
Data integration e mining
Data integration
Federated databases
Data warehouse
Mediatori
Adornments
Esercizi possibili
Entity resolution
Algoritmo per entity resolution
Data mining
Frequent itemset mining
Trovare oggetti simili
Min-hashing
Locality Sensitive Hashing
Clustering
Clustering agglomerativo
Distanza/unione di cluster
Condizioni di stop
Point assignment clustering
k-means
Algoritmo BFR
OLAP
Data cube
Schema a stella
Slicing e dicing
Data cube formale
Internet
Rispondere a query
PageRank
Teleporting
Altri modelli alternativi al PageRank
Risolvere il problema dei link spam
Pubblicizzare prodotti
Ranking
Adwords
Un semplice algoritmo greedy
Balance algorithm
Argomenti trattati
Due principali argomenti verranno approfonditi nel corso: dati strutturati e data integration and mining
Dati Strutturati
1. Object oriented model
2. Object relational e linguaggi usati per Object-relational
3. Semi-structured data (senza schema)
4. XML
Cos'è, come è fatto, a cosa serve
Schema models: DTD e XSD
Linguaggi per fare queries: XPath, XQuery e XSLT
Data integration and mining
1. Data integration
Come integrare diversi tipi di dato
Come identificare oggetti (entità) simili o uguali anche se rappresentati in modo diverso
2. Introduzione al data mining: ricerca di strutture ricorrenti nei dati
Frequent items
Clustering
Oggetti simili in pagine web (minhash)
OLAP e datawarehousing
Ricerca nel web
Dati strutturati
Object oriented model
Definisce oggetti invece di relazioni (da tabelle a classi).
Se vogliamo per esempio definire un film, possiamo creare la classe Movie:
class Movie {
attribute string title;
attribute integer year;
attribute integer length;
attribute enum Genres {drama, comedy, sciFi, teen} genre;
}
Genres è di tipo enumerato, ovvero dichiara i possibili valori che può avere.
Un attributo Address invece può essere definito come Struct, in questo caso rappresenta un tipo
composto:
attribute Struct Addr
{string street, string city} address;
Per aggiungere relazioni si usa la parola relationship, che nell'esempio permettono di definire insiemi di
classi.
relationship Set<Star> stars; (in Movie)
relationship Set<Movie> starredIn; (in Star)
Si possono esplicitamente definire relazioni inverse:
relationship Set<Star> stars inverse Star::starredIn
o riutilizzare tipi di dato definiti altrove:
attribute Star::Addr address;
Una classe può inoltre generalizzare (cioè estendere) un'altra con la parola chiave extends
class HistoricalMovie extends Movie {
attribute integer period;
};
Tipi di dato
Dati base: integer, real, string, character
Enumerazioni: enum {}
Classi e struct: per definire tipi e relazioni
Collezioni (insiemi):
Set: insiemi di oggetti senza ripetizioni
Bag: insiemi di oggetti con ripetizioni
List: oggetti ordinati
Array: i oggetti di tipo T
Dictionary: oggetti associativi, simili alle hash map
Chiavi
Per definire chiavi (come nel modello relazionale) su determinati attributi si usa la parola key dopo il nome
della classe:
class Movie (key (title, year)) {
...
Esercizi possibili
1. Rappresentare in ODL una base di dati, poi in XML.
2. Per la base di dati in ODL: tradurla in relazionale (prerequisito) [slide 28-36].
Object-relational model
Sostanzialmente si tratta di un compromesso che accetta Oggetti + Tabelle. Caratteristiche principali: *
Attributi solo strutturati * Metodi di classe * Identificatori per le singole tuple * Riferimenti
La caratteristica principale è la possibilità di definire Nested relations: le relazioni annidate sono tabelle nel
modello relazionale. Per esempio: se si definisce Star si possono definire relazioni annidate Address e
Movie per ogni attore.
Problema: duplicazione di tabelle e di valori.
Soluzione: definire puntatori (riferimenti) ad una relazione R e le sue tuple con sintassi ∗R.
Movies(title, year, length)
Stars(name, address(street, city), birthdate, movies ({*Movies})
Nota: in questo modo, però, gli id delle tuple nella tabella Stars divengono visibili perché sono riferimenti
a tuple nella tabella Movies.
User defined types (UDT)
È possibile creare nomi alternativi (alias) a tipi già definiti per sollevare errori di type check (ovvero
confrontare tipi di dato diversi non è possibile).
CREATE TYPE T AS <primitive type>;
Inoltre si possono definire tipi di dato complessi:
CREATE TYPE street AddressType AS (
street CHAR(50),
city CHAR(20)
);
Si possono anche creare relazioni (TABLE) di UDT:
CREATE TABLE MovieStar OF StarType ( PRIMARY KEY (name) );
References (puntatori)
Per poter referenziare una tabella T si usa la sintassi REF(T); inoltre, se due tabelle hanno lo stesso tipo, si
può definire uno scope per restringere il riferimento ad una sola di esse.
CREATE TYPE StarType AS (
name CHAR(30),
address AddressType,
bestMovie REF(MovieType) SCOPE Movies
)
È possibile riferirsi esplicitamente all'id di una tabella (o di una tupla) utilizzando la sintassi:
REF IS <campo id> SYSTEM GENERATED alla crezione della tabella stessa. Il campo può essere SYSTEM GENERATED o DERIVED (ovvero la
chiave primaria viene usata come id).
Dereferenziare puntatori
Ma a cosa punta effettivamente un puntatore? Sia dato un puntatore x ad una tupla t di tipo T . Allora il
costrutto DEREF(x) restituisce t e x->a restituisce l'attributo a di t.
Ecco un esempio di dereferenziazione:
SELECT DEREF(movie)
FROM StarsIn
WHERE star-­‐>name=Brad Pitt;
Dimenticare il DEREF significa non lavorare con l'oggetto, ma solo con i suoi riferimenti.
Per accedere al valore di un campo x in una tupla t si usa
estrazione del valore x al tipo (come un metodo getter).
t. x() , che in pratica applica il metodo di
SELECT m.year()
FROM Movies m
WHERE m.title()=’KingKong’;
Nota: Una caratteristica fondamentale dei database object-relational è che non richiedono JOIN, in
quanto basta utilizzare relazioni annidate e dereferenziare puntatori.
Inserimento e ordinamento
Per inserire un nuovo oggetto bisogna prima crearne uno vuoto e poi popolarlo.
L'ordinamento deve essere esplicitamente dichiarato attraverso il costrutto:
CREATE ORDERING for <type name> <details>
dove <details> è: * EQUALS ONLY BY STATE: definisce l'uguaglianza se gli attributi sono uguali * FULL
BY RELATIVE WITH F definisce un determinato ordine con F.
CREATE ORDERING FOR StarType EQUALS ONLY BY STATE;
Attenzione: se l'oggetto contiene altri tipi, l'uguaglianza deve essere definita per ogni tipo annidato.
Introduzione ai dati semistrutturati
I dati semistrutturati: * Non hanno uno schema fissato, ma viene inferito dai dati stessi. * Sono utilizzati per
data integration o per interscambio di dati. * Possono essere prodotti da tecnologie diverse. * Possono
essere utilizzati per creare "wrappers" che convertano query in diversi linguaggi. * Maggiore flessibilità ↔ ,
difficile ottimizzazione delle query. * Vengono rappresentati come nodi e archi. * Il modello prevede: * Un
nodo radice (root). * Nodi intermedi senza etichetta (rappresentano classi). * Etichette sugli archi: nomi
degli attributi. * I dati memorizzati sulle foglie.
XML
XML è lo pseudonimo di eXtensible Markup Language, nato per presentare documenti. Si è evoluto come
standard per la descrizione di dati in maniera semistrutturata.
Attenzione: XML non richiede uno schema di dato, perciò in molti casi può risultare ambiguo o difficile
da interpretare.
HTML è progenitore di XML, seppure sia meno flessibile. HTML viene utilizzato per la presentazione del
contenuto di pagine web. Le regole di presentazione di HTML sono molto libere, a differenza di XML (vedi
sotto), e perciò non risulta adatto a descrivere dati.
Principali caratteristiche di XML
Vediamo un esempio di XML:
<?xml version="1.0" encoding="ISO-­‐8859-­‐1"?>
<?xml-­‐stylesheet type="text/xsl" href="books.xsl"?>
<books>
<book title="Learning XML">
<authors>
<author>Erik Ray</author>
</authors>
<publisher>O’Reilly</publisher>
</book>
<book title="XQuery">
<authors>
<author>Priscilla Walmsley</author>
</authors>
<publisher>O’Reilly</publisher>
</book>
</books>
I tag possono essere definiti dall'utente ed esprimono una struttura logica.
Il documento XML è rappresentato ad albero.
HTML può essere rappresentato in XML.
Lo schema non obbligatorio viene definito nel DTD o XML Schema.
Si possono applicare trasformazioni al file XML per convertirlo in un qualsiasi altro formato. Le
trasformazioni XML sono chiamate anche XSL(t).
XML viene utilizzato per l'interscambio di dati.
Essendo un file di testo, può essere letto e interpretato da diverse piattaforme software e librerie di
programmazione.
Lo standard XML è definito dal World Wide Web Consortium (W3C)1.
Lo standard XML è definito dal World Wide Web Consortium (W3C)1.
La sintassi
Risulta importante considerare due concetti fondamentali:
1. Elementi: può essere una qualsiasi cosa racchiusa in tag (come book nell'esempio in alto).
2. Attributi: definiscono caratteristiche di un tag (come title nell'esempio in alto).
Un documento XML si dice well-formed se:
1. Ogni elemento è circondato da < ... >.
2. Esiste un solo elemento radice.
3. Ogni elemento aperto deve essere chiuso, dove la chiusura di un elemento <tag> si indica con </tag>.
4. Gli elementi possono essere innestati: <tag><nestedtag><\nestedtag><\tag> e i tag più interni vanno
chiusi per primi.
5. I tag possono avere attributi: <tag attribute="value">.
6. Elementi senza contenuto (nessun tag/testo al loro interno) possono essere chiusi con <tag />.
7. Un elemento può contenere testo.
8. I nomi degli attributi in un elemento sono univoci.
Un documento XML si dice valido se rispetta lo schema (vedremo DTD e XML schema).
Nota: Il documento XML rappresenta quasi fedelmente l'albero in memoria. Quasi perché l'ordine dei
tag non viene catturato dall'albero (a meno di particolari istruzioni) e perché gli spazi bianchi ed altri
caratteri vengono ignorati. Se non si vuole che una particolare sezione di testo venga interpretata come
XML, deve essere inclusa in un blocco CDATA
<![CDATA[
Tags in XML are delimited by "<" and ">".
]]>
Altrimenti per rappresentare < e > bisogna usare caratteri di escape < e >.
Namespace
Per evitare di definire più volte lo stesso tag si possono usare i namespace (analoghi ai package nei
linguaggi di programmazione) inserendo prefissi definiti attraverso speciali attributi nei tag o all'inizio del
documento XML nella root. Ecco un esempio per una tabella:
<xh:table xmlns:xh="http://www.w3.org/1999/xhtml">
<xh:tr>
<xh:td>Apples</xh:td><xh:td>Bananas</xh:td>
</xh:tr>
</xh:table>
DTD
Il Documento delle Definizioni di Tipi (DTD) serve per definire una struttura agli elementi di un
documento XML.
Il DTD è basato sulle espressioni regolari (regexp o regular expressions).
Nota: definire un DTD (come XML schema d'altronde) significa dare delle regole per dire quando un
particolare documento è valido, inducendo regole di struttura.
Attenzione: come vedremo il DTD è poco espressivo, perciò è stato introdotto XSchema.
Sintassi DTD
I tag definiscono gli elementi (che sono, di fatto, tipi complessi).
A parte gli elementi, non ci sono altri tipi base (interi, booleani, ...): tutto è una stringa (indicata con
#PCDATA).
In DTD, oltre agli elementi (tag) che possono contenere altri tag, si possono definire i seguenti
contenuti:
#PCDATA: indica sequenze di caratteri (parsed, ovvero interpretabili dal parser).
EMPTY: nessun contenuto.
ANY: qualsiasi contenuto.
(e): un gruppo di espressioni (di solito serve per riferirsi al particolare gruppo con un nome o un
numero e non doverlo riscrivere ogni volta).
Un documento DTD inizia con !DOCTYPE, seguito dal nome della radice del documento XML
Ecco un esempio per definire Stars:
<!DOCTYPE Stars [
<!ELEMENT Stars (Star*)>
<!ELEMENT Star (Name, Address+, Movies)>
<!ELEMENT Name (#PCDATA)>
<!ELEMENT Address (Street, City)>
<!ELEMENT Street (#PCDATA)>
<!ELEMENT City (#PCDATA)>
<!ELEMENT Movies (Movie*)>
<!ELEMENT Movie(Title, Year)>
<!ELEMENT Title (#PCDATA)>
<!ELEMENT Year (#PCDATA)>
]>
Come si nota, gli elementi (come Movie) possono essere definiti da altri elementi o da espressioni regolari
(cfr. Stars (Star*)). Per esempio:
Stars (Star*)
definisce che Stars (l'elemento radice) contiene 0 o più elementi Star.
Se un elemento non contiene altri elementi allora è una foglia e, come Name nell'esempio precedente, può
contenere solo testo o essere vuoto.
Attributi
Gli attributi degli elementi XML in DTD sono indicati con <!ATTLIST>.
Gli attributi possono essere:
Stringhe: indicate con CDATA.
Enumerazioni: indicate con (valore1 | valore2 | ...).
Chiavi: indicate con ID.
Chiavi esportate: indicate con IDREF (chiavi che sono definite in altri elementi).
Liste di chiavi esportate: indicate con IDREFS.
Possono inoltre avere un valore:
Di default, se l'attributo è opzionale ed assume un valore fisso (per esempio età=10).
#REQUIRED: se l'attributo è obbligatorio.
#IMPLIED: se è opzionale.
#FIXED value: se assume un valore fisso.
Nota: Se un attributo è dichiarato come ID, allora i suoi valori devono essere univoci.
Nota: Un elemento può non avere nessuna chiave (a differenza del modello relazionale).
Esempio:
<!ELEMENT height (#PCDATA)>
<!ATTLIST height
dimension (cm|in) #REQUIRED
accuracy CDATA #IMPLIED
resizable CDATA #FIXED "yes"
>
Attenzione: Gli attributi non possono essere definiti una volta sola.
Definizioni ricorsive
Un elemento può essere definito in termini di se stesso. Per esempio, una persona può essere definita da
due altre persone (genitori).
<!DOCTYPE Person [
<!ELEMENT Person (Person?, Person?)>
<!ATTLIST name #CDATA>
]>
Attenzione: le definizioni ricorsive devono avere un modo per definire un caso base (nel caso sopra,
una persona non ha nessun figlio).
Usare i DTD nei documenti XML
Per importare un DTD e definire la validità dell'XML si usano le seguenti direttive:
<?xml version="1.0" encoding="utf-­‐8" standalone="no"?>
<!DOCTYPE Stars SYSTEM "star.dtd">
dove standalone="no" indica che il documento ha un DTD (nello stesso file o in uno esterno). Il sistema
controlla che il documento XML sia valido, quindi conforme al DTD.
Attenzione: un DTD deve essere deterministico, il che vuol dire che non è possibile generare le stesse
strutture in due (o più) pattern ugualmente validi.
Esercizi possibili
1. Riconoscere quando un DTD è ambiguo.
2. Generare un DTD per un determinato XML .
3. Riconoscere se una struttura è valida per un DTD.
4. Generare un DTD ricorsivo per determinate strutture.
Query su documenti XML
Tra i diversi linguaggi, solo XQuery è un linguaggio per interrogazioni2 su documenti XML, mentre XPath
definisce un linguaggio per navigare l'albero XML e XSL trasformazioni tra i documenti.
XPath
XPath3 è un linguaggio navigazionale che produce documenti XML come output, perché restituisce tutti i
nodi che rispettano particolari condizioni.
Nota: La navigazione del documento può partire da un punto qualsiasi, anche se solitamente si parte
dalla radice, indicata con "/".
Espressioni XPath
Sono concatenazioni di tag e "selettori" su di esse, separate da "/", il che significa "considera il livello
dell'albero sottostante al corrente".
XPath permette di specificare attributi, valori e restringere i nodi da restituire.
L'espressione:
/T1/T2/ ... /Tn
significa che, partendo dalla radice, si selezionano tutti i tag Tn figli della sequenza di elementi fino a T1.
Per selezionare l'attributo att si usa @att. /StarMovieData/Star/@StarID.
Assi:
Si può navigare da padre a figlio e da figlio a padre usando ".." per risalire l'albero.
Il selettore "." restituisce il nodo corrente.
Il selettore "//" restituisce tutti i discendenti di un nodo (esempio //City).
Wildcard:
* significa "qualsiasi tag/elemento".
@* significa "qualsiasi attributo".
Attenzione: se si scrive un'espressione non valida o sbagliata, XPath non segnala un errore, ma
restituisce una lista vuota.
Condizioni nelle espressioni XPath
Una condizione viene espressa con p[c], dove p è un tag e c una condizione booleana (uguaglianza,
disuguglianza, ...).
/StarMovieData/Star[name="Fisher"] (star con nome "Fisher")
/StarMovieData/Star[.//City="Malibu"] (star che hanno almeno una casa a "Malibu")
//religions[@percentage > 30]/..[name="Germany"]/name (filtri su attributi -­‐ nomi delle religioni in Germania con una percentuale di fedeli di almeno 30%)
Attenzione: scrivere //City e .//City è profondamente diverso, in quanto la prima espressione parte dalla
radice, la seconda dal nodo corrente.
La condizione [i] restituisce l'i-esimo nodo, mentre [name] seleziona i nodi con un determinato figlio.
/Movies/Movie/Version[1]/@year (anno della prima versione del film)
/Movies/Movie/Version[Star] (film di cui esiste almeno una star)
XPath (esteso)
[nelle slide]
XQuery
XQuery è un linguaggio che permette di fare interrogazioni ad un documento XML utilizzando una sintassi
paragonabile all'SQL per i database relazionali. XQuery utilizza i costrutti principali for, let, where, return.
Nota: ulteriori informazioni e esempi su XQuery si possono trovare nella pagina del W3C4
Sintassi di XQuery
Una query inizia con "for" (iterazione) o "let" (assegnamento di variabile), con, a seguire, un "where"
opzionale e termina con un "return". La query:
return <Greeting>Hello World</Greeting>
restituisce un nuovo documento XML.
I costrutti principali di XQuery sono:
let: dichiara una nuova variabile che contiene la valutazione di un'espressione (un insieme di nodi).
Sintassi: let variabile := espressione
let $stars := doc("stars.xml")
for: itera su una lista di nodi, rappresentata da un'espressione.
Sintassi: for variabile in espressione
let $movies := doc("movies.xml")
for $m in $movies/Movies/Movie
dove la variabile $m conterrà, ad ogni iterazione, un singolo nodo che corrisponde all'espressione
$movies/Movies/Movie.
where: come il "where" in SQL, ma applicato ai nodi di un documento XML.
return:
aggiunge elementi ai risultati, non interrompe il ciclo!
let $movies := doc("movies.xml")
for $m in $movies/Movies/Movie
return $m/Version/Star
Data la caratteristica "costruttiva" di return, è possibile costruire nuovi elementi/attributi che non
appartengono al documento XML, per esempio la sintassi:
return <Movie title="{$m/@title}">{$m/Version/Star}</Movie> costruisce un nuovo film con titolo come attributo e l'insieme delle star.
Attenzione: non bisogna dimenticare le { ... } nei selettori di "return", altrimenti non vengono interpretate
come espressioni XPath, ma copiate senza interpretazione in output!!!
Nota: è possibile dichiarare una variabile che contenga la valutazione di un'espressione XQuery intera,
come per esempio nel caso seguente:
let $starSeq := (
let $movies := doc("movies.xml")
for $m in $movies/Movies/Movie
return $m/Version/Star
)
Join
Il confronto in XML è definito sull'identità dei nodi dell'albero, mentre l'operazione di join avviene sui valori.
Per poter confrontare valori si usa la funzione data(E), che estrae i dati da un nodo.
Usando un ciclo annidato è possibile effettuare join sui valori dei nodi.
for $sl in $movies/Movies/Movie/Version/Star,
$s2 in $stars/Stars/Star
where data($sl)=data($s2/Name)
Attenzione: se si scorre lo stesso tag più volte per esempio
for $o1 in $doc//Order, $o2 in $doc//Order
ricordarsi di includere una clausula where nel quale si eviti di fare il confronto più volte
where $o1 << $o2 Attenzione: l'uguaglianza con "=" controlla l'esistenza di almeno un nodo che verifichi l'espressione in
input, per testare, infatti, ogni singolo nodo, è necessario usare "eq". Ad esempio, in questo caso:
let $stars := doc("stars.xml")
for $s in $stars/Stars/Star
where $s/Address/Street eq "123 Maple St." and
$s/Address/City eq "Malibu"
return $s/Name
se si usasse "=" invece di eq, la condizione sarebbe vera se esistesse almeno una star con indirizzo "123
Maple St." a "Malibu".
Eliminazione dei duplicati
Per eliminare i duplicati è possibile utilizzare il costrutto distinct-values prima di restituire i risultati (e/o
memorizzarli in una variabile).
Test su insiemi di nodi
Esiste (∃): some variable in expression1 satisfies expression2
Per ogni ( ∀): every variable in expression1 satisfies expression2
Esempio: ~~~xml let stars
:= doc(" stars. xml ")f or s in stars//Starwhereevery c in
s//Citysatisf ies c="Hollywood" return $s/Name ~~~
Aggregazione
Stessi operatori di SQL: count, max, min, avg, sum
La somma di stringhe converte la stringa prima in numero (se possibile), poi calcola la somma dei
risultati.
Condizioni if
Hanno la stessa semantica e sintassi di un normale linguaggio di programmazione.
Sintassi: if (expression1) then expression2 else expression3
Attenzione: il ramo else è obbligatorio, ma può essere vuoto.
Ordinamento
Come in SQL, esiste il costrutto order by, che può essere utilizzato per scorrere gli elementi di un ciclo
for in maniera ordinata.
Sintassi: for ... order by attribute1,...,attributeN
XML Schema
XML Schema è un linguaggio (un dialetto XML, per la precisione) che definisce lo schema di un documento
XML, proprio come DTD, ma più espressivo e verboso. Alcune caratteristiche principali: * I tag sono
separati dal tipo: è infatti possibile definire lo stesso tag più volte. * I tipi base sono già definiti. * XSchema è
un documento XML!
⟹ non si deve imparare una nuova sintassi.
Nota: Dato che XML Schema è analogo a XML, per disambiguare i tag definiti dall'utente da quelli
definiti dallo standard si usano i namespace (vedi sezione corrispondente). Di solito si indica il namespace
di XML Schema con xs, per esempio xs:element.
Sintassi di XML Schema
Tipi semplici
Il tag xs:element definisce la struttura di un nodo XML del documento.
<xs:element name="[nome elemento]" type="[tipo elemento]"[vincoli o informazioni struttu
rali] />
Per esempio, si può definire il tag Year di tipo intero, ma in questo modo se si indica all'anno un tipo
diverso in fase di validazione, verrà segnalato un errore.
<xs:element name="Year" type="xs:integer" />
Tipi complessi
Si possono definire anche tag ed elementi più complessi, come insiemi di elementi semplici (per esempio
Movie è un elemento complesso).
<xs:complexType name="[nome dell'elemento]">
<xs:sequence>
[Lista di definizioni di elementi]
</xs:sequence>
</xs:complexType>
Nota: Si possono definire tipi complessi senza nomi, detti tipi anonimi.
Nota: se vogliamo elementi con nodi e test mescolati, si può usare mixed="true"
Sequenze
Serie di elementi che definiscono i figli di un tag attraverso <xs:sequence>.
Possono avere una cardinalità espressa con gli attributi minOccurs e maxOccurs, con valore intero
OPPURE "unbounded" (se infinito).
Attenzione: le sequenze definiscono elementi figli, ma nel caso si voglia vincolarne il numero si usa
xs:all per dire di volere esattamente una occorrenza di ogni elemento, oppure xs:choice per dire che uno
solo degli elementi nella sequenza deve essere presente (in maniera esclusiva).
Attributi
Gli attributi vengono definiti con xs:attribute attraverso la sintassi:
<xs:attribute name="[nome attributo]" type="[tipo attributo]" [altre informazioni] />
Per esempio: ~~~xml ~~~ definisce l'attributo year di tipo intero con valore di default (se non è presente
l'attributo) a 0
⟹ l'attributo è in questo caso opzionale.
Per definire un attributo obbligatorio si deve usare la sintassi use="required".
Altre definizioni utili
<xs:attribute name="country" type="xs:NMTOKEN" fixed="US"/>
xs:NMTOKEN modella stringhe senza spazi e caratteri speciali.
fixed significa che quando l'attributo country è presente, ha il valore "US".
xs:date rappresenta date.
<xs:attribute name="orderDate" type="xs:date"/>
ref modella attributi definiti altrove.
<xs:element ref="comment" minOccurs="0"/>
Altri tipi e restrizioni
I valori sugli elementi possono essere condizionati definendo una restrizione che vincoli il valore minimo e
massimo (con minInclusive e maxInclusive), oppure attraverso una serie di valori (per creare un
enumerazione).
Restrizione sui valori
<xs:simpleType name="movieYearType">
<xs:restriction base="xs:integer">
<xs:minInclusive value="1915" />
</xs:restriction>
</xs:simpleType>
Enumerazioni: definiscono possibili valori accettati dal tipo
<xs:simpleType name="genreType">
<xs:restriction base="xs:string">
<xs:enumeration value="comedy" />
<xs:enumeration value="drama" />
<xs:enumeration value="sciFi" />
<xs:enumeration value="teen" />
</xs:restriction>
</xs:simpleType>
Pattern: servono a specificare restrizioni sulle stringhe accettate attraverso la sintassi <xs:pattern
value="pattern" />. I pattern sono definiti dalla sintassi delle espressioni regolari (vedi sotto):
<xs:simpleType name="SKU">
<xs:restriction base="xs:string">
<xs:pattern value="\d{3}-­‐[A-­‐Z]{2}"/>
</xs:restriction>
</xs:simpleType>
Nota: la sintassi dei pattern è la seguente:
Nota: la sintassi dei pattern è la seguente:
Liste: è possibile definire anche elementi di tipo lista e restrizioni nella dimensione (separati da
spazio).
<xs:simpleType name="USStateList">
<xs:list itemType="USState"/>
</xs:simpleType>
<xs:simpleType name="SixUSStates">
<xs:restriction base="USStateList">
<xs:length value="6"/>
</xs:restriction>
</xs:simpleType>
Unioni: tipi che devono essere ristretti a uno tra una lista di tipi:
<xs:simpleType name="zipUnion">
<xs:union memberTypes="USState listOfMyIntType"/>
</xs:simpleType>
la quale modella i seguenti elementi validi:
<zips>CA</zips>
<zips>95630 95977 95945</zips>
<zips>AK</zips>
Attenzione: Solo i tipi complessi possono avere attributi. Per avere attributi su un tipo semplice, si
definisce un tipo complesso con un contenuto semplice (tag simpleContent).
<xs:element name="internationalPrice">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:decimal">
<xs:attribute name="currency" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
Attenzione: per avere un tag "vuoto" (cioè senza contenuto, ma con attributi) si può costruire un
complexType con un complexContent, ma con restrizione xs:anyType e descrizione degli attributi, oppure
più semplicemente:
<xs:element name="internationalPrice">
<xs:complexType>
<xs:attribute name="currency" type="xs:string"/>
<xs:attribute name="value" type="xs:decimal"/>
</xs:complexType>
</xs:element>
Chiavi e chiavi esportate
In XML schema ci sono due tipi di chiavi: selettori e campi. * I selettori: identificano l'elemento a cui
applicare una chiave attraverso XPath. * I campi: identificano i campi usati come chiave attraverso XPath.
<xs:key name="[nome chiave]" >
<xs:selector xpath="[espressione xpath]" />
<xs:field xpath="[espressione xpath]" />
</xs:key>
Nota: ci può essere più di un selettore per lo stesso elemento.
Nota: si può usare xs:unique invece di xs:key, con la differenza che per key "xs:field" deve sempre
esistere, invece per unique no.
<xs:key name="movieKey">
<xs:selector xpath="Movie" />
<xs:field xpath="Title" />
<xs:field xpath="Year" />
</xs:key>
Allo stesso modo si possono definire le chiavi esportate, con la seguente sintassi:
<xs:keyref name="[nome chiave esportata]" refer="[nome chiave a cui si riferisce]" >
<xs:selector xpath="[espressione xpath]" />
<xs:field xpath="[espressione xpath]" />
</xs:keyref>
Estensioni ai tipi
Una volta definito un tipo è possibile estenderlo, che significa aggiungere altri elementi ad un tipo già
esistente. Si deve usare il tag <extension>.
<extension base="[tipo esistente]">
[elementi aggiunti al tipo]
</extension>
Per esempio, definito un tipo Address è possibile definire un tipo USAddress in questo modo:
<complexType name="USAddress">
<complexContent>
<extension base="Address">
<sequence>
<element name="state" type="USState"/><!-­‐-­‐ USState è un tipo già definito altrov
e -­‐-­‐>
<element name="zip" type="positiveInteger"/>
</sequence>
</extension>
</complexContent>
</complexType>
Substitutions groups
Gli elementi in un "gruppo di sostituzione" (traduzione dall'inglese) possono essere usati in un qualsiasi
posto in cui l'elemento che sostituiscono sia stato usato.
Attenzione: se un elemento usa elementi che sono sostituzioni, allora sarà richiesto lo specifico tag da
essi definito (applicando una restrizione al tipo che sostituisce, non al sostituito).
<element name="comment" type="string"/> ...
<element name="shipComment" type="string" substitutionGroup="ipo:comment"/>
<element name="customerComment" type="string" substitutionGroup="ipo:comment"/>
XQuery con tipi
Per fare una query ristretta ad un particolare tipo si può usare la sintassi:
instance of element(tag, tipo)
Per esempio:
count(
doc("ipo.xml")//shipTo[. instance of element(*, ipo:UKAddress)])
Nota: In questo modo si possono costruire funzioni che controllano solo particolari tag e particolari tipi e
che effettuano operazioni su di esse.
XSLT
XSLT è l'acronimo di Extensible Stylesheet Language for Transformation ed è un linguaggio che permette
di trasformare un documento XML in qualsiasi altro formato attraverso XQuery e XPath.
XSLT è (nuovamente) un documento XML definito attraverso un preciso schema5. Un documento XSLT è
così strutturato:
<? xml version = "1.0" encoding = "utf-­‐8" ?>
<xsl:stylesheet xmlns:xsl="http ://www.w3.org/1999/XSL/Transform">
[elenco trasformazioni]
</xsl:stylesheet>
Un XSLT è un insieme di template che, attraverso espressioni XPath, matchano parti di documento ed
effettuano opportune trasformazioni.
<xsl:template match="[espressione XPath]">
Ora descriviamo i principali costrutti di XSLT:
value-of
Seleziona il valore di una particolare espressione e lo stampa in output
<xsl:value-­‐of select="[espressione]"/>
Per esempio, se volessimo l'attributo title di ogni film:
<? xml version="1.0" encoding="utf-­‐8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/Movies/Movie">
<xsl:value-­‐of select="@title" />
<br/>
</xsl:template>
</xsl:stylesheet>
apply-templates
È possibile applicare ricorsivamente template una volta definiti. Per esempio, per ogni elemento
corrispondente ad un'espressione è possibile applicare un template di trasformazione.
<xsl:apply-­‐templates select="[espressione]" />
Per esempio:
<xsl:template match="/Movies">
<Movies>
<xsl:apply-­‐templates />
</Movies>
</xsl:template>
Nota: l'assenza di un select dopo apply-templates significa: "applica tutti i template che matchano tutti i
figli" (nel caso dell'esempio, da solo non produce nessun output).
for-each
Si può eseguire la trasformazione per ognuno dei tag corrispondenti.
<xsl:for-­‐each select="[espressione]" />
Per esempio si può iterare ogni Star e produrre una lista di nomi:
<ol>
<xsl:for-­‐each select = "Stars/Star">
<li>
<xsl:value-­‐of select = "Name">
</li>
</xsl:for-­‐each>
</ol>
if
La trasformazione entro il tag si attiva ad un particolare condizione booleana.
Attenzione: non c'è nessun else.
<xsl:if test="[espressione booleana]" />
Data integration e mining
L'importanza di gestire, integrare e analizzare i dati è vitale in molte applicazioni. In questo capitolo
verranno introdotti i seguenti argomenti:
Integrazione di dati
Data mining
OLAP
Trovare informazioni nel web
Data integration
Problema: abbiamo diverse basi di dati eterogenee che contengono cose simili ma con schemi diversi,
tipi di dato diversi, rappresentazioni diverse. Come troviamo le informazioni da cercare in maniera
trasparente?
Assumiamo che i dati abbiano lo stesso schema, ma valori leggermente diversi negli attributi.
Esistono tre approcci:
1. Federated databases: database indipendenti, ma ognuno in grado di chiamare/spedire informazioni
all'altro.
2. Warehousing: integrazione dei dati in un unico grande database (esempio, OLAP).
3. Mediation: crea un'interfaccia comune di accesso ai vari dati e converte le query per ognuno dei
database.
Federated databases
Supponiamo di avere n database con informazioni diverse e indipendenti. Un approccio potrebbe essere
che ogni database effettua una query su ogni altro database.
Problema: Approccio troppo dispendioso dato il numero di query da fare, ossia tutte le possibili coppie:
(n2 )
Soluzione: Scrivere una query diversa per ogni database.
Problema: Difficile costruire una query del genere.
Data warehouse
Un'unico grande database che combina i dati di n database indipendenti.
I dati vengono integrati e aggiornati periodicamente nella warehouse.
Vengono utilizzate soprattutto per calcolare aggregati e per questo non devono essere
necessariamente aggiornati in tempo reale.
Vantaggio: dobbiamo scrivere una sola query.
Problema: Come mappare tanti dati in un'unico database? Come mantenere i dati aggiornati?
Soluzione: Integrare i dati in maniera manuale producendo tabelle e mediatori per ogni database, in
modo tale da tradurre i dati in un'unica tabella (si ricorda che i campi dei singoli database possono avere
nomi diversi).
Attenzione: mentre inserimenti e interrogazioni alla data warehouse sono abbastanza automatici, la
cancellazione è più complicata, in quanto cancellare un dato nella tabella integrata potrebbe voler dire
cancellarlo in multiple tabelle (se è un dato replicato) oppure in una sola. Il problema è che se il dato è più
complesso non si può sapere se si debba preservare o no in un database.
Mediatori
I mediatori sono delle viste (view in SQL) virtuali di un insieme di database.
I mediatori non memorizzano nessun dato.
Ogni database ha un "wrapper" o un mapping tra campi mediati e campi nel singolo database, in modo
da "tradurre" le query nei diversi database.
Per tradurre una query in un database in una query utente si possono usare template per wrapper (si
ricorda che un wrapper è un pezzo di software che effettua la traduzione degli attributi). Ecco un esempio
dove AutosMed è lo schema del mediatore:
SELECT *
FROM AutosMed
WHERE color = $c;
=>
SELECT serialNo, model, color, autoTrans, "dealer1"
FROM Cars
WHERE color = $c;
Problema: le query possono diventare molto complesse ed in molti casi è impossibile trovare un
Problema: le query possono diventare molto complesse ed in molti casi è impossibile trovare un
mapping.
Soluzione: restringere il problema a determinate classi di query e costruire un wrapper generator.
Problema: non è possibile costruire un template per ogni query. Si immagini di volere macchine di un
certo colore e di un certo modello (condizioni in AND su attributi).
Soluzione: creare dei template meno rigidi che restituiscano meno risultati (per esempio solo vincolati al
colore), per poi restringere la query in un secondo momento.
Problema: non è sempre possibile scrivere una query più generica (privacy, costo computazionale o di
rete).
Soluzione: definire un modello che descriva quali query si possano fare o sono vietate → adornments
Adornments
È una sorta di linguaggio che specifica le possibilità su un database.
f (free): l'attributo può essere specificato.
b (bound): dobbiamo specificare un valore per l'attributo.
u (unspecified): l'attributo non può essere specificato.
c[S] (choice from set S): un valore deve essere specificato entro l'insieme S.
o[S] (optional, from S): se specificato deve avere un valore in S.
f': l'attributo non può essere parte dell'output.
L'insieme degli adornments definisce le capabilities specification.
Cars(serialNo, model, color, autoTrans, navi)
Cars(ubbo[yes,no]o[yes,no])
Sono specificati modello e colore e, opzionalmente, trasmissione automatica e navi
gatore.
Il mediatore semplicemente analizza le specifiche e decide la miglior strategia (ha una sorta di cost model
interno).
Esercizi possibili
1. Scrivere una soluzione di integrazione per diversi database (e.g. 3 database).
2. Scrivere adornments per un particolare sistema.
3. Dato un'insieme di specifiche con adornments verificare se possono rispondere a determinate query o
costruire un plan di esecuzione di una query.
Entity resolution
Molte volte alla stessa entità (oggetto, persona, stato ...) ci si può riferire in modi diversi. Questo problema
si verifica spesso in database diversi e ancor più spesso nel web a causa del linguaggio naturale.
Problema: come capire che due espressioni si riferiscono alla stessa entità?
Soluzione: Edit distance: approssimare le stringhe con la stringa più "vicina", cioè quella che è ottenuta
trasformando (inserendo, cancellando o modificando) il minor numero di caratteri possibili.
Attraverso l'edit distance è possibile definire una somiglianza tra stringhe: le stringhe che hanno una
distanza minore di
τ fissato sono considerate simili.
Attenzione: la similarità non è transitiva.
Algoritmo per entity resolution
Problema: dato un database, unire (merge) tuple simili.
Soluzione: un algoritmo che unisca tuple simili, ma solo nel caso che l'operazione di merge rispetti
alcune proprietà.
Sia ⊕ un'operazione di merge che rispetta le seguenti proprietà:
t ⊕ t (riflessività).
t ⊕ s = s ⊕ t (commutatività).
(r ⊕ s) ⊕ t = r ⊕ (s ⊕ t) (associatività).
mentre la relazione di similarità ≈ deve essere tale che:
r ≈ r (riflessività).
r ≈ s iff s ≈ r (simmetria).
if r ≈ s then r ≈ (s ⊕ t) (rappresentabilità).
Input: un insieme I di record, similarità ≈, una funzione di merge ⊕.
Ouptut: un insieme O
⊆ I.
Procedura: L'algoritmo parte dall'insieme dei risultati, inizialmente vuoto, e cerca di aggiungere tuple dal
database che non sono simili a nessuno dei risultati già aggiunti. Questo è lo pseudocodice:
O := emptyset;
WHILE I is not empty DO BEGIN
let r be any record in I;
find, if possible, some record s in O that is similar to r;
IF no record s exists THEN
move r from I to O
ELSE BEGIN
delete r from I;
delete s from O;
add the merger of r and s to I;
END; END;
Attenzione: per utilizzare l'algoritmo bisogna dimostrare le proprietà per ≈ e ⊕.
Problema: se la funzione ⊕ non rispetta le proprietà?
Soluzione: si definisce una dominance relation r
(contiene) e perciò si può ignorare r .
≤ s nella quale s contiene tutte le informazioni di r
Data mining
Molte volte si hanno a disposizione dati non strutturati o per i quali si hanno poche informazioni preliminari
(prior), ma si vogliono fare delle analisi per scoprire importanti relazioni o inferire nuove informazioni. Il
data-mining si occupa di questo.
Frequent itemset mining
Problema: Abbiamo un insieme di oggetti venduti da un negozio e una serie di transazioni, ossia oggetti
comperati da utenti in un singolo acquisto. È possibile trovare quali oggetti vengono comperati insieme più
frequentemente? Questo problema è detto association rule mining.
Assumiamo di avere un insieme di  oggetti e uno B di transazioni. Vogliamo trovare tutte le regole del tipo
I ⇒ i , dove i ∈  e I ⊆  .
Definiamo una nozione di "frequenza" basata sul supporto, che misura quante volte un sottoinsieme di
oggetti compare nelle transazioni degli utenti. Diciamo che un insieme di oggetti è frequente se ha un
supporto maggiore di un s fissato.
Definiamo inoltre la confidenza di una regola I
contengono I.
⇒ i come la probabilità di trovare i negli insiemi che
Problema: come trovare efficientemente tutte le regole che abbiano un minimo supporto
confidenza c?
Soluzione:
s e una minima
Soluzione naive
SELECT I.item, J.item, C0UNT(I.basket)
FROM Baskets I, Baskets J
WHERE I.basket = J.basket AND
I.item < J.item
GROUP BY I.item, J.item
HAVING COUNT(I.basket) >= s;
Chiaramente richiede troppe comparazioni e potrebbe generare regole poco interessanti.
Algoritmo A-priori
Sfrutta il risultato teorico che la frequenza è antimonotona, ovvero: i sottoinsiemi di un insieme frequente
sono insiemi frequenti.
Ecco lo pseudo-pseudo codice (nelle slide ne è presente uno più formale):
1. Sia C1 l'insieme degli itemset frequenti con un item.
2.
i=1
3. Per ogni (a, b)
1.
4.
∈ Ci
Ci+1 contiene tutti gli a ∪ b frequenti,
i = i + 1 e riparti da 3. finché Ci+1 ≠ ∅
Nota: A livello di implementazione l'algoritmo può essere ottimizzato con strutture dati intelligenti.
Attenzione: L'algoritmo genera itemset frequenti, non regole frequenti. Per generare regole frequenti
bisogna aggiungere anche una confidenza minima e considerare le sole regole che hanno una confidenza
minima.
L'algoritmo si può ottimizzare utilizzando hashing: una funzione di hash viene sfruttata per produrre dei
bucket tra coppie di oggetti negli item frequenti. Si mantiene un unico contatore di frequenza nel
bucket. Se il contatore è sotto una soglia allora gli item non sono frequenti e possiamo eliminarli,
altrimenti non possiamo concludere nulla. Per trovare gli itemset frequenti possiamo eseguire A-priori
sugli insiemi di item già ridotti dopo hashing.
Trovare oggetti simili
Una semplice metrica per definire la similarità tra insiemi di oggetti è Jaccard, che rappresenta la
percentuale di oggetti condivisi. Siano dati due insiemi S, T :
Jaccard(S, T) =
|S ∩ T|
|S ∪ T|
La misura Jaccard per quanto semplice è utile per:
1. Suggerire oggetti da acquistare ad utenti trovando oggetti, o utenti simili (recommending systems).
2. Se rappresentati come insiemi di parole o insiemi di n-grammi, trovare documenti simili.
3. Trovare la distanza semantica tra due ricerche su un motore di ricerca confrontando i risultati.
Problema: computare Jaccard per insiemi grandi è computazionalmente costoso.
Soluzione: approssimare Jaccard con un hash "furbo": min-hashing o locality sensitive hashing.
Min-hashing
n elementi e si prenda una permutazione casuale ma fissa dei suoi elementi. Il minhash di un insieme S è definito come il primo elemento degli elementi permutati che è membro di S.
Sia dato un insieme di
Per esempio, sia {1, 2, 3, 4, 5 } l'insieme di elementi e (2, 5, 1, 4, 3 ) una sua permutazione fissa. * Il minhash di {5,2,3} è 2 (primo elemento nella permutazione presente nell'insieme)
Nota: di per sé è una soluzione debole, ma se si effettuano m permutazioni si possono prendere i primi
m numeri in ogni permutazione come firma dell'insieme, aumentandone quindi il potere espressivo.
Perché funziona? Se la permutazione è casuale calcolare il min-hash è come selezionare un sottoinsieme
a caso di due insiemi e confrontarlo. Il sotto-insieme nel min-hash è generato però in entrambi gli insiemi
dallo stesso insieme di permutazione. Queste tecniche randomizzate infatti funzionano perché il valore
atteso si avvicina al valore statistico da misurare (ossia Jaccard in questo caso).
Se prendiamo una permutazione casuale, la probabilità che produca lo stesso minhash per due insiemi
diversi è uguale a Jaccard.
Quindi possiamo approssimare Jaccard con min-hash!
Problema: anche calcolare una permutazione è dispendioso.
Soluzione: utilizzare un insieme di funzioni di hash h con B bucket per calcolare un'approssimazione
delle permutazioni e risolvere le collisioni (una collisione è una coppia di elementi
h(x) = h(x′ ) in qualche modo).
x ≠ x′ tali che
Algoritmo min-hash
Sia dato un insieme S di
n elementi, una funzione di hash h e un numero M > n. L'idea è di iterare per tutti
gli elementi e trovare l'elemento S con hash minimo.
V := M;
for i := 1 to n do
if h(ai) < V then
V := h(ai);
Nota: si può ripetere la stessa idea per
diverse funzioni di hash.
Nota: si può ripetere la stessa idea per m diverse funzioni di hash.
Nota: L'hash approssima una permutazione.
Locality Sensitive Hashing
Si sfrutta un'hashing function tale per cui coppie di documenti simili finiscano nello stesso bucket con
alta probabilità.
Una volta computati i min-hash di ogni insieme (tupla) si possono dividere in b bande di uguale
dimensione, ognuna contenente r valori.
Sia s la distanza di Jaccard tra due insiemi, con un'analisi teorica si può calcolare che la probabilità
che i documenti concordino su tutte le righe di almeno una banda è 1 − (1 − sr )b .
Clustering
Metodi per trovare e raggruppare oggetti simili. Sono basati su nozioni di distanza in spazi n dimensionali,
ogni punto dello spazio rappresenta un oggetto6.
Due approcci principali al clustering: * Agglomerativo o gerarchico: dato un insieme di cluster si tenta di
unire (merge) cluster di oggetti simili * Point assignemnt: dopo aver assegnato i punti ad un insieme di
cluster si tenta di assegnarli al cluster più vicino in modo tale da aumentare la qualità dei raggruppamenti.
Gli algoritmi di clustering dipendono dalla misura di distanza. Dati due oggetti qualsiasi x e
y una funzione
di distanza d(x, y) deve soddisfare: * d(x, y) ≥ 0 : non negatività * d(x, y) = 0 se e soltanto se x = y :
assioma di coincidenza * d(x, y) = d(y, x) : simmetria * d(x, y) ≤ d(x, z) + d(z, y) per ogni x, y, z :
disuguaglianza triangolare
Un'importante misura di distanza è la Lr -norm, definita come
d(x, y) =
n
∣xi − yi∣ r
∑
(
)
1/r
i=1
da cui derivano la Manhattan distance (L1-norm) e la euclidian distance (L2-norm).
Un'altra importante misura è la distanza di Jaccard (è facile provare che è una metrica):
d(x, y) = 1 − J(x, y)
Nell'ambito dell'information retrieval una misura particolarmente interessante è la cosine distance che
misura l'angolo tra due vettori (è massima quando l'angolo tra di loro è di 90º). La distanza coseno è
definita come:
d(x, y) = 1 −
x⋅y
d(x, y) = 1 −
dove x ⋅ y è il prodotto scalare tra x e y e
x⋅y
‖x‖‖y‖
‖x‖ indica la norma del vettore x.
Altre misure: Edit distance (stringhe), Hamming distance (booleani).
Attenzione: gli oggetti sono tipicamente rappresentati da vettori in uno spazio multidimensionale. Se il
numero di dimensioni è elevato (e tende ad infinito) allora la media delle distanze tra due oggetti a caso
tende a 1. Questo fenomeno è conosciuto col nome di "curse of dimensionality".
Clustering agglomerativo
Famiglia di algoritmi molto semplici:
1. Si parte da un iniziale assegnamento dei punti a cluster
2. Finché non si raggiunge la condizione di stop
1. Unire i due cluster più vicini
Nota: il risultato del clustering agglomerativo, molte volte è un albero ottenuto dall'unione di cluster.
Distanza/unione di cluster
Si può definire in molti modi
minimo tra le distanze dei punti tra due cluster
distanza media tra i punti dei cluster
n punti è il punto ottenuto dalla media delle coordinate di
ogni punto. Sia per esempio A = (x1 , y 1 ) e B = (x2 , y 2 ), allora il centroide sarà
C = ((x1 + x2 )/2, (y1 + y2 )/2)
distanza tra i centroidi, dove il centroide di
definito il raggio di un Cluster come la distanza del punto più distante dal centroide, si uniscono i due
cluster che risultano nel raggio minimo
definito diametro come la distanza massima tra due punti di un cluster, si uniscono i due cluster che
risultano nel diametro minimo
Condizioni di stop
In base alla distanza si possono definire molte condizioni di stop. * Dato in input k , ci si ferma quando si
ottengono k cluster. * Si continua finché non si ottiene un singolo cluster * La coesione (distanza media tra i
punti) del cluster non è maggiore di una certa soglia. * Il diametro del cluster ottenuto dall'unione supera
una determinata soglia. * Fermarsi quando la densità del cluster unione (il migliore) è sotto una certa soglia.
La densità può essere definita come il numero di punti diviso una certa potenza del raggio.
Problema: Cosa succede se lo spazio non è euclideo e quindi non possiamo trovare un centroide per il
cluster?
Soluzione: Possiamo prendere il punto del cluster che minimizzi la somma/massimo/somma quadratica
Soluzione: Possiamo prendere il punto del cluster che minimizzi la somma/massimo/somma quadratica
delle distanze da sé stesso. Questo punto si chiama clustroide.
Point assignment clustering
k-means
k-means è il più famoso algoritmo per clustering a punti, dove k è il numero di clustering che deve essere
prodotto (è un parametro in input).
1. Scegli k punti iniziali come cluster
2. Assegna i centroidi ai punti scelti in 1.
3. Finche i centroidi cambiano
* per ogni altro punto p
* trova il centroide c del cluster più vicino
* aggiungi p a c
* ricalcola il centroide del cluster
Attenzione: la qualità dei cluster in alcuni casi dipende dalla scelta dei punti d'inizio.
Inizializzare i cluster
Un modo per inizializzare i cluster è di scegliere punti che sono il più distante possibile tra loro. Ecco un
possibile algoritmo per la scelta dei punti
1. Scegli il primo punto a random
2. Finché non sono stati scelti k punti
* Scegli il punto il quale ha distanza minima con i punti già scelti massima.
Alternativamente si può fare clustering di un campione di punti tale per cui ci siano
k cluster e prendere i
punti tra di loro più vicini al centroide del cluster.
Problema: k deve essere conosciuto in anticipo.
Soluzione: Adottare una misura per la qualità dei cluster (per esempio il diametro medio) e fare ripetute
prove con k
= 1, 2, 4, . . . finché non si trova il miglior k
Algoritmo BFR
Problema: I dati non riescono ad essere caricati tutti in memoria
Soluzione: partizionare e caricare i dati in memoria e mantenere statistiche dei cluster e degli altri dati.
Nota: si assumono dati distribuiti normalmente (e quindi si deve conoscere media e varianza)
1. Seleziona k punti iniziali
2. Leggi i dati in memoria in chunk (partizioni)
3. Mantieni statistiche dei dati e dei cluster
4. I punti sono divisi in:
Discard set: punti già assegnati ad un cluster che non richiedono di essere in memoria
Compressed set: punti vicini ad altri che si credono appartenere allo stesso cluster, ma non vicini
abbastanza al centroide (rappresentati come statistiche)
Retained set: non sono vicini a nessun altro punto (stanno in memoria)
Dato che bisogna calcolare media e varianza, per ogni set bisogna mantenere:
1. Il numero di punti
2. La somma per componente (ricordati che siamo in uno spazio multidimensionale) di ogni punto. Per
esempio se si hanno due punti (x1, y1) e (x2, y2) si memorizza
(x1 + x2, y1 + y2)
3. La somma per componente dei quadrati (per il calcolo della varianza).
Nota: per calcolare i centroidi basta usare la statistica al punto 2. e dividere per il numero di punti!
OLAP
OLAP significa (On-Line Analytic Processing) e si intende un insieme di tecniche per esaminare dati alla
ricerca di pattern o trend.
OLAP richiede query molto complesse (esempio, join multipli) e aggregati (avg, max, min) per poter
calcolare statistiche ecco perché si mantiene copie dei dati nelle data warehouse che vengono aggiornate
tipicamente una volta al giorno (di notte).
Considera la seguente query su tre tabelle diverse: se i dati sono tanti potrebbe impiegare molto tempo in
quanto analizza la gran parte del database.
SELECT state, AVG(price)
FROM Sales,Dealers
WHERE Sales.dealer = Dealers.name AND
date >= "2006-­‐01-­‐04"
GROUP BY state; Data cube
Immaginiamo di avere i dati organizzati in uno spazio multi-dimensionale (un cubo per semplicità). Ogni
punto rappresenta una tupla ottenuta attraverso tutte le join delle tabelle di un database. La tabella che
contiene i punti si chiama fact table. Immagina una vendita nell'esempio precedente rappresentata dalla
tripla (macchina, dealer, data).
Due tipi di data cube: * raw data cube: un modo per visualizzare i dati originali in modo diverso, nessun
dato o ottimizzazione viene memorizzata * formal data cube: i punti potrebbero già rappresentare
un'aggregazione di dati (vendite totali o modello) e vengono materializzati in un cubo vero e proprio.
Schema a stella
Al centro della stella c'è la fact table collegata a delle dimension tables che rappresentano una un attributo
o un aggregato. Le dimensioni possono essere il numero di macchine vendute, il metodo di pagamento e
così via. Ci possono essere alcuni attributi dipendenti che rappresentano dei valori vincolati alla scelta delle
dimensioni (per esempio il costo).
Per esempio
Fact table: Sales(serialNo, date, dealer, price)
Dimensioni: serialNo, date, dealer (sono chiavi esportate per una dimension table)
Attributo dipendente: price
Dimesion tables: Autos(serialNo, model, color), Dealers(name, city, state, phone) e date? Per date si
immagina una tabella virtuale Date(day, weerk, month, year)
Slicing e dicing
SELECT e GROUP BY si focalizzano su parti del cubo (dice) attraverso la proiezioni di dati nelle diverse
dimensioni (per esempio il modello di macchina, il colore).
Nota: Si può dividere il cubo i cubi più piccoli e calcolare degli aggregati.
Slicing si riferisce alla clausola WHERE che restringe e partiziona i dati.
La forma generale di query "slicing and dicing" è la seguente:
SELECT <grouping attributes and aggregations>
FROM <fact table joined with some dimension tables>
WHERE <certain attributes are constant>
GROUP BY <grouping attributes > ;
Un esempio: ~~~sql SELECT color, month, SUM(price) FROM (Sales NATURAL JOIN Autos) JOIN Days
ON date = day WHERE model = "Gobi" GROUP BY color, month; ~~~ queste query permettono analisi dei
dati in profondità, come chiedersi se alcuni modelli di macchine particolari non sono state vendute e
perché.
Data cube formale
Si memorizzano dati riguardanti gli aggregati di determinate dimensioni o valori. Non è richiesta
genericamente troppa memoria fisica. Nell'esempio delle macchine, invece di rappresentare il numero
seriale, si può memorizzare il modello e il numero di vendite totali per modello.
CUBE(F): è un operatore sulla fact table F che aggiunge un "*" a ogni dimensione. Vuol dire proiettare i
valori del data cube su una particolare "faccia" o spigolo per poter costruire fisicamente il cubo.
Prendiamo per esempio: ~~~ Sales(model, color, date, dealer, value, count) ~~~ dove value è la somma di
tutti i prezzi per un dato modello, colore, data e dealer; count è il numero di auto vendute. CUBE(Sales)
contiene esattamente tutte le tuple che hanno lo schema della fact table.
Nota: con value e count possiamo calcolare la media dei valori!
La tupla
~~~ (Gobi, *, 2001-05-21, Friendly Fred, 152000, 7) ~~~
rappresenta la somma e il valore delle macchine vendute di tipo Gobi, in data 2001-05-21, dal venditore
Friendly Fred ⇒ un'aggregazione in Sales è divenuta una semplice SELECT (notare che è molto semplice
da scrivere) su CUBE(Sales).
In SQL attraverso la sintassi GROUP BY ... WITH CUBE
CREATE MATERIALIZED VIEW SalesCube AS
SELECT model, color, date, dealer, SUM(val), SUM(cnt)
FROM Sales
GROUP BY model, color, date, dealer WITH CUBE;
Internet
Il web contiene enormi quantità di informazioni che devono essere indicizzate e ordinate da motori di
ricerca (quali Google), che hanno bisogno di costruire statistiche e ordinamenti sui documenti memorizzati.
Un motore di ricerca deve essere in grado di rispondere a query in linguaggio naturale (e quindi ambiguo)
in tempi rapidi e con alta precisione.
Tutto questo è reso possibile da programmi detti crawler che ritrovano, spezzano e indicizzano le
informazioni nei documenti contenuti in siti web aventi particolari indirizzi (URL).
Dato un insieme S di URL da analizzare, per produrre un repository R di pagine, un crawler: ~~~ 1. Sceglie
una pagina p dall'insieme S. 2. Scarica la pagina p e controlla se è già in R. 3. Se p non è in R: 1. Aggiunge
p a R. 2. Aggiunge ad S i link uscenti di p se non sono già in R o S. 3. Ripete 1.
~~~
Problema: Per costruire un crawler servono diversi accorgimenti. * Come terminare la ricerca: limite
sulle pagine da analizzare oppure limite sulla profondità. * Come trovare pagine già presenti in S o R: si
può usare hashing sulle pagine anche in forma efficiente (min-hash con locality sensitive hashing). *
Selezionare la pagina p da analizzare: - random oppure - con una coda (breadth first search sul grafo
web), - stima dell'importanza della pagina. * Velocizzare il crawling: parallelizzazione in diverse macchine.
Rispondere a query
Problema: le query sono in linguaggio naturale e non in SQL.
Soluzione: Indicizzazione: usare uno speciale indice inverso (per ogni parola, la lista dei documenti che
la contiene).
Problema: come ordinare i risultati?
Soluzione: Ranking functions che prendono in considerazione diversi fattori come: la presenza delle
parole chiave della query, presenza delle parole in parti importanti della pagina, autorevolezza della pagina,
attualità della pagina ...
PageRank
Algoritmo creato da S. Brin e L. Page, ha rivoluzionato il modo di assegnare valori di importanza alle pagine
e ha influenzato enormemente la qualità dei motori di ricerca.
È basato sul concetto di link: più pagine importanti si riferiscono (attraverso un link) ad una pagina, più la
pagina a sua volta sarà importante. In qualche modo la definizione è ricorsiva.
PageRank: è un numero che rappresenta l'importanza di una pagina.
Il Web viene rappresentato come un grafo diretto: i nodi sono le pagine e un arco da una pagina ad un'altra
indica un link tra di esse.
Immaginiamo un random walker che sta navigando su pagine web, partendo da un punto e muovendosi
seguendo solamente i link che trova nelle varie pagine. Supponiamo di ripetere questo processo moltissime
volte e di calcolare la frequenza con cui il walker si è trovato su una pagina. Questo valore (normalizzato
per trasformarlo in probabilità) rappresenta il PageRank.
Formalmente: * Il web è rappresentato da un grafo diretto in una matrice di transizione. * n pagine
numerate da 1 a n. * La matrice di transizione è una matrice M n × n tale per cui la cella: * mij
pagina j è collegata i e a
r ≥ 1 pagine in totale. * mij = 0, altrimenti.
=
1
r se
j la
Nota: per definizione la somma dei valori di una singola colonna è sempre 1.
Algoritmo (sketch)
Supponiamo che il walker parta da una qualsiasi delle pagine con equi-probabilità (cioè 1/n ). Il vettore
del PageRank iniziale v 0 avrà quindi ogni componente assegnato a 1/n .
Dopo ogni passo la distribuzione del walker sarà M ⋅ v 0 , in quanto con probabilità proporzionale ai link
uscenti compirà un passo nel grafo.
Al passo t il vettore sarà uguale a M t
⋅ v0 .
Si può dimostrare che questo processo converge sotto particolari condizioni dei processi di Markov ad
un vettore stazionario v
M.
La soluzione
= M ⋅ v . Si può notare come questo vettore sia un autovettore della matrice
v di questa equazione è il PageRank.
Problema: calcoli su matrici gigantesche, quale quella del Web, sono troppo dispendiosi.
Soluzione: parallelizzare la computazione e calcolare un'approssimazione dividendo la matrice in
Soluzione: parallelizzare la computazione e calcolare un'approssimazione dividendo la matrice in
sottomatrici (componenti connesse o fortemente connesse del grafo oppure clique) e calcolando il
pagerank nelle sottomatrici.
Altre soluzioni usano "Map/Reduce" per fare la moltiplicazione di matrici riga × colonna in maniera parallela
e poi unire i risultati.
Nota: Il web è caratterizzato da una componente fortemente connessa e da pagine che entrano in
questa (ma non raggiungibili da esse) e pagine che escono e non possono tornarvi. Se un walker esce
dalla componente, allora le pagine in essa avranno PageRank 0, in quanto non potrà più tornare, queste
sono le famose "spider-traps" e "dead-ends"
Problema: Come risolvere il problema delle spider-traps?
Soluzione: (1) togliere i dead-ends dal grafo ricorsivamente (non ideale) (2) cambiare il modello di
movimento del random walker (teleporting).
Teleporting
Il random walker può occasionalmente saltare ad una pagina a caso.
v = βM ⋅ v + (1 − β)e/n
β è una costante tra 0.8 e 0.9 (0.85 genericamente accettato).
e è un vettore di n elementi tutti uguali a 1 (in realtà può essere anche utilizzato come vettore di
partenza o di personalizzazione).
(1 − β)e/n è la probabilità di tornare a una delle pagine che sono settate a 1 nel vettore (in buona
sostanza è un modo per evitare le trappole).
Altri modelli alternativi al PageRank
Per argomento: il page rank può essere calcolato per pagine di un determinato argomento (si può
usare il vettore di personalizzazione e e porre a 1 le sole pagine di un argomento).
Trust-rank: introdurre un concetto di "pagine fidate" nel modello.
Hubs-Authorities: ci sono pagine che parlano di un argomento (authorities) e pagine che contengono
link per le pagine che parlano di argomento (hubs). Una pagina è un buon hub se è collegato a buone
authorities ed è una buona authority se è raggiungibile da un buon hub.
Risolvere il problema dei link spam
Problema: Un potenziale spammer è in grado di costruire pagine collegate a pagine "oneste" le quali
pagine sono collegate a soli link di spam.
La target page t è una pagina costruita ad-hoc dallo spammer e viene linkata da siti noti (ad esempio forum
di discussione) e collegata a m altre pagine di spam. Le pagine collegate a t sono collegate solo ad essa.
Se si assume y il PageRank della pagina t allora si ottiene (risolvendo per y e omettendo i passaggi:
y=
x
1 − β2
+c
m
n
il che potrebbe essere una frazione significativa anche solo con β
c=
β
1+β
= .85 , infatti 1/(1 − β2 ) = 3.6 e
= .45 . Significa che y dipende al 360% (3.6) dal valore delle pagine esterne (perché moltiplica x)
e al 45% dal rapporto di pagine interne! Questo è un problema.
Soluzione: riconoscere e rimuovere le spam farm, adattare il PageRank a questa minaccia (attraverso
pagine fidate) oppure calcolare la massa di spam data dal PageRank r e dal TrustRank t nella formula
(r − t)/r .
Pubblicizzare prodotti
Banner, link sponsorizzati, pubblicità nei siti sono importanti metodi per pubblicizzare la propria azienda o i
propri prodotti.
Problema: come presentare il banner in base alle informazioni nella pagina o ad una particolare ricerca
dell'utente?
Nota: effettuare il ranking dei link di pubblicità è difficile perché non si può usare PageRank (link non
presenti).
Ranking
Ordinare i più recenti per primi.
Attractiveness: metrica basata sul numero di click (però ads più rari saranno sempre più bassi in
classifica e quindi mai clickati).
Gli algoritmi per ranking possono essere on-line e off-line anche se poche informazioni possono essere
calcolate in anticipo (off-line).
Attenzione: gli algoritmi offline sono spesso inutilizzabili praticamente perché bisogna avere a
disposizione i bid (puntate) di ogni advertiser per ogni query e calcolare il guadagno massimo e il numero di
volte che l'annuncio è mostrato. Questi algoritmi producono la soluzione ottima ma sono inutilizzabili.
Gli algoritmi online producono invece risultati in base alla query dell'utente e in base ad informazioni
passate e click (personalizzazione), cercando di predire il funzionamento dell'algoritmo offline.
Gli algoritmi online sono perlopiù greedy e quindi compiono una scelta "localmente" ottima. Possono ogni
volta selezionare l'oggetto con il più alto competitive ratio (il rapporto tra il risultato di un algoritmo rispetto
al migliore algoritmo off-line).
Adwords
Dopo il 2000, è nato il concetto di bid sulle parole. Ad ogni parola usata nelle query i venditori possono fare
una sorta di puntata, in questo modo l'annuncio pubblicitario può venire pubblicato e se viene cliccato il
venditore deve pagare.
Formalmente:
Un insieme di bid per ogni advertiser per particolari query.
Il numero di click alla pubblicità per ogni query.
Un budget per ogni advertiser.
Un limite al numero di annunci visualizzabili.
Problema: trovare l'insieme di annunci massimo (in base al limite) tale per cui il budget per advertiser
sia massimo e sia massimizzata la puntata (bid).
Soluzione: Si misura: * la revenue, ossia il valore totale degli annunci selezionati. * il valore dato dal
prodotto del numero di click e dalla puntata. * il merito, che è la somma mensile della revenue.
Si tenta di massimizzare la competitive ratio data dal revenue minimo dell'algoritmo per una sequenza di
query, diviso il valore ottimo dell'algoritmo off-line.
Un semplice algoritmo greedy
Semplifichiamo: un solo annuncio mostrato, tutti gli advertiser con lo stesso budget, il numero di click è
uguale, le puntate sono 0 o 1.
L'algoritmo prende, per ogni query, un qualsiasi advertiser che ha bid a 1 per quella query.
Attenzione: Il competitive ratio è 1/2 in quanto un algoritmo del genere non si cura di fare la scelta in
base a ciò che condizionerà nel futuro. Se due bidder hanno budget 2, ma il primo ha bid su una query, il
secondo su una query e un'altra, è possibile che il secondo advertiser consumi il budget sulla prima query e
quando arriva la seconda nessuna dei due può rispondere.
Balance algorithm
Questo algoritmo assegna ad una query all'advertiser che ha bid sulla query e ha il budget rimanente
massimo (in questo modo si previene il problema precedente, in parte).
Questo algoritmo, nel modello semplificato, ha un competitive ratio di 3/4.
L'algoritmo può essere generalizzato se i bid non sono solo 0 e 1 in questo modo: * prediligiamo sempre
bid più alti. * siamo più flessibili sul budget considerando la parte del budget rimanente per ogni advertiser.
Supponiamo che un particolare advertiser A ha una puntata x su una query q e che f sia la parte di budget
non spesa di A.
x(1 −
f)
Assegnamo la query
q all'advertiser A che massimizza x(1 − ef ) .
1
Competitive ratio: si può dimostrare un competitive ratio di 1 − e
≈ 0.63 .
1. W3C XML Recommendation ↩
2. Verranno usati alla stessa maniera query e interrogazione, anche se il termine inglese ha un'accezione
più specifica e tecnica. ↩
3. W3C XPath Recommendation ↩
4. W3C XQuery casi d'uso ↩
5. W3C XSLT Recommendation ↩
6. I gruppi sono detti anche cluster. ↩