Porque na matriz realiza las operaciones básicas de suma, resta y multiplicación sobre los vectores canonicos Al aplicar una matriz a un vector estoy obteniendo los cambios resultantes de estas operaciones sobre el vectr.
Una matriz diagonal es un reescalamiento mientras que una ortogonal es una rotación.
La descomposición en valores singulares de una matriz es una aproximación a $A = U*D*V^{t}$ Donde: $U$ y $V$ son los valores singulares de $A$ y $D$ es una matriz diagonal.
La diagonalización de una matriz cuadrada $A_{m x m}$ es llevar el sistema de ecuaciones a la forma canonica, es decir encontrar sus eigenvectores. Los eigenvectores representan los valores propios de la ecuación.
Los eigenvectores son la base ortogonal del espacio de la matriz. Ellos hacen las rotaciones y son reescalados por lambda.
La descomposición SVD lo que hace es rotar, reescalar y volver a rotar, siendo que en el caso de que la matriz A sea cuadrada, la segunda rotación llevará a la matriz a su posición original.
Los elementos $U,D,V$ ,resultantes de una descomposición en valores singulares, son los eigenvectores de la matriz A. Donde $D$ es una diagonalizacion.
En la descomposición $A = U*D*V^{t}$ , $D$ puede verse como una multiplicacion de matrices menores $\begin{bmatrix}D_{1} & 0\\0 & D_{2}\end{bmatrix}$ con el rango de D{1} y D{2} menor al rango de D. Entonces $A^{*}=U_{1}D_{1}V_{1}^{t}$ aquel que resuelve el problema de $ min ||A-A^{*}||$ s.a. $rank(A^{*})<rank(A)$
El metodo de optimización de la función $f(x)$ por descenso gradiente busca, de manera local: 1)encontrar los valores $x^{*}$ tal que $\nabla f(x^*)$ sea la dirección de mayor decenso(o asenso en caso de maximizar) 2)moverse en la dirección encontrada en un factor $\beta$ conocido como coeficiente de aprendizaje (o learning rate) de manera que $\hat{x}=x-\beta*\nabla f(x)$
1) Maximizar el tiempo de uso de cierta aplicación móvil (un juego) y el life spam de esta. 2) Maximizar la probabilidad de encontrar vida en otros planetas.
1) Mejorar el acceso a servicios públicos mejorando la planeación urbana. 2) Optimización de despliegue de paneles solares o molinos para energía eolica dada una superficie limitada y condiciones climatológicas
In [ ]:
# Segunda parte: Aplicaciones en Python
In [2]:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import time
from PIL import Image
##Aquí abro la imagen y la convierto a gris
im = Image.open("/Users/usuario/Documents/MaestriaCD/Propedeutico/PropedeuticoDataScience2017/Tarea/Simpsons.png")
gris =im.convert("1")
plt.figure(figsize=(9, 6))
##convierto los datos de la imagen en una matriz con valores
mat_val = np.array(gris)
plt.title("Imagen Original")
plt.imshow(mat_val, cmap='gray');
In [4]:
###hago el SVD
U, D, V = np.linalg.svd(mat_val)
##Reconstruyo y grafíco la imagen de manera completa
img_rec = np.matrix(U) * np.diag(D) * np.matrix(V)
plt.title("Imagen reconstruida de manera completa")
plt.imshow(img_rec, cmap='gray');
In [5]:
##Escogiendo K=100 para reconstruir la imagen con solo K elementos del SVD
k=100
rec =np.matrix(U[:,:k]) *np.diag(D[:k])* np.matrix (V[:k,:])
plt.title("Imagen reconstruida con 100 valores")
plt.imshow(rec, cmap='gray')
Out[5]:
In [6]:
##Escogiendo K=150 para reconstruir la imagen con solo K elementos del SVD
k=150
rec =np.matrix(U[:,:k]) *np.diag(D[:k])* np.matrix (V[:k,:])
plt.title("Imagen reconstruida con 150 valores")
plt.imshow(rec, cmap='gray')
Out[6]:
In [7]:
##Escogiendo K=200 para reconstruir la imagen con solo K elementos del SVD
k=200
rec =np.matrix(U[:,:k]) *np.diag(D[:k])* np.matrix (V[:k,:])
plt.title("Imagen reconstruida con 200 valores")
plt.imshow(rec, cmap='gray')
Out[7]:
In [28]:
import numpy as np
def pseudo (A):
X =np.array(A)
U, D, V = np.linalg.svd(X, full_matrices=False)
V_t = np.transpose(V)
U_t = np.transpose(U)
D_diag=np.diag(D)
rows, col =D_diag.shape
D_inv = np.zeros((rows,col))
##Aquí calculo la inversa de D, invirtiendo los valores y poniendo 0 en vez de 1/0
for i in range(0,max(rows,col)):
if D_diag[i,i]!= 0 :
D_inv[i,i]=1/D_diag[i,i]
else :
D_inv[i,i]= 0
##aquí reconstruyo la pseudoinversa de A
pseudo = np.dot(np.dot(V_t, D_inv), U_t)
return pseudo
In [29]:
def solve (A,y):
A= np.array(A)
Y=np.array(y)
## reviso el tamaño
rows, col =A.shape
vec_rows, vec_col = Y.shape
if rows != vec_rows:
raise Exception ("El tamaño de la matriz y el vector no coinciden")
else:
inv=pseudo(A)
solve= np.dot(inv, Y)
return (solve)
In [19]:
A=[[1,1],[0,0]]
b=[[1],[1]]
solve(A,b)
Out[19]:
In [20]:
pseudo(A)
Out[20]:
A es una matriz es que representa al sistema de ecuaciones $ X_{1}+X_{2}=b_{1}$ y $b_{2}=0$, su imagen es $b = \begin{bmatrix}b_{1}\\0 \end{bmatrix}$. La solución no es única ya que hay una variable libre. Dada la forma de la pseudoinversa de A $\begin{bmatrix}.5 & 0\\.5 & 0 \end{bmatrix}$ la función siempre regresará una respuesta $\begin{bmatrix}x_{1}=b_{1}/2\\x_{2}=b_{2}/2 \end{bmatrix}$ aunque $b_{2} != 0$
In [ ]:
In [ ]:
In [24]:
import math
A=[[1,1],[0,1*math.exp(-32)]]
print(pseudo(A))
In [25]:
solve(A,b)
Out[25]:
En este caso la matriz tiene una solución única ya que $b_{2}=exp-32$ y las x´s son diferentes a las del caso anterior.
In [23]:
##Programando un script para descargar el archivo .csv de Github y convertirlo en un data frame
import numpy as np
import pandas as pd
import statsmodels.formula.api as sm
import matplotlib.pyplot as plt
#Script para descargar archivo y convertirlo en Data Frame con Pandas
#url="/Users/usuario/Documents/MaestriaCD/Propedeutico/PropedeuticoDataScience2017/study_vs_sat.csv"
url="https://raw.githubusercontent.com/mauriciogtec/PropedeuticoDataScience2017/master/Tarea/study_vs_sat.csv"
data = pd.read_csv(url)
data=pd.read_csv(url)
data= pd.DataFrame(data)
Al hacer una aproximación de la forma $sat_score= \alpha + \beta*study_hours + \epsilon$ podemos plantear la minimización de errores al cuadrado de tal manera que $$min \epsilon^{2} = min_{\alpha,\hat{\beta}} satscore - \alpha-\hat{\beta}*study hours$$ $$min_{\alpha,\hat{\beta}} y - X\hat{\beta}$$ En este caso $\alpha$ y $\beta$ resultantes de las condiciones de primer orden del problema de minimización son los gradientes que estamos buscando
In [24]:
##Deefine una función que me de una predicción para cada valor de sat_score
##
def prediction (S,alpha,beta):
prediction=np.zeros(len(data))
for i in range(len(data)):
score=S[i]
prediction[i]=alpha+beta*score
return prediction
In [25]:
##puedo usar datos que se me ocurran
alpha=-353.164879499
beta= 25.3264677779
S=data["study_hours"]
##Entonces usando esta información puedo hacer la predicción usando mi función
score_pred=prediction(S,alpha,beta)
print(score_pred)
In [26]:
##Definiendo el numpy array con 1 en el primer vector
##y sat_score en el segundo
Origen= data['Origen'] = np.ones(( len(data), ))
X=data[["Origen","study_hours"]]
print(X)
In [30]:
###Calculando X^+ * study_hours para obtener la alpha y beta
X_inv=pseudo(X)
alpha_aprox,beta_aprox=np.dot(X_inv,data["sat_score"])
print(alpha_aprox, beta_aprox)
In [32]:
##ahora, haciendo la formula de estimadores de OLS de veras para calcular alpha t beta
X_t=np.transpose(X)
Sxx=np.dot(X_t,X)
Sxy=np.dot(X_t,data["sat_score"])
Sxx_inv= pseudo(Sxx)
alpha,beta= np.dot(Sxx_inv,Sxy)
print(alpha,beta)
In [33]:
##visualizando los datos correctos vs las aproximaciones
alpha=353.164879499
beta= 25.3264677779
S=data["study_hours"]
prediccion=prediction(S, alpha,beta)
colors = ['red', 'blue']
pred=plt.plot(prediccion, 'bo', markersize=10) # blue circle with size 10
val=plt.plot(data["sat_score"], 'ro', ms=10,)
plt.legend((pred, val),
('Valores de la predicción',"Valor Real"),
scatterpoints=1,
loc='lower left',
ncol=3,
fontsize=8)
plt.show()
In [ ]:
In [ ]: