diff --git "a/week1/1\355\214\200_\354\230\244\353\217\231\355\233\210.md" "b/week1/1\355\214\200_\354\230\244\353\217\231\355\233\210.md"
new file mode 100644
index 0000000..6052c16
--- /dev/null
+++ "b/week1/1\355\214\200_\354\230\244\353\217\231\355\233\210.md"
@@ -0,0 +1,145 @@
+# KNN 알고리즘 개요
+
+- 개념 : 어떤 데이터가 주어지면 그 주변의 데이터를 살펴본 뒤 더 많은 데이터가 포함되어 있는 범주로 분류하는 방식
+- 특징 : 훈련 데이터를 저장하는 것이 훈련의 전부이다.
+
+
+
+
+
+# 혼공머신 - knn 알고리즘을 이용한 생선 분류
+
+## **데이터 살펴보기**
+
+
+
+왼쪽 영역에 분포하는 데이터가 빙어, 오른쪽 영역에 분포하는 데이터가 도미를 의미한다.
+
+앞으로 사용할 데이터를 다음과 같이 정의한다.
+
+```python
+length = bream_length + smelt_length
+weight = bream_weight + smel_weight
+
+fish_data = [[l, w]] for l,w in zip(length, weight)
+
+# 1: 도미, 2: 빙어
+# 35 개의 도미 데이터와 14개의 빙어 데이터를 사용한다.
+fish_target = [1]*35 + [0]*14
+
+```
+
+## knn 알고리즘을 이용한 도미 빙어 데이터 구분
+
+사이킷 런의 KneighborsClassifer 를 통해 knn 알고리즘을 사용할 수 있다.
+```python
+from sklearn.neighbors import KNeighborsClassifier
+
+# KNN 객체 생성
+kn = KNeighborsClassifier(n_neighbors=49)
+# fit() : 주어진 데이터로 알고리즘을 훈련
+kn.fit(fish_data, fish_target)
+# score() : 0~1 사이의 값 반환
+kn.score(fish_data, fish_target)
+```
+
+## **훈련 세트 & 데이터 세트 분리**
+
+혼공머신 Chapter1,2 에서는 다음의 두 가지 방식으로 훈련 데이터와 테스트 데이터를 분류한다.
+
+- 각 데이터의 index를 랜덤으로 정렬해서 데이터를 임의로 뽑아내는 방식으로 훈련 데이터와 테스트 데이터를 분류한다.
+- 사이킷런의 train_test_split 을 사용한다.
+
+두 번째 방식으로 데이터를 분리하는 것이 깔끔하다.
+
+```python
+from sklearn.model_selection import train_test_split
+
+train_input, test_input, train_target, test_target = train_test_split(fish_data, fish_target, random_state = 42)
+```
+
+## **데이터 학습**
+
+데이터 전처리를 거치지 않고 일단, train data / test data 분리 된 것을 훈련시켰을 때 다음과 같은 결과가 나온다.
+
+*코드*
+```python
+kn = KNeighborsClassifier()
+# train
+kn.fit(train_input, train_target)
+# test
+kn.score(test_input, test_target)
+
+# (25, 150) 특성 값을 가지는 데이터를 예측해보자.
+kn.predict([[25,150]]) >>> 결과값은 빙어(0) 를 가리킨다.
+
+# 최근접 이웃을 확인해보자.
+# import matplotlib.pyplot as plt
+plt.scatter(train_input[:, 0], train_input[:,1])
+plt.scatter(25, 150, marker='^')
+# 최근접 이웃 표시
+plt.scatter(train_input[indexes,0], train_input[indexes,1], marker='D')
+plt.show()
+```
+
+
+
+> 최근접 이웃 k = 5로 지정했을 때 과반수 이상의 3 개의 이웃이 빙어 데이터를 가리키므로 산접도 상 샘플 데이터는 도미에 가깝지만 빙어로 예측하게 된다. 이를 해결하기 위해 데이터 전처리 과정을 거쳐야 한다.
+
+
+
+## **데이터 전처리**
+
+z-표준점수 정규화 방법을 사용한다. 즉, 다음의 수식을 활용한다.
+
+$$z = \frac{자료 값 - 평균}{표준편차}$$
+
+*코드*
+```python
+# 평균, 표준편차
+# import nupmy as np
+mean = np.mean(train_input, axis=0)
+std = np.std(train_input, axis=0)
+
+# 전처리 데이터
+train_scaled = (train_input - mean) / std
+
+# 전처리 데이터로 모델 훈련
+plt.scatter(train_scaled[:,0], train_scaled[:,1])
+# 전처리 데이터와 마찬가지로 테스트 데이터도 전처리 해야됨.
+plt.scatter(25, 150,marker='^')
+plt.show()
+```
+*결과*
+
+
+> 빙어 데이터 와 샘플 데이터의 차이가 뚜렷해졌다.
+
+
+## **전처리 데이터로 모델 훈련**
+
+*코드*
+```python
+new_sample_scaled = ([25, 150] - mean) / std
+plt.scatter(train_scaled[:,0], train_scaled[:,1])
+plt.scatter(new_sample_scaled[0], new_sample_scaled[1])
+
+# 최근접 이웃 표시
+distances, indexes = kn.kneighbors([new_sample_scaled])
+plt.scatter(train_scaled[:,0], train_scaled[:,1])
+plt.scatter(new_sample_scaled[0], new_sample_scaled[1], marker='^')
+plt.scatter(train_scaled[indexes, 0], train_scaled[indexes, 1], marker='D')
+plt.show()
+
+```
+
+*결과*
+
+
+
+최근접 이웃 모두 도미 데이터 이미로 샘플 데이터 역시 '도미' 로 예측하게 된다.
+
+```python
+print(kn.predict([new_sample_scaled]))
+>>> [1]
+```
diff --git a/week1/images/2022-03-22-11-24-12.png b/week1/images/2022-03-22-11-24-12.png
new file mode 100644
index 0000000..2c257ae
Binary files /dev/null and b/week1/images/2022-03-22-11-24-12.png differ
diff --git a/week1/images/2022-03-22-11-33-30.png b/week1/images/2022-03-22-11-33-30.png
new file mode 100644
index 0000000..398164a
Binary files /dev/null and b/week1/images/2022-03-22-11-33-30.png differ
diff --git a/week1/images/2022-03-22-11-33-47.png b/week1/images/2022-03-22-11-33-47.png
new file mode 100644
index 0000000..398164a
Binary files /dev/null and b/week1/images/2022-03-22-11-33-47.png differ
diff --git a/week1/images/2022-03-22-11-34-17.png b/week1/images/2022-03-22-11-34-17.png
new file mode 100644
index 0000000..e6adad8
Binary files /dev/null and b/week1/images/2022-03-22-11-34-17.png differ
diff --git a/week1/images/2022-03-22-14-17-45.png b/week1/images/2022-03-22-14-17-45.png
new file mode 100644
index 0000000..4c70f3f
Binary files /dev/null and b/week1/images/2022-03-22-14-17-45.png differ
diff --git a/week1/images/2022-03-22-14-24-50.png b/week1/images/2022-03-22-14-24-50.png
new file mode 100644
index 0000000..0213407
Binary files /dev/null and b/week1/images/2022-03-22-14-24-50.png differ
diff --git a/week1/images/2022-03-22-14-29-46.png b/week1/images/2022-03-22-14-29-46.png
new file mode 100644
index 0000000..af19e7d
Binary files /dev/null and b/week1/images/2022-03-22-14-29-46.png differ
diff --git a/week1/images/2022-03-22-14-34-34.png b/week1/images/2022-03-22-14-34-34.png
new file mode 100644
index 0000000..81ea0bb
Binary files /dev/null and b/week1/images/2022-03-22-14-34-34.png differ
diff --git "a/week2/1\355\214\200_\354\230\244\353\217\231\355\233\210.md" "b/week2/1\355\214\200_\354\230\244\353\217\231\355\233\210.md"
new file mode 100644
index 0000000..4740dcd
--- /dev/null
+++ "b/week2/1\355\214\200_\354\230\244\353\217\231\355\233\210.md"
@@ -0,0 +1,328 @@
+# Notation
+
+## K-최근접 이웃 회귀
+
+- k-최근접 이웃 회귀 알고리즘은 가장 가까운 n 개의 이웃을 선택, 확률을 계산하여 새로운 데이터 특성을 예측하는 방식이다.
+- 계산 과정이 간단하지만 기존 데이터 범위를 넘어서는 경우 정확도가 매우 떨어진다.
+
+
+
+
+## 선형 회귀
+
+- 선형 회귀란 y = ax + b 와 같은 선형 방정식 형태로 표현. a 를 coefficient 라고 하고 b를 weight 라고 한다.
+- 다항 회귀란, y를 x에 대한 다항식으로 표현하여 모델링하는 것을 말한다. n차 방정식과 동일.
+
+
+## 다중 회귀
+
+- 다중 회귀란 목표 변수 y를 여러 개의 독립된 변수 a,b,c ... 들의 관계로 나타내는 알고리즘이다.
+- 다항 회귀는 독립변수 x의 차수가 n으로 높아진 것이며 다중 회귀는 이와 달리 서로 다른 독립 변수 a,b,c... 가 존재한다.
+
+
+
+
+## Overfitting vs. Underfitting
+
+- overfitting : 어떤 모델이 훈련 데이터의 성질에 너무 깊게 학습되어 훈련 데이터에 대한 예측 성능은 매우 높지만 새로운 데이터에 대해서 score 가 매우 떨어지는 현상.
+
+- underfitting : 훈련 데이터의 특성이 충분히 학습되지 않아 성능이 떨어지는 현상.
+-
+
+## 규제(릿지&라쏘)
+
+- 오버피팅을 막기 위해 모델이 과도하게 학습되는 것을 규제를 통해 조절.
+- 계수를 제곱한 기준으로 규제를 가한 모델을 릿지, 절댓값을 기준으로 하면 라쏘 라고 한다.
+
+
+
+
+
+
+# 혼공머신 K-최근접 회귀 문제
+
+목표 : 농어 길이 데이터를 바탕으로 무게를 추론하는 회귀 모델을 학습.
+
+## 산점도로 데이터 살펴 보기
+
+(미리 준비된 'perch_length', 'perch_weight' 데이터 이용.)
+
+
+
+
+## train data & test data 분리
+
+```python
+from sklearn.model_selection import train_test_split
+train_input, test_input, train_target, test_target = train_test_split(
+ perch_length, perch_weight, random_state=42
+)
+
+# column vector 로 input 데이터 조정.
+train_input = train_input.reshape(-1,1)
+test_input = test_input.reshape(-1,1)
+```
+
+## k-최근접 이웃 회귀 모델 훈련
+
+```python
+from sklearn.neighbors import KNeighborsRregressor
+knr = KNeighborsRegressor()
+knr.fit(train_input, train_target) # 모델 훈련
+
+# 모델을 결정계수로 평가.
+print(knr.score(test_input, test_target))
+
+>>> 0.992809406101064
+
+# 이웃의 개수를 3으로 설정해서 모델을 조금 더 예민하게 조정.
+knr.fit(train_input, train_target)
+print(knr.score(train_input, train_target))
+print(knr.score(test_input, test_target))
+
+>>> 0.9804899950518966
+>>> 0.9746459963987609
+```
+
+## 선형 회귀 문제
+
+- k-최근접 이웃 회귀 모델로 예측하기 어려운 새로운 데이터를 사용할 수 있도록 선형 회귀 모델 사용.
+```python
+# 기존 데이터에 없는 50cm 농어 데이터, 100cm 농어 데이터
+knr.predict([[50]])
+
+>>> array([1033.33333333])
+
+knr.predict([[100]])
+
+>>> array([1033.33333333])
+```
+이웃 샘플이 동일 하기 때문에 같은 값으로 예측이 되는 문제 발생. 이런 문제를 선형 회귀를 통해 해결.
+
+
+## 선형 회귀 모델
+```python
+from sklearn.linear_model import LinearRegression
+lr = LinearRegression()
+
+# 선형 회귀 모델을 훈련합니다.
+lr.fit(train_input, train_target)
+
+# 15에서 50까지 1차 방정식 그래프를 그립니다.
+plt.plot([15,50], [15*lr.coef_ + lr.intercept_, 50*lr.coef_ + lr.intercept_])
+
+# 훈련 세트의 산점도를 그립니다.
+plt.scatter(train_input, train_target)
+
+# 50cm 농어 데이터를 따로 표시합니다.
+plt.scatter(50, lr.predict([[50]]), marker='^')
+plt.xlabel('length')
+plt.ylabel('weight')
+plt.show()
+```
+
+
+```python
+# 훈련 점수와 테스트 점수 비교
+print(lr.score(train_input, train_target))
+print(lr.score(test_input, test_target))
+
+>>> 0.939846333997604
+>>> 0.8247503123313558
+```
+
+모델이 train data에 과도하게 학습되었음을 알 수 있다. overfitting 발생.
+
+```python
+# 기존 데이터를 제곱한 값을 특성으로 추가.
+train_poly = np.column_stack((train_input ** 2, train_input))
+test_poly = np.column_stack((test_input ** 2, test_input))
+
+# 모델 훈련
+lr = LinearRegression()
+lr.fit(train_poly, train_target)
+
+# train score, test score 재확인
+print(lr.score(train_poly, train_target))
+print(lr.score(test_poly, test_target))
+
+>>> 0.9706807451768623
+>>> 0.9775935108325122
+```
+train score 와 test score 를 비교했을 때 이전 모델과는 다르게 overfitting 발생을 방지.
+
+
+# 특성 공학과 규제
+
+목표
+- 사이킷런의 다양한 도구를 활용하여 여러 특성을 사용한 다중 회귀 모델 구현
+- 복잡한 모델의 과대적합을 막기 위해 릿지와 라쏘 회귀 사용.
+
+## 데이터 준비
+
+앞서 사용했던 데이터에 특성이 하나 더 추가 된 'perch_full' 데이터 사용.
+```python
+import pandas as pd
+df = pd.read_csv('https://bit.ly/perch_csv_data')
+perch_full = df.to_numpy() # 판다스 -> 넘파이 배열
+```
+
+```python
+train_input, test_input, train_target, test_target = train_test_split(
+ perch_full, perch_weight, random_state=42)
+```
+
+## PolynomialFeatures 클래스
+
+PolynomialFeatures 클래스의 경우, 입력한 특성 관련해서 (특성)^2, (특성1)*(특성2) 같은 새로운 특성들을 계산하여 제공한다.
+
+train_input 데이터를 해당 클래스에 통과시키면 다음과 같은 결과를 보인다.
+
+```python
+from sklearn.preprocessing import PolynomialFeatures
+poly = PolynomialFeatures(include_bias=False)
+
+poly.fit(train_input)
+train_poly = poly.transform(train_input)
+
+print(train_poly.shape)
+print(poly.get_feature_names())
+
+>>> (42, 9) # 9개의 특성.
+>>> ['x0', 'x1', 'x2', 'x0^2', 'x0 x1', 'x0 x2', 'x1^2', 'x1 x2', 'x2^2']
+```
+위의 train_poly 데이터를 사용해 선형 회귀 모델을 훈련시켜 본다.
+
+```python
+lr = LinearRegression()
+lr.fit(train_poly, train_target)
+
+print(lr.score(train_poly, train_target))
+print(lr.score(test_poly, test_target))
+
+>>> 0.9903183436982124
+>>> 0.9714559911594134
+```
+여전히 overfitting 현상이 남아 있다.
+
+특성의 개수를 추가시켜서 모델을 학습시켜 보자.
+
+```python
+# PolynomialFeatures 클래스의 degree 파라미터를 변경하여 특성의 개수를 추가합니다.
+poly = PolynomialFeatures(degree=5, include_bias=False)
+poly.fit(train_input)
+train_poly = poly.transform(train_input)
+test_poly = poly.transform(test_input)
+
+# 모델 훈련 및 score 평가
+lr.fit(train_poly, train_target)
+print(lr.score(train_poly, train_target))
+print(lr.score(test_poly, test_target))
+
+>>> 0.9999999999938143
+>>> -144.40744532797535
+```
+오히려 훈련 세트에 대해 너무 과대적합되므로 테스트 데이터에 대한 점수가 굉장히 낮게 나온다.
+
+
+## 규제
+
+각 특성을 정규화한 후 규제를 적용해보자.
+
+### 릿지 회귀
+```python
+from sklearn.preprocessing import StandardScaler
+ss = StandardScaler()
+ss.fit(train_poly)
+
+train_scaled = ss.transform(train_poly)
+test_scaled = ss.transform(test_poly)
+
+# 각 계수를 제곱한 값을 바탕으로 규제를 적용하는 릿지 회귀를 사용합니다.
+from sklearn.linear_model import Ridge
+ridge = Ridge()
+
+ridge.fit(train_scaled, train_target)
+print(ridge.score(train_scaled, train_target))
+print(ridge.score(test_scaled, test_target))
+
+>>> 0.9896101671037343
+>>> 0.979069397761539
+```
+score 사이 간의 차이가 줄어들었다. 최적의 규제깂을 확인해보자.
+```python
+train_score = []
+test_score = []
+
+alpha_list = [0.001, 0.01, 0.1, 1, 10, 100]
+for alpha in alpha_list:
+ # 릿지 모델을 만듭니다.
+ ridge = Ridge(alpha = alpha)
+ # 릿지 모델을 훈련합니다.
+ ridge.fit(train_scaled, train_target)
+ # 훈련 점수와 테스트 점수를 저정합니다.
+ train_score.append(ridge.score(train_scaled, train_target))
+ test_score.append(ridge.score(test_scaled, test_target))
+
+plt.plot(np.log10(alpha_list), train_score)
+plt.plot(np.log10(alpha_list), test_score)
+plt.xlabel('log10(alpha)') #로그 스케일
+plt.ylabel('R^2')
+plt.show()
+```
+
+
+alpha = 0.1일 때 결정계수가 가장 큰 값을 보인다.
+
+```python
+# alpha=0.1을 사용하여 최종 학습 후 평가를 해 봅니다.
+ridge = Ridge(alpha=0.1)
+ridge.fit(train_scaled, train_target)
+
+print(ridge.score(train_scaled, train_target))
+print(ridge.score(test_scaled, test_target))
+
+>>> 0.9903815817570368
+>>> 0.9827976465386954
+```
+
+### 라쏘 회귀
+
+```python
+# 각 계수의 절대값을 바탕으로 규제를 적용하는 라쏘 회귀를 사용합니다.
+from sklearn.linear_model import Lasso
+lasso = Lasso()
+lasso.fit(train_scaled, train_target)
+
+print(lasso.score(train_scaled, train_target))
+print(lasso.score(test_scaled, test_target))
+
+>>> 0.989789897208096
+>>> 0.9800593698421884
+```
+alpha 조정을 통해 라쏘 회귀 역시 규제를 조절할 수 있다. 라쏘 회귀 역시 릿지 회귀에서와 동일한 과정을 거쳐 alpha 값에 따른 결정계수 그래프를 그려보면 다음과 같으며, 적절한 alpha 값을 찾을 수 있다.
+
+
+
+```python
+# 그래프에서 보이는 최적의 alpha 값 10을 적용해보자.
+lasso = Lasso(alpha=10)
+lasso.fit(train_scaled, train_target)
+
+print(lasso.score(train_scaled, train_target))
+print(lasso.score(test_scaled, test_target))
+
+>>> 0.9888067471131867
+>>> 0.9824470598706695
+```
+
+두 score 사이의 차이가 줄어들었다. overfitting을 어느 정도 조절하게 되었다.
+
+## 라쏘 회귀의 또다른 기능
+```python
+print(np.sum(lasso.coef_ == 0))
+>>> 40
+```
+라쏘 회귀는 절댓값을 사용하기 때문에 특정 계수를 0으로 만들 수 있다. 위의 코드 결과는 훈련과정에서 0이 된 파라미터의 개수가 40개 임을 확인할 수 있다.
+
+55개의 특성 중 40개가 0이고 나머지 15개 weights 만이 실질적으로 사용되며 이러한 특징은 라쏘 모델을 유용한 특성을 골라내는 용도로도 사용할 수 있음을 보여준다.
\ No newline at end of file
diff --git a/week2/images/2022-03-29-10-23-10.png b/week2/images/2022-03-29-10-23-10.png
new file mode 100644
index 0000000..3e3bdc0
Binary files /dev/null and b/week2/images/2022-03-29-10-23-10.png differ
diff --git a/week2/images/2022-03-29-10-27-49.png b/week2/images/2022-03-29-10-27-49.png
new file mode 100644
index 0000000..d68aa59
Binary files /dev/null and b/week2/images/2022-03-29-10-27-49.png differ
diff --git a/week2/images/2022-03-29-10-32-28.png b/week2/images/2022-03-29-10-32-28.png
new file mode 100644
index 0000000..4c56dec
Binary files /dev/null and b/week2/images/2022-03-29-10-32-28.png differ
diff --git a/week2/images/2022-03-29-10-39-43.png b/week2/images/2022-03-29-10-39-43.png
new file mode 100644
index 0000000..6b286e9
Binary files /dev/null and b/week2/images/2022-03-29-10-39-43.png differ
diff --git a/week2/images/2022-03-29-11-11-19.png b/week2/images/2022-03-29-11-11-19.png
new file mode 100644
index 0000000..cb7a64d
Binary files /dev/null and b/week2/images/2022-03-29-11-11-19.png differ
diff --git a/week2/images/2022-03-29-11-34-07.png b/week2/images/2022-03-29-11-34-07.png
new file mode 100644
index 0000000..44a365a
Binary files /dev/null and b/week2/images/2022-03-29-11-34-07.png differ
diff --git a/week2/images/2022-03-29-11-38-43.png b/week2/images/2022-03-29-11-38-43.png
new file mode 100644
index 0000000..d2f37f7
Binary files /dev/null and b/week2/images/2022-03-29-11-38-43.png differ
diff --git "a/week3/1\355\214\200_\354\230\244\353\217\231\355\233\210.md" "b/week3/1\355\214\200_\354\230\244\353\217\231\355\233\210.md"
new file mode 100644
index 0000000..bd9e5cb
--- /dev/null
+++ "b/week3/1\355\214\200_\354\230\244\353\217\231\355\233\210.md"
@@ -0,0 +1,212 @@
+# 이론 요약
+## 로지스틱 회귀
+
+- 로지스틱 회귀는 선형 방정식을 통해 학습하는 분류 모델이다.
+> ${z = a*( 특성1 ) + b*( 특성2 ) + ...}$
+- 시그모이드 함수를 통해 z 값을 0 과 1 사이로 만든다.
+- ## 시그모이드 함수 : ${\Phi ={\frac {1}{1+e^-z}}}$
+
+
+## 로지스틱 회귀 다중 분류
+
+- 로지스틱 회귀 함수는 이진 분류일 때 가장 강력한 성능을 발휘한다.
+- 또한, 다중 분류일 때는 시그모이드 함수가 아닌 소프트맥스 함수를 사용한다.
+
+
+## 소프트맥스 함수 : ${ y_i ={\frac {e^{z_i}}{\sum_{i=1}^K e^{z_i}}}}$
+- 소프트맥스 함수는 시그모이드 함수의 일반화 버전이다.
+- k 개의 클래스에 대해 확률을 계산하여 분류할 수 있다.
+
+
+## 손실함수, loss function
+- 어떤 문제에서 머신러닝 알고리즘이 얼마나 부정확한지 측정하는 기준
+- 머신러닝은 손실 함수 결과가 최솟값이 나오도록 모델을 최적화하는 것이 목표가 된다.
+- 로지스틱 손실함수는 '-log(예측확률)' 함수를 사용한다.
+
+
+## 경사하강법
+
+- Z = a*X0 + b*X1 + c*X2 + d 라고 할 때, 적절한 a,b,c,d 값을 찾기위한 최적화 알고리즘이다.
+- 샘플 X = [ X0, X1, X2 ] 라고 하면 Z 는 a,b,c,d 에 대한 함수로 표현 가능하고 이 a,b,c,d 값으 바꿔가면서 경사가 최소값일 때를 찾는 알고리즘이다.
+
+#### 확률적 경사 하강법 (Stochastic gradient descent)
+- 랜덤하게 하나의 샘플을 선택해 경사 하강법을 수행하는 방식
+
+#### 미니 배치 경사 하강법
+- 여러 개의 샘플을 사용해 경사 하강법을 수행하는 방식
+
+#### 배치 경사 하강법
+- 전체 샘플을 사용해 경사 하강법을 수행하는 방식
+
+
+# 혼공머신_예제
+
+## K-최근접 이웃 분류기의 확률 예측
+
+- ['Species'] 를 7개의 클래스로 설정(target_data)
+- 특성 5개: 길이, 높이, 두께, 대각선, 무게 (train_data)
+- train_test_split 으로 훈련 데이터, 테스트 데이터 분리
+- StandardScaler 클래스를 사용해 훈련 세트 및 테스트 세트 표준화 전처리
+
+```python
+import pandas as pd
+fish = pd.read_csv('https://bit.ly/fish_csv_data')
+# unqiue() 함수를 사용해서 어떤 종류의 생선이 있는지 확인
+print(pd.unique(fish['Species']))
+
+>>> ['Bream' 'Roach' 'Whitefish' 'Parkki' 'Perch' 'Pike' 'Smelt']
+
+# input data 설정
+fish_input = fish[['Weight', 'Length', 'Diagonal','Height','Width']].to_numpy()
+
+# target data 설정
+fish_target = fish['Species'].to_numpy()
+
+# 훈련 데이터, 테스트 데이터 분리
+from sklearn.model_selection import train_test_split
+train_input, test_input, train_target, test_target = train_test_split(
+ fish_input, fish_target, random_state=42)
+
+# 표준화 전처리
+from sklearn.preprocessing import StandardScaler
+ss = StandardScaler()
+ss.fit(train_input)
+train_scaled = ss.transform(train_input)
+test_scaled = ss.transform(test_input)
+```
+
+```python
+# 모델 생성 및 훈련
+from sklearn.neighbors import KNeighborsClassifier
+kn = KNeighborsClassifier(n_neighbors=3)
+kn.fit(train_scaled, train_target)
+```
+
+## 로지스틱 회귀로 이진 분류 수행
+
+- 데이터는 '도미'와 '빙어' 데이터를 사용.
+- 시그모이드 함수의 출력 0.5보다 크면 양성 클래스, 0.5와 같거나 작으면 음성 클래스.
+
+```python
+# 전체 데이터에서 boolean indexing 을 통해 도미와 빙어 데이터만 추출
+bream_smelt_indexes = (train_target == 'Bream') | (train_target == 'Smelt')
+train_bream_smelt = train_scaled[bream_smelt_indexes]
+target_bream_smelt = train_target[bream_smelt_indexes]
+
+# 로지스틱 회귀 모델 생성 및 훈련
+from sklearn.linear_model import LogisticRegression
+lr = LogisticRegression()
+lr.fit(train_bream_smelt, target_bream_smelt)
+```
+
+```python
+# 처음 5개 샘플의 클래스를 분류 및 예측 확률 출력
+print(lr.predict(train_bream_smelt[:5]))
+
+>>> ['Bream' 'Smelt' 'Bream' 'Bream' 'Bream']
+
+print(lr.predict_proba(train_bream_smelt[:5]))
+
+>>> [0.99759855 0.00240145]
+ [0.02735183 0.97264817]
+ [0.99486072 0.00513928]
+ [0.98584202 0.01415798]
+ [0.99767269 0.00232731]
+```
+
+## 로지스틱 회귀로 다중 분류 수행하기
+
+- 반복 횟수 (max_iter) = 1000 으로 설정
+- 계수의 제곱을 규제하는 L2 규제 적용
+
+```python
+# 다중 분류 모델 생성 및 훈련
+lr = LogisticRegression(C=20, max_iter=1000)
+lr.fit(train_scaled, train_target)
+```
+
+```python
+# 테스트 세트 처음 5개 샘플에 대한 분류, 예측 확률 출력
+print(lr.predict(test_scaled[:5]))
+
+>>> ['Perch' 'Smelt' 'Pike' 'Roach' 'Perch']
+
+# 예측 확률 출력
+proba = lr.predict_proba(test_scaled[:5])
+print(np.round(proba, decimals=3))
+
+>>> [0. 0.014 0.841 0. 0.136 0.007 0.003]
+ [0. 0.003 0.044 0. 0.007 0.946 0. ]
+ [0. 0. 0.034 0.935 0.015 0.016 0. ]
+ [0.011 0.034 0.306 0.007 0.567 0. 0.076]
+ [0. 0. 0.904 0.002 0.089 0.002 0.001]
+```
+
+```python
+# 처음 샘플 5개에 대한 z 값을 소프트맥스 함수에 통과시키기
+decision = lr.decision_function(test_scaled[:5])
+
+from scipy.special import softmax
+proba = softmax(decision, axis=1) # 열 기준, 행에 대해 소프트맥스 계산.
+print(np.round(proba, decimals=3))
+
+>>> [0. 0.014 0.841 0. 0.136 0.007 0.003]
+ [0. 0.003 0.044 0. 0.007 0.946 0. ]
+ [0. 0. 0.034 0.935 0.015 0.016 0. ]
+ [0.011 0.034 0.306 0.007 0.567 0. 0.076]
+ [0. 0. 0.904 0.002 0.089 0.002 0.001]
+```
+
+## SGDClassifier
+
+- 이진 분류의 경우, 이진 크로스엔트로피 손실 함수
+- 다중 분류의 경우, 크로스엔트로피 손실 함수
+- 경사 하강법 예제 데이터의 경우 앞선 7개 클래스에 대한 데이터를 그대로 사용한다.
+
+```python
+# SGDClassifier 로드
+from sklearn.linear_model import SGDClassifier
+
+# 손실함수: loss='log' 로지스틱, 에포크: max_iter=10
+sc =SGDClassifier(loss='log', max_iter=10, random_state=42)
+sc.fit(train_scaled, train_target)
+
+# score 출력
+print(sc.score(train_scaled, train_target))
+print(sc.score(test_scaled, test_target))
+
+>>> 0.773109243697479 // score 가 다소 낮게 나오는 경향이 있다.
+ 0.775
+```
+
+## epoch와 과대/과소적합
+
+- 확률적 경사 하강법을 사용한 모델은 epoch 횟수에 따라 과대/과소적합 현상이 나타난다.
+- epoch 횟수가 적으면 과소적합이 발생하며, epoch 가 너무 많으면 과대적합이 발생한다.
+- 과대적합이 시작되기 전 훈련을 멈추는 것을 'early stopping' 이라고 한다.
+- 예제에서는 np.unique() 함수로 7개 생선 클래스 목록(=classes) 을 만든다.
+- 과대적합이 발생하는 지점을 찾기 위해 epoch 1회 마다 train_score, test_score를 리스트로 logging 한다.
+- partial_fit() 메서드를 통해 모델을 훈련한다.
+
+```python
+# 모델 생성 및 훈련 준비
+import numpy as np
+sc = SGDClassifier(loss='log', random_state=42)
+train_score = []
+test_score = []
+classes = np.unique(train_target)
+
+# epochs= 300으로 설정하여 훈련
+for _ in range(0,300):
+ sc.partial_fit(train_scaled, train_target, classes=classes)
+ train_score.append(sc.score(train_scaled, train_target)) # train_score logging
+ test_score.append(sc.score(test_scaled, test_target)) # test_score logging
+
+# matplotlib 그래프로 확인
+import matplotlib.pyplot as plt
+plt.plot(train_score)
+plt.plot(test_score)
+plt.xlabel('epoch')
+plt.ylabel('accuracy')
+plt.show()
+```
\ No newline at end of file
diff --git "a/week6/1\355\214\200_\354\230\244\353\217\231\355\233\210.md" "b/week6/1\355\214\200_\354\230\244\353\217\231\355\233\210.md"
new file mode 100644
index 0000000..3ed49ce
--- /dev/null
+++ "b/week6/1\355\214\200_\354\230\244\353\217\231\355\233\210.md"
@@ -0,0 +1,111 @@
+# 퍼셉트론(Perceptron)
+
+- 로지스틱 회귀 : 가중치와 편향을 이용하여 input에 대해 특정 확률을 계산.
+
+- McCulloch-Pitts Neuron : 로지스틱 회귀와 유사하게 선형 방정식을 통해 Yes / No 를 판별.
+
+- Perceptron : McCulloch-Pitts Neuron 과 유사하지만, input이 boolean이 아니어도 동작한다. 퍼셉트론의 약점은 XOR 문제를 해결하지 못한다는 점이며 이는 multi-layer perceptron 으로 해결할 수 있다.
+
+
+# Multi-Layer Perceptron(MLP)
+
+- 퍼셉트론을 여러 개 쌓은 것
+- 입력층 + 은닉층 + 출력층 으로 구성되어 있다.
+
+
+
+## MLP (1) : 데이터로드 및 처리
+
+```python
+from tensorflow import keras
+from sklearn.model_selection import train_test_split
+
+(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()
+train_scaled = train_input / 255.0
+train_scaled = train_scaled.reshape(-1, 28*28)
+
+train_scaled, val_scaled, train_target, val_target = train_test_split(
+ train_scaled, train_target, test_size=0.2, random_state=42)
+```
+
+
+## MLP (2) : 모델 생성
+
+```python
+# 28*28 크기, grayscale image data 사용
+
+model = keras.Sequential()
+model.add(keras.layers.Flatten(input_shape=(28,28)))
+model.add(keras.layers.Dense(100, activation='relu'))
+model.add(keras.layers.Dense(10, activation='softmax'))
+```
+
+
+## MLP (3.1) : 컴파일 및 훈련
+
+```python
+model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics='accuracy')
+history = model.fit(train_scaled, train_target, epochs=20, verbose=0,
+ validation_data=(val_scaled, val_target))
+```
+
+
+## MLP (3.2) : callback 추가, 컴파일 및 훈련
+
+```python
+# 컴파일은 그대로
+model.compile(optimizer='adam', loss='sparse_categorical_crossentropy',
+ metrics='accuracy')
+
+# ModelCheckpoint : 가장 낮은 검증 점수의 모델을 자동으로 저장
+checkpoint_cb = keras.callbacks.ModelCheckpoint('best-model.h5',
+ save_best_only=True)
+
+# EarlyStopping : patience 만큼 연속으로 검증 점수 향상되지 않으면 조기 종료.
+early_stopping_cb = keras.callbacks.EarlyStopping(patience=2,
+ restore_best_weights=True)
+
+history = model.fit(train_scaled, train_target, epochs=20, verbose=0,
+ validation_data=(val_scaled, val_target),
+ callbacks=[checkpoint_cb, early_stopping_cb])
+```
+
+
+## MLP (4) : 모델의 저장과 복원
+
+```python
+# 모델 저장
+# 모델 파라미터만 저장.
+model.save_weights('model-weights.h5')
+
+# 모델 구조와 모델 파라미터를 함께 저장.
+model.save('model-whole.h5')
+
+# 모델 복원
+model_re = keras.models.load_model('model-whole.h5')
+```
+
+ModelCheckpoint 에서 이미 가장 좋은 성적을 내는 모델을 저장했기에 그대로 불러올 수 있다.
+
+```python
+model_re_best = keras.models.load_model('best-model.h5')
+```
+
+# 최적화 문제
+
+## 손실 함수(Loss Function)
+
+- 모델 성능이 얼마나 나쁜지 보여주는 함수이다.
+
+- 이진분류의 경우 binary_crossentropy, 회귀 모델의 경우 MSE 등을 사용한다.
+
+- DNN 에서는 손실값을 줄이는 방향으로 모델의 update가 진행되며 이를 최적화 라고 한다.
+
+## optimizer
+
+- 케라스는 다양한 경사 하강법 알고리즘을 제공하며 이들을 optimizer 라고 한다.
+
+- 모델 최적화를 위해 optimizer 종류를 선정하고 learning rate 를 조정하는 작업이 필요하다.
+
+- 기본 경사 하강법 optimizer : SGD / momentum
+- 적응적 학습률 optimizer : RMSprop / Adam / Adagrad (모델이 최적점에 가까이 갈수록 학습률을 낮출 수 있다.)
\ No newline at end of file