import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import yfinance as yf
import PIL
import io
import requests
10wk-1: 중간고사
제출은 *.ipynb
, *.html
, *.pdf
파일로 제출할 것
ipynb
파일형태제출을 권장함.
Imports
1. Numpy and Pandas (35점)
FIFA23
(1)--(3)
아래는 FIFA23 자료를 불러오는 코드이다.
=pd.read_csv('https://raw.githubusercontent.com/guebin/DV2022/master/posts/FIFA23_official_data.csv').drop(columns=['Loaned From', 'Best Overall Rating']).dropna().reset_index(drop=True)
df df.head()
ID | Name | Age | Photo | Nationality | Flag | Overall | Potential | Club | Club Logo | ... | Work Rate | Body Type | Real Face | Position | Joined | Contract Valid Until | Height | Weight | Release Clause | Kit Number | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 209658 | L. Goretzka | 27 | https://cdn.sofifa.net/players/209/658/23_60.png | Germany | https://cdn.sofifa.net/flags/de.png | 87 | 88 | FC Bayern München | https://cdn.sofifa.net/teams/21/30.png | ... | High/ Medium | Unique | Yes | <span class="pos pos28">SUB | Jul 1, 2018 | 2026 | 189cm | 82kg | €157M | 8.0 |
1 | 212198 | Bruno Fernandes | 27 | https://cdn.sofifa.net/players/212/198/23_60.png | Portugal | https://cdn.sofifa.net/flags/pt.png | 86 | 87 | Manchester United | https://cdn.sofifa.net/teams/11/30.png | ... | High/ High | Unique | Yes | <span class="pos pos15">LCM | Jan 30, 2020 | 2026 | 179cm | 69kg | €155M | 8.0 |
2 | 224334 | M. Acuña | 30 | https://cdn.sofifa.net/players/224/334/23_60.png | Argentina | https://cdn.sofifa.net/flags/ar.png | 85 | 85 | Sevilla FC | https://cdn.sofifa.net/teams/481/30.png | ... | High/ High | Stocky (170-185) | No | <span class="pos pos7">LB | Sep 14, 2020 | 2024 | 172cm | 69kg | €97.7M | 19.0 |
3 | 192985 | K. De Bruyne | 31 | https://cdn.sofifa.net/players/192/985/23_60.png | Belgium | https://cdn.sofifa.net/flags/be.png | 91 | 91 | Manchester City | https://cdn.sofifa.net/teams/10/30.png | ... | High/ High | Unique | Yes | <span class="pos pos13">RCM | Aug 30, 2015 | 2025 | 181cm | 70kg | €198.9M | 17.0 |
4 | 224232 | N. Barella | 25 | https://cdn.sofifa.net/players/224/232/23_60.png | Italy | https://cdn.sofifa.net/flags/it.png | 86 | 89 | Inter | https://cdn.sofifa.net/teams/44/30.png | ... | High/ High | Normal (170-) | Yes | <span class="pos pos13">RCM | Sep 1, 2020 | 2026 | 172cm | 68kg | €154.4M | 23.0 |
5 rows × 27 columns
(1)
공백이 포함된 column이름이 총 몇개인지 count하는 코드를 작성하라.
hint 모두 11개의 column name에 공백이 포함되어있음
(풀이)
sum([' ' in name for name in df.columns])
11
(2)
column name에 공백이 포함된 열을 출력하라.
(풀이)
' ' in name for name in df.columns]] df.loc[:,[
Club Logo | Preferred Foot | International Reputation | Weak Foot | Skill Moves | Work Rate | Body Type | Real Face | Contract Valid Until | Release Clause | Kit Number | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | https://cdn.sofifa.net/teams/21/30.png | Right | 4.0 | 4.0 | 3.0 | High/ Medium | Unique | Yes | 2026 | €157M | 8.0 |
1 | https://cdn.sofifa.net/teams/11/30.png | Right | 3.0 | 3.0 | 4.0 | High/ High | Unique | Yes | 2026 | €155M | 8.0 |
2 | https://cdn.sofifa.net/teams/481/30.png | Left | 2.0 | 3.0 | 3.0 | High/ High | Stocky (170-185) | No | 2024 | €97.7M | 19.0 |
3 | https://cdn.sofifa.net/teams/10/30.png | Right | 4.0 | 5.0 | 4.0 | High/ High | Unique | Yes | 2025 | €198.9M | 17.0 |
4 | https://cdn.sofifa.net/teams/44/30.png | Right | 3.0 | 3.0 | 3.0 | High/ High | Normal (170-) | Yes | 2026 | €154.4M | 23.0 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
16359 | https://cdn.sofifa.net/teams/114628/30.png | Right | 1.0 | 3.0 | 1.0 | Medium/ Medium | Normal (185+) | No | 2027 | €218K | 35.0 |
16360 | https://cdn.sofifa.net/teams/1478/30.png | Right | 1.0 | 2.0 | 1.0 | Medium/ Medium | Lean (185+) | No | 2026 | €188K | 21.0 |
16361 | https://cdn.sofifa.net/teams/113796/30.png | Right | 1.0 | 2.0 | 1.0 | Medium/ Medium | Lean (185+) | No | 2023 | €142K | 12.0 |
16362 | https://cdn.sofifa.net/teams/112260/30.png | Right | 1.0 | 2.0 | 1.0 | Medium/ Medium | Normal (185+) | No | 2021 | €214K | 40.0 |
16363 | https://cdn.sofifa.net/teams/702/30.png | Left | 1.0 | 2.0 | 1.0 | Medium/ Medium | Normal (185+) | No | 2021 | €131K | 30.0 |
16364 rows × 11 columns
(3)
데이터프레임을 올바르게 해석한 사람을 모두 고르시오 (모두 맞출경우만 정답으로 인정)
- 세민: 데이터프레임에는 모두 27개의 열이 있다.
- 성재: 한국선수(
Nationality==Korea Republic
)와 일본선수(Nationality==Japan
)의Overall
의 평균값은 일본이 더 높다. - 민정: 총 159개의 나라선수들이 포함되어 있다.
- 슬기: 선수들의 연령이 25세이상(>=)인 선수들은 그렇지 않은 선수들보다 평균적으로 키(
Height
)가크다.
(풀이)
세민: 데이터프레임에는 모두 27개의 열이 있다 -> True
len(df.columns) == 27
True
성재: 한국선수(Nationality==Korea Republic)와 일본선수(Nationality==Japan)의 Overall의 평균값은 일본이 더 높다. -> True
'Nationality == "Korea Republic"').Overall.mean() < df.query('Nationality == "Japan"').Overall.mean() df.query(
True
민정: 총 159개의 나라선수들이 포함되어 있다. -> True
len(set(df.Nationality))==159
True
슬기: 선수들의 연령이 25세이상(>=)인 선수들은 그렇지 않은 선수들보다 평균적으로 키(Height
)가크다. -> True
= np.mean([int(height[:3]) for height in df.query('Age>=25').Height.tolist()])
_old = np.mean([int(height[:3]) for height in df.query('Age<25').Height.tolist()])
_young > _young _old
True
삼성전자의 주가
(4)--(5)
다음은 삼성전자의 주가를 크롤링하는 코드이다.
= "2023-01-01"
start_date = "2023-05-02"
end_date = yf.download("005930.KS", start=start_date, end=end_date)['Adj Close'].to_numpy() y
[*********************100%***********************] 1 of 1 completed
삼성전자의 주가 \({\boldsymbol y}\)를 시각화하면 아래와 같다.
plt.plot(y)
(4)
아래와 같은 변환을 이용하여 \({\boldsymbol y}\)를 \(\tilde {\boldsymbol y}\)로 변환하고 결과를 시각화하라.
- \(\tilde{y}_1= \frac{1}{4}(3y_1 + y_2)\)
- \(\tilde{y}_i= \frac{1}{4}(y_{i-1}+2y_i+y_{i+1})\), for \(i=2,3,\dots,n-1\)
- \(\tilde{y}_n= \frac{1}{4}(y_{n-1}+3y_{n})\)
hint: 아래의 코드를 관찰
4) + np.array([abs(i-j)<2 for i in range(4) for j in range(4)]).reshape(4,4) np.eye(
array([[2., 1., 0., 0.],
[1., 2., 1., 0.],
[0., 1., 2., 1.],
[0., 0., 1., 2.]])
(풀이)
= len(y)
T = (np.eye(T) + np.array([abs(i-j)<2 for i in range(T) for j in range(T)]).reshape(T,T))/4
M 0,0] = 3/4; M[-1,-1]= 3/4
M[=r'$y$')
plt.plot(y,label@y,'--',label=r'$M@y$')
plt.plot(M plt.legend()
<matplotlib.legend.Legend at 0x7f6efc12bb80>
(5)
(4)
의 변환을 50회 반복적용하고 결과를 시각화하라.
=r'$y$')
plt.plot(y,label50)@y,'--',label=r'$M^{50}@y$')
plt.plot(np.linalg.matrix_power(M, plt.legend()
<matplotlib.legend.Legend at 0x7f6efc6694f0>
회귀모형
(6)--(7)
\((x_i,y_i)\)가 아래와 같이 주어졌다고 가정하자.
= np.array([0.00983, 0.01098, 0.02951, 0.0384 , 0.03973, 0.04178, 0.0533 ,
x 0.058 , 0.09454, 0.1103 , 0.1328 , 0.1412 , 0.1497 , 0.1664 ,
0.1906 , 0.1923 , 0.198 , 0.2141 , 0.2393 , 0.2433 , 0.3157 ,
0.3228 , 0.3418 , 0.3552 , 0.3918 , 0.3962 , 0.4 , 0.4482 ,
0.496 , 0.507 , 0.53 , 0.5654 , 0.582 , 0.5854 , 0.5854 ,
0.6606 , 0.7007 , 0.723 , 0.7305 , 0.7383 , 0.7656 , 0.7725 ,
0.831 , 0.8896 , 0.9053 , 0.914 , 0.949 , 0.952 , 0.9727 ,
0.982 ])
= np.array([0.7381, 0.7043, 0.3937, 0.1365, 0.3784, 0.3028, 0.1037, 0.3846,
y 0.706 , 0.7572, 0.2421, 0.232 , 0.9855, 1.162 , 0.4653, 0.6791,
0.6905, 0.6865, 0.9757, 0.7665, 0.9522, 0.4641, 0.5498, 1.1509,
0.5288, 1.1195, 1.1659, 1.4341, 1.2779, 1.1648, 1.4002, 0.7472,
0.9142, 0.9658, 1.0707, 1.4501, 1.6758, 0.8778, 1.3384, 0.7476,
1.3086, 1.7537, 1.5559, 1.2928, 1.3832, 1.3115, 1.3382, 1.536 ,
1.9177, 1.2069])
'o') plt.plot(x,y,
6
. 아래의 수식을 이용하여 적절한 추세선 \(\hat{y}_i= \hat{\beta}_0 +\hat{\beta}_1 x_i\)를 구하고 시각화하라.
\[\begin{bmatrix} \hat{\beta}_0 \\ \hat{\beta}_1 \end{bmatrix} = ({\bf X}^T {\bf X})^{-1}{\bf X}^T {\boldsymbol y}, \quad {\bf X}=\begin{bmatrix} 1 & x_1 \\ 1 & x_2 \\ \dots \\ 1 & x_n \end{bmatrix}\]
(풀이)
= len(x)
n = np.stack([np.ones(n),x],axis=1)
X = np.linalg.inv(X.T@X)@X.T@y
b,a = b+a*x
yhat 'o')
plt.plot(x,y,'--') plt.plot(x,yhat,
7
. \(\frac{1}{n}\sum_{i=1}^{n}(y_i-\hat{y}_i)^2\)을 계산하라.
(풀이)
-yhat)**2) np.mean((y
0.07602899763337416
2. fashion MNIST data (60점)
아래는 9가지의 의류이미지가 저장된 이미지데이터를 불러오는 코드이다.
=pd.read_csv('https://media.githubusercontent.com/media/guebin/PP2023/main/posts/fashion-mnist_train.csv')
df_train=pd.read_csv('https://media.githubusercontent.com/media/guebin/PP2023/main/posts/fashion-mnist_test.csv') df_test
def rshp(row):
return row.reshape(28,28)
= np.apply_along_axis(rshp,axis=1,arr=np.array(df_train.iloc[:,1:]))
xtrain = np.apply_along_axis(rshp,axis=1,arr=np.array(df_test.iloc[:,1:]))
xtest = np.array(df_train.label)
ytrain = np.array(df_test.label) ytest
아래는 데이터에 대한 설명이다.
- 전체의 이미지의 수는 70000개이며, 60000개의 이미지 \({\tt xtrain}\)에 10000개의 이미지는 \({\tt xtest}\)에 저장되어 있다.
- 이미지에 대한 라벨은 각각 \({\tt ytrain}\)과 \(\tt ytest\)에 저장되어 있다. 따라서 \(\tt ytrain\)에는 60000개의 이미지에 해당하는 라벨이, \(\tt ytest\)에는 10000개의 이미지에 해당하는 라벨이 기록되어 있다.
- 보통 분석에서는 60000개의 이미지를 가지고 라벨을 맞추는 “훈련”을 하고 (\({\tt xtrain}\)을 이용하여 \({\tt ytrain}\)을 맞추는 방법을 학습하고), 그러한 훈련이 잘 되었는지 10000개의 이미지를 이용하여 “테스트”한다.
- 위와 같은 의미로 \(({\tt xtrain}, {\tt ytrain})\) 을 training data set, \(({\tt xtest},{\tt ytest})\) 를 test data set 이라고 부른다. (ref: 위키참고)
아래는 이미지자료와 시각화에 대한 설명이다.
- 각 이미지는 (28,28) 픽셀의 흑백이미지이다. 따라서 각 이미지는 (28,28,3) 이 아니라 (28,28) 의 shape을 가진 텐서로 구성되어있다.
- 흑백이미지를 시각화 하기 위해서는
plt.imshow(img, cmap='gray')
를 이용한다. 여기에서 \({\tt img}\)은 임의의 2차원 텐서이며 이 예제의 경우 (28,28)의 shape을 가진다.
아래는 \({\tt xtrain}\)의 두번째 이미지, 즉 \({\tt xtrain[1,:,:]}\)를 확인하는 코드의 예시이다.
# plt.imshow(xtrain[1,:,:],cmap='gray')
1],cmap='gray') ## 같은코드임 plt.imshow(xtrain[
<matplotlib.image.AxesImage at 0x7f6efb174730>
이 이미지에 대한 label은 \({\tt ytrain[1]}\)의 값으로 확인가능하다.
1] ytrain[
9
이미지와 라벨을 한번에 표현하는 코드는 아래와 같이 작성가능하다.
1],cmap='gray')
plt.imshow(xtrain['label={}'.format(ytrain[1])); plt.title(
여기에서 9가 의미하는 것은 ’Ankel boot’이며, 다른 숫자가 의미하는 것은 각각 아래와 같다.
= {0:'T-shirt/top',
labels1:'Trouser',
2:'Pullover',
3:'Dress',
4:'Coat',
5:'Sandal',
6:'Shirt',
7:'Sneaker',
8:'Bag',
9:'Ankel boot'}
아래는 \({\tt xtrain}\)의 처음 10개의 이미지를 라벨과 함께 출력하는 코드이다.
= plt.subplots(2,5,figsize=(10,5))
fig, ax
0][0].imshow(xtrain[0],cmap='gray'); ax[0][0].set_title('label={}'.format(labels[ytest[0]]));
ax[0][1].imshow(xtrain[1],cmap='gray'); ax[0][1].set_title('label={}'.format(labels[ytest[1]]));
ax[0][2].imshow(xtrain[2],cmap='gray'); ax[0][2].set_title('label={}'.format(labels[ytest[2]]));
ax[0][3].imshow(xtrain[3],cmap='gray'); ax[0][3].set_title('label={}'.format(labels[ytest[3]]));
ax[0][4].imshow(xtrain[4],cmap='gray'); ax[0][4].set_title('label={}'.format(labels[ytest[4]]));
ax[
1][0].imshow(xtrain[5],cmap='gray'); ax[1][0].set_title('label={}'.format(labels[ytest[5]]));
ax[1][1].imshow(xtrain[6],cmap='gray'); ax[1][1].set_title('label={}'.format(labels[ytest[6]]));
ax[1][2].imshow(xtrain[7],cmap='gray'); ax[1][2].set_title('label={}'.format(labels[ytest[7]]));
ax[1][3].imshow(xtrain[8],cmap='gray'); ax[1][3].set_title('label={}'.format(labels[ytest[8]]));
ax[1][4].imshow(xtrain[9],cmap='gray'); ax[1][4].set_title('label={}'.format(labels[ytest[9]]));
ax[
fig.tight_layout()
(1)
\({\tt xtrain}\)에서 각 라벨에 대한 평균이미지를 계산하고 계산결과를 \({\tt imgmean}\)에 길이가 10인 list
로 저장하라. 즉 \({\tt imgmean}\)은 아래와 같은 자료구조를 가지고 있어야 한다.
- \({\tt imgmean}=\big[{\tt imgmean[0]},\dots, {\tt imgmean[9]}\big]\)
- \({\tt imgmean[0]}, \dots, {\tt imgmean[9]}\) 는 각각 (28,28)의 shape을 가진 numpy array
- \({\tt imgmean[0]}, \dots, {\tt imgmean[9]}\) 는 각각 숫자 0,1, …, 9의 평균이미지를 의미
\({\tt imgmean[0]},\dots, {\tt imgmean[9]}\)를 시각화 하라.
(풀이)
= [xtrain[ytrain==i].mean(axis=0) for i in range(10)]
imgmean
= plt.subplots(2,5,figsize=(10,5))
fig, ax 0][0].imshow(imgmean[0],cmap='gray'); ax[0][0].set_title('label={}'.format(labels[0]));
ax[0][1].imshow(imgmean[1],cmap='gray'); ax[0][1].set_title('label={}'.format(labels[1]));
ax[0][2].imshow(imgmean[2],cmap='gray'); ax[0][2].set_title('label={}'.format(labels[2]));
ax[0][3].imshow(imgmean[3],cmap='gray'); ax[0][3].set_title('label={}'.format(labels[3]));
ax[0][4].imshow(imgmean[4],cmap='gray'); ax[0][4].set_title('label={}'.format(labels[4]));
ax[1][0].imshow(imgmean[5],cmap='gray'); ax[1][0].set_title('label={}'.format(labels[5]));
ax[1][1].imshow(imgmean[6],cmap='gray'); ax[1][1].set_title('label={}'.format(labels[6]));
ax[1][2].imshow(imgmean[7],cmap='gray'); ax[1][2].set_title('label={}'.format(labels[7]));
ax[1][3].imshow(imgmean[8],cmap='gray'); ax[1][3].set_title('label={}'.format(labels[8]));
ax[1][4].imshow(imgmean[9],cmap='gray'); ax[1][4].set_title('label={}'.format(labels[9]));
ax[ fig.tight_layout()
(2)
아래와 같은 numpy array 를 생성하라.
\[{\tt loss}= \begin{bmatrix} {\tt loss[0,0]} & \dots & {\tt loss[0,9]} \\ {\tt loss[1,0]} & \dots & {\tt loss[1,9]} \\ \dots & \dots & \dots \\ {\tt loss[59999,0]}& \dots &{\tt loss[59999,9]} \\ \end{bmatrix}\]
여기에서
\[{\tt loss[i,j]} = \frac{1}{28\times 28} \sum_{p=0}^{27}\sum_{q=0}^{27}\big({\tt xtrain[i,p,q]}-{\tt imgmean[j][p,q]}\big)^2\]
이다. 이제 \({\tt loss}\)에서 “최소값을 가지는 원소의 인덱스를 출력”하는 함수를 행별로 적용해 이미지를 분류하라. 예를들어 모든 \(j=0,1,\dots,9\) 에 대하여 아래를 계산한 결과
\[\frac{1}{28\times 28} \sum_{p=0}^{27}\sum_{q=0}^{27}\big({\tt xtrain[1,p,q]}-{\tt imgmean[j][p,q]}\big)^2\]
\(j=9\)일 경우 그 값이 가장 작다면 \({\tt xtrain[1]}\) 이미지는 9번으로 분류한다. 분류한 결과와 실제 라벨 \({\tt ytrain}\)을 비교하라. 얼마나 많은 결과가 일치하는지 비율을 계산하라.
(풀이)
= np.array([[np.mean((xtrain[j,:,:]- imgmean[i])**2) for i in range(10)] for j in range(60000)])
training_loss = training_loss.argmin(axis=1)
ytrain_hat == ytrain) np.mean(ytrain_hat
0.6850666666666667
(3)
\({\tt xtrain}\)에서 학습한 평균이미지 \({\tt imgmean}\)를 바탕으로 \({\tt xtest}\)의 1번라벨에 해당하는 이미지만을 분류하라. 아래의 물음에 답하라.
- 1번라벨에 해당하는 이미지를 0번라벨로 분류한 경우는 모두 몇건인가? (잘못된 분류)
- 1번라벨에 해당하는 이미지를 1번라벨로 분류한 경우는 모두 몇건인가? (올바른 분류)
- \(\dots\)
- 1번라벨에 해당하는 이미지를 9번라벨로 분류한 경우는 모두 몇건인가? (잘못된 분류)
hint: 아래와 같은 결과를 주는 dictionary를 만들면 된다.
{0: 28, 1: 895, 2: 11, 3: 36, 4: 8, 5: 12, 6: 10, 7: 0, 8: 0, 9: 0}
- 1번라벨에 해당하는 이미지를 0번라벨로 분류한 경우는 모두 28건
- 1번라벨에 해당하는 이미지를 1번라벨로 분류한 경우는 모두 895건
- \(\dots\)
- 1번라벨에 해당하는 이미지를 9번라벨로 분류한 경우는 모두 0건
(풀이)
= np.array([[np.mean((xtest[j,:,:]- imgmean[i])**2) for i in range(10)] for j in range(10000)])
test_loss = test_loss.argmin(axis=1)
ytest_hat ==1].tolist().count(j) for j in range(10)} {j: ytest_hat[ytest
{0: 28, 1: 895, 2: 11, 3: 36, 4: 8, 5: 12, 6: 10, 7: 0, 8: 0, 9: 0}
(4)
\({\tt xtest}\)의 이미지를 올바르게 분류한 비율을 카테고리별로 정리하라.
(풀이)
==j].tolist().count(j)/sum(ytest==j) for j in range(10)} {labels[j]:ytest_hat[ytest
{'T-shirt/top': 0.7,
'Trouser': 0.895,
'Pullover': 0.496,
'Dress': 0.802,
'Coat': 0.599,
'Sandal': 0.757,
'Shirt': 0.202,
'Sneaker': 0.794,
'Bag': 0.761,
'Ankel boot': 0.851}
3. 파이썬의 설치 (5점)
다음을 읽고 파이썬과 가상환경에 대하여 올바른 진술을 한 사람을 모두 골라라. (모두 맞출 경우만 정답으로 인정함)
민정: 구글코랩은 사용자의 컴퓨터에 설치된 아나콘다를 기반으로 동작하며, 실제적으로는 사용자의 ipython과 크롬과의 통신만을 담당한다. 따라서 구글코랩은 반드시 파이썬만 연결하여 사용가능하지 않으며 실제로 구글코랩에 R을 연결하여 사용하기도 한다.
구환: 아래와 같이 스크립트로 구성된 mysum.py
와 같은 파이썬파일을 실행하기 위해서는 반드시 ipython 이나 주피터랩이 설치된 상태이어야 한다.
## mysum.py
= 0
total for i in range(1,11):
= total + i
total print(total)
슬기: 아나콘다를 이용하여 가상환경을 만들 경우 두 가지버전 이상의 python을 동시에 관리할 수 있다.
승민: 아래와 같이 myfuns.py
파일을 구성하였다고 하자.
# myfuns.py
def vec2_add(a,b):
return [a[0]+b[0], a[1]+b[1]]
이 경우 아래와 같이 임의의 주피터 노트북에서 myfuns
를 임포트하면 vec2_add
함수를 사용할 수 있다.
import myfuns
단, 여기에서 myfuns.py
는 현재 실행중인 노트북과 같은 폴더에 있다고 가정한다.
(풀이)
슬기, 승민
- 민정: 코랩은 사용자의 컴퓨터에 설치된 아나콘다를 기반으로 동작하며 (X)
- 구환: 반드시 ipython 이나 주피터랩이 설치된 상태이어야 한다. (X)
4. 삼성전자의 주가 추가문제 (30점)
다음은 삼성전자의 주가를 크롤링하는 코드이다.
= "2023-01-01"
start_date = "2023-05-02"
end_date = yf.download("005930.KS", start=start_date, end=end_date)['Adj Close'].to_numpy() y
[*********************100%***********************] 1 of 1 completed
삼성전자의 주가 \({\boldsymbol y}\)를 시각화하면 아래와 같다.
plt.plot(y)
(1)
아래와 같은 \({\bf x}\)를 설정하라.
\[{\bf x}=(x_1,x_2,\dots,x_n)=\big(\frac{1}{n},\frac{2}{n},\dots,1\big)\]
\({\bf x}=(x_1,\dots,x_n)\)을 바탕으로 아래와 같은 매트릭스 \({\bf X}\)를 생성하라. 단, \(n={\tt len}({\boldsymbol y})\).
\[{\bf X}=\begin{bmatrix} 1 & x_1 \\ 1 & x_2\\ \dots & \dots \\ 1 & x_n \end{bmatrix}\]
hint: \({\bf X}\)를 아래와 같이 해석해도 무방하다.
\[{\bf X}=\begin{bmatrix} x_1^0 & x_1^1 \\ x_2^0 & x_2^1\\ \dots & \dots \\ x_n^0 & x_n^1 \end{bmatrix}\]
= np.arange(1,83)/82 # x = np.arange(0,82)/82 정도의 실수는 정답으로 인정..
x = np.stack([x**k for k in range(2)],axis=1) X
(2)
(1)
에서 계산된 \({\bf X}\)에 대하여 아래를 계산하라.
\[\hat{\bf y}= {\bf X}({\bf X}^T {\bf X})^{-1}{\bf X}^T {\bf y}\]
\((x_i,y_i)\)와 \((x_i,\hat{y}_i)\)을 겹쳐서 시각화하라. 단, \(\hat{\bf y}=(\hat{y}_1,\dots,\hat{y}_n)\).
hint: 계산의 편의를 위하여 \({\bf y}\)와 \(\hat{\bf y}\)은 모두 \(n\times 1\) col-vector가 아닌 길이가 \(n\)인 벡터로 해석해도 무방하다.
(풀이)
= X@np.linalg.inv(X.T@ X)@ X.T @ y
yhat=r'$(x_i,y_i)$')
plt.plot(x,y, label'--',label=r'$(x_i,\hat{y}_i)$')
plt.plot(x,yhat, plt.legend()
<matplotlib.legend.Legend at 0x7f6ebb83c700>
3
. 아래와 같이 \({\bf X}\)를 수정하라.
\[{\bf X}=\begin{bmatrix} 1 & x_1 & x_1^2 & x_1^3 & \dots & x_1^{10} \\ 1 & x_2 & x_2^2 & x_2^3 & \dots & x_2^{10} \\ \dots & \dots & \dots & \dots & \dots & \dots \\ 1 & x_n & x_n^2 & x_n^3 & \dots & x_n^{10} \end{bmatrix}\]
수정된 \({\bf X}\)에 대하여 아래의 수식으로 \(\hat{\bf y}\)을 구하라.
\[\hat{\bf y}= {\bf X}({\bf X}^T {\bf X})^{-1}{\bf X}^T {\bf y}\]
\((x_i,y_i)\)와 \((x_i,\hat{y}_i)\)을 겹쳐서 시각화하라. 단, \(\hat{\bf y}=(\hat{y}_1,\dots,\hat{y}_n)\).
(풀이)
= np.stack([x**k for k in range(11)],axis=1)
X =r'$(x_i,y_i)$')
plt.plot(x,y, label@np.linalg.inv(X.T@ X)@ X.T @ y,'--',label=r'$(x_i,\hat{y}_i)$')
plt.plot(x, X plt.legend()
<matplotlib.legend.Legend at 0x7f6ebb7cd370>
5. fashin MNIST data 추가문제 (30점)
이 문제는 2번문항의 추가문항입니다.
# read data
=pd.read_csv('https://media.githubusercontent.com/media/guebin/PP2023/main/posts/fashion-mnist_train.csv')
df_train=pd.read_csv('https://media.githubusercontent.com/media/guebin/PP2023/main/posts/fashion-mnist_test.csv')
df_test
# rshp 함수정의
def rshp(row):
return row.reshape(28,28)
# cleaning data
= np.apply_along_axis(rshp,axis=1,arr=np.array(df_train.iloc[:,1:]))
xtrain = np.apply_along_axis(rshp,axis=1,arr=np.array(df_test.iloc[:,1:]))
xtest = np.array(df_train.label)
ytrain = np.array(df_test.label) ytest
(1)
\({\tt xtrain}\)에서 각 라벨에 대한 평균이미지를 계산하고 계산결과를 \({\tt imgmean}\)에 길이가 10인 list
로 저장하라. 즉 \({\tt imgmean}\)은 아래와 같은 자료구조를 가지고 있어야 한다.
- \({\tt imgmean}=\big[{\tt imgmean[0]},\dots, {\tt imgmean[9]}\big]\)
- \({\tt imgmean[0]}, \dots, {\tt imgmean[9]}\) 는 각각 (28,28)의 shape을 가진 numpy array
- \({\tt imgmean[0]}, \dots, {\tt imgmean[9]}\) 는 각각 숫자 0,1, …, 9의 평균이미지를 의미
모든 \(i=0,\dots,9\)에 대하여 아래를 계산하고
\[{\tt dist}[i] = \frac{1}{28\times 28} \sum_{p=0}^{27}\sum_{q=0}^{27}\big({\tt imgmean}[2][p,q]-{\tt imgmean}[i][p,q]\big)^2\]
\({\tt dist}[i]\)의 값이 가장 작은 \(i\)를 찾아라. 단 \({\tt dist}[i]=0\) 인 경우는 제외한다. (즉 2번 라벨과 평균이미지가 가장 비슷한 카테고리를 찾아라)
hint: 4번라벨이 2번라벨과 가장 비슷하다.
(풀이1)
= [xtrain[ytrain==i].mean(axis=0) for i in range(10)]
imgmean - imgmean[2])**2) for i in range(10)] [np.mean((imgmean[i]
[2597.2085496295,
5878.065097639916,
0.0,
4213.533631714888,
498.11027318129953,
7492.365150424071,
565.4023419996103,
8216.785686526042,
2762.121757294324,
6135.9385566330075]
(풀이2)
= [xtrain[ytrain==i].mean(axis=0) for i in range(10)]
imgmean - imgmean[2])**2,axis=(1,2)) np.mean((imgmean
array([2597.20854963, 5878.06509764, 0. , 4213.53363171,
498.11027318, 7492.36515042, 565.402342 , 8216.78568653,
2762.12175729, 6135.93855663])
(2)
(1)
의 과정을 반복하여 아래의 평균이미지를 비슷한 카테고리로 묶는 작업을 하였다고 하자.
# 평균이미지
작업결과 아래와 같이 비슷한 카테고리를 생각하였다고 하자.
= {0:[0,2,3,4,6], 1:[1], 2:[5,7,9], 3:[8]}
mapping_rule mapping_rule
{0: [0, 2, 3, 4, 6], 1: [1], 2: [5, 7, 9], 3: [8]}
즉 기존의 0,2,3,4,6번에 해당하는 이미지는 모두 비슷하다고 판단하였다. 위에 제시된 mapping_rule에 의거하여 아래와 같이 라벨의 수정하는 변환을 수행하라.
Before | After |
---|---|
0 | 0 |
1 | 1 |
2 | 0 |
3 | 0 |
4 | 0 |
5 | 2 |
6 | 0 |
7 | 2 |
8 | 3 |
9 | 2 |
수정된 라벨에 대하여 평균이미지를 다시 계산하여 imgmean2
에 저장하고 아래의 코드를 이용하여 시각화하라.
= plt.subplots(1,4,figsize=(10,5))
fig, ax for i in range(4):
='gray') ax[i].imshow(imgmean2[i],cmap
(풀이1)
= np.array([m for y in ytrain for m in mapping_rule if y in mapping_rule[m]]) ytrain2
= [xtrain[ytrain2==i].mean(axis=0) for i in range(4)] imgmean2
= plt.subplots(1,4,figsize=(10,5))
fig, ax for i in range(4):
='gray') ax[i].imshow(imgmean2[i],cmap
(풀이2)
= {v:k for k in mapping_rule for v in mapping_rule[k]}
inv inv
{0: 0, 2: 0, 3: 0, 4: 0, 6: 0, 1: 1, 5: 2, 7: 2, 9: 2, 8: 3}
= np.array([inv[y] for y in ytrain]) ytrain2
= [xtrain[ytrain2==i].mean(axis=0) for i in range(4)] imgmean2
= plt.subplots(1,4,figsize=(10,5))
fig, ax for i in range(4):
='gray') ax[i].imshow(imgmean2[i],cmap
(3)
수정된 라벨에 대하여 xtrain의 이미지를 분류하고 분류결과를 카테고리별로 제시하라.
(풀이1)
= np.array([[np.mean((xtrain[j,:,:]- imgmean2[i])**2) for i in range(4)] for j in range(60000)])
training_loss2 = training_loss2.argmin(axis=1)
ytrain2_hat ==i].tolist().count(i)/sum(ytrain2==i) for i in range(4)} {i:ytrain2_hat[ytrain2
{0: 0.7493333333333333,
1: 0.9443333333333334,
2: 0.9379444444444445,
3: 0.7983333333333333}
(풀이2)
= np.array([[np.mean((xtrain[j,:,:]- imgmean2[i])**2) for i in range(4)] for j in range(60000)])
training_loss2 = training_loss2.argmin(axis=1) ytrain2_hat
==i]==i) for i in range(4)] [np.mean(ytrain2_hat[ytrain2
[0.7493333333333333,
0.9443333333333334,
0.9379444444444445,
0.7983333333333333]
6. 동물명: 최하니 (20점)
아래는 동물명 “최하니”의 이미지이다.
= 'https://raw.githubusercontent.com/guebin/SC2022/main/hani.jpeg'
url = np.einsum('ijk->jik',np.array(PIL.Image.open(io.BytesIO(requests.get(url).content))),dtype=np.int64)/255 hani
plt.imshow(hani)
<matplotlib.image.AxesImage at 0x7f6efc778130>
아래는 하니를 적당히 분리하여 아래와 같이 hani_left
와 hini_right
를 만들고 시각화한 것이다.
= hani[:,:1512,:].copy()
hani_left = hani[:,1512:,:].copy() hani_right
= plt.subplots(1,2)
fig, ax 0].imshow(hani_left)
ax[1].imshow(hani_right) ax[
<matplotlib.image.AxesImage at 0x7f6ebb92b280>
(1)
hani_right[:,:,2]
의 모든 원소에 아래와 같은 변환을 수행하라.
- \(f(x)=\begin{cases} x & 1.15x >1.0 \\ 1.15x & 1.15x \leq 1.0 \end{cases}\)
(풀이1)
= hani_right[:,:,2] * (hani_right[:,:,2]*1.15 > 1.0)
_a = hani_right[:,:,2]*1.15 * (hani_right[:,:,2]*1.15 < 1.0)
_b 2] = _a + _b hani_right[:,:,
(풀이2)
def f(x):
if 1.15*x > 1.0:
return x
else:
return 1.15*x
for i in range(4023):
for j in range(1512):
2] = f(hani_right[i,j,2]) hani_right[i,j,
(2)
hani_left
와 (1)
에서 변환된 hani_right
를 np.concatenate
을 이용하여 합치고 결과를 시각화하라.
(풀이)
=1)) plt.imshow(np.concatenate([hani_left,hani_right],axis
<matplotlib.image.AxesImage at 0x7f6ebae56c10>
7. Naive Bayes classifier (120점)
ref: https://towardsdatascience.com/the-naive-bayes-classifier-how-it-works-e229e7970b84
아래의 데이터프레임은 날씨, 도로 상태, 교통 상황, 엔진 문제 및 사고 여부와 같은 여러 가지 변수를 포함하는 10개의 행과 5개의 열로 구성되어있다.
= pd.DataFrame({
df 'WeatherCondition': ['rain', 'snow', 'clear', 'clear', 'snow', 'rain', 'rain', 'snow', 'clear', 'clear'],
'RoadCondition': ['bad','average','bad','good','good','average','good','bad','good','bad'],
'TrafficCondition': ['high','normal','light','light','normal','light','normal','high','high','high'],
'EngineProblem': ['no','yes','no','yes','no','no','no','no','yes','yes'],
'Accident': ['yes','yes','no','yes','no','no','no','yes','no','yes']
})
df
WeatherCondition | RoadCondition | TrafficCondition | EngineProblem | Accident | |
---|---|---|---|---|---|
0 | rain | bad | high | no | yes |
1 | snow | average | normal | yes | yes |
2 | clear | bad | light | no | no |
3 | clear | good | light | yes | yes |
4 | snow | good | normal | no | no |
5 | rain | average | light | no | no |
6 | rain | good | normal | no | no |
7 | snow | bad | high | no | yes |
8 | clear | good | high | yes | no |
9 | clear | bad | high | yes | yes |
각 열에 대한 설명은 아래와 같다.
- ‘WeatherCondition’: 각 행에서 기록된 날씨 조건을 설명하며, ’rain’은 비, ’snow’는 눈, ’clear’는 맑은 날씨를 나타낸다.
- ‘RoadCondition’:각 행에서 기록된 도로 상태를 설명하며, ’bad’는 안 좋은, ’average’는 보통, ’good’은 좋은 도로 상태를 나타낸다.
- ‘TrafficCondition’:각 행에서 기록된 교통 상황을 설명하며, ’light’는 움직이기 쉬운, ’normal’은 평균, ’high’는 교통이 많은 상황을 나타낸다.
- ‘EngineProblem’: 각 행에서 기록된 엔진 문제 여부를 설명하며, ’yes’는 문제가 있음을 나타내고, ’no’는 문제가 없음을 나타낸다.
- ‘Accident’: 각 행에서 기록된 사고 여부를 설명하며, ’yes’는 사고가 있음을 나타내고, ’no’는 사고가 없음을 나타낸다.
우리는 ‘WeatherCondition’, ‘RoadCondition’, ‘TrafficCondition’, ‘EngineProblem’ 를 이용하여 ‘Accident’ 행의 값이 yes일지 no일지를 판단하는 일에 관심이 있다고 하자. 아래의 (1)-(4) 이러한 분류를 수행하는 방법을 구체화 한 것이다. (1)-(4)의 물음에 답하라.
(1)
주어진 자료에서 \(P({\tt Accident == no})\)를 계산하여라.
hint: Accident=='no'인 데이터수 / 전체데이터수
를 계산하면 되며 답은 0.5이다.
(풀이)
len(df.query('Accident=="no"')) / 10
0.5
(2)
아래와 같은 조건부 확률은
\[P({\tt WeatherCondition == rain} ~|~ {\tt Accident==no})\]
아래와 같이 계산한다고 하자.
# 방법1
len(df.query('WeatherCondition == "rain" and Accident == "no"'))/len(df.query('Accident=="no"'))
0.4
# 방법2
'WeatherCondition'] == 'rain') & (df['Accident']== 'no')).sum() / (df['Accident']== 'no').sum() ((df[
0.4
이와 유사한 방식으로 아래를 계산하라.
- \(P({\tt WeatherCondition == rain} ~|~ {\tt Accident==no})\)
- \(P({\tt WeatherCondition == snow} ~|~ {\tt Accident==no})\)
- \(\dots\)
- \(P({\tt EngineProblem == no} ~|~ {\tt Accident==yes})\)
- \(P({\tt EngineProblem == yes} ~|~ {\tt Accident==yes})\)
(풀이1)
*cond, _ = df.columns
'P({}={}|Accident={})'.format(i,j,k): ((df[i]==j)&(df['Accident']==k)).sum()/(df['Accident']==k).sum() for i in cond for j in set(df[i]) for k in ['no','yes']} {
{'P(WeatherCondition=clear|Accident=no)': 0.4,
'P(WeatherCondition=clear|Accident=yes)': 0.4,
'P(WeatherCondition=rain|Accident=no)': 0.4,
'P(WeatherCondition=rain|Accident=yes)': 0.2,
'P(WeatherCondition=snow|Accident=no)': 0.2,
'P(WeatherCondition=snow|Accident=yes)': 0.4,
'P(RoadCondition=average|Accident=no)': 0.2,
'P(RoadCondition=average|Accident=yes)': 0.2,
'P(RoadCondition=bad|Accident=no)': 0.2,
'P(RoadCondition=bad|Accident=yes)': 0.6,
'P(RoadCondition=good|Accident=no)': 0.6,
'P(RoadCondition=good|Accident=yes)': 0.2,
'P(TrafficCondition=normal|Accident=no)': 0.4,
'P(TrafficCondition=normal|Accident=yes)': 0.2,
'P(TrafficCondition=light|Accident=no)': 0.4,
'P(TrafficCondition=light|Accident=yes)': 0.2,
'P(TrafficCondition=high|Accident=no)': 0.2,
'P(TrafficCondition=high|Accident=yes)': 0.6,
'P(EngineProblem=yes|Accident=no)': 0.2,
'P(EngineProblem=yes|Accident=yes)': 0.6,
'P(EngineProblem=no|Accident=no)': 0.8,
'P(EngineProblem=no|Accident=yes)': 0.4}
(풀이2)
= {(j,k):((df[i]==j)&(df['Accident']==k)).sum()/(df['Accident']==k).sum() for i in cond for j in set(df[i]) for k in ['no','yes']}
dct dct
{('clear', 'no'): 0.4,
('clear', 'yes'): 0.4,
('rain', 'no'): 0.4,
('rain', 'yes'): 0.2,
('snow', 'no'): 0.2,
('snow', 'yes'): 0.4,
('average', 'no'): 0.2,
('average', 'yes'): 0.2,
('bad', 'no'): 0.2,
('bad', 'yes'): 0.6,
('good', 'no'): 0.6,
('good', 'yes'): 0.2,
('normal', 'no'): 0.4,
('normal', 'yes'): 0.2,
('light', 'no'): 0.4,
('light', 'yes'): 0.2,
('high', 'no'): 0.2,
('high', 'yes'): 0.6,
('yes', 'no'): 0.2,
('yes', 'yes'): 0.6,
('no', 'no'): 0.8,
('no', 'yes'): 0.4}
(3)
아래와 같은 새로운 상황이 발생하였다고 가정하자.
- \({\tt WeatherCondition==rain}\)
- \({\tt RoadCondition==good}\)
- \({\tt TraffictCondition==normal}\)
- \({\tt EngineProblem==no}\)
아래를 각각 계산하라.
\(\begin{align} A&=P({\tt Accident == yes})\\ &\times P({\tt WeatherCondition==rain~ |~ Accident == yes}) \\ &\times P({\tt RoadCondition==good~|~ Accident == yes}) \\ &\times P({\tt TrafficCondition==normal~ |~ Accident == yes}) \\ &\times P({\tt EngineProblem=no~ |~ Accident == yes}) \end{align}\)
\(\begin{align} B&=P({\tt Accident ==no})\\ &\times P({\tt WeatherCondition==rain~ |~ Accident == no}) \\ &\times P({\tt RoadCondition==good~|~ Accident == no}) \\ &\times P({\tt TrafficCondition==normal~ |~ Accident == no}) \\ &\times P({\tt EngineProblem=no~ |~ Accident == no}) \end{align}\)
여기에서 \(\frac{A}{A+B}\)와 \(\frac{B}{A+B}\)를 각각 주어진 상황에 대하여 사고가 날 확률, 사고가 나지 않을 확률을 의미한다고 하자. 주어진 상황에서 사고가 날 확률은 얼마인가?
hint: 답은 1/25
(풀이)
= {(j,k):((df[i]==j)&(df['Accident']==k)).sum()/(df['Accident']==k).sum() for i in cond for j in set(df[i]) for k in ['no','yes']}
dct dct
{('clear', 'no'): 0.4,
('clear', 'yes'): 0.4,
('rain', 'no'): 0.4,
('rain', 'yes'): 0.2,
('snow', 'no'): 0.2,
('snow', 'yes'): 0.4,
('average', 'no'): 0.2,
('average', 'yes'): 0.2,
('bad', 'no'): 0.2,
('bad', 'yes'): 0.6,
('good', 'no'): 0.6,
('good', 'yes'): 0.2,
('normal', 'no'): 0.4,
('normal', 'yes'): 0.2,
('light', 'no'): 0.4,
('light', 'yes'): 0.2,
('high', 'no'): 0.2,
('high', 'yes'): 0.6,
('yes', 'no'): 0.2,
('yes', 'yes'): 0.6,
('no', 'no'): 0.8,
('no', 'yes'): 0.4}
- dct의 키는
(WeatherCondition~EngineProblem의 라벨, Accident의 라벨)
로 이루어짐
= dct['rain','yes']*dct['good','yes']*dct['normal','yes']*dct['no','yes']
A = dct['rain','no']*dct['good','no']*dct['normal','no']*dct['no','no'] B
/(A+B) # 실제정답은 0.04, 0.000000000000000015는 에러 A
0.040000000000000015
(4)
모든 상황에 대하여 사고가 날 확률을 구하여라.
(풀이1)
= set(df.WeatherCondition)
W = set(df.RoadCondition)
R = set(df.TrafficCondition)
T = set(df.EngineProblem) E
= pd.DataFrame([[w,r,t,e,dct[w,'yes']*dct[r,'yes']*dct[t,'yes']*dct[e,'yes'],dct[w,'no']*dct[r,'no']*dct[t,'no']*dct[e,'no']] for w in W for r in R for t in T for e in E])
df2 = pd.Index(['WeatherCondition','RoadCondition','TrafficCondition','EngineProblem','A','B'])
df2.columns eval('Prob = A/(A+B)') df2.
WeatherCondition | RoadCondition | TrafficCondition | EngineProblem | A | B | Prob | |
---|---|---|---|---|---|---|---|
0 | clear | average | normal | yes | 0.0096 | 0.0064 | 0.600000 |
1 | clear | average | normal | no | 0.0064 | 0.0256 | 0.200000 |
2 | clear | average | light | yes | 0.0096 | 0.0064 | 0.600000 |
3 | clear | average | light | no | 0.0064 | 0.0256 | 0.200000 |
4 | clear | average | high | yes | 0.0288 | 0.0032 | 0.900000 |
5 | clear | average | high | no | 0.0192 | 0.0128 | 0.600000 |
6 | clear | bad | normal | yes | 0.0288 | 0.0064 | 0.818182 |
7 | clear | bad | normal | no | 0.0192 | 0.0256 | 0.428571 |
8 | clear | bad | light | yes | 0.0288 | 0.0064 | 0.818182 |
9 | clear | bad | light | no | 0.0192 | 0.0256 | 0.428571 |
10 | clear | bad | high | yes | 0.0864 | 0.0032 | 0.964286 |
11 | clear | bad | high | no | 0.0576 | 0.0128 | 0.818182 |
12 | clear | good | normal | yes | 0.0096 | 0.0192 | 0.333333 |
13 | clear | good | normal | no | 0.0064 | 0.0768 | 0.076923 |
14 | clear | good | light | yes | 0.0096 | 0.0192 | 0.333333 |
15 | clear | good | light | no | 0.0064 | 0.0768 | 0.076923 |
16 | clear | good | high | yes | 0.0288 | 0.0096 | 0.750000 |
17 | clear | good | high | no | 0.0192 | 0.0384 | 0.333333 |
18 | rain | average | normal | yes | 0.0048 | 0.0064 | 0.428571 |
19 | rain | average | normal | no | 0.0032 | 0.0256 | 0.111111 |
20 | rain | average | light | yes | 0.0048 | 0.0064 | 0.428571 |
21 | rain | average | light | no | 0.0032 | 0.0256 | 0.111111 |
22 | rain | average | high | yes | 0.0144 | 0.0032 | 0.818182 |
23 | rain | average | high | no | 0.0096 | 0.0128 | 0.428571 |
24 | rain | bad | normal | yes | 0.0144 | 0.0064 | 0.692308 |
25 | rain | bad | normal | no | 0.0096 | 0.0256 | 0.272727 |
26 | rain | bad | light | yes | 0.0144 | 0.0064 | 0.692308 |
27 | rain | bad | light | no | 0.0096 | 0.0256 | 0.272727 |
28 | rain | bad | high | yes | 0.0432 | 0.0032 | 0.931034 |
29 | rain | bad | high | no | 0.0288 | 0.0128 | 0.692308 |
30 | rain | good | normal | yes | 0.0048 | 0.0192 | 0.200000 |
31 | rain | good | normal | no | 0.0032 | 0.0768 | 0.040000 |
32 | rain | good | light | yes | 0.0048 | 0.0192 | 0.200000 |
33 | rain | good | light | no | 0.0032 | 0.0768 | 0.040000 |
34 | rain | good | high | yes | 0.0144 | 0.0096 | 0.600000 |
35 | rain | good | high | no | 0.0096 | 0.0384 | 0.200000 |
36 | snow | average | normal | yes | 0.0096 | 0.0032 | 0.750000 |
37 | snow | average | normal | no | 0.0064 | 0.0128 | 0.333333 |
38 | snow | average | light | yes | 0.0096 | 0.0032 | 0.750000 |
39 | snow | average | light | no | 0.0064 | 0.0128 | 0.333333 |
40 | snow | average | high | yes | 0.0288 | 0.0016 | 0.947368 |
41 | snow | average | high | no | 0.0192 | 0.0064 | 0.750000 |
42 | snow | bad | normal | yes | 0.0288 | 0.0032 | 0.900000 |
43 | snow | bad | normal | no | 0.0192 | 0.0128 | 0.600000 |
44 | snow | bad | light | yes | 0.0288 | 0.0032 | 0.900000 |
45 | snow | bad | light | no | 0.0192 | 0.0128 | 0.600000 |
46 | snow | bad | high | yes | 0.0864 | 0.0016 | 0.981818 |
47 | snow | bad | high | no | 0.0576 | 0.0064 | 0.900000 |
48 | snow | good | normal | yes | 0.0096 | 0.0096 | 0.500000 |
49 | snow | good | normal | no | 0.0064 | 0.0384 | 0.142857 |
50 | snow | good | light | yes | 0.0096 | 0.0096 | 0.500000 |
51 | snow | good | light | no | 0.0064 | 0.0384 | 0.142857 |
52 | snow | good | high | yes | 0.0288 | 0.0048 | 0.857143 |
53 | snow | good | high | no | 0.0192 | 0.0192 | 0.500000 |
(풀이2)
– 좀 더 일반적인 풀이
import itertools
= []
lst for cond_details in itertools.product(*[set(df[col_name]) for col_name in cond]):
=1;
A=1;
Bfor c in cond_details:
= A* dct[c,'yes']
A = B*dct[c,'no']
B *cond_details,A,B,A/(A+B)]) lst.append([
= pd.DataFrame(lst)
df2 = pd.Index(['WeatherCondition','RoadCondition','TrafficCondition','EngineProblem','A','B','Prob'])
df2.columns df2
WeatherCondition | RoadCondition | TrafficCondition | EngineProblem | A | B | Prob | |
---|---|---|---|---|---|---|---|
0 | clear | average | normal | yes | 0.0096 | 0.0064 | 0.600000 |
1 | clear | average | normal | no | 0.0064 | 0.0256 | 0.200000 |
2 | clear | average | light | yes | 0.0096 | 0.0064 | 0.600000 |
3 | clear | average | light | no | 0.0064 | 0.0256 | 0.200000 |
4 | clear | average | high | yes | 0.0288 | 0.0032 | 0.900000 |
5 | clear | average | high | no | 0.0192 | 0.0128 | 0.600000 |
6 | clear | bad | normal | yes | 0.0288 | 0.0064 | 0.818182 |
7 | clear | bad | normal | no | 0.0192 | 0.0256 | 0.428571 |
8 | clear | bad | light | yes | 0.0288 | 0.0064 | 0.818182 |
9 | clear | bad | light | no | 0.0192 | 0.0256 | 0.428571 |
10 | clear | bad | high | yes | 0.0864 | 0.0032 | 0.964286 |
11 | clear | bad | high | no | 0.0576 | 0.0128 | 0.818182 |
12 | clear | good | normal | yes | 0.0096 | 0.0192 | 0.333333 |
13 | clear | good | normal | no | 0.0064 | 0.0768 | 0.076923 |
14 | clear | good | light | yes | 0.0096 | 0.0192 | 0.333333 |
15 | clear | good | light | no | 0.0064 | 0.0768 | 0.076923 |
16 | clear | good | high | yes | 0.0288 | 0.0096 | 0.750000 |
17 | clear | good | high | no | 0.0192 | 0.0384 | 0.333333 |
18 | rain | average | normal | yes | 0.0048 | 0.0064 | 0.428571 |
19 | rain | average | normal | no | 0.0032 | 0.0256 | 0.111111 |
20 | rain | average | light | yes | 0.0048 | 0.0064 | 0.428571 |
21 | rain | average | light | no | 0.0032 | 0.0256 | 0.111111 |
22 | rain | average | high | yes | 0.0144 | 0.0032 | 0.818182 |
23 | rain | average | high | no | 0.0096 | 0.0128 | 0.428571 |
24 | rain | bad | normal | yes | 0.0144 | 0.0064 | 0.692308 |
25 | rain | bad | normal | no | 0.0096 | 0.0256 | 0.272727 |
26 | rain | bad | light | yes | 0.0144 | 0.0064 | 0.692308 |
27 | rain | bad | light | no | 0.0096 | 0.0256 | 0.272727 |
28 | rain | bad | high | yes | 0.0432 | 0.0032 | 0.931034 |
29 | rain | bad | high | no | 0.0288 | 0.0128 | 0.692308 |
30 | rain | good | normal | yes | 0.0048 | 0.0192 | 0.200000 |
31 | rain | good | normal | no | 0.0032 | 0.0768 | 0.040000 |
32 | rain | good | light | yes | 0.0048 | 0.0192 | 0.200000 |
33 | rain | good | light | no | 0.0032 | 0.0768 | 0.040000 |
34 | rain | good | high | yes | 0.0144 | 0.0096 | 0.600000 |
35 | rain | good | high | no | 0.0096 | 0.0384 | 0.200000 |
36 | snow | average | normal | yes | 0.0096 | 0.0032 | 0.750000 |
37 | snow | average | normal | no | 0.0064 | 0.0128 | 0.333333 |
38 | snow | average | light | yes | 0.0096 | 0.0032 | 0.750000 |
39 | snow | average | light | no | 0.0064 | 0.0128 | 0.333333 |
40 | snow | average | high | yes | 0.0288 | 0.0016 | 0.947368 |
41 | snow | average | high | no | 0.0192 | 0.0064 | 0.750000 |
42 | snow | bad | normal | yes | 0.0288 | 0.0032 | 0.900000 |
43 | snow | bad | normal | no | 0.0192 | 0.0128 | 0.600000 |
44 | snow | bad | light | yes | 0.0288 | 0.0032 | 0.900000 |
45 | snow | bad | light | no | 0.0192 | 0.0128 | 0.600000 |
46 | snow | bad | high | yes | 0.0864 | 0.0016 | 0.981818 |
47 | snow | bad | high | no | 0.0576 | 0.0064 | 0.900000 |
48 | snow | good | normal | yes | 0.0096 | 0.0096 | 0.500000 |
49 | snow | good | normal | no | 0.0064 | 0.0384 | 0.142857 |
50 | snow | good | light | yes | 0.0096 | 0.0096 | 0.500000 |
51 | snow | good | light | no | 0.0064 | 0.0384 | 0.142857 |
52 | snow | good | high | yes | 0.0288 | 0.0048 | 0.857143 |
53 | snow | good | high | no | 0.0192 | 0.0192 | 0.500000 |