7.2. Conjuntos de datos del mundo real¶
scikit-learn proporciona herramientas para cargar conjuntos de datos más grandes, descargándolos si es necesario.
Se pueden cargar mediante las siguientes funciones:
|
Carga el conjunto de datos de caras Olivetti de AT&T (clasificación). |
|
Carga los nombres de archivo y los datos del conjunto de datos de 20 grupos de noticias (clasificación). |
|
Carga y vectoriza el conjunto de datos de 20 grupos de noticias (clasificación). |
|
Carga el conjunto de datos de personas Labeled Faces in the Wild (LFW) (clasificación). |
|
Carga el conjunto de datos de pares Labeled Faces in the Wild (LFW) (clasificación). |
|
Carga el conjunto de datos de covertype (clasificación). |
|
Carga el conjunto de datos multietiqueta RCV1 (clasificación). |
|
Carga el conjunto de datos kddcup99 (clasificación). |
|
Carga el conjunto de datos de viviendas de California (regresión). |
7.2.1. El conjunto de datos de caras Olivetti¶
Este conjunto de datos contiene un conjunto de imágenes faciales tomadas entre abril de 1992 y abril de 1994 en AT&T Laboratories Cambridge. La función sklearn.datasets.fetch_olivetti_faces
es la función de obtención/almacenamiento en caché de datos que descarga el archivo de datos de AT&T.
Como se describe en el sitio web original:
Hay diez imágenes diferentes de cada uno de los 40 sujetos distintos. En el caso de algunos sujetos, las imágenes se tomaron en diferentes momentos, variando la iluminación, las expresiones faciales (ojos abiertos/cerrados, sonriendo/no sonriendo) y los detalles faciales (con lentes/sin lentes). Todas las imágenes se tomaron sobre un fondo oscuro homogéneo, con los sujetos en posición vertical y frontal (con tolerancia para algún movimiento lateral).
Características del Conjunto de Datos:
Clases
40
Total de muestras
400
Dimensionalidad
4096
Características
real, entre 0 y 1
La imagen se cuantifica en 256 niveles de gris y se almacena como enteros de 8 bits sin signo; el cargador los convertirá en valores de punto flotante en el intervalo [0, 1], que son más fáciles de trabajar para muchos algoritmos.
El «target» para esta base de datos es un número entero de 0 a 39 que indica la identidad de la persona fotografiada; sin embargo, con sólo 10 ejemplos por clase, este conjunto de datos relativamente pequeño es más interesante desde una perspectiva no supervisada o semisupervisada.
El conjunto de datos original constaba de 92 x 112, mientras que la versión disponible aquí consta de 64x64 imágenes.
Al utilizar estas imágenes, por favor, dar crédito a AT&T Laboratories Cambridge.
7.2.2. El conjunto de datos de texto de 20 grupos de noticias¶
El conjunto de datos de 20 grupos de noticias comprende unos 18000 posts de grupos de noticias sobre 20 temas divididos en dos subconjuntos: uno para el entrenamiento (o desarrollo) y el otro para pruebas (o para la evaluación del rendimiento). La división entre el conjunto de entrenamiento y el de prueba se basa en los mensajes publicados antes y después de una fecha específica.
Este módulo contiene dos cargadores. El primero, sklearn.datasets.fetch_20newsgroups
, devuelve una lista de los textos en bruto que pueden ser alimentados a extractores de características de texto como CountVectorizer
con parámetros personalizados para extraer vectores de características. El segundo, sklearn.datasets.fetch_20newsgroups_vectorized
, devuelve características listas para usar, es decir, no es necesario utilizar un extractor de características.
Características del Conjunto de Datos:
Clases
20
Total de muestras
18846
Dimensionalidad
1
Características
texto
7.2.2.1. Uso¶
sklearn.datasets.fetch_20newsgroups
es una función de obtención / almacenamiento en caché de datos que descarga el archivo de datos del sitio web original de 20 newsgroups, extrae el contenido del archivo en la carpeta ~/scikit_learn_data/20news_home
y llama a la función sklearn.datasets.load_files
en la carpeta del conjunto de entrenamiento o de pruebas, o en ambas:
>>> from sklearn.datasets import fetch_20newsgroups
>>> newsgroups_train = fetch_20newsgroups(subset='train')
>>> from pprint import pprint
>>> pprint(list(newsgroups_train.target_names))
['alt.atheism',
'comp.graphics',
'comp.os.ms-windows.misc',
'comp.sys.ibm.pc.hardware',
'comp.sys.mac.hardware',
'comp.windows.x',
'misc.forsale',
'rec.autos',
'rec.motorcycles',
'rec.sport.baseball',
'rec.sport.hockey',
'sci.crypt',
'sci.electronics',
'sci.med',
'sci.space',
'soc.religion.christian',
'talk.politics.guns',
'talk.politics.mideast',
'talk.politics.misc',
'talk.religion.misc']
Los datos reales se encuentran en los atributos filenames
y target
. El atributo target es el índice entero de la categoría:
>>> newsgroups_train.filenames.shape
(11314,)
>>> newsgroups_train.target.shape
(11314,)
>>> newsgroups_train.target[:10]
array([ 7, 4, 4, 1, 14, 16, 13, 3, 2, 4])
Es posible cargar sólo una sub-selección de las categorías pasando la lista de las categorías a cargar a la función sklearn.datasets.fetch_20newsgroups
:
>>> cats = ['alt.atheism', 'sci.space']
>>> newsgroups_train = fetch_20newsgroups(subset='train', categories=cats)
>>> list(newsgroups_train.target_names)
['alt.atheism', 'sci.space']
>>> newsgroups_train.filenames.shape
(1073,)
>>> newsgroups_train.target.shape
(1073,)
>>> newsgroups_train.target[:10]
array([0, 1, 1, 1, 0, 1, 1, 0, 0, 0])
7.2.2.2. Convertir texto en vectores¶
Para alimentar modelos predictivos o de análisis de conglomerados con los datos de texto, primero hay que convertir el texto en vectores de valores numéricos adecuados para el análisis estadístico. Esto se puede lograr con las utilidades de sklearn.feature_extraction.text
como se demuestra en el siguiente ejemplo que extrae vectores TF-IDF de tokens de unigramas de un subconjunto de 20news:
>>> from sklearn.feature_extraction.text import TfidfVectorizer
>>> categories = ['alt.atheism', 'talk.religion.misc',
... 'comp.graphics', 'sci.space']
>>> newsgroups_train = fetch_20newsgroups(subset='train',
... categories=categories)
>>> vectorizer = TfidfVectorizer()
>>> vectors = vectorizer.fit_transform(newsgroups_train.data)
>>> vectors.shape
(2034, 34118)
Los vectores TF-IDF extraídos son muy dispersos, con un promedio de 159 componentes distintos de cero por muestra en un espacio de más de 30000 dimensiones (menos del 0.5% de características distintas de cero):
>>> vectors.nnz / float(vectors.shape[0])
159.01327...
sklearn.datasets.fetch_20newsgroups_vectorized
es una función que devuelve características de conteo de tokens listas para usar en lugar de nombres de archivos.
7.2.2.3. Filtrar el texto para un entrenamiento más realista¶
Es fácil que un clasificador se sobreajuste a cosas particulares que aparecen en los datos de 20 Newsgroups, como los encabezados de los grupos de noticias. Muchos clasificadores consiguen puntuaciones F muy altas, pero sus resultados no se generalizarían a otros documentos que no son de esta ventana de tiempo.
Por ejemplo, veamos los resultados de un clasificador multinomial Naive Bayes, que es rápido de entrenar y consigue una puntuación F decente:
>>> from sklearn.naive_bayes import MultinomialNB
>>> from sklearn import metrics
>>> newsgroups_test = fetch_20newsgroups(subset='test',
... categories=categories)
>>> vectors_test = vectorizer.transform(newsgroups_test.data)
>>> clf = MultinomialNB(alpha=.01)
>>> clf.fit(vectors, newsgroups_train.target)
MultinomialNB(alpha=0.01, class_prior=None, fit_prior=True)
>>> pred = clf.predict(vectors_test)
>>> metrics.f1_score(newsgroups_test.target, pred, average='macro')
0.88213...
(El ejemplo Clasificación de documentos de texto utilizando características dispersas revuelve los datos de entrenamiento y de prueba, en lugar de segmentar por tiempo, y en ese caso el Naive Bayes multinomial obtiene una puntuación F mucho más alta de 0.88. ¿Sospechas ya de lo que ocurre dentro de este clasificador?)
Veamos cuáles son las características más informativas:
>>> import numpy as np
>>> def show_top10(classifier, vectorizer, categories):
... feature_names = np.asarray(vectorizer.get_feature_names())
... for i, category in enumerate(categories):
... top10 = np.argsort(classifier.coef_[i])[-10:]
... print("%s: %s" % (category, " ".join(feature_names[top10])))
...
>>> show_top10(clf, vectorizer, newsgroups_train.target_names)
alt.atheism: edu it and in you that is of to the
comp.graphics: edu in graphics it is for and of to the
sci.space: edu it that is in and space to of the
talk.religion.misc: not it you in is that and to of the
Ahora puedes ver muchas cosas a las que estas características se han sobreajustado:
Casi todos los grupos se distinguen por el hecho de que encabezados como
NNTP-Posting-Host:
yDistribution:
aparecen con mayor o menor frecuencia.Otra característica significativa es si el remitente está afiliado a una universidad, como lo indican sus encabezados o su firma.
La palabra «article» es una característica significativa, basada en la frecuencia con la que la gente cita posts anteriores de esta manera: «In article [article ID], [name] <[e-mail address]> wrote:»
Otras características coinciden con los nombres y direcciones de correo electrónico de personas particulares que estaban publicando en ese momento.
Con tal abundancia de pistas que distinguen a los grupos de noticias, los clasificadores apenas tienen que identificar los temas a partir del texto en absoluto, y todos ellos rinden al mismo alto nivel.
Por esta razón, las funciones que cargan los datos de 20 Newsgroups proporcionan un parámetro llamado remove, que le indica qué tipo de información debe eliminar de cada archivo. remove debe ser una tupla que contenga cualquier subconjunto de ('headers', 'footers', 'quotes')
, indicándole que elimine las cabeceras, los bloques de firmas y los bloques de citas respectivamente.
>>> newsgroups_test = fetch_20newsgroups(subset='test',
... remove=('headers', 'footers', 'quotes'),
... categories=categories)
>>> vectors_test = vectorizer.transform(newsgroups_test.data)
>>> pred = clf.predict(vectors_test)
>>> metrics.f1_score(pred, newsgroups_test.target, average='macro')
0.77310...
Este clasificador perdió mucho de su puntuación F, sólo porque eliminamos metadatos que tienen poco que ver con la clasificación de temas. Pierde aún más si también eliminamos estos metadatos de los datos de entrenamiento:
>>> newsgroups_train = fetch_20newsgroups(subset='train',
... remove=('headers', 'footers', 'quotes'),
... categories=categories)
>>> vectors = vectorizer.fit_transform(newsgroups_train.data)
>>> clf = MultinomialNB(alpha=.01)
>>> clf.fit(vectors, newsgroups_train.target)
MultinomialNB(alpha=0.01, class_prior=None, fit_prior=True)
>>> vectors_test = vectorizer.transform(newsgroups_test.data)
>>> pred = clf.predict(vectors_test)
>>> metrics.f1_score(newsgroups_test.target, pred, average='macro')
0.76995...
Algunos otros clasificadores se adaptan mejor a esta versión más difícil de la tarea. Intenta ejecutar Ejemplo de pipeline para la extracción y evaluación de características de texto con y sin la opción --filter
para comparar los resultados.
Recomendación
Cuando se evalúan los clasificadores de texto en los datos de 20 Newsgroups, se deben eliminar los metadatos relacionados con los grupos de noticias. En scikit-learn, puedes hacerlo estableciendo remove=('headers', 'footers', 'quotes')
. La puntuación F será menor porque es más realista.
7.2.3. El conjunto de datos de reconocimiento facial Labeled Faces in the Wild¶
Este conjunto de datos es una colección de fotografías JPEG de personas famosas recopiladas en Internet; todos los detalles están disponibles en el sitio web oficial:
Cada imagen se centra en un solo rostro. La tarea típica se llama Verificación Facial: dado un par de fotografías, un clasificador binario debe predecir si las dos imágenes son de la misma persona.
Una tarea alternativa, el Reconocimiento Facial o la Identificación Facial es: dada la imagen de la cara de una persona desconocida, identificar el nombre de la persona haciendo referencia a una galería de imágenes previamente vistas de personas identificadas.
Tanto la Verificación Facial como el Reconocimiento Facial son tareas que suelen realizarse a partir de la salida de un modelo entrenado para realizar la Detección Facial. El modelo más popular para la Detección Facial se llama Viola-Jones y está implementado en la biblioteca OpenCV. Los rostros de LFW fueron extraídos por este detector de rostros de varios sitios web en línea.
Características del Conjunto de Datos:
Clases
5749
Total de muestras
13233
Dimensionalidad
5828
Características
real, entre 0 y 255
7.2.3.1. Uso¶
scikit-learn
proporciona dos cargadores que automáticamente descargarán, almacenarán en caché, analizarán los archivos de metadatos, decodificarán el jpeg y convertirán los cortes interesantes en arreglos numpy memmapped. Este conjunto de datos tiene un tamaño de más de 200 MB. La primera carga suele tardar más de un par de minutos en decodificar completamente la parte relevante de los archivos JPEG en arreglos numpy. Si el conjunto de datos ha sido cargado una vez, las próximas veces los tiempos de carga serán inferiores a 200ms utilizando una versión memmapped memorizada en el disco en la carpeta ~/scikit_learn_data/lfw_home/
utilizando joblib
.
El primer cargador se utiliza para la tarea de Identificación Facial: una tarea de clasificación multiclase (por tanto, aprendizaje supervisado):
>>> from sklearn.datasets import fetch_lfw_people
>>> lfw_people = fetch_lfw_people(min_faces_per_person=70, resize=0.4)
>>> for name in lfw_people.target_names:
... print(name)
...
Ariel Sharon
Colin Powell
Donald Rumsfeld
George W Bush
Gerhard Schroeder
Hugo Chavez
Tony Blair
El corte por defecto es una forma rectangular alrededor de la cara, eliminando la mayor parte del fondo:
>>> lfw_people.data.dtype
dtype('float32')
>>> lfw_people.data.shape
(1288, 1850)
>>> lfw_people.images.shape
(1288, 50, 37)
Cada una de las 1140
caras se asigna a un único id de persona en el arreglo target
:
>>> lfw_people.target.shape
(1288,)
>>> list(lfw_people.target[:10])
[5, 6, 3, 1, 0, 1, 3, 4, 3, 0]
El segundo cargador se utiliza normalmente para la tarea de Verificación Facial: cada muestra es un par de fotografías pertenecientes o no a la misma persona:
>>> from sklearn.datasets import fetch_lfw_pairs
>>> lfw_pairs_train = fetch_lfw_pairs(subset='train')
>>> list(lfw_pairs_train.target_names)
['Different persons', 'Same person']
>>> lfw_pairs_train.pairs.shape
(2200, 2, 62, 47)
>>> lfw_pairs_train.data.shape
(2200, 5828)
>>> lfw_pairs_train.target.shape
(2200,)
Tanto para la función sklearn.datasets.fetch_lfw_people
como para la función sklearn.datasets.fetch_lfw_pairs
es posible obtener una dimensión adicional con los canales de colores RGB pasando color=True
, en ese caso la forma será (2200, 2, 62, 47, 3)
.
Los conjuntos de datos sklearn.datasets.fetch_lfw_pairs
se dividen en 3 subconjuntos: el conjunto de desarrollo train
, el conjunto de desarrollo test
y un conjunto de evaluación 10_folds
destinado a calcular las métricas de rendimiento utilizando un esquema de validación cruzada de 10 pliegues (folds).
Referencias:
Labeled Faces in the Wild: A Database for Studying Face Recognition in Unconstrained Environments. Gary B. Huang, Manu Ramesh, Tamara Berg y Erik Learned-Miller. University of Massachusetts, Amherst, Technical Report 07-49, Octubre, 2007.
7.2.3.2. Ejemplos¶
Ejemplo de reconocimiento de rostros mediante eigenfaces y SVM
7.2.4. Tipos de cobertura forestal¶
Las muestras de este conjunto de datos corresponden a fragmentos de 30×30m de bosque en EE.UU., recopiladas para la tarea de predecir el tipo de cobertura de cada fragmento, es decir, las especies dominantes de árboles. Hay siete tipos de cobertura, por lo que se trata de un problema de clasificación multiclase. Cada muestra tiene 54 características, descritas en la página de inicio del conjunto de datos. Algunas de las características son indicadores booleanos, mientras que otras son medidas discretas o continuas.
Características del Conjunto de Datos:
Clases
7
Total de muestras
581012
Dimensionalidad
54
Características
int
sklearn.datasets.fetch_covtype
cargará el conjunto de datos covertype; devuelve un objeto dictionary-like “Bunch” con la matriz de características en el miembro data
y los valores objetivo en target
. Si el argumento opcional “as_frame” se establece en “True”, devolverá data
y target
como un marco de datos de pandas, y también habrá un miembro adicional frame
. El conjunto de datos se descargará de la web si es necesario.
7.2.5. Conjunto de datos RCV1¶
Reuters Corpus Volume I (RCV1) es un archivo de más de 800,000 noticias clasificadas manualmente que Reuters, Ltd. pone a disposición de los investigadores. El conjunto de datos se describe ampliamente en 1.
Características del Conjunto de Datos:
Clases
103
Total de muestras
804414
Dimensionalidad
47236
Características
real, entre 0 y 1
sklearn.datasets.fetch_rcv1
cargará la siguiente versión: RCV1-v2, vectores, conjuntos completos, temas multietiquetas:
>>> from sklearn.datasets import fetch_rcv1
>>> rcv1 = fetch_rcv1()
Devuelve un objeto dictionary-like, con los siguientes atributos:
data
: La matriz de características es una matriz dispersa CSR de scipy, con 804414 muestras y 47236 características. Los valores distintos de cero contienen vectores coseno-normalizados, log TF-IDF. En 1 se propone una división casi cronológica: Las primeras 23149 muestras son el conjunto de entrenamiento. Las últimas 781265 muestras son el conjunto de pruebas. Esto sigue la división cronológica oficial de LYRL2004. El arreglo tiene un 0.16% de valores distintos de cero:
>>> rcv1.data.shape
(804414, 47236)
target
: Los valores objetivo se almacenan en una matriz dispersa CSR de scipy, con 804414 muestras y 103 categorías. Cada muestra tiene un valor de 1 en sus categorías, y 0 en las demás. El arreglo tiene un 3.15% de valores distintos de cero:
>>> rcv1.target.shape
(804414, 103)
sample_id
: Cada muestra puede ser identificada por su ID, que oscila entre 2286 y 810596 (con brechas):
>>> rcv1.sample_id[:3]
array([2286, 2287, 2288], dtype=uint32)
target_names
: Los valores objetivo son los temas de cada muestra. Cada muestra pertenece al menos a un tema, y a un máximo de 17 temas. Hay 103 temas, cada uno representado por una cadena. Sus frecuencias en el corpus abarcan cinco órdenes de magnitud, desde 5 ocurrencias para “GMIL”, hasta 381327 para “CCAT”:
>>> rcv1.target_names[:3].tolist()
['E11', 'ECAT', 'M11']
El conjunto de datos se descargará de rcv1 homepage si es necesario. El tamaño comprimido es de unos 656 MB.
7.2.6. Conjunto de datos Kddcup 99¶
El conjunto de datos KDD Cup “99 se creó procesando las partes de tcpdump del conjunto de datos de Evaluación del Sistema de Detección de Intrusiones (Intrusion Detection System, IDS) de DARPA 1998, creado por el MIT Lincoln Lab 2. Los datos artificiales (descritos en la página de inicio del conjunto de datos) se generaron utilizando una red cerrada y ataques inyectados a mano para producir un gran número de diferentes tipos de ataque con actividad normal en segundo plano. Como el objetivo inicial era producir un gran conjunto de entrenamiento para los algoritmos de aprendizaje supervisado, hay una gran proporción (80.1%) de datos anormales, lo que no es realista en el mundo real, y es inapropiado para la detección de anomalías no supervisada, cuyo objetivo es detectar datos “anormales”, es decir:
cualitativamente diferente de los datos normales
en gran minoría entre las observaciones.
Así, transformamos el conjunto de datos de KDD en dos conjuntos de datos diferentes: SA y SF.
SA se obtiene simplemente seleccionando todos los datos normales, y una pequeña proporción de datos anormales para dar una proporción de anomalías del 1%.
SF se obtiene como en 3 simplemente recogiendo los datos cuyo atributo logged_in es positivo, centrándose así en el ataque de intrusión, lo que da una proporción del 0.3% del ataque.
http y smtp son dos subconjuntos de SF correspondientes a la tercera característica igual a “http” (respectivamente a “smtp”).
Estructura general KDD:
Total de muestras
4898431
Dimensionalidad
41
Características
discreto (int) o continuo (float)
Objetivos
str, “normal.” o nombre del tipo de anomalía
Estructura SA:
Total de muestras
976158
Dimensionalidad
41
Características
discreto (int) o continuo (float)
Objetivos
str, “normal.” o nombre del tipo de anomalía
Estructura SF:
Total de muestras
699691
Dimensionalidad
4
Características
discreto (int) o continuo (float)
Objetivos
str, “normal.” o nombre del tipo de anomalía
Estructura http:
Total de muestras
619052
Dimensionalidad
3
Características
discreto (int) o continuo (float)
Objetivos
str, “normal.” o nombre del tipo de anomalía
Estructura smtp:
Total de muestras
95373
Dimensionalidad
3
Características
discreto (int) o continuo (float)
Objetivos
str, “normal.” o nombre del tipo de anomalía
sklearn.datasets.fetch_kddcup99
cargará el conjunto de datos kddcup99; devuelve un objeto dictionary-like con la matriz de características en el miembro data
y los valores objetivo en target
. El argumento opcional «as_frame» convierte data
en un DataFrame de pandas y target
en una Serie de pandas. El conjunto de datos se descargará de la web si es necesario.
Referencias
- 2
Analysis and Results of the 1999 DARPA Off-Line Intrusion Detection Evaluation, Richard Lippmann, Joshua W. Haines, David J. Fried, Jonathan Korba, Kumar Das.
- 3
K. Yamanishi, J.-I. Takeuchi, G. Williams, and P. Milne. Online unsupervised outlier detection using finite mixtures with discounting learning algorithms. In Proceedings of the sixth ACM SIGKDD international conference on Knowledge discovery and data mining, pages 320-324. ACM Press, 2000.
7.2.7. Conjunto de datos California Housing¶
Características del Conjunto de Datos:
- Número de Instancias
20640
- Número de Atributos
8 atributos numéricos y predictivos y el objetivo
- Información de Atributo
MedInc mediana del ingreso en bloque
HouseAge edad de la casa mediana en bloque
AveRooms número promedio de habitaciones
AveBedrms número promedio de dormitorios
Population población en bloque
AveOccup ocupación media de la casa
Latitude latitud del bloque de la casa
Longitude longitud del bloque de la casa
- Valores de Atributos Faltantes
None
Este conjunto de datos se obtuvo del repositorio StatLib. http://lib.stat.cmu.edu/datasets/
La variable objetivo es el valor mediano de la casa para los distritos de California.
Este conjunto de datos se obtuvo a partir del censo de EE.UU. de 1990, utilizando una fila por grupo de bloques censales. Un grupo de bloques es la unidad geográfica más pequeña para la que la Oficina del Censo de EE.UU. (U.S. Census Bureau) publica datos muestrales (un grupo de bloques suele tener una población de entre 600 y 3,000 personas).
Puede descargarse/cargarse utilizando la función sklearn.datasets.fetch_california_housing
.
Referencias
Pace, R. Kelley y Ronald Barry, Sparse Spatial Autoregressions, Statistics and Probability Letters, 33 (1997) 291-297