<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 TAREA 2
Federico Riveroll Gonzalez 105898
Parte 1
Step1:  Resolviendo caso A=[[1,1],[0,0]]
Step2:  El experimento anerior nos da error por ser una matriz singular, ahora intentamos con A=[[1,1],[0,1e-32]]
Step3:  Intentando con b en imagen de A
Para esto necesitamos que b resulte del producto de un vector multiplicado por A, por ejemplo [1,0]
Step4:  Vemos que tampoco funciona por que da el error de "matriz singular".
Gradiente con PANDAS
Step5:  Definamos la función de <b>minimización lineal</b> como
Step6:  Por lo tanto tenemos que <b>&theta;</b> es una linea solución óptima que se intersecta el orígen en <b>&alpha;</b> = <b>353.16</b> y que tiene una pendiente de <b>&beta;</b> = <b>25.326</b>. De tal modo que
Step7:  Descenso de gradiente
<br>
Cálculo de Theta mediante descenso de gradiente.
<ASSISTANT_TASK:>
Python Code:
import numpy as np
from numpy import *
Eq = np.array([[1, 1, -1, 9],[0, 1, 3, 3],[-1, 0, -2, 2]])
A = Eq[:,0:3] # As
b = Eq[:,3] # Resultados 9, 3, 2
# Las soluciones son: [0.666666666666667, 7.0, -1.3333333333333333] 
U,s,V = linalg.svd(A) # descomposición SVD de A
# inversa usando pinv
pinv = linalg.pinv(A)
# inversa usando descomposición SVD
pinv_svd = dot(dot(V.T,linalg.inv(diag(s))),U.T)
xPinv = dot(pinv_svd, b) # Resolviendo Ax=b con x = A^-1*b
xPinv.T
# Resolviendo Ax=b usando ecuación
c = dot(U.T,b) # c = U^t*b
w = linalg.solve(diag(s),c) # w = V^t*c
xSVD = dot(V.T,w) # x = V*w
xSVD.T
Explanation: TAREA 2
Federico Riveroll Gonzalez 105898
Parte 1: Teoría de Álgebra Lineal y Optimización
<b>1) ¿Por qué una matriz equivale a una transformación lineal entre espacios vectoriales?</b>
<br><br>
 Porque cualquier matriz se puede ver como una transformación de los vectores canónicos (matriz diagonal de unos). Siendo las parejas de valores las coordenadas de "la punta de la flecha" que viene desde el orígen (0,0). En el siguiente diagrama están 3 vectores canónicos representados por una matriz:<br>
 <img src = "https://stevehazen.files.wordpress.com/2010/02/identitymatrix3dswith-labels1.jpg"/>
 <br>
 Y ahora con un nuevo vector que es una transformación de los tres canónicos:
 <img src = "https://stevehazen.files.wordpress.com/2010/02/idmatrixwithtranslationvec.jpg?w=595"/>
 <br><br><br>
 <b>2) ¿Cuál es el efecto de transformación lineal de una matriz diagonal y el de una matriz ortogonal?</b>
 <br><br>
 En el caso de la <i>matriz diagonal</i> la transformación solamente escala los vectores canónicos, es decír, no rota ni se desplaza, de tal forma que los vectores resultantes de la transformación están en el span de los vectores iniciales.<br>
 <img src="https://mathsmartinthomas.files.wordpress.com/2014/12/diag41.png"/>
 <br>
 En el caso de la <i> matriz ortogonal</i> la transformación es una rotación y/o reflexión, preserva angulos y longitudes y el volumen no cambia (el determinante es 1 ó -1). 
 <br>
 <img src="http://fourier.eng.hmc.edu/e101/lectures/unitary_transform_2.gif"/>
  <br><br><br>
 <b>3) ¿Qué es la descomposición en valores singulares de una matriz?</b><br><br>
 La descomposición de una matriz en valores singulares es representar una matriz <b>A</b> como el producto de tres matrices; <b>U</b>, <b>&Sigma;</b> y <b>V</b>. De tal forma que:<br><br>
 <b>A</b> = <b>U&Sigma;V</b>(t)<br><br>
 Donde:<br>
 <b>A</b> es una matriz de mxn
 <br>
 <b>U</b> es una matriz ortogonal de mxm
  <br>
 <b>V</b> es una matriz ortogonal de nxn
  <br>
 <b>&Sigma;</b> es una matriz diagonal acompletada por ceros en las dimensiones sobrantes
 <br><br>
 <img src = "http://www.alglib.net/matrixops/general/i/svd1.gif"/>
  <br><br><br>
 <b>4) ¿Qué es diagonalizar una matriz y qué representan los eigenvectores?</b><br><br>
 Una matriz es <b>diagonalizable</b> si mediante un cambio de base puede (una transformación) reducirse al producto entre dos matrices ortogonales y <b>una matriz diagonal</b>. De tal forma que se puedan hacer transformaciones a dicha matriz diagonal y luego regresar a su base original, ya que las operaciones en matrices diagonales son mucho menos costosas y el resultado es equivalente.<br><br>
 Se dice que la matriz A es diagonalizable cuando; <br><br>
 <b>A</b> = <b>PDP</b>(-)<br><br>
 Donde:<br>
 <b>A</b> es una matriz de mxn
 <br>
 <b>P</b> es una matriz invertible cuyos vectores son los eigenvectores de A
 <br>
 <b>D</b> es una matriz diagonal cuyos valores son los eigenvalores de A
 <br><br>
 <img src="https://www.matesfacil.com/diagonalizable.jpg"/>
<br><br><br>
<b>5) ¿Intuitivamente qué son los eigenvectores?</b><br><br>
 Los eigenvectores son aquellos que en una transformación solamente escalan sus magnitudes pero no se mueven, dicho de otra forma, son aquellos vectores que van a permanecer en su <b>span</b> después de ser transformados, por lo tanto;<br><br>
 Se dice que el vector <b>x</b> es <u>eigenvector</u> si se cumple que;<br><br>
 <b>Ax</b> = <b>&lambda;x</b>
 <br><br>
 Donde:<br>
 <b>A</b> es una matriz
 <br>
 <b>x</b> es un vector
 <br>
 <b>&lambda;</b> es un escalar (y un eigenvalor)
 <br><br>
 <img src = "https://upload.wikimedia.org/wikipedia/commons/thumb/5/58/Eigenvalue_equation.svg/500px-Eigenvalue_equation.svg.png"/>
<b>6) ¿Cómo interpretas la descomposición en valores singulares como una composición de tres tipos de transformaciones lineales simples?</b><br><br>
<b>M</b> = <b>U&Sigma;V</b>(t)<br><br>
 Donde:<br>
 <b>M</b> es una matriz de mxn
 <br>
 <b>U</b> es una matriz ortogonal de mxm
  <br>
 <b>V</b> es una matriz ortogonal de nxn
  <br>
 <b>&Sigma;</b> es una matriz diagonal acompletada por ceros en las dimensiones sobrantes
 <br><br>
 La interpretación intiuitiva es que una matriz o transformación lineal (<b>M</b>) se puede representar de manera equivalente como una rotación (<b>V</b>(t)) más una redimensión (<b>&Sigma;</b>) más una rotación de los ejes canónicos (<b>U</b>).<br><br>
 <img src="https://upload.wikimedia.org/wikipedia/commons/b/bb/Singular-Value-Decomposition.svg"/>
<b>7) ¿Qué relación hay entre la descomposición en valores singulares y la diagonalización?</b><br><br>
La diagonalización de una matriz <b>A</b> se lleva a cabo de la siguiente forma:<br><br>
<b>A</b> = <b>PDP</b>(-)<br><br>
 Donde:<br>
 <b>A</b> es una matriz de mxn
 <br>
 <b>P</b> es una matriz invertible cuyos vectores son los eigenvectores de A
 <br>
 <b>D</b> es una matriz diagonal cuyos valores son los eigenvalores de A
 <br><br>
 Y la descomposición en valores singulares para dicha matriz <b>A</b> de la siguiente forma:<br><br>
 <b>A</b> = <b>U&Sigma;V</b>(t)<br><br>
 Donde:<br>
 <b>A</b> es una matriz de mxn
 <br>
 <b>U</b> es una matriz ortogonal de mxm
  <br>
 <b>V</b> es una matriz ortogonal de nxn
  <br>
 <b>&Sigma;</b> es una matriz diagonal acompletada por ceros en las dimensiones sobrantes
 <br><br>
Pero si multiplicamos cada lado por la transpuesta nos da:<br><br>
 <b>A</b>(t)<b>A</b> = <b>V&Sigma;</b>(t)<b>U</b>(t) * <b>U&Sigma;V</b>(t)<br><br>
Cancelamos <b>U</b>(t) * <b>U</b> y nos queda:<br><br>
  <b>A</b>(t)<b>A</b> = <b>V&Sigma;</b>(t) * <b>&Sigma;V</b>(t)<br><br>
Pero como <b>&Sigma;</b>(t) * <b>&Sigma;</b> es diagonal llamemosla <b>D</b>, llegamos a la forma de matriz diagonalizada:<br><br>
<b>A</b>(t)<b>A</b>  = <b>VDV</b>(-)<br><br>
Donde:<br>
<b>V</b> son los ergenvectores de <b>A</b>(t)<b>A</b> con ergenvalores los cuadrados de los valores singulares.
<br><br>
<b>8) ¿Cómo se usa la descomposición en valores singulares para dar una aproximación de rango menor a una matriz?</b><br><br>
Se descompone la matriz (digamos <b>A</b>) en valores singulares, dado un <b>rango</b> un valor entero se recortan las matrices ortogonales hasta dicho rango elegido '<b>r</b>'. Llamemos la matriz resultante: "<b>B</b>", de tal modo que:
<br><br>
<b>A</b> es una matriz de mxn (convertida de la imágen)
<br>
<b>r</b> es un entero que representa el rango elegido
<br><br> y:
<br>
<b>Ur</b> es una matriz de mx<b>r</b>
<br>
<b>&Sigma;r</b> es una matriz diagonal de <b>r</b>x<b>r</b>
<br>
<b>Vr</b> es una matriz de <b>r</b>xm
<br><br>
Y <b>B</b> es una nueva matriz pseudo-inversa de mxn que <b>aproxima</b> la matriz <b>A</b> multiplicando Ur&Sigma;rVr.
<br>
<br><br>
<b>9) Describe el método de minimización por descenso gradiente</b><br><br>
Se llama <u>gradiente</u> a un <b>vector de derivadas de una función en varias direcciones</b>. El gradiente se puede representar como un vector que apunta en la dirección donde mayor crecimiento (ó decrecimiento) hay de una función multidimiensional, en el caso de un espacio tridimensional, el vector es una función de <b>x</b> y <b>y</b> apuntando hacia donde la superficie (<b>z</b>) sea mayor (ó menor). Si el gradiente tiene un valor negativo implica que la función, hacia donde está apuntando el gradiente, tiene pendiente descendiente.<br><br>
<img src="http://www.sharetechnote.com/image/Calculus_Gradient_02.png"/>
<br><br>
Cabe mencionar que los gradientes son perpendiculares a las <i>curvas de nivel</i>;<br><br>
<img src="http://www.sharetechnote.com/image/Calculus_Gradient_04.png"/>
<br><br>
Por lo tanto, el algoritmo de <b>DESCENSO DE GRADIENTE</b> utiliza este vector dirección para maximizar (o minimizar) algún objetivo, haciendo uso de esta técnica se dan "pasos" hacia la dirección en la que la función aumenta (o disminuye) más para llegar al óptimo. El tamaño de los pasos que se dan se podría determinar con el escalar <b>&alpha;</b>.<br><br> El algoritmo de descenso de gradiente consiste en acutalizar una ubicación cada "paso" hasta llegar al mínimo como se muestra en la siguiente figura:
<br><br>
<img src="https://s3-ap-south-1.amazonaws.com/av-blog-media/wp-content/uploads/2017/03/06100746/grad.png"/>
<br><br>
<b>10) Menciona cuatro ejemplos de problemas de optimización (dos con restricciones y dos sin restricciones) que te parezcan interesantes como Científico de Datos</b><br><br>
1) Maximizar la utilidad esperada de una inversión distribuyendo el capital en tres productos financieros diferentes. Restricción: el mínimo a invertír en cualquiera de los tres productos financieros es 20% (para distribuír el riesgo).<br>
2) Sistema de recomendación de canciones; Maximizar pronóstico de que la siguiente canción le guste al usuario. Restricción: Una misma canción no puede aparecer más de 1 vez cada 3 días (para no 'quemar' la canción).
<br>
3) Optimización de algoritmo de predicción de rotación de empleados. Se define el costo como la diferencia cuadrática entre la predicción (en meses) y el valor real de la duración de cada empleado. Utilizando algoritmo de descenso de gradiente sobre la función de costo se llega a la mejor solución.
<br>
4) Maximización de utilidad de tienda departamental. Se cambian semanalmente los precios de todos los artículos de una zona durante varios meses y se "apunta" la utilidad (ventas - costos y gastos de venta) entre el número de personas que estuvieron en la tienda. El problema es buscar para cada variación de precios la máxima utilidad de cada tipo de artículo (probablemente sean diferentes en diferentes variaciones).
<br>
Aproximar Imagen por medio de SVD (low rank)
Para la transformación de imagen en varios tamaños de aproximación utilicé <a href="https://github.com/kaityo256/image_svd"> este proyecto</a>. <br><br>
El programa toma una imágen y la convierte en una matriz "<b>A</b>" de pixeles "grises" por medio de la función <b>Numpy.asarray(imagen)</b>, a dicha imágen le realiza la descomposición y la  aproxima con el rango elegido '<b>r</b>'. Llamemos la matriz resultante: "<b>B</b>", de tal modo que:
<br><br>
<b>A</b> es una matriz de mxn (convertida de la imágen)
<br>
<b>r</b> es un entero que representa el rango elegido
<br><br> y:
<br>
<b>Ur</b> es una matriz de mx<b>r</b>
<br>
<b>&Sigma;r</b> es una matriz diagonal de <b>r</b>x<b>r</b>
<br>
<b>Vr</b> es una matriz de <b>r</b>xm
<br><br>
Y <b>B</b> es una nueva matriz pseudo-inversa de mxn que <b>aproxima</b> la matriz <b>A</b> multiplicando Ur&Sigma;rVr.
<br>
<br>
De tal modo que pudimos aproximar la matriz A de nxm utilizando tres matrices de (mxr, rxr y rxm) respectivamente, utilizanado muchísima menos información. <br>Una posible aplicación es el envío de imágenes de baja resolución para videos en dispositivos con internet lento. Se envía una aproximación de la información pero con muchos menos 'datos' de tal forma que puedan ver el video en tiempo real aunque sea con menor resolución.
Solución de equación mediante pseudoinversa SVD
End of explanation
Eq = np.array([[1, 1, 4],[0, 0, 0]])
A = Eq[:,0:2] # As
b = Eq[:,2] # Resultados 9, 3, 2
U,s,V = linalg.svd(A)
c = dot(U.T,b) # c = U^t*b
w = linalg.solve(diag(s),c) # w = V^t*c
xSVD = dot(V.T,w) # x = V*w
xSVD.T
Explanation: Resolviendo caso A=[[1,1],[0,0]]
End of explanation
Eq = np.array([[1, 1, 44],[0, 1e-32, 5]])
A = Eq[:,0:2] # As
b = Eq[:,2] # 
U,s,V = linalg.svd(A)
pinv_svd = dot(dot(V.T,linalg.inv(diag(s))),U.T)
xPinv = dot(pinv_svd, b) # Resolviendo Ax=b con x = A^-1*b
xPinv.T
Explanation: El experimento anerior nos da error por ser una matriz singular, ahora intentamos con A=[[1,1],[0,1e-32]]
End of explanation
Eq = np.array([[1, 1, 0],[0, 0, 1]])
A = Eq[:,0:2] # As
b = Eq[:,2] # 
U,s,V = linalg.svd(A)
pinv_svd = dot(dot(V.T,linalg.inv(diag(s))),U.T)
xPinv = dot(pinv_svd, b) # Resolviendo Ax=b con x = A^-1*b
xPinv.T
Explanation: Intentando con b en imagen de A
Para esto necesitamos que b resulte del producto de un vector multiplicado por A, por ejemplo [1,0]
End of explanation
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
sat = pd.read_csv("study_vs_sat.csv")
sat.insert(0, "col_unos", 1)
sat
Explanation: Vemos que tampoco funciona por que da el error de "matriz singular".
Gradiente con PANDAS
End of explanation
X = sat[['col_unos', 'study_hours']]
y = sat[['sat_score']]
Th = np.dot(np.dot(linalg.inv(np.dot(X.T,X)),X.T),y)
Th
Explanation: Definamos la función de <b>minimización lineal</b> como:<br> <br>
<b>&Theta; = (X(t)*X).inv * X(t)y</b><br>
<br> Donde:<br>
<b>X</b> = vector de nx2; "col_unos y study_hours"<br>
<b>y</b> = vector de nx1; "sat_score"<br>
<b>&Theta;</b> = vector de 1x2 para obtener escalares minimizadores.
End of explanation
sat.insert(2, "hipotesis", np.dot(X,Th))
sat
import matplotlib.pyplot as plt
import matplotlib
from matplotlib import interactive
from sklearn.preprocessing import MinMaxScaler
interactive(True)
matplotlib.style.use('ggplot')
scaler = MinMaxScaler()
sat[['study_hours', 'sat_score', 'hipotesis']] = scaler.fit_transform(sat[['study_hours', 'sat_score', 'hipotesis']])
sat.plot()
sat
Explanation: Por lo tanto tenemos que <b>&theta;</b> es una linea solución óptima que se intersecta el orígen en <b>&alpha;</b> = <b>353.16</b> y que tiene una pendiente de <b>&beta;</b> = <b>25.326</b>. De tal modo que:<br><br>
<b>Hipótesis</b> = <b>X</b> * <b>&theta;</b>
End of explanation
# m es el número de filas
def descensoGradiente(X, y, theta, alpha, m, numIterations):
    xTrans = X.transpose()
    for i in range(0, numIterations):
        hypothesis = np.dot(X, theta)
        loss = hypothesis - y
        # avg cost per example (the 2 in 2*m doesn't really matter here.
        # But to be consistent with the gradient, I include it)
        cost = np.sum(loss ** 2) / (2 * m)
        #print("Iteration %d | Cost: %f" % (i, cost))
        # avg gradient per example
        gradient = np.dot(xTrans, loss) / m
        # update
        theta = theta - alpha * gradient
    return theta
m, n = np.shape(X)
numIterations= 10000
alpha = 0.003
theta = np.ones(n)
theta = descensoGradiente(X, y['sat_score'], theta, alpha, m, numIterations)
print(theta)
Explanation: Descenso de gradiente
<br>
Cálculo de Theta mediante descenso de gradiente.
End of explanation
<END_TASK>