Una multiplicación de una matriz, implica escalamientos, reducciones de dimensiones y rotaciones que se pueden observar en el espacio geométrico. Todas estas transformaciones son lineales en tanto se pueden representar como combinaciones lineales de la forma $\alpha*x + \beta$, donde $\alpha$ y $\beta$ son parámetros que determina la matriz.
Una matriz diagonal va a rescalar cada una de las columnas del vector o matriz al que se le aplique la transformación lineal, mientras que una matriz ortogonal va a generar una transformación isométrica que puede ser cualquiera de tres tipos: rotación, traslación o generar el reflejo.
Es la factorización de una matriz en la multiplicación de tres matrices: la de eigenvectores, los componentes singulares y la transpuesta de eigenvectores. La descomposicion se lleva a cabo de la siguiente manera: $ A = U \Sigma V^{T} $ En donde U = matriz de eigenvectores, $\Sigma$ = matriz de valores singulares o raices cuadradas de eigenvalores de $A^{T}A$ y $V^{T}$ = matriz transpuesta de eigenvectores por derecha. La descomposición SVD tiene muchas aplicaciones en las áreas de principal component analytsis, dimensionality reduction, compresión de imágenes, etcétera.
Es la factorización de la matriz en las tres matrices básicas mencionadas arriba (eigenvectores, eigenvalores e inversa de eigenvectores). Esto se observa de la siguiente manera: $A = PDP^{-1}$ donde P = matriz de eigenvectores, D = Matriz diagonal de eigenvalores y $P^{-1}$ = matriz inversa de eigenvectores. Los eigenvectores de una transformación lineal son vectores que cumplen que el resultado de multiplicarlos por la matriz de transformación equivale a multiplicarlos por un escalar que llamamos 'eigenvalor' ($ Ax = \lambda x $). Esto implica que a estos vectores al aplicarles la transformación lineal (multiplicarlos por la matriz de transformación) no cambian su dirección solamente cambian su longitud o su sentido (en caso de que haya eigenvalor con signo negativo).
Se pueden interpretar como ejes cartesianos de la transformación lineal.
Las tres matrices que conforman la SVD se pueden ver como transformaciones simples que son una rotación inicial, un escalamiento a lo largo de los ejes principales (valores singulares) y una rotación final.
La descomposición svd es una generalización de la diagonalización de una matriz. Cuando una matriz no es cuadrada, no es diagonalizable, sin embargo si se puede descomponer mediante svd. Así mismo si se utiliza la descomposición svd de una matriz, es posible resolver sistemas de ecuaciones lineales que no tengan una única solución sino que la solución devuelta es el ajuste a mínimos cuadrados, (obviamente si tienen solución, regresa la solución al sistema).
En la descomposición svd de una matriz mxn, se obtiene una descomposición de tres matrices cuya multiplicación resulta en la matriz original completa, sin embargo dadas las propiedades de la descomposición, se pueden utilizar solamente las componentes principales de mayor relevancia desechando columnas de la matriz $U_{mxr}$, filas o columnas de la matriz de componentes principales $\Sigma _{rxr} $ y filas de la matriz $V_{rxn}^{T}$ La multiplicación de estas resulta en el tamaño mxn de la matriz original pero con un determinado error y a medida que se consideran más componentes principales, columnas y vectores de las matrices U,S,VT , mejor será la reconstrucción de la matriz original. Esta descomposición es muy útil para comprimir información y análisis de componentes principales (PCA).
Es un método iterativo de primer orden de minimización de una función dado su gradiente. Conociendo la función a optimizar, se calcula el gradiente (vector de derivadas parciales), posteriormente se considera un punto aleatorio de inicio, se substituye la coordenada en el vector gradiente, se analiza en cuál de las componentes del vector gradiente (x, y, o z) es el valor más negativo y se da un pequeño incremento en esa dirección de manera que se acerca al mínimo local, y así sucesivamente hasta llegar a un punto de convergencia (mínimo local). Entre sus aplicaciones están: Encontrar mínimos locales de funciones, Solución de sistemas de ecuaciones lineales y solución de sistemas de ecuaciones no lineales.
Con restricciones: Modelos de crecimiento económico, Modelos de impuestos óptimos. Sin restricciones: Maximización intertemporal de extracción de recursos de una mina, minimización la varianza.
In [24]:
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
#url = sys.argv[1]
url = 'pikachu.png'
img = Image.open(url)
imggray = img.convert('LA')
In [25]:
imggrayArray = np.array(list(imggray.getdata(band=0)), float)
imggrayArray.shape = (imggray.size[1], imggray.size[0])
imggrayArray = np.matrix(imggrayArray)
plt.imshow(imggray)
plt.show()
u, s, v = np.linalg.svd(imggrayArray)
print("U: ")
print(u)
print("S: ")
print(s)
print("V: ")
print(v)
In [26]:
for i in range(1,60,15):
reconstimg = np.matrix(u[:, :i]) * np.diag(s[:i]) * np.matrix(v[:i,:])
plt.imshow(reconstimg, cmap='gray')
plt.show()
In [5]:
def lin_solve_pseudo(A,b):
pseudoinv = pseudoinverse(A)
return np.matmul(pseudoinv,b)
def pseudoinverse(A):
u,s,v = np.linalg.svd(A)
diagonal = np.diag(s)
if v.shape[0] > diagonal.shape[1]:
print("Agregando columnas a la sigma")
vector = np.array([[0 for x in range(v.shape[0] - diagonal.shape[1])] for y in range(diagonal.shape[0])])
diagonal = np.concatenate((diagonal, vector), axis=1)
elif u.shape[1] > diagonal.shape[0]:
print("Agregando renglones a la sigma")
vector = np.array([[0 for x in range(diagonal.shape[0])] for y in range(u.shape[1]-diagonal.shape[0])])
diagonal = np.concatenate((diagonal, vector), axis=0)
for a in range(diagonal.shape[0]):
for b in range(diagonal.shape[1]):
if diagonal[a][b] != 0:
diagonal[a][b] = 1/diagonal[a][b]
resultante = np.dot(np.transpose(v),np.transpose(diagonal))
resultante = np.dot(resultante,np.transpose(u))
return resultante
In [6]:
A = np.array([[1,1,1],[1,1,3],[2,4,4]])
b = np.array([[18,30,68]])
solve = lin_solve_pseudo(A,np.transpose(b))
print(solve)
(a) Observar que pasa si b esta en la imagen de A (contestar cuál es la imagen) y si no está (ej. b = [1,1]).
In [7]:
print("La imagen de A es cualquier vector de dos coordenadas en donde la segunda componente siempre sea cero")
print("Vector b en imagen de A")
A = np.array([[1,1],[0,0]])
b = np.array([[12,0]])
solve = lin_solve_pseudo(A, np.transpose(b))
print(solve)
print("Cuando b esta en la imagen, la funcion lin_solve_pseudo devuelve la solucion unica a su sistema")
print("Vector b no en imagen de A")
b = np.array([[12,8]])
solve = lin_solve_pseudo(A, np.transpose(b))
print(solve)
print("Cuando b no esta en la imagen, devuelve la solucion mas aproximada a su sistema")
(b) Contestar, ¿la solución resultante es única? Si hay más de una solución, investigar que carateriza a la solución devuelta.
In [8]:
print("Vector b no en imagen de A")
b = np.array([[12,8]])
solve = lin_solve_pseudo(A, np.transpose(b))
print(solve)
print("Cuando b no esta en la imagen, devuelve la solucion mas aproximada a su sistema")
(c) Repetir cambiando A=[[1,1],[0,1e-32]], ¿En este caso la solucíon es única? ¿Cambia el valor devuelto de x en cada posible valor de b del punto anterior?
In [9]:
A = np.array([[1,1],[0,1e-32]])
b = np.array([[12,9]])
solve = lin_solve_pseudo(A, np.transpose(b))
print(solve)
cadena = """En este caso, la solucion devuelta siempre es el valor de la segunda coordenada del vector b por e+32\
y es el valor de ambas incognitas, solo que con signos contrarios ej(x1=-9.0e+32, x2=9.0e+32) \
esto debido a que cualquier numero entre un numero muy pequenio tiende a infinito, de manera que la \
coordenada dos del vector tiene mucho peso con referencia a la coordenada uno del vector
"""
print(cadena)
In [11]:
import pandas as pd
import matplotlib.pyplot as plt
data = pd.read_csv("./study_vs_sat.csv", sep=',')
print(data)
In [12]:
hrs_studio = np.array(data["study_hours"])
sat_score = np.array(data["sat_score"])
A = np.vstack([hrs_studio, np.ones(len(hrs_studio))]).T
m,c = np.linalg.lstsq(A,sat_score)[0]
print("Beta y alfa: ")
print(m,c)
In [13]:
def predict(alfa, beta, study_hours):
study_hours_i=[]
for a in range(len(study_hours)):
study_hours_i.append(alfa + beta*np.array(study_hours[a]))
return study_hours_i
print("prediccion")
print(predict(353.165, 25.326, hrs_studio))
In [14]:
unos = np.ones((len(hrs_studio),1))
hrs_studio = [hrs_studio]
hrs_studio = np.transpose(hrs_studio)
x = np.hstack((unos, hrs_studio))
print("La prediccion es: ")
print(np.matmul(x,np.array([[353.165],[25.326]])))
In [15]:
X_pseudo = pseudoinverse(x)
print("Las alfas y betas son: ")
print(np.matmul(X_pseudo,sat_score))
In [16]:
def comparacion(X, sat_score):
x_transpose = np.transpose(X)
return np.matmul(np.linalg.inv(np.matmul(x_transpose,X)), np.matmul(x_transpose,sat_score))
In [27]:
plt.plot(hrs_studio, sat_score, 'x', label='Datos', markersize=20)
plt.plot(hrs_studio, m*hrs_studio + c, 'r', label='Línea de regresión')
plt.legend()
plt.show()
No hice el ejercicio muy avanzado.