<a href="https://colab.research.google.com/github/TAVAU/data/blob/master/DS_Unit_1_Sprint_Challenge_3_Linear_Algebra.ipynb" target="_parent"></a>

#Linear Algebra

## 1.1 Graph vector $\vec{a}$ 

\begin{align}
\vec{a} = \begin{bmatrix} 3 \\ 2 \end{bmatrix}
\end{align}


```
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
```


```
a = [3,2]
plt.arrow(0,0, a[0], a[1],head_width=.05, head_length=0.05, color ='red')
plt.xlim(-1,4)          
plt.ylim(-1,4)
plt.show()
```

## 1.2 Find $||\vec{b}||$. What does the norm of a vector represent?
\begin{align}
\vec{b} = \begin{bmatrix} 17 & -4 & -2 & 1\end{bmatrix}
\end{align}


\begin{align}
 ||b|| = \sqrt{17^2 + (-4)^2 + (-2)^2 + 1^2} = \sqrt{289 + 16 + 4 + 1} = \sqrt{310} = 17.6
\end{align}

norm is the length of the vector.

## 1.3 Find $\vec{c} \cdot \vec{d}$ - Are these vectors orthogonal? Why or why not?

\begin{align}
\vec{c} = \begin{bmatrix}3 & 7 & -2 & 12\end{bmatrix}
\qquad
\vec{d} = \begin{bmatrix}9 & -7 & 4 & 6\end{bmatrix}
\end{align}


```
c = [3,7,-2,12]
d = [9,-7,4,6]
np_c = np.array(c)
np_d = np.array(d)
np.dot(np_c, np_d)
```




    42



These vectors are not orthogonal, because the dot product is non-zero.

## 1.4 Find $E^{-1}$ and $E^{T}$

\begin{align}
E = 
\begin{bmatrix}
    7 & 4 & 2 \\
    1 & 3 & -1 \\
    2 & 6 & -4
\end{bmatrix}
\end{align}


```
from numpy.linalg import inv

E = np.array([[7,4,2],[1,3,-1],[2,6,-4]])
EE = inv(E)
print(EE)
```

    [[ 0.17647059 -0.82352941  0.29411765]
     [-0.05882353  0.94117647 -0.26470588]
     [ 0.          1.         -0.5       ]]



```
df = pd.DataFrame({'a':[7,1,2],'b':[4,3,6],'c':[2,-1,-4]})
df.head()
df.T
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>0</th>
      <th>1</th>
      <th>2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>a</th>
      <td>7</td>
      <td>1</td>
      <td>2</td>
    </tr>
    <tr>
      <th>b</th>
      <td>4</td>
      <td>3</td>
      <td>6</td>
    </tr>
    <tr>
      <th>c</th>
      <td>2</td>
      <td>-1</td>
      <td>-4</td>
    </tr>
  </tbody>
</table>
</div>



## 1.5 Find $|F|$ - What is one reason why the determinant of a matrix would be 0? 

\begin{align}
F = 
\begin{bmatrix}
    2 & -2 & 5 \\
    4 & 1 & 10 \\
    12 & 6 & 30
\end{bmatrix}
\end{align}


```
from numpy import linalg as LA

F = np.array([[2,-2,5],[4,1,10],[12,6,30]])

print(LA.norm(F))
#What is one reason why the determinant of a matrix would be 0?
#The columns of the matrix are dependent vectors 
```

    35.07135583350036


# Intermediate Linear Algebra

## 2.1 Suppose that the number of customers at a ski resort as well as the number of inches of fresh powder (snow)  was recorded for 7 days. 

### Customers: [820, 760, 1250, 990, 1080, 1450, 1600]

### Inches of new snow: [0, 1, 7, 1, 0, 6, 4 ]

## Find the mean, sample variance, and sample standard deviation for both the number of customers and inches of new snow for the week. Remember that on SCs you can use library functions, dataframes, .describe(), etc. 




```
customers = [820, 760, 1250, 990, 1080, 1450, 1600]
snow = [0, 1, 7, 1, 0, 6, 4]
```


```
##### Your Code Here #####
df = pd.DataFrame({'customers': customers, 'snow': snow})
df
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>customers</th>
      <th>snow</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>820</td>
      <td>0</td>
    </tr>
    <tr>
      <th>1</th>
      <td>760</td>
      <td>1</td>
    </tr>
    <tr>
      <th>2</th>
      <td>1250</td>
      <td>7</td>
    </tr>
    <tr>
      <th>3</th>
      <td>990</td>
      <td>1</td>
    </tr>
    <tr>
      <th>4</th>
      <td>1080</td>
      <td>0</td>
    </tr>
    <tr>
      <th>5</th>
      <td>1450</td>
      <td>6</td>
    </tr>
    <tr>
      <th>6</th>
      <td>1600</td>
      <td>4</td>
    </tr>
  </tbody>
</table>
</div>




```
customers_mean = df.customers.mean()
print("Customers mean:", customers_mean)
snow_mean = df.snow.mean()
print("Snow mean:", snow_mean)

```

    Customers mean: 1135.7142857142858
    Snow mean: 2.7142857142857144



```
print("Customers sample variance: ",df.customers.var(ddof=0))
print("Snow sample variance: ",df.snow.var(ddof=0))
```

    Customers sample variance:  84653.06122448981
    Snow sample variance:  7.346938775510203



```
print("Customers sample standard deviation: ",df.customers.std(ddof=0))
print("Snow sample standard deviation: ",df.snow.std(ddof=0))
```

    Customers sample standard deviation:  290.95199127087926
    Snow sample standard deviation:  2.7105237087157534


## 2.2 Are the variances of the number of customers and inches of snow comparable? 
## Why or why not? 


```
# no, they are exaggerated differences from the mean, if we have to compare, we need the standard deviation value
```

## 2.3 Find the variance-covariance matrix for the number of customers and inches of snow at the ski resort. 


```
df.cov()
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>customers</th>
      <th>snow</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>customers</th>
      <td>98761.904762</td>
      <td>670.238095</td>
    </tr>
    <tr>
      <th>snow</th>
      <td>670.238095</td>
      <td>8.571429</td>
    </tr>
  </tbody>
</table>
</div>



# PCA

## 3.1 Standardize the data so that it has a mean of 0 and a standard deviation of 1. 

We have included some code to get you started so that you don't get stuck on something that isn't standardizing the data or PCA.

This might be helpful:

<https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html>


```
# Let me get you some data to start you off.
import pandas as pd

data = {"Country": ["England","Wales","Scotland","North Ireland"], 
        "Cheese": [105,103,103,66], 
        "Carcass_Meat": [245,227,242,267], 
        "Other_Meat": [685, 803, 750, 586], 
        "Fish": [147, 160, 122, 93], 
        "Fats_and_Oils": [193, 235, 184, 209], 
        "Sugars": [156, 175, 147, 139], 
        "Fresh_Potatoes": [720, 874, 566, 1033], 
        "Fresh_Veg": [253, 265, 171, 143], 
        "Other_Veg": [488, 570, 418, 355], 
        "Processed_Potatoes": [198, 203, 220, 187], 
        "Processed_Veg": [360, 365, 337, 334], 
        "Fresh_Fruit": [1102, 1137, 957, 674], 
        "Cereals": [1472, 1582, 1462, 1494], 
        "Beverages": [57,73,53,47], 
        "Soft_Drinks": [1374, 1256, 1572, 1506], 
        "Alcoholic Drinks": [375, 475, 458, 135], 
        "Confectionery": [54, 64, 62, 41]}

df = pd.DataFrame(data)

# Look at the data
df.head()
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>Country</th>
      <th>Cheese</th>
      <th>Carcass_Meat</th>
      <th>Other_Meat</th>
      <th>Fish</th>
      <th>Fats_and_Oils</th>
      <th>Sugars</th>
      <th>Fresh_Potatoes</th>
      <th>Fresh_Veg</th>
      <th>Other_Veg</th>
      <th>Processed_Potatoes</th>
      <th>Processed_Veg</th>
      <th>Fresh_Fruit</th>
      <th>Cereals</th>
      <th>Beverages</th>
      <th>Soft_Drinks</th>
      <th>Alcoholic Drinks</th>
      <th>Confectionery</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>England</td>
      <td>105</td>
      <td>245</td>
      <td>685</td>
      <td>147</td>
      <td>193</td>
      <td>156</td>
      <td>720</td>
      <td>253</td>
      <td>488</td>
      <td>198</td>
      <td>360</td>
      <td>1102</td>
      <td>1472</td>
      <td>57</td>
      <td>1374</td>
      <td>375</td>
      <td>54</td>
    </tr>
    <tr>
      <th>1</th>
      <td>Wales</td>
      <td>103</td>
      <td>227</td>
      <td>803</td>
      <td>160</td>
      <td>235</td>
      <td>175</td>
      <td>874</td>
      <td>265</td>
      <td>570</td>
      <td>203</td>
      <td>365</td>
      <td>1137</td>
      <td>1582</td>
      <td>73</td>
      <td>1256</td>
      <td>475</td>
      <td>64</td>
    </tr>
    <tr>
      <th>2</th>
      <td>Scotland</td>
      <td>103</td>
      <td>242</td>
      <td>750</td>
      <td>122</td>
      <td>184</td>
      <td>147</td>
      <td>566</td>
      <td>171</td>
      <td>418</td>
      <td>220</td>
      <td>337</td>
      <td>957</td>
      <td>1462</td>
      <td>53</td>
      <td>1572</td>
      <td>458</td>
      <td>62</td>
    </tr>
    <tr>
      <th>3</th>
      <td>North Ireland</td>
      <td>66</td>
      <td>267</td>
      <td>586</td>
      <td>93</td>
      <td>209</td>
      <td>139</td>
      <td>1033</td>
      <td>143</td>
      <td>355</td>
      <td>187</td>
      <td>334</td>
      <td>674</td>
      <td>1494</td>
      <td>47</td>
      <td>1506</td>
      <td>135</td>
      <td>41</td>
    </tr>
  </tbody>
</table>
</div>




```
df = df.drop(['Country'],axis=1)
df
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>Cheese</th>
      <th>Carcass_Meat</th>
      <th>Other_Meat</th>
      <th>Fish</th>
      <th>Fats_and_Oils</th>
      <th>Sugars</th>
      <th>Fresh_Potatoes</th>
      <th>Fresh_Veg</th>
      <th>Other_Veg</th>
      <th>Processed_Potatoes</th>
      <th>Processed_Veg</th>
      <th>Fresh_Fruit</th>
      <th>Cereals</th>
      <th>Beverages</th>
      <th>Soft_Drinks</th>
      <th>Alcoholic Drinks</th>
      <th>Confectionery</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>105</td>
      <td>245</td>
      <td>685</td>
      <td>147</td>
      <td>193</td>
      <td>156</td>
      <td>720</td>
      <td>253</td>
      <td>488</td>
      <td>198</td>
      <td>360</td>
      <td>1102</td>
      <td>1472</td>
      <td>57</td>
      <td>1374</td>
      <td>375</td>
      <td>54</td>
    </tr>
    <tr>
      <th>1</th>
      <td>103</td>
      <td>227</td>
      <td>803</td>
      <td>160</td>
      <td>235</td>
      <td>175</td>
      <td>874</td>
      <td>265</td>
      <td>570</td>
      <td>203</td>
      <td>365</td>
      <td>1137</td>
      <td>1582</td>
      <td>73</td>
      <td>1256</td>
      <td>475</td>
      <td>64</td>
    </tr>
    <tr>
      <th>2</th>
      <td>103</td>
      <td>242</td>
      <td>750</td>
      <td>122</td>
      <td>184</td>
      <td>147</td>
      <td>566</td>
      <td>171</td>
      <td>418</td>
      <td>220</td>
      <td>337</td>
      <td>957</td>
      <td>1462</td>
      <td>53</td>
      <td>1572</td>
      <td>458</td>
      <td>62</td>
    </tr>
    <tr>
      <th>3</th>
      <td>66</td>
      <td>267</td>
      <td>586</td>
      <td>93</td>
      <td>209</td>
      <td>139</td>
      <td>1033</td>
      <td>143</td>
      <td>355</td>
      <td>187</td>
      <td>334</td>
      <td>674</td>
      <td>1494</td>
      <td>47</td>
      <td>1506</td>
      <td>135</td>
      <td>41</td>
    </tr>
  </tbody>
</table>
</div>




```
data = df[['Cheese','Carcass_Meat','Other_Meat','Fish','Fats_and_Oils','Sugars','Fresh_Potatoes','Fresh_Veg','Other_Veg','Processed_Potatoes','Processed_Veg','Fresh_Fruit','Cereals','Beverages','Soft_Drinks','Alcoholic Drinks','Confectionery']].values
data

```




    array([[ 105,  245,  685,  147,  193,  156,  720,  253,  488,  198,  360,
            1102, 1472,   57, 1374,  375,   54],
           [ 103,  227,  803,  160,  235,  175,  874,  265,  570,  203,  365,
            1137, 1582,   73, 1256,  475,   64],
           [ 103,  242,  750,  122,  184,  147,  566,  171,  418,  220,  337,
             957, 1462,   53, 1572,  458,   62],
           [  66,  267,  586,   93,  209,  139, 1033,  143,  355,  187,  334,
             674, 1494,   47, 1506,  135,   41]])




```
##### Your Code Here #####
from numpy import array
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA

scaler = StandardScaler()
Z = scaler.fit_transform(data)
Z

```




    array([[ 0.65827466, -0.01749546, -0.25954622,  0.64458535, -0.63242919,
             0.13055067, -0.45007561,  0.86331183,  0.37773603, -0.33626508,
             0.80547723,  0.73740709, -0.64432226, -0.05191741, -0.43523112,
             0.10499766, -0.13830319],
           [ 0.53580495, -1.27716878,  1.19885635,  1.15244047,  1.53589947,
             1.54795798,  0.43569619,  1.09352832,  1.40168163,  0.08406627,
             1.17160324,  0.9292974 ,  1.67946294,  1.60943981, -1.40423624,
             0.84182336,  0.96812236],
           [ 0.53580495, -0.22744102,  0.54381113, -0.33205912, -1.09707105,
            -0.54085279, -1.33584741, -0.70983418, -0.49636387,  1.51319287,
            -0.87870243, -0.0575671 , -0.85557546, -0.46725672,  1.19072664,
             0.71656299,  0.74683725],
           [-1.72988456,  1.52210526, -1.48312126, -1.4649667 ,  0.19360077,
            -1.13765587,  1.35022682, -1.24700598, -1.28305378, -1.26099406,
            -1.09837804, -1.60913739, -0.17956522, -1.09026568,  0.64874072,
            -1.66338402, -1.57665641]])



## 3.2 Perform PCA on the data and graph Principal Component 1 against Principal Component 2. 

This might be helpful:

<https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html>


```
##### Your Code Here #####
pca = PCA(2)
# fit on data
pca.fit(Z)
print("\n Eigenvectors: \n", pca.components_)
print("\n Eigenvalues: \n",pca.explained_variance_)
# transform data
B = pca.transform(Z)
print("\n Projected Data: \n", B)
```

    
     Eigenvectors: 
     [[-0.24572131  0.28562914 -0.26481055 -0.28611787 -0.12719487 -0.2811012
       0.09775901 -0.26544997 -0.28708628 -0.12073819 -0.25767815 -0.27890521
      -0.17843996 -0.27747513  0.22771961 -0.25509484 -0.25275834]
     [ 0.24708041 -0.07716993  0.13610704 -0.01100602 -0.40054501 -0.13684092
      -0.45468785 -0.0964863  -0.09282322  0.41036129 -0.1539603   0.08174644
      -0.32902948 -0.13773847  0.29323981  0.23231808  0.21105701]]
    
     Eigenvalues: 
     [15.48765084  5.63749203]
    
     Projected Data: 
     [[-0.95448984  0.32831832]
     [-4.52095094 -1.73537967]
     [ 0.48797835  3.23367195]
     [ 4.98746242 -1.8266106 ]]



```
PC1 = B[:,0:1]
# print(PC1)
PC2 = B[:,1:2]
plt.scatter(PC1,PC2)
```

## 3.3 What are Eigenvalues and Eigenvectors? -In general, not just in PCA.

Eigenvectors is a vector that tell us some information about the data set.

Eigenvalue is the scalar that represents how its corresponding eigenvector was scaled during the transformation. 

Eigenvectors and eigenvalues always come in pairs.

# Clustering

## 4.1 Use K-Means to cluster the following data and then graph your results. 

We have included some code to get you started so that you don't get stuck on something that isn't standardizing clustering.

Prioritize calculating the clusters over graphing them. 

Scikit-Learn K-Means Documentation:

<https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html>


```
points = pd.read_csv('https://raw.githubusercontent.com/ryanleeallred/datasets/master/points.csv')
points.head()
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>x</th>
      <th>y</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>-7.846803</td>
      <td>-3.421277</td>
    </tr>
    <tr>
      <th>1</th>
      <td>-3.554323</td>
      <td>-6.884729</td>
    </tr>
    <tr>
      <th>2</th>
      <td>-0.192822</td>
      <td>-9.671030</td>
    </tr>
    <tr>
      <th>3</th>
      <td>-6.401456</td>
      <td>-5.223972</td>
    </tr>
    <tr>
      <th>4</th>
      <td>-0.804026</td>
      <td>-9.704457</td>
    </tr>
  </tbody>
</table>
</div>




```
##### Your Code Here #####
print(points.shape)
```

    (200, 2)



```
plt.scatter(points.x, points.y)
plt.show()
```


```
dataset_centroid_x = points.x.mean()
dataset_centroid_y = points.y.mean()

print(dataset_centroid_x, dataset_centroid_y)
```

    -2.32329816340267 -3.4228690080745237



```
centroids = points.sample(4)
centroids.head()
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>x</th>
      <th>y</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>3</th>
      <td>-6.401456</td>
      <td>-5.223972</td>
    </tr>
    <tr>
      <th>107</th>
      <td>-8.816448</td>
      <td>-4.532454</td>
    </tr>
    <tr>
      <th>187</th>
      <td>7.430405</td>
      <td>3.004416</td>
    </tr>
    <tr>
      <th>53</th>
      <td>-4.103054</td>
      <td>4.058929</td>
    </tr>
  </tbody>
</table>
</div>




```
ax = plt.subplot(1,1,1)
ax.scatter(points.x, points.y)
ax.plot(centroids.iloc[0].x, centroids.iloc[0].y, "or")
ax.plot(centroids.iloc[1].x, centroids.iloc[1].y, "og")
ax.plot(centroids.iloc[2].x, centroids.iloc[2].y, "oy")
ax.plot(centroids.iloc[3].x, centroids.iloc[3].y, "ob")
plt.show()
```


```
import math
import numpy as np
from scipy.spatial import distance

# Calculate the Nearest Centroid to each data point
def find_nearest_centroid(df, centroids, iteration):
 
  # calculate the distances between each point and each centroid
  distances = distance.cdist(df, centroids, 'euclidean')
  
  # Get nearest centroid to each point based on distance
  nearest_centroids = np.argmin(distances, axis=1)

  se = pd.Series(nearest_centroids)
  df['cluster_'+iteration] = se.values
  
  return df
```


```
first_pass = find_nearest_centroid(points.select_dtypes(exclude='int64'), centroids, '1')
first_pass.head()
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>x</th>
      <th>y</th>
      <th>cluster_1</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>-7.846803</td>
      <td>-3.421277</td>
      <td>1</td>
    </tr>
    <tr>
      <th>1</th>
      <td>-3.554323</td>
      <td>-6.884729</td>
      <td>0</td>
    </tr>
    <tr>
      <th>2</th>
      <td>-0.192822</td>
      <td>-9.671030</td>
      <td>0</td>
    </tr>
    <tr>
      <th>3</th>
      <td>-6.401456</td>
      <td>-5.223972</td>
      <td>0</td>
    </tr>
    <tr>
      <th>4</th>
      <td>-0.804026</td>
      <td>-9.704457</td>
      <td>0</td>
    </tr>
  </tbody>
</table>
</div>




```
def plot_clusters(df, column_header, centroids):
  # colors = {0:'red', 1:'green', 2:'yellow', 3:'blue', 4:'black'}
  fig, ax = plt.subplots()
  ax.plot(centroids.iloc[0].x, centroids.iloc[0].y, "ok")
  ax.plot(centroids.iloc[1].x, centroids.iloc[1].y, "ok")
  ax.plot(centroids.iloc[2].x, centroids.iloc[2].y, "ok")
  ax.plot(centroids.iloc[3].x, centroids.iloc[3].y, "ok")
  grouped = df.groupby(column_header)
  for key, group in grouped:
      group.plot(ax=ax, kind='scatter', x='x', y='y', label=key)
  plt.show()
  
plot_clusters(first_pass, 'cluster_1', centroids)
```


```
def get_centroids(df, column_header):
  new_centroids = df.groupby(column_header).mean()
  return new_centroids

centroids = get_centroids(first_pass, 'cluster_1')
```


```
# Calculate New Centroids
centroids = get_centroids(first_pass, 'cluster_1')

# Get Clusters for New Centroids
second_pass = find_nearest_centroid(first_pass.select_dtypes(exclude='int64'), centroids, '2')

# Plot New Cluster
plot_clusters(second_pass, 'cluster_2', centroids)
```


```
convergence = np.array_equal(first_pass['cluster_1'], second_pass['cluster_2'])
print("Are we at convergence?? - ", convergence)
```

    Are we at convergence?? -  False



```
# Calculate New Centroids
centroids = get_centroids(second_pass, 'cluster_2')

# Get Clusters for New Centroids
third_pass = find_nearest_centroid(second_pass.select_dtypes(exclude='int64'), centroids, '3')

# Plot New Cluster
plot_clusters(third_pass, 'cluster_3', centroids)
```


```
convergence = np.array_equal(second_pass['cluster_2'], third_pass['cluster_3'])
print("Are we at convergence?? - ", convergence)
```

    Are we at convergence?? -  True



```
centroids = points.sample(4)
centroids.head()
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>x</th>
      <th>y</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>23</th>
      <td>6.405280</td>
      <td>4.383793</td>
    </tr>
    <tr>
      <th>118</th>
      <td>7.189418</td>
      <td>4.430709</td>
    </tr>
    <tr>
      <th>81</th>
      <td>-4.417031</td>
      <td>-6.245594</td>
    </tr>
    <tr>
      <th>149</th>
      <td>-3.710453</td>
      <td>-7.548886</td>
    </tr>
  </tbody>
</table>
</div>




```
from scipy.spatial.distance import cdist 
def find_nearest_centroid(df, centroids):
  last_centroids = [np.random.choice([0,1,2,3])] * df.shape[0]
  df_temp = df.copy()
  i = 0
  
  while True:
    if i>0:
      centroids = get_centroids(df_temp, 'cluster' + str(i-1))

    distances = cdist(df_temp[['x', 'y']], centroids[['x', 'y']])
    nearest_centroids = np.argmin(distances, axis=1)
    
    df_temp['cluster' + str(i)] = nearest_centroids
    
    if (list(nearest_centroids) == list(last_centroids)):
      return df_temp
    else:
      i +=1
      last_centroids = nearest_centroids
      
def get_centroids(df, column_header):
  x = [df.x[df[column_header]==0].mean(), df.x[df[column_header]==1].mean(), df.x[df[column_header]==2].mean()]
  y = [df.y[df[column_header]==0].mean(), df.y[df[column_header]==1].mean(), df.y[df[column_header]==2].mean()]
  data = {'x': x, 'y' : y}
  return pd.DataFrame(data)
  
  
final_df = find_nearest_centroid(points, centroids)
final_df.head()
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>x</th>
      <th>y</th>
      <th>cluster0</th>
      <th>cluster1</th>
      <th>cluster2</th>
      <th>cluster3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>-7.846803</td>
      <td>-3.421277</td>
      <td>2</td>
      <td>2</td>
      <td>2</td>
      <td>2</td>
    </tr>
    <tr>
      <th>1</th>
      <td>-3.554323</td>
      <td>-6.884729</td>
      <td>3</td>
      <td>2</td>
      <td>2</td>
      <td>2</td>
    </tr>
    <tr>
      <th>2</th>
      <td>-0.192822</td>
      <td>-9.671030</td>
      <td>3</td>
      <td>2</td>
      <td>2</td>
      <td>2</td>
    </tr>
    <tr>
      <th>3</th>
      <td>-6.401456</td>
      <td>-5.223972</td>
      <td>2</td>
      <td>2</td>
      <td>2</td>
      <td>2</td>
    </tr>
    <tr>
      <th>4</th>
      <td>-0.804026</td>
      <td>-9.704457</td>
      <td>3</td>
      <td>2</td>
      <td>2</td>
      <td>2</td>
    </tr>
  </tbody>
</table>
</div>




```
plt.scatter(final_df['x'],final_df['y'])
```

# Stretch Goals (AKA how to get a 3):

Complete the stretch goals for each section in order to get a 3 on that section.

## Parts 1 & 2 (do all of the following): 
  - Comment your code well with both markdown and inline comments where appropriate
  - Show your work with code and possibly LaTeX 
  - Justify your answers particularly well to show advanced mastery of this section

## Part 3 (do all of the following): 
 - Create a Scree Plot to show the Proportion of Explained Variance of each Principal Component (more than the first two)
    - If you want to include a the cumulative proportion of explained variance, you might be interested in this NumPy Function: [numpy.cumsum](https://docs.scipy.org/doc/numpy/reference/generated/numpy.cumsum.html)
 - Give a top-notch explanation of eigenvalues and eigenvectors. Feel free to any materials, images, code, graphs, LaTeX, etc. to spruce up your answer.

## Part 4 (do all of the following):
- Justify your choice of k, both visually (scatterplot) and mathematically (elbow plot).


```

```

380daf2d75291ef79309589843bcb52b2ede9cd5
ipynb
Jupyter Notebook
DS_Unit_1_Sprint_Challenge_3_Linear_Algebra.ipynb
TAVAU/data
8aeeb6359c09c929f0aab13892e7a63e0fd8917a
CC-BY-4.0
DS_Unit_1_Sprint_Challenge_3_Linear_Algebra.ipynb
TAVAU/data
8aeeb6359c09c929f0aab13892e7a63e0fd8917a
CC-BY-4.0
DS_Unit_1_Sprint_Challenge_3_Linear_Algebra.ipynb
TAVAU/data
8aeeb6359c09c929f0aab13892e7a63e0fd8917a
CC-BY-4.0
2021-12-17T20:13:27.000Z
2021-12-17T20:13:27.000Z
Qwen/Qwen-72B
1. YES
2. YES