<jupyter_start><jupyter_text>The purpose of this quick entry is to show the difference in computation-time between a for loop and a vectorized dot-product.<jupyter_code>import numpy as np
import time
import math
x = np.random.rand(10000000)
w = np.random.rand(10000000)
y=0
tic = time.time()
y = np.dot(w,x)
toc = time.time()

print(toc-tic)
y=0
tic = time.time()
for i in range(len(x)):
    y = y + (x[i] * w[i])
toc = time.time()

print(toc - tic)<jupyter_output>11.33963394165039<jupyter_text>Wow... the for loop took almost 1000 times the time as the vectorized dot-product!!!Let's look at another example:<jupyter_code>tic = time.time()
y = np.exp(x)
toc = time.time()
print(toc-tic)
y = np.zeros([len(x), 1])
tic = time.time()
for i in range(len(x)):
    y[i] = math.exp(x[i])
toc = time.time()

print(toc - tic)<jupyter_output>10.307820320129395<jupyter_text>Once again, vectorizing speeds up the process by ALOT!!!  Now let's take a look at the logistic regression algorithm, and what it looks like vectorized vs unvectorized: 1. $m$ is the number of datapoints in $X$2. $n$ is the number of features each datapoint in $X$ has3. $X$ is an $mxn$ matrix. It's got $m$ rows and $n$ columns. Each row corresponds to an individual datapoint $\vec{x}$, holding information about $n$ features each. It's randomly generated. 4. $Y$ is a vector holding the correct labels for each of our $\vec{x}_s$ - the $i_{th}$ entry in $\vec{Y}$, which we'll call $y_i$, is the correct label for the $i_{th}$ row of $X$, which we'll call $\vec{x}_i$. Each entry (row) in $Y$ is given by the sigmoid of the linear combination of the two features *(columns)* of each row of $X: 0.2C_0 - 0.3C_1$. In other words, $0.2 \hat{i} - 0.3\hat{j}$ is the correct weight vector that we hope our logistic regression algorithm will get to. $Y$ can only hold $1_s$ and $0_s$, *(we're assuming that the correct labels are binary)* which is what the next few lines are doing - turning the labels in $Y$ into $1_s$ and $0_s$<jupyter_code>m = 10 
n=2
X = np.random.rand(m, n)
Y = np.dot(X, ([.2, -.3]))

for val in range(len(Y)):
    Y[val] = (1/(1 + math.exp(-Y[val])))
Y = np.round(Y)
print(X)
print(Y)
W = [.1, -.1]
b = np.random.randint(-5, 5)
E=0; db=0;
dW = [0,0]
for loopyloop in range(1000):
    for i in range(m):    
        z = 0
        for j in range(n):
            z += W[j]*X[i,j]
            z += b
        a = 1 / (1 + math.exp(-z))
        L = -(Y[i]*math.log(a) + (1-Y[i])*math.log(1-a))
        E += L


        dz = a-Y[i]
        for j in range(n):
            dW[j] += X[i,j]*dz

        db += dz

    db = db/m
    dW = [dw/m for dw in dW]
    E = E/m

    for w in range(len(W)):
        W[w] -= (dW[w])
    b -= db
    
    if loopyloop%20 == 0:
        print(E)
print(E)
print(dW)
print(W)
print(b)<jupyter_output>4.432921336272889e-05
[1.9962283174205204e-05, 2.477167713284318e-05]
[0.07879016806161626, -0.12630085216799286]
-5.046993099574763
{'fraction_non_alphanumeric': 0.1539768864717879, 'fraction_numerical': 0.07070020394289599, 'mean_word_length': 3.180397727272727, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '382094', 'license': 'MIT', 'n_tokens_mistral': 1296, 'n_tokens_neox': 1151, 'n_words': 383, 'path': 'Vectorizing vs For-Loop.ipynb', 'repo_name': 'joshuaronis/Coursera-Course-Programs', 'size': '2942'}