2. Visualize the data in 2D space to show the distribution of the attributes. You should show all possible combinations of pairs of attributes, six cases in total. Find your optimal decision boundary in each case to minimize the costs. Report your analysis about the result.
(1) Visualize the data in 2D space
(2) Find your optimal decision boundary in each case to minimize the costs.
for i in myrange(-7, -5, 0.1):
for j in myrange(15, 19, 0.1):
error_sum, error_sum1, error_sum2 = 0, 0, 0
gap, gap_sum1, gap_sum2 = 0, 0, 0
for k in range(50):
for x in zip(versicolor_petal_length, setosa_petal_length): # x 병합 x1 x2
if (i * x[0] + j) > versicolor_petal_width[k]: # 바운더리 아래 y1
error1 = (i * x[0] + j) - versicolor_petal_width[k] # y빼기 y1
error_sum1 += error1
gap1 = versicolor_petal_width[k] - (i * x[0] + j) # 겹치는 것이 없을 때 차 y1
gap_sum1 += gap1
if setosa_petal_width[k] > (i * x[1] + j): # 바운더리 위 y2
error2 = setosa_petal_width[k] - (i * x[1] + j) # y빼기 y2
error_sum2 += error2
gap2 = (i * x[1] + j) - setosa_petal_width[k] # 겹치는 것이 없을 때 차 y2
gap_sum2 += gap2
error_sum = error_sum1 + error_sum2 #두 클래스의 에러 합
gap = gap_sum1 - gap_sum2 #두 클래스의 gap의 차
if gap < 0: #gap이 음수인 경우 양수로
gap = -gap
if error_sum < smallest: #가장 작은 error_sum인 경우가 바운더리
smallest = error_sum
min_i = i
min_j = j
if gap < gap_small: #두 클래스의 gap의 차가 가장 작은 경우 바운더리
gap_small = gap
small_i = i
small_j = j
if smallest == 0:
print("gap")
print(gap_small, small_i, small_j)
else:
print("error")
print(smallest, min_i, min_j)
Error_sum과 gap 변수를 사용하여 error_sum이 가장 작은 경우를 바운더리로 선택하였고, 만일 두 개의 scatter plot이 겹치는 구간이 없다면(error_sum이 0일 경우) 바운더리로부터 얼마나 멀리 분포되어 있는지를 계산한 후 모두 합하여 각 클래스에서 그 차가 작은 경우가 그 클래스 중간에 있는 값이라고 생각했기 때문에 바운더리로 선택하였다.
일차함수가 일반화하기 용이하다고 판단하여 1차함수로 선정하였고 i, j는 y = i*x + j의 식에 대입하게 될 변수이다. For문으로 바운더리를 결정할 i와 j의 값을 계산하였다.
zip(setosa_sepal_length, versicolor_sepal_length)를 이용하여 두 리스트를 병합해주었고 x[0]으로 setosa_sepal_length의 값을, x[1]로 versicolor_sepal_length의 값을 가져왔다. i*x[0]+j의 값이 실제의 y값인 setosa_sepal_width[k]의 값보다 큰 경우에는 바운더리 아래에 있는 cost의 값으로 판단하고 이를 모두 k(50)번 더했다. (error_sum1) 반대로 i*x[0]+j의 값이 실제의 y값인 versicolor_sepal_width[k]의 값보다 작은 경우에는 바운더리 위에 있는 cost의 값으로 판단하고 이를 모두 k번 더했다.(error_sum2) 이 둘의 값을 합한 error_sum이 가장 작은 smallest의 i, j의 값을 일차함수의 계수로 하는 바운더리를 선택하였다.
두 클래스가 겹치는 구간이 없는 경우 gap1 = setosa_sepal_length[k] – (i * x[0] + j)을 이용하여 실제의 값에서 바운더리의 값을 뺀 값을 계산한 후 이를 k번 더해 이를 gap_sum1이라고 하였다. 이를 두 번째 클래스인 versicolor_sepal_length[k]에 대해서도 시행하였고 이를 gap_sum2로 설정하였다. 이 둘의 차이인 gap이 가장 작은 경우 두 클래스의 분포 중간에 바운더리가 위치한다고 판단하여 그 경우의 i, j의 값을 일차함수의 계수로 하는 바운더리를 선택하였다.
다음과 같이 값이 나와서 f(x) = 1*x-2.3으로 setosa-virginica는 1, -2.5가 나왔으므로 g(x) = 1*x-2.5, versicolor-virginica는 0.8, -2.1이 나와서 u(x) = 0.8*x-2.1로 설정하였고 바운더리의 결과는 다음과 같다. 이를 모두 동일한 방법으로 3 * 6 = 18번 시행하여 각 클래스에 대한 모든 경우의 바운더리를 구하였다.
3. Write a code to classify three classes of iris based on the Bayesian decision rule; by finding a pmf(probability mass function) of likelihood and defining a prior. Evaluate your classifier by computing precision and recall. Use 5-fold cross validation for evaluation. You may set or test your own priors.
list_setosa_sepal_length = list(set(setosa_sepal_length)) #list_setosa_sepal_length: 중복없는 배열
n = len(list_setosa_sepal_length)
listSetosaSepalLength = [[0 for _ in range(2)] for _ in range(n)] #list1: 2차원배열 50*2
for i in range(n):
listSetosaSepalLength[i][0] = list_setosa_sepal_length[i]
for j in range(50):
if setosa_sepal_length[j] in list_setosa_sepal_length: #있으면
x = list_setosa_sepal_length.index(setosa_sepal_length[j])
listSetosaSepalLength[x][1] += 1
list_versicolor_sepal_length = list(set(versicolor_sepal_length)) #list_versicolor_sepal_length: 중복없는 배열
m = len(list_versicolor_sepal_length)
listVersicolorSepalLength = [[0 for _ in range(2)] for _ in range(m)] #list1: 2차원배열 50*2
for i in range(m):
listVersicolorSepalLength[i][0] = list_versicolor_sepal_length[i]
for j in range(50):
if versicolor_sepal_length[j] in list_versicolor_sepal_length: #있으면
y = list_versicolor_sepal_length.index(versicolor_sepal_length[j])
listVersicolorSepalLength[y][1] += 1
list_virginica_sepal_length = list(set(virginica_sepal_length)) #list_virginica_sepal_length: 중복없는 배열
l = len(list_virginica_sepal_length)
listVirginicaSepalLength = [[0 for _ in range(2)] for _ in range(l)] #list1: 2차원배열 50*2
for i in range(l):
listVirginicaSepalLength[i][0] = list_virginica_sepal_length[i]
for j in range(50):
if virginica_sepal_length[j] in list_virginica_sepal_length: #있으면
z = list_virginica_sepal_length.index(virginica_sepal_length[j])
listVirginicaSepalLength[z][1] += 1
for i in range(n):
for j in range(m):
for r in range(l):
if (listSetosaSepalLength[i][0] == listVersicolorSepalLength[j][0]):
x2 = listSetosaSepalLength[i][1] + listVersicolorSepalLength[j][1]
x2 = 1/x2
listSetosaSepalLength[i][1] *= x2
listVersicolorSepalLength[j][1] *= x2
elif (listSetosaSepalLength[i][0] == listVirginicaSepalLength[r][0]):
x3 = listSetosaSepalLength[i][1] + listVirginicaSepalLength[r][1]
x3 = 1/x3
listSetosaSepalLength[i][1] *= x3
listVirginicaSepalLength[r][1] *= x3
elif (listVirginicaSepalLength[r][0] == listVersicolorSepalLength[j][0]):
x4 = listVirginicaSepalLength[r][1] + listVersicolorSepalLength[j][1]
x4 = 1/x4
listVirginicaSepalLength[r][1] *= x4
listVersicolorSepalLength[j][1] *= x4
for i in range(n):
for j in range(m):
for r in range(l):
if (listSetosaSepalLength[i][0] == listVersicolorSepalLength[j][0] == listVirginicaSepalLength[r][0]):
x1 = listSetosaSepalLength[i][1] + listVersicolorSepalLength[j][1] + listVirginicaSepalLength[r][1]
x1 = 1/x1
listSetosaSepalLength[i][1] *= x1
listVersicolorSepalLength[j][1] *= x1
listVirginicaSepalLength[r][1] *= x1
for i in range(n):
for j in range(m):
for r in range(l):
if listSetosaSepalLength[i][1] >= 1:
listSetosaSepalLength[i][1] = 1
elif listVersicolorSepalLength[j][1] >= 1:
listVersicolorSepalLength[j][1] = 1
elif listVirginicaSepalLength[r][1] >= 1:
listVirginicaSepalLength[r][1] = 1
listSetosaSepalLength.sort()
listVersicolorSepalLength.sort()
listVirginicaSepalLength.sort()
print("Setosa Sepal Length: ", listSetosaSepalLength)
print("Versicolor Sepal Length: ", listVersicolorSepalLength)
print("Virginica Sepal Length: ", listVirginicaSepalLength)
중복이 있는 1차원 배열을 중복이 없는 2차원 배열로 만들었고, 1열에는 원래의 데이터 값을, 2열에는 그 값이 몇 번 중복이 되어 있는지 중복 카운트를 넣었다. 이를 versicolor_sepal_length와 virginica_sepal_length에도 시행하여 sepal_length에 대해 각 클래스에 대한 2차원 배열을 만들었다.
각 클래스의 배열 1열의 값이 겹치는 경우가 있다면 총합이 1이 되도록 만들었다. 각 클래스의 중복 카운트를 합한 값을 모두 더하여 그 수를 1로 나누었고, 그 값을 각 클래스의 중복 카운트에 곱하였다.
다른 클래스와 값이 겹치지 않는 경우 중에 중복 카운트가 1이 넘는 경우가 존재한다면 확률이 1이 되도록 값을 모두 변경하였다.
결과적으로 sepal length에 대해 각 클래스에 대한 pmf를 구할 수 있다.
→ Setosa Sepal Length: [[4.3, 1], [4.4, 1], [4.5, 1], [4.6, 1], [4.7, 1], [4.8, 1], [4.9, 0.46006389776357826], [5.0, 0.8], [5.1, 0.8888888888888888], [5.2, 0.75], [5.3, 1], [5.4, 0.8333333333333333], [5.5, 0.28571428571428575], [5.7, 0.591623374825833], [5.8, 0.3870967741935484]]
→ Versicolor Sepal Length: [[4.9, 0.38268537348629883], [5.0, 0.2], [5.1, 0.1111111111111111], [5.2, 0.25], [5.4, 0.16666666666666666], [5.5, 0.7142857142857143], [5.6, 0.8333333333333333], [5.7, 0.32178217821782185], [5.8, 0.32958003651856355], [5.9, 0.6666666666666666], [6.0, 0.6666666666666666], [6.1, 0.6666666666666666], [6.2, 0.5], [6.3, 0.3333333333333333], [6.4, 0.28571428571428575], [6.5, 0.2], [6.6, 1], [6.7, 0.375], [6.8, 0.3333333333333333], [6.9, 0.25], [7.0, 1]]
→ Virginica Sepal Length: [[4.9, 0.1572507287501228], [5.6, 0.16666666666666666], [5.7, 0.08659444695634523], [5.8, 0.28332318928788797], [5.9, 0.3333333333333333], [6.0, 0.3333333333333333], [6.1, 0.3333333333333333], [6.2, 0.5], [6.3, 0.6666666666666666], [6.4, 0.7142857142857143], [6.5, 0.8], [6.7, 0.625], [6.8, 0.6666666666666666], [6.9, 0.75], [7.1, 1], [7.2, 1], [7.3, 1], [7.4, 1], [7.6, 1], [7.7, 1], [7.9, 1]]
이를 같은 방법으로 sepal width, petal length, petal width에 대해 시행을 하면 모든 경우의 pmf를 구할 수 있다.
→ Setosa Sepal width: [[2.3, 0.25], [2.9, 0.42469018112488083], [3.0, 0.053571428571428555], [3.1, 0.4647825663975094], [3.2, 0.46339501206757855], [3.3, 0.4225690276110444], [3.4, 0.47763318422122814], [3.5, 1], [3.6, 0.6666666666666666], [3.7, 1], [3.8, 0.6666666666666666], [3.9, 1], [4.0, 1], [4.1, 1], [4.2, 1], [4.4, 1]]
→ Versicolor Sepal width: [[2.0, 1], [2.2, 0.6666666666666666], [2.3, 0.75], [2.4, 1], [2.5, 0.5], [2.6, 0.6000000000000001], [2.7, 0.5555555555555556], [2.8, 0.42857142857142855], [2.9, 0.3742552111854711], [3.0, 0.47734224538348247], [3.1, 0.38034911892872686], [3.2, 0.36758156058101865], [3.3, 0.28189585485421337], [3.4, 0.3942903328470257]]
→ Virginica Sepal width: [[2.2, 0.3333333333333333], [2.5, 0.5], [2.6, 0.4], [2.7, 0.4444444444444444], [2.8, 0.5714285714285714], [2.9, 0.20105460768964803], [3.0, 0.4690863260450889], [3.1, 0.15486831467376366], [3.2, 0.16902342735140294], [3.3, 0.29553511753474226], [3.4, 0.12807648293174617], [3.6, 0.3333333333333333], [3.8, 0.3333333333333333]]
→ Setosa Petal length: [[1.0, 1], [1.1, 1], [1.2, 1], [1.3, 1], [1.4, 1], [1.5, 1], [1.6, 1], [1.7, 1], [1.9, 1]]
→ Versicolor Petal length: [[3.0, 1], [3.3, 2], [3.5, 2], [3.6, 1], [3.7, 1], [3.8, 1], [3.9, 3], [4.0, 5], [4.1, 3], [4.2, 4], [4.3, 2], [4.4, 4], [4.5, 0.875], [4.6, 3], [4.7, 5], [4.8, 0.5], [4.9, 0.4], [5.0, 0.25], [5.1, 0.125]]
→ Virginica Petal length: [[4.5, 0.125], [4.8, 0.5], [4.9, 0.6000000000000001], [5.0, 0.75], [5.1, 0.875], [5.2, 2], [5.3, 2], [5.4, 2], [5.5, 3], [5.6, 6], [5.7, 3], [5.8, 3], [5.9, 2], [6.0, 2], [6.1, 3], [6.3, 1], [6.4, 1], [6.6, 1], [6.7, 2], [6.9, 1]]
→ Setosa Petal width: [[0.1, 1], [0.2, 1], [0.3, 1], [0.4, 1], [0.5, 1], [0.6, 1]]
→ Versicolor Petal width: [[1.0, 7], [1.1, 3], [1.2, 5], [1.3, 13], [1.4, 0.875], [1.5, 0.8333333333333335], [1.6, 0.75], [1.7, 0.5], [1.8, 0.08333333333333333]]
→ Virginica Petal width: [[1.4, 0.125], [1.5, 0.16666666666666669], [1.6, 0.25], [1.7, 0.5], [1.8, 0.9166666666666666], [1.9, 5], [2.0, 6], [2.1, 6], [2.2, 3], [2.3, 8], [2.4, 3], [2.5, 3]]
'데이터 분석 > 컴퓨터응용확률' 카테고리의 다른 글
binomial random variable (0) | 2022.06.23 |
---|---|
uniform distribution (0) | 2022.06.23 |
Iris flower identification using Bayesian Classifier - 2 (0) | 2022.06.23 |
Iris flower identification using Bayesian Classifier - 1 (0) | 2022.06.22 |
Data transform (0) | 2022.06.22 |
댓글