Datos altamente dimensionales#
Ultima modificación: 2024-01-22 | YouTube
Vecinos próximos y maldición de la dimensionalidad#
[1]:
import numpy as np
from sklearn import datasets
iris_X, iris_y = datasets.load_iris(return_X_y=True)
np.unique(iris_y)
[1]:
array([0, 1, 2])
[2]:
# Los datos son divididos en entrenamiento y prueba
# Los datos son permutados aleatoriamente.
np.random.seed(0)
indices = np.random.permutation(len(iris_X))
iris_X_train = iris_X[indices[:-10]]
iris_y_train = iris_y[indices[:-10]]
iris_X_test = iris_X[indices[-10:]]
iris_y_test = iris_y[indices[-10:]]
# Se crea un clasificador k-NN
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier()
knn.fit(
iris_X_train,
iris_y_train,
)
[2]:
KNeighborsClassifier()In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
KNeighborsClassifier()
[3]:
# Pronóstico para el conjunto de test
display(
knn.predict(iris_X_test),
iris_y_test,
)
array([1, 2, 1, 0, 0, 0, 2, 1, 2, 0])
array([1, 1, 1, 0, 0, 0, 2, 1, 2, 0])
Maldición de la dimensionalidad:
Para que el estimador sea efectivo, se requiere que la distancia entre vecinos sea menor que un valor ‘d’.
En una dimensión se requiere en promedio n ~ 1/d puntos para cubrir el espacio.
Si se tienen p dimensiones se requiere en promedio n ~ 1/d^p puntos para cubrir el espacio.
Si se requieren 10 puntos en una dimensión, para 5 dimensiones se requieren 10^5 puntos.
La cantidad de puntos crece exponencialmente con la cantidad de dimensiones.
Modelos lineales#
[4]:
#
# Carga del dataset de diabetes
#
diabetes_X, diabetes_y = datasets.load_diabetes(return_X_y=True)
diabetes_X_train = diabetes_X[:-20]
diabetes_X_test = diabetes_X[-20:]
diabetes_y_train = diabetes_y[:-20]
diabetes_y_test = diabetes_y[-20:]
[5]:
#
# Regresión lineal
#
from sklearn import linear_model
regr = linear_model.LinearRegression()
regr.fit(diabetes_X_train, diabetes_y_train)
regr.coef_
[5]:
array([ 3.06094248e-01, -2.37635570e+02, 5.10538048e+02, 3.27729878e+02,
-8.14111926e+02, 4.92799595e+02, 1.02841240e+02, 1.84603496e+02,
7.43509388e+02, 7.60966464e+01])
[6]:
#
# Error cuadrático medio
#
np.mean((regr.predict(diabetes_X_test) - diabetes_y_test) ** 2)
[6]:
2004.5186863342092
[7]:
#
# Explained variance score: 1 es la predicción perfecta
# y 0 significa que no hay relación lineal entre x y y.
#
regr.score(diabetes_X_test, diabetes_y_test)
[7]:
0.585085427447195
[8]:
#
# Shrinkage: pocos puntos por dimension induce una alta varianza
#
X = np.c_[0.5, 1].T
y = [0.5, 1]
test = np.c_[0, 2].T
regr = linear_model.LinearRegression()
[9]:
import matplotlib.pyplot as plt
plt.figure()
np.random.seed(0)
for _ in range(6):
this_X = 0.1 * np.random.normal(size=(2, 1)) + X
regr.fit(this_X, y)
plt.plot(test, regr.predict(test))
plt.scatter(this_X, y, s=3)

[10]:
#
# Una solución para aprendizaje estadístico altamente
# dimensional es llevar los coeficientes a cero.
# Este es un ejemplo del dilema sesgo-varianza
#
regr = linear_model.Ridge(alpha=0.1)
plt.figure()
np.random.seed(0)
for _ in range(6):
this_X = 0.1 * np.random.normal(size=(2, 1)) + X
regr.fit(this_X, y)
plt.plot(test, regr.predict(test))
plt.scatter(this_X, y, s=3)

[11]:
#
# Se construye una malla para escoger el valor optimo del
# hiperparámetro alpha
#
alphas = np.logspace(-4, -1, 6)
[
regr.set_params(alpha=alpha)
.fit(diabetes_X_train, diabetes_y_train)
.score(diabetes_X_test, diabetes_y_test)
for alpha in alphas
]
[11]:
[0.5851211547549662,
0.5852172781570948,
0.5854773661274462,
0.5855599854998634,
0.583079520872396,
0.5705970628037382]
Máquinas de vectores de soporte#
[12]:
import matplotlib.pyplot as plt
from sklearn import datasets, svm
from sklearn.inspection import DecisionBoundaryDisplay
iris = datasets.load_iris()
# Se toman unicamente las dos primeras dimensiones para
# convertir el problema a 2D
X = iris.data[:, :2]
y = iris.target
# Se crea una instancia de una SVM y se entrena con los datos.
# Los datos no se escalan.
C = 1.0 # Parámetro de regularización.
models = (
svm.SVC(kernel="linear", C=C),
svm.LinearSVC(C=C, max_iter=10000, dual="auto"),
svm.SVC(kernel="rbf", gamma=0.7, C=C),
svm.SVC(kernel="poly", degree=3, gamma="auto", C=C),
)
models = (clf.fit(X, y) for clf in models)
# Titulo de las gráficas
titles = (
"SVC with linear kernel",
"LinearSVC (linear kernel)",
"SVC with RBF kernel",
"SVC with polynomial (degree 3) kernel",
)
# Grafica de 2x2
fig, sub = plt.subplots(2, 2)
plt.subplots_adjust(wspace=0.4, hspace=0.4)
X0, X1 = X[:, 0], X[:, 1]
for clf, title, ax in zip(models, titles, sub.flatten()):
disp = DecisionBoundaryDisplay.from_estimator(
clf,
X,
response_method="predict",
cmap=plt.cm.coolwarm,
alpha=0.8,
ax=ax,
xlabel=iris.feature_names[0],
ylabel=iris.feature_names[1],
)
ax.scatter(X0, X1, c=y, cmap=plt.cm.coolwarm, s=20, edgecolors="k")
ax.set_xticks(())
ax.set_yticks(())
ax.set_title(title)
plt.show()
