mushrooms.csv
1.17MB

 

 

 

자료형태

범주형

명목형

순서형

수치형

이산형

연속형

 

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# 나이브베이즈알고리즘을 이용하여 식용버섯과 독버섯 분류하기
mushroom = read.csv("c:/data/mushrooms.csv",header=T,stringsAsFactors = T)
 
# factor로 변환하는 이유
# factor로 변환하지 않으면 프로그램이 문자를 단지 형(string)으로만 인식하지만
# factor로 변환하면 각각의 문자를 범주로 인식하기 때문에 나이브 베이즈를 사용하는 명목형 데이터는 Factor 형태여야 함
 
# R은 테이블로도 데이터를 확인할 수 있음
View(mushroom)
 
# 결측치 확인
colSums(is.na(mushroom))
 
dim(mushroom) # 8124(데이터 개수) 23(컬럼 개수)
 
# 데이터 shuffle
set.seed(1)
train_cnt <- round( 0.75*dim(mushroom)[1] )
train_cnt # 6093
 
# mushroom의 1부터 8124 중 6093개(train_cnt)만큼 임의의 숫자를 뽑음
train_index <- sample( 1:dim(mushroom)[1], train_cnt, replace=F)
train_index
 
# 임의로 뽑힌 6093개의 인덱스들을 추출해서 train / test 로 나눔
mushroom_train <- mushroom[ train_index, ]
mushroom_test <- mushroom[-train_index, ]
 
nrow(mushroom_train) #6093
nrow(mushroom_test) #2031 
 
# mushroom_train 확인
str(mushroom_train)
 
# 없다면 'e1071 패키지 깔기'
# install.packages('e1071')
# 나이브 베이즈 알고리즘 사용
library(e1071)
model1 <- naiveBayes(type~.,data=mushroom_train) # type~. : 예측하고자 하는 컬럼 의미
model1
result1 <- predict( model1, mushroom_test[  , -1] )
result1 
 
library(gmodels)
CrossTable(mushroom_test[ ,1], result1)
 
# 어떤 laplace 값이 정확도가 가장 높을까?
temp = c()
laplace_num = c()
for (i in 1:10) {
   laplace_num = append(laplace_num,i*0.001)
    mushroom_test_pred = naiveBayes(type~ . ,  data=mushroom_train, laplace=i*0.001)
    result2 <- predict(mushroom_test_pred, mushroom_test[ , -1] )
    g2 <- CrossTable(mushroom_test[ ,1], result2)
    g3 <- g2$prop.tbl[1]+g2$prop.tbl[4]
    temp = append(temp,g3)
}
 
result = data.frame("laplace"=laplace_num,"정확도"=temp)
library(plotly)
plot_ly(x=~result[,"laplace"],y=~result[,"정확도"],type='scatter',mode='lines') %>%
  layout(xaxis=list(title="laplace값"),yaxis=list(title="정확도"))
cs

 

 

 

 

 

 

 

 

 

wine.csv
0.01MB

 

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# KNN알고리즘을 이용하여 와인 등급 분류하기
wine = read.csv('c:/data/wine.csv',header=T)
 
# stringsAsFactors를 선언하지 않으면 자동적으로 stringsAsFactors=TRUE
 
# 데이터를 섞음 (wine 데이터는 예측값이 컬럼[1]인 type이므로 일단 다 섞음)
# 유방암 데이터를 섞을 때 [-1]을 한 이유는 유방암 데이터는 불필요한 환자 코드가 있었기 때문
# 하지만 와인 데이터는 모두 쓸모 있는 데이터 뿐이기 때문에 굳이 어떠한 컬럼을 빼지 않아도 됨
 
# 데이터를 shuffle하는 이유
# 처음부터 데이터가 섞여있을 수도 있지만, wine 데이터와 같이 type별로 구분되어져 있으면
# train, test로 나눌 때 train에는 type1,type2 데이터만 test에는 type3 데이터만 있을 수 있기 때문
set.seed(15)
wine_shuffle <- wine[sample(nrow(wine)), ]
wine_shuffle
 
# wine 데이터를 섞은 결과인 wine2 확인
wine2 <- wine_shuffle
str(wine2)
 
# 정규화 함수
normalize <- function(x) {
  return ( (x-min(x)) / (max(x) - min(x)))
}
 
# wine 데이터의 컬럼 개수를 파악하고,
ncol(wine)
 
# wine_n이라는 새로운 값을 만듦
# 여기서 우리가 학습에 필요한 데이터는 [1]에 위치하고 예측할 결과인 type을 제외한 모든 컬럼이기 때문에 wine2[2:13]까지를 정규화함
# 정규화를 하는 이유는 각각의 데이터가 단위가 다르기 때문에 정규화를 하여 비교, 계산하기 편하게 하기 위함임
wine_n<- as.data.frame(lapply(wine2[2:13],normalize))
summary(wine_n)
 
 
# 데이터 나누기 train(90%)/test(10%)
train_num<-round(0.9*nrow(wine_n),0)
wine_train<-wine_n[1:train_num,]
wine_test<-wine_n[(train_num+1):nrow(wine_n),]
 
# 라벨 나누기 train/test
wine_train_label <- wine2[1:train_num,1]
wine_test_label <- wine2[(train_num+1):nrow(wine_n),1]
 
# 확인
wine_train_label
wine_test_label
 
wine_train
wine_test
 
# knn 알고리즘 사용
library(class)
result1 <- knn(train=wine_train, test=wine_test,cl=wine_train_label, k=21# k는 내 마음대로 (대체로 홀수)
result1
wine_test_label
 
# 예측값과 정답을 테이블로 만듦
= data.frame('실제'=wine_test_label,"예측"=result1)
x
table(x)
 
# 예측률(정확도) 평가
library(gmodels)
g2 =CrossTable(x=wine_test_label,y=result1,prop.chisq=FALSE)
g2
 
# wine은 분류하고자 하는 type이 3가지이므로 prob값도 3개를 합해야 함
g2$prop.tbl[1+ g2$prop.tbl[5+ g2$prop.tbl[9# 1
 
 
# 어떤 k값이 정확도가 가장 높을까?
temp = c()
k_num = c()
for (i in 1:200) {
  if (i%%2 != 0) {
    k_num = append(k_num,i)
    wine_test_pred = knn(train=wine_train, test=wine_test, cl=wine_train_label, k=i)
    g2 = CrossTable(x=wine_test_label,y=wine_test_pred,chisq=F)
    g3 = g2$prop.tbl[1+ g2$prop.tbl[5+ g2$prop.tbl[9]
    temp = append(temp,g3)
  }
}
 
result = data.frame("k"=k_num,"정확도"=temp)
 
library(plotly)
plot_ly(x=~result[,"k"],y=~result[,"정확도"],type='scatter',mode='lines') %>%
  layout(xaxis=list(title="k값"),yaxis=list(title="정확도"))
cs
 

 

이 그래프와 동일하지 않아도 됩니다. K값이 증가할수록 대체로 언더피팅 되는 것만 확인하세요!

 

 

 

 

 

 

wisc_bc_data.csv
0.12MB

 

 

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# KNN알고리즘을 이용하여 유방암 분류하기
wbcd = read.csv('c:/data/wisc_bc_data.csv',header=T,stringsAsFactors=FALSE)
 
# data.frame()으로 데이터프레임을 생성할 때 변수에 문자가 있을 경우 자동으로 factor타입으로 변환됨
# factor 변수는 연산이 되지 않으므로 stringsAsFactors() 함수를 써서 factor타입으로 변환되지 않게 하자
 
# factor로 변환하고 하지 않는 이유
# factor로 변환하지 않으면 프로그램이 문자를 단지 형(string)으로만 인식하지만
# factor로 변환하면 각각의 문자를 범주로 인식하기 때문에 이 경우는 일단 stringsAsFactors=F로 함
 
# 진단 컬럼 확인
table(wbcd$diagnosis)
 
# R에서 Grubb's Test를 이용한 이상치 검출방법 (출처 : https://sosal.kr/945)
library(outliers)
grubbs.flag <- function(x) {
  outliers <- NULL
  test <- x
  grubbs.result <- grubbs.test(test)
  pv <- grubbs.result$p.value
  while(pv < 0.05) {
    outliers <- c(outliers,as.numeric(strsplit(grubbs.result$alternative," ")[[1]][3]))
    test <- x[!x %in% outliers]
    grubbs.result <- grubbs.test(test)
    pv <- grubbs.result$p.value
  }
  return(data.frame(X=x,Outlier=(x %in% outliers)))
}
 
# 3부터 시작하는 이유는 [1], [2] 컬럼은 수치가 아니기 때문
for (i in 3:length(colnames(wbcd))){
  a = grubbs.flag(wbcd[,colnames(wbcd)[i]])
  b = a[a$Outlier==TRUE,"Outlier"]
  print (paste(colnames(wbcd)[i],'--->',length(b)))
}
 
# 결측치(NA)값 확인
colSums(is.na(wbcd)) # 유방암 데이터는 결측치 없음
 
# factor는 범주형 자료에서 사용한다. 진단을 factor로 만들어줌
wbcd$diagnosis <- factor(wbcd$diagnosis,
                         levels =c("B","M"),
                         labels = c("Benign","Maliganant"))
 
# 진단 컬럼 확인
prop.table(table(wbcd$diagnosis))
 
 
# seed를 설정하여 항상 똑같게 shuffle 되도록 함
set.seed(1)
wbcd_shuffle <- wbcd[sample(nrow(wbcd)), ]
wbcd2 <- wbcd_shuffle[-1# 1번째 컬럼은 불필요한 환자번호이므로 없애고 shuffle
 
# 셔플한 데이터 확인
str(wbcd2)
 
# 정규화 함수
normalize <- function(x) {
  return ((x-min(x)) / (max(x) - min(x)))
}
 
ncol(wbcd2) # 31
wbcd_n <- as.data.frame(lapply(wbcd2[2:31],normalize)) # 진단인 [1] 을 제외하고 전체 컬럼을 정규화함
 
train_num<-round(0.9*nrow(wbcd_n),0# 512 (90%)
 
# 데이터 나누기 train/test
wbcd_train<-wbcd_n[1:train_num,] # 512개의 데이터
wbcd_test<-wbcd_n[(train_num+1):nrow(wbcd_n),] # 57개의 데이터
 
# 라벨 나누기 train/test
wbcd_train_label <- wbcd2[1:train_num,1]
wbcd_test_label <- wbcd2[(train_num+1):nrow(wbcd_n),1]
 
# knn 알고리즘 사용
library(class)
result1 <- knn(train=wbcd_train, test=wbcd_test,cl=wbcd_train_label, k=21# k는 내 마음대로 (대체로 홀수)
 
# 예측값과 정답을 테이블로 만듦
= data.frame('실제'=wbcd_test_label,"예측"=result1)
table(x)
 
# 예측률 평가
library(gmodels)
g2 = CrossTable(x=wbcd_test_label,y=result1,chisq=FALSE)
g2$prop.tbl[1+ g2$prop.tbl[4# 0.9298246
 
 
# 어떤 k값이 정확도가 가장 높을까?
temp = c()
k_num = c()
for (i in 1:200) {
  if (i%%2 != 0) {
    k_num = append(k_num,i)
    wbcd_test_pred = knn(train=wbcd_train, test=wbcd_test, cl=wbcd_train_label, k=i)
    g2 = CrossTable(x=wbcd_test_label,y=wbcd_test_pred,chisq=F)
    g3 = g2$prop.tbl[1+ g2$prop.tbl[4]
    temp = append(temp,g3)
  }
}
result = data.frame("k"=k_num,"정확도"=temp)
library(plotly)
plot_ly(x=~result[,"k"],y=~result[,"정확도"],type='scatter',mode='lines') %>%
  layout(xaxis=list(title="k값"),yaxis=list(title="정확도"))
 
cs

 

 

 

좋은 데이터는.... 좋은 결과물을 낳는다... 

 

 

 

 

 

 

 

Perceptron (퍼셉트론)

 

퍼셉트론은 딥러닝에서 사용된다. 이것은 인간의 뉴런을 본 떠 만들었다. 퍼셉트론은 다수의 신호(Input)를 입력받아서 하나의 신호(Output)를 출력한다. 이는 뉴런이 전기신호를 내보내 정보를 전달하는 것과 비슷하게 동작한다. 퍼셉트론의 Weight(가중치)는 뉴런끼리 서로의 신호를 전달하는 것과 같은 역할을 한다.

 

 

 

 

Weight(가중치)는 각각의 입력신호에 부여되어 입력신호와의 계산을 하고 신호의 총합이 정해진 임계값(θ; theta,세타)을 넘었을 때 1을 출력한다. (이를 뉴련의 활성화activation 으로도 표현) 넘지 못하면 0 또는 -1을 출력한다. 결론적으로 우리는 딥러닝을 통해 Weight(가중치)의 값을 조정함으로서 원하는 모델을 만들어내고자 한다.

 

+) 추가적으로 편향(Bias)에 대해 설명하자면 편향은 학습 데이터가 가중치와 계산되어 넘어야 하는 임계점으로, 이 값이 높으면 높을수록 분류의 기준이 엄격하고 낮을수록 한계점이 낮아져 데이터의 허용 범위가 넓어진다. Bias가 높을수록 모델이 간단해지는 경향이 있고 (변수가 적고 일반화됨) 과소적합(Underfitting : 모델이 너무 단순해서 데이터의 내재된 구조를 학습하지 못하는 현상)이 발생할 수 있다. 반대로 편향이 낮을수록 모델이 복잡해지고 오버피팅(Overfitting)이 발생할 수 있으며 필요없는 노이즈가 포함될 가능성이 높아진다.

 

Bias 값이 클 경우 모델이 간단해지는 경향
Underfitting 발생
Bias 값이 작을 경우 모델이 복잡해지는 경향
Overfitting 발생

 

편향에 대한 이러한 내용은 여기를 참고하면 좋은데, 이러한 내용은 편향과 분산의 트레이드오프 관계라고 한다.

(근데 이 트레이드오프가 머신러닝, 특히 회귀 쪽의 개념이기 때문에 이 트레이드오프가 신경망에서도 해당되는지에 대해서는 사실 정확하게 모르겠다... 어차피 신경망의 편향은 학습을 통해 자체적으로 갱신되는 파라미터이기 때문에 노란색 밑줄 정도로만 이해해도 충분하다고 생각한다. 그럼 왜 쓴건데)

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

24.07.06 ChatGPT 내용 추가

과적합(overfitting)은 모델이 학습 데이터에 너무 잘 맞아서, 새로운 데이터(테스트 데이터)에 대해서는 성능이 떨어지는 현상을 말합니다.

모델이 학습 데이터의 노이즈까지 학습해버리면, 일반화(generalization) 능력이 떨어집니다.

 

편향과 분산

  1. 편향 (Bias):
    • 모델이 실제 데이터의 패턴을 단순화해서 나타내는 정도를 의미합니다.
    • 높은 편향: 모델이 지나치게 단순해서 데이터의 복잡한 패턴을 잘 잡아내지 못하는 경우.
    • 예: 선형 회귀 모델이 비선형 데이터에 적합하려 할 때.
  2. 분산 (Variance):
    • 모델이 학습 데이터의 변동에 얼마나 민감하게 반응하는지를 나타냅니다.
    • 높은 분산: 모델이 학습 데이터의 작은 변동에도 지나치게 민감하게 반응하여 과적합되는 경우.
    • 예: 복잡한 다항 회귀 모델이 학습 데이터에 지나치게 잘 맞추는 경우.

 

편향, 분산, 과적합의 상관관계 표

낮은 분산 적절한 모델 미적합 (Underfitting)
높은 분산 과적합 (Overfitting) 적절한 모델

 

  • 낮은 편향 - 낮은 분산: 이상적인 상황으로, 모델이 학습 데이터와 테스트 데이터 모두에서 좋은 성능을 보입니다.
  • 낮은 편향 - 높은 분산: 과적합(overfitting)이 발생하는 상황으로, 모델이 학습 데이터에 너무 잘 맞춰져서 테스트 데이터에서 성능이 떨어집니다.
  • 높은 편향 - 낮은 분산: 미적합(underfitting)이 발생하는 상황으로, 모델이 너무 단순해서 학습 데이터와 테스트 데이터 모두에서 성능이 낮습니다.
  • 높은 편향 - 높은 분산: 이는 드물지만, 모델이 복잡하면서도 데이터의 패턴을 잘 학습하지 못하는 경우입니다. 이 경우 모델이 학습 데이터와 테스트 데이터 모두에서 성능이 낮습니다.

 

예시

  1. 선형 회귀 (높은 편향, 낮은 분산):
    • 선형 회귀 모델은 비선형 데이터에서 높은 편향으로 인해 패턴을 제대로 잡아내지 못합니다. 그러나 분산은 낮아서 데이터 변동에 민감하게 반응하지 않습니다.
  2. 복잡한 다항 회귀 (낮은 편향, 높은 분산):
    • 복잡한 다항 회귀 모델은 낮은 편향으로 인해 데이터의 복잡한 패턴을 잘 잡아내지만, 높은 분산으로 인해 과적합이 발생할 수 있습니다.

 

요약

  • 편향 (Bias): 모델이 단순해서 데이터의 패턴을 잘 잡아내지 못하는 경우.
  • 분산 (Variance): 모델이 학습 데이터의 변동에 민감하게 반응하여 과적합되는 경우.
  • 과적합 (Overfitting): 모델이 학습 데이터에 너무 잘 맞아서 테스트 데이터에서 성능이 떨어지는 현상.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

퍼셉트론은 AND, OR , NAND, XOR 게이트 등으로 구성되어있다. 그냥 디지털논리회로와 비슷하다고 보면 되겠다. 입력값에 따라 원하는 출력값을 만들어내기 위해 이런 저런 단순한 게이트들을 이용하여 원하는 결과를 도출해낸다. 하지만 단층 퍼셉트론은 원하는 결과를 모두 도출해낼 수는 없다. 예를 들어 내가 0부터 9까지 차례대로 나타내는 프로그램을 만든다고 가정하자. 딱 하나의 게이트로는 절대 이런 프로그램을 만들어낼 수 없다. 하지만 여러 개의 게이트를 사용할 수 있다면 어떻게될까? 당연히 가능할 것이다. 이렇게 단층 퍼셉트론으로 불가능한 것을 하기 위해 우리는 다층 퍼셉트론을 사용한다.

 

단층 퍼셉트론을 쉽게 이해할 수 있는 예제가 있는 블로그를 남겨두겠다. 다들 참고하길 바란다.

'인공지능 > 인공지능 이론' 카테고리의 다른 글

15. 항등함수와 Softmax 함수  (2) 2020.08.03
14. 다층퍼셉트론 / Sigmoid / ReLU  (0) 2020.07.01
12. Clustering  (0) 2019.09.13
11. 차원의 저주 / PCA  (0) 2019.09.13
10. ROC Curve  (1) 2019.09.12

 

 

 

 

Clustering (군집화)

 

앞서도 설명했지만 까먹었을까봐 다시 한 번 언급하겠다. Clustering과 Classification(분류)은 굉장히 비슷한 개념이다. 하지만 Clustering은 비지도학습(Unsupervised)으로, 정답이 없는 데이터들을 비슷한 것 끼리 묶을 때 사용한다. 그와 반대로 Classification(분류)은 정답이 있는 데이터들을 사용하므로 지도학습(Supervised)이다.

 

클러스터링은 (1) 군집 간 분산(inter-cluster variance) 최대화 (2) 군집 내 분산(inner-cluster variance) 최소화 를 목표로 둔다.

 


 

 

어떻게 해야 잘 군집화했다고 소문이 날까? 위의 그림처럼 잘 구분되어 있는 데이터들같은 경우는 군집화하기가 쉬울것이다. 하지만 아래와 같은 경우는 어떨까?

 

데이터를 몇 개로 군집화시켜야할까?

 

위의 그림처럼 우리는 데이터들을 2개로도, 6개로도 혹은 그 이상으로 군집화할 수 있다. 왜냐하면 정답이 없기 때문이다. 하지만 군집화 개수에 따라 우리의 모델은 천차만별로 달라질 수 있다. 깔끔하고 정확하게 군집화하기 위해서는 어떻게 해야할까? 이러한 고민을 해결하기 위해 우리는 군집 타당성 지표를 생각한다. 간단하게 설명하자면 각 데이터 간의 거리를 계산하여 군집화하는 것을 의미한다. 이에 대해 자세한 내용은 블로그를 참고하기를 바란다.

 

 

 

 

 

- K-means

 

K-means 방법

 

K-means의 K는 클러스터 수를 의미한다. 위의 예는 K가 2인 경우이다. 군집의 무게중심(빨간색 점)을 랜덤으로 초기화한다. 그 후 모든 점들(파란색 점)의 가장 가까운 무게중심을 기준으로 클러스터링한다. (E스텝) 그리고 클러스터의 무게중심을 업데이트한다. (M스텝)

이렇게 E스텝과 M스텝을 반복하며 최종적으로 결과가 바뀌지 않거나(=해가 수렴), 사용자가 정한 반복수를 채우게 되면 학습을 끝내는 것을 K-means라고 한다.

 

하지만 K-means는 초기값 위치에 따라 원하는 결과가 나오지 않을 수 있고  클러스터의 밀도나 크기가 다를 경우 원하는 결과가 나오지 않을 수 있으며 데이터의 분포가 특이한 경우에도 잘 적용되지 않는다. 이에 대한 시각적인 부분은 블로그를 참고하기를 바란다.

 

 

 

+ KNN (K-Nearest Neighbors) : KNN은 Classification이다.

 

KNN은 새로운 데이터가 주어졌을 때 기존 데이터 가운데 가장 가까운 K개 이웃의 정보로 새로운 데이터를 예측하는 방법론으로 지도학습(Supervised)이다. 레이지(Lazy)모델이라고도 불리는데 딱히 학습할만한 것이 없기 때문이다. KNN에 대해 궁금하다면 더 자세히 설명한 블로그를 참고하기를 바란다.

 

K가 1이면 오렌지색, K가 3라면 녹색으로 분류하게 될 것이다. (+ K는 홀수개여야함)

 

+) K-means와 KNN의 공통점과 차이점

  KNN K-means
공통점 데이터를 비슷한 집단으로 묶는 방법
차이점 지도학습 (분류) 비지도학습 (군집화)

 

 

- GMM (Gaussian Mixture Model)

 

GMM은 전체 데이터의 확률분포가 여러개의 정규분포의 조합으로 이루어져 있다고 가정하고 각 분포에 속할 확률이 높은 데이터끼리 클러스터링 하는 방법이다. GMM은 K-means등의 클러스터링 알고리즘으로 잘 묶을수 없었던 아래 데이터에서도 잘 작동한다. 자세한 내용은 블로그를 참고하길 바란다.

 

 

 

- Hierarchical Clustering (계층적 군집화)

 

Hierarchical Clustering은 계층적 트리 모형을 이용해 개별 개체들을 순차적, 계층적으로 유사한 개체 내지 그룹과 통합하여 군집화를 수행하는 알고리즘이다. Hierarchical Clustering은 클러스터의 수를 사전에 정하지 않아도 학습 수행가능하다. 이에 대해 자세한 내용은 블로그를 참고하길 바란다.

 

 

 

 


 

 

 

 

정리

 

 

 

'인공지능 > 인공지능 이론' 카테고리의 다른 글

14. 다층퍼셉트론 / Sigmoid / ReLU  (0) 2020.07.01
13. Perceptron (퍼셉트론)  (0) 2019.09.14
11. 차원의 저주 / PCA  (0) 2019.09.13
10. ROC Curve  (1) 2019.09.12
9. Classification (분류)  (0) 2019.09.11

+ Recent posts