In [1]:
from __future__ import division # want 3 / 2 == 1.5
import re, math, random # regexes, math functions, random numbers
import matplotlib.pyplot as plt # pyplot
from collections import defaultdict, Counter
from functools import partial, reduce # For python3, "reduce" function is added
import numpy as np
In [2]:
def vector_add(v, w):
"""adds two vectors componentwise"""
return [v_i + w_i for v_i, w_i in zip(v,w)]
In [3]:
v = [x for x in range(1, 11,2)]
w = [y for y in range(11, 21,2)]
In [4]:
vector_add(v, w)
# [v for v in range(1, 11, 2)] == [1, 3, 5, 7, 9]
# [w for w in range(10, 21, 2)] == [11, 13, 15, 17, 19]
Out[4]:
In [5]:
# Numpy version
np.array(v) + np.array(w)
Out[5]:
In [6]:
# 벡터 덧셈의 속도 비교, Numpy의 속도가 더 빠른 것을 확인할 수 있음
%timeit vector_add(v, w)
%timeit np.array(v) + np.array(w)
In [7]:
def vector_subtract(v, w):
"""subtracts two vectors componentwise"""
return [v_i - w_i for v_i, w_i in zip(v,w)]
In [8]:
vector_subtract(v, w)
Out[8]:
In [9]:
# Numpy version (Not in Book)
np.array(v) - np.array(w)
Out[9]:
In [10]:
# Original book version
def vector_sum(vectors):
return reduce(vector_add, vectors)
In [11]:
vectors = [v,w,v,w,v,w]
vector_sum(vectors)
Out[11]:
In [12]:
# Modified version by sc82.choi at Gachon - *은 여러개의 argument를 list로 전환해줌
def vector_sum_modified(vectors):
return [sum(value) for value in zip(*vectors)]
In [13]:
vectors = [v,w,v,w,v,w]
vector_sum_modified(vectors)
Out[13]:
In [14]:
# Numpy operation
np.sum([v,w,v,w,v,w], axis=0)
# axis=0 는 row [v,w,v,w,v,w]를 하나의 matrix로 생각했을 때, column별로 sum operation을 하라는 의미
# axis=1 는 row [v,w,v,w,v,w]를 하나의 matrix로 생각했을 때, row별로 sum operation을 하라는 의미
Out[14]:
In [15]:
# Original book verstion
def scalar_multiply(c, v):
return [c * v_i for v_i in v]
In [16]:
v = [5, 6, 7, 8]
scalar = 3
scalar_multiply(scalar, v)
Out[16]:
In [17]:
# Numpy version: Numpy는 배열의 크기가 다르더라도 기본적인 vector연산을 가능하도록 지원해준다. 이를 broadcasting이라고 함
scalar * np.array(v)
Out[17]:
In [18]:
# Original book version
def vector_mean(vectors):
"""compute the vector whose i-th element is the mean of the
i-th elements of the input vectors"""
n = len(vectors)
return scalar_multiply(1/n, vector_sum(vectors))
In [19]:
v = [1,2,3,4]
w = [-4,-3,-2,-1]
vector_mean([v,v,v,v])
Out[19]:
In [20]:
# Original book version
np.mean([v,v,v,v], axis=0)
# axis=0 는 row [v,w,v,w,v,w]를 하나의 matrix로 생각했을 때, column별로 mean operation을 하라는 의미
# axis=1 는 row [v,w,v,w,v,w]를 하나의 matrix로 생각했을 때, row별로 mean operation을 하라는 의미
Out[20]:
In [21]:
# Original book version
def dot(v, w):
"""v_1 * w_1 + ... + v_n * w_n"""
return sum(v_i * w_i for v_i, w_i in zip(v, w))
In [22]:
v = [1,2,3,4]
w = [-4,-3,-2,-1]
dot(v, w)
Out[22]:
In [23]:
# Numpy version
np.dot(v,w)
Out[23]:
In [24]:
# Original book version
def sum_of_squares(v):
"""v_1 * v_1 + ... + v_n * v_n"""
return dot(v, v)
In [25]:
v = [1,2,3,4]
sum_of_squares(v) # v * v = [1,4,9,16]
Out[25]:
In [26]:
# Numpy version
np.dot(v,v) # or sum(np.square(v))
Out[26]:
In [27]:
# Orginal book version
def magnitude(v):
return math.sqrt(sum_of_squares(v))
In [28]:
magnitude(v)
Out[28]:
In [29]:
# Numpy version
np.linalg.norm(v)
Out[29]:
In [30]:
#original version
def squared_distance(v, w):
return sum_of_squares(vector_subtract(v, w))
def distance(v, w):
return math.sqrt(squared_distance(v, w))
In [31]:
v = [1,2,3,4]
w = [-4,-3,-2,-1]
squared_distance(v,w)
Out[31]:
In [32]:
distance(v,w)
Out[32]:
In [33]:
# Numpy version
np.linalg.norm(np.subtract(v,w)) # or np.sqrt(np.sum(np.subtract(v,w)**2))
Out[33]:
In [34]:
def shape(A):
num_rows = len(A)
num_cols = len(A[0]) if A else 0
return num_rows, num_cols
def get_row(A, i):
return A[i]
def get_column(A, j):
return [A_i[j] for A_i in A]
In [35]:
example_matrix = [[1,2,3,4,5], [11,12,13,14,15], [21,22,23,24,25]]
shape(example_matrix)
Out[35]:
In [36]:
get_row(example_matrix, 0)
Out[36]:
In [37]:
get_column(example_matrix,3)
Out[37]:
In [38]:
# Numpy version
np.shape(example_matrix)
Out[38]:
In [39]:
example_matrix = np.array(example_matrix)
example_matrix[0] #row slicing
Out[39]:
In [40]:
example_matrix[:,3] #row slicing
Out[40]:
In [41]:
def make_matrix(num_rows, num_cols, entry_fn):
"""returns a num_rows x num_cols matrix
whose (i,j)-th entry is entry_fn(i, j)"""
return [[entry_fn(i, j) for j in range(num_cols)]
for i in range(num_rows)]
In [42]:
def is_diagonal(i, j):
"""1's on the 'diagonal', 0's everywhere else"""
return 1 if i == j else 0
In [43]:
identity_matrix = make_matrix(5, 5, is_diagonal)
identity_matrix
Out[43]:
In [44]:
# Numpy version
np.identity(5)
Out[44]:
In [45]:
friendships = [[0, 1, 1, 0, 0, 0, 0, 0, 0, 0], # user 0
[1, 0, 1, 1, 0, 0, 0, 0, 0, 0], # user 1
[1, 1, 0, 1, 0, 0, 0, 0, 0, 0], # user 2
[0, 1, 1, 0, 1, 0, 0, 0, 0, 0], # user 3
[0, 0, 0, 1, 0, 1, 0, 0, 0, 0], # user 4
[0, 0, 0, 0, 1, 0, 1, 1, 0, 0], # user 5
[0, 0, 0, 0, 0, 1, 0, 0, 1, 0], # user 6
[0, 0, 0, 0, 0, 1, 0, 0, 1, 0], # user 7
[0, 0, 0, 0, 0, 0, 1, 1, 0, 1], # user 8
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0]] # user 9
In [46]:
def matrix_add(A, B):
if shape(A) != shape(B):
raise ArithmeticError("cannot add matrices with different shapes")
num_rows, num_cols = shape(A)
def entry_fn(i, j): return A[i][j] + B[i][j]
return make_matrix(num_rows, num_cols, entry_fn)
In [47]:
A = [[ 1., 0., 0.], [ 0., 1., 2.]]
B = [[ 5., 4., 3.], [ 2., 2., 2.]]
matrix_add(A,B)
Out[47]:
In [48]:
# Numpy version
np.add(A,B) # vector 마찬가지로 크기 같은 matrix 형태의 list가 돌아오면 자동으로 변환함
Out[48]:
In [51]:
def make_graph_dot_product_as_vector_projection(plt):
v = [2, 1]
w = [math.sqrt(.25), math.sqrt(.75)]
c = dot(v, w)
vonw = scalar_multiply(c, w)
o = [0,0]
plt.arrow(0, 0, v[0], v[1],
width=0.002, head_width=.1, length_includes_head=True)
plt.annotate("v", v, xytext=[v[0] + 0.1, v[1]])
plt.arrow(0 ,0, w[0], w[1],
width=0.002, head_width=.1, length_includes_head=True)
plt.annotate("w", w, xytext=[w[0] - 0.1, w[1]])
plt.arrow(0, 0, vonw[0], vonw[1], length_includes_head=True)
plt.annotate(u"(v•w)w", vonw, xytext=[vonw[0] - 0.1, vonw[1] + 0.1])
plt.arrow(v[0], v[1], vonw[0] - v[0], vonw[1] - v[1],
linestyle='dotted', length_includes_head=True)
plt.scatter(*zip(v,w,o),marker='.')
plt.axis([0,2,0,2]) # 짤리는 부분이 있어서 변경
plt.show()
In [52]:
%pylab inline
make_graph_dot_product_as_vector_projection(plt)