data analysis & visualization

파이썬은 쓰면 쓸 수록 제공하는 부분에서는 친절하고 제공 안하는 부분에 대해서는 불친절한 것 같다.

 

pandas data frame 형태 데이터를 gridSearch 를 한번 해보려했는데 구조가 뭔가 복잡해서 

 

검색해도 바로 찾지 못하겠어서 공유를 하고자 한다.

 

https://scikit-learn.org/stable/

 

scikit-learn: machine learning in Python — scikit-learn 0.23.1 documentation

Model selection Comparing, validating and choosing parameters and models. Applications: Improved accuracy via parameter tuning Algorithms: grid search, cross validation, metrics, and more...

scikit-learn.org

 

위 사이트는 scikit-learn 사이트이다. 이 사이트를 왜 공유하냐면 모델마다 하이퍼파라메터가 상이한데 이에 해당하지 않으면 에러가 뜨기 때문이다. 

 

사실 영어를 잘하면 도큐먼트를 읽으면되나 시간도 없고.. 영어도 못하고..

 

우선 scikit-learn에서 제공하는게 뭔지 잘 모르겠다면,

 

anaconda의 경로로 가보자.

 

default세팅이라고하면, 사용자>계정명>Anaconda3>Lib>site-packages>sklean에 있을 것이다.

 

가상환경의 경우, 사용자>계정명>Anaconda3>envs>가상환경명>Lib>site-packages>sklean이다.

 

무튼 잘 들어왔다면, 다양한 폴더들이 있는데

 

우리가 import sklearn을 하지 않고

 

from sklearn.svm import BaseCrossValidator를 임력했다고하면, 

 

sklearn패키지 안에 svm이라는 폴더안에 객체인 BaseCrossValidator를 의미한다.

 

BaseCrossValidator에 해당하는 부분은 __init__.py 파일에 있는 것 같다.

 

다시 본론으로 grid Search를 어떻게 하느냐로 돌아가겠다.

 

우선 document에서 우리가 쓰고자 하는 모델을 검색해보자. 

 

RandomForestRegressor를 쓰고자 한다면 

 

 

아래와 같이 입력.

 

입력에는 parameter가 다양하게 있는데

 

이를 grid search 할 수 있다. 

from sklearn.ensemble import RandomForestRegressor

rf=RandomForestRegressor()

grid search 할 목록을 딕셔너리의 형태로 구성해보자.

rf_grid={'criterion':['mse','mae'],
		'max_features':['auto','sqrt','log2',None]}

다음과 같이 구성되었다면 

from sklearn.model_selection import GridSearchCV
model=GridSearch(rf,rf_grid)
model.fit(X_train,Y_train)

 이렇게 간단히 할 수 있다. 

 

'python' 카테고리의 다른 글

pypy  (0) 2020.08.31
python package 생성  (0) 2020.08.17
명령프롬프트로 anaconda 열기  (0) 2020.07.01
pandas-profiling  (0) 2020.06.11
anaconda 활용법  (0) 2020.06.04

공간 보간 기법 중 하나인 Kriging 을 R에서는 사용하기 편리하기 위해서 automap패키지에서 autoKrige로 지원하고 있다. 하지만 최근 fitting 과정에서 fit.method가 gstats 패키지에 있어 옵션이 수정되지 않는 현상을 겪었다.

따라서 아래와같이 function을 올려보겠다.

 

 

 


autoKrige2=function (formula, input_data, new_data, data_variogram = input_data, 
                     block = 0, model = c("Sph", "Exp", "Gau", "Ste"), kappa = c(0.05, 
                                                                                 seq(0.2, 2, 0.1), 5, 10), fix.values = c(NA, NA, NA), 
                     remove_duplicates = TRUE, verbose = FALSE, GLS.model = NA, fit.method=fit.method,
                     start_vals = c(NA, NA, NA), miscFitOptions = list(), ...) 
{
  if (inherits(formula, "SpatialPointsDataFrame")) {
    input_data = formula
    formula = as.formula(paste(names(input_data)[1], "~ 1"))
  }
  if (!inherits(input_data, "SpatialPointsDataFrame") | !inherits(data_variogram, 
                                                                  "SpatialPointsDataFrame")) {
    stop(paste("\nInvalid input objects: input_data or data_variogram not of class 'SpatialPointsDataFrame'.\n\tClass input_data: '", 
               class(input_data), "'", "\n\tClass data_variogram: '", 
               class(data_variogram), "'", sep = ""))
  }
  if (as.character(formula)[3] != 1 & missing(new_data)) 
    stop("If you want to use Universal Kriging, new_data needs to be specified \n  because the predictors are also required on the prediction locations.")
  if ("newdata" %in% names(list(...))) 
    stop("The argument name for the prediction object is not 'newdata', but 'new_data'.")
  if (remove_duplicates) {
    zd = zerodist(input_data)
    if (length(zd) != 0) {
      warning("Removed ", length(zd)/2, " duplicate observation(s) in input_data:", 
              immediate. = TRUE)
      print(input_data[c(zd), ])
      input_data = input_data[-zd[, 2], ]
    }
  }
  col_name = as.character(formula)[2]
  if (length(unique(input_data[[col_name]])) == 1) 
    stop(sprintf("All data in attribute '%s' is identical and equal to %s\n   Can not interpolate this data", 
                 col_name, unique(input_data[[col_name]])[1]))
  if (missing(new_data)) 
    new_data = create_new_data(input_data)
  p4s_obj1 = proj4string(input_data)
  p4s_obj2 = proj4string(new_data)
  if (!all(is.na(c(p4s_obj1, p4s_obj2)))) {
    if (is.na(p4s_obj1) & !is.na(p4s_obj2)) 
      proj4string(input_data) = proj4string(new_data)
    if (!is.na(p4s_obj1) & is.na(p4s_obj2)) 
      proj4string(new_data) = proj4string(input_data)
    if (any(!c(is.projected(input_data), is.projected(new_data)))) 
      stop(paste("Either input_data or new_data is in LongLat, please reproject.\n", 
                 "  input_data: ", p4s_obj1, "\n", "  new_data:   ", 
                 p4s_obj2, "\n"))
    if (proj4string(input_data) != proj4string(new_data)) 
      stop(paste("Projections of input_data and new_data do not match:\n", 
                 "  input_data: ", p4s_obj1, "\n", "  new_data:    ", 
                 p4s_obj2, "\n"))
  }
  
  variogram_object = autofitVariogram2(formula, data_variogram, 
                                       model = model, kappa = kappa, fix.values = fix.values, 
                                       verbose = verbose, GLS.model = GLS.model, start_vals = start_vals, 
                                       miscFitOptions = miscFitOptions, fit.method =fit.method)
  krige_result = krige(formula, input_data, new_data, variogram_object$var_model, 
                       block = block, ...)
  krige_result$var1.stdev = sqrt(krige_result$var1.var)
  result = list(krige_output = krige_result, exp_var = variogram_object$exp_var, 
                var_model = variogram_object$var_model, sserr = variogram_object$sserr)
  class(result) = c("autoKrige", "list")
  return(result)
}
autofitVariogram2=function (formula, input_data, model = c("Sph", "Exp", "Gau", 
                                                           "Ste"), kappa = c(0.05, seq(0.2, 2, 0.1), 5, 10), fix.values = c(NA, 
                                                                                                                            NA, NA), verbose = FALSE, GLS.model = NA, start_vals = c(NA, 
                                                                                                                                                                                     NA, NA), miscFitOptions = list(),fit.method = 1, ...) 
{
  if ("alpha" %in% names(list(...))) 
    warning("Anisotropic variogram model fitting not supported, see the documentation of autofitVariogram for more details.")
  miscFitOptionsDefaults = list(merge.small.bins = TRUE, min.np.bin = 5)
  miscFitOptions = modifyList(miscFitOptionsDefaults, miscFitOptions)
  longlat = !is.projected(input_data)
  if (is.na(longlat)) 
    longlat = FALSE
  diagonal = spDists(t(bbox(input_data)), longlat = longlat)[1, 
                                                             2]
  boundaries = c(2, 4, 6, 9, 12, 15, 25, 35, 50, 65, 80, 100) * 
    diagonal * 0.35/100
  if (!is(GLS.model, "variogramModel")) {
    experimental_variogram = variogram(formula, input_data, 
                                       boundaries = boundaries, ...)
  }
  else {
    if (verbose) 
      cat("Calculating GLS sample variogram\n")
    g = gstat(NULL, "bla", formula, input_data, model = GLS.model, 
              set = list(gls = 1))
    experimental_variogram = variogram(g, boundaries = boundaries, 
                                       ...)
  }
  if (miscFitOptions[["merge.small.bins"]]) {
    if (verbose) 
      cat("Checking if any bins have less than 5 points, merging bins when necessary...\n\n")
    while (TRUE) {
      if (length(experimental_variogram$np[experimental_variogram$np < 
                                           miscFitOptions[["min.np.bin"]]]) == 0 | length(boundaries) == 
          1) 
        break
      boundaries = boundaries[2:length(boundaries)]
      if (!is(GLS.model, "variogramModel")) {
        experimental_variogram = variogram(formula, 
                                           input_data, boundaries = boundaries, ...)
      }
      else {
        experimental_variogram = variogram(g, boundaries = boundaries, 
                                           ...)
      }
    }
  }
  if (is.na(start_vals[1])) {
    initial_nugget = min(experimental_variogram$gamma)
  }
  else {
    initial_nugget = start_vals[1]
  }
  if (is.na(start_vals[2])) {
    initial_range = 0.1 * diagonal
  }
  else {
    initial_range = start_vals[2]
  }
  if (is.na(start_vals[3])) {
    initial_sill = mean(c(max(experimental_variogram$gamma), 
                          median(experimental_variogram$gamma)))
  }
  else {
    initial_sill = start_vals[3]
  }
  if (!is.na(fix.values[1])) {
    fit_nugget = FALSE
    initial_nugget = fix.values[1]
  }
  else fit_nugget = TRUE
  if (!is.na(fix.values[2])) {
    fit_range = FALSE
    initial_range = fix.values[2]
  }
  else fit_range = TRUE
  if (!is.na(fix.values[3])) {
    fit_sill = FALSE
    initial_sill = fix.values[3]
  }
  else fit_sill = TRUE
  getModel = function(psill, model, range, kappa, nugget, 
                      fit_range, fit_sill, fit_nugget, verbose) {
    if (verbose) 
      debug.level = 1
    else debug.level = 0
    if (model == "Pow") {
      warning("Using the power model is at your own risk, read the docs of autofitVariogram for more details.")
      if (is.na(start_vals[1])) 
        nugget = 0
      if (is.na(start_vals[2])) 
        range = 1
      if (is.na(start_vals[3])) 
        sill = 1
    }
    obj = try(gstat::fit.variogram(experimental_variogram, model = vgm(psill = psill, 
                                                                       model = model, range = range, nugget = nugget, kappa = kappa), 
                                   fit.ranges = c(fit_range), fit.sills = c(fit_nugget, 
                                                                            fit_sill), debug.level = 0,fit.method = fit.method), TRUE)
    if ("try-error" %in% class(obj)) {
      warning("An error has occured during variogram fitting. Used:\n", 
              "\tnugget:\t", nugget, "\n\tmodel:\t", model, 
              "\n\tpsill:\t", psill, "\n\trange:\t", range, 
              "\n\tkappa:\t", ifelse(kappa == 0, NA, kappa), 
              "\n  as initial guess. This particular variogram fit is not taken into account. \nGstat error:\n", 
              obj)
      return(NULL)
    }
    else return(obj)
  }
  test_models = model
  SSerr_list = c()
  vgm_list = list()
  counter = 1
  for (m in test_models) {
    if (m != "Mat" && m != "Ste") {
      model_fit = getModel(initial_sill - initial_nugget, 
                           m, initial_range, kappa = 0, initial_nugget, 
                           fit_range, fit_sill, fit_nugget, verbose = verbose)
      if (!is.null(model_fit)) {
        vgm_list[[counter]] = model_fit
        SSerr_list = c(SSerr_list, attr(model_fit, "SSErr"))
      }
      counter = counter + 1
    }
    else {
      for (k in kappa) {
        model_fit = getModel(initial_sill - initial_nugget, 
                             m, initial_range, k, initial_nugget, fit_range, 
                             fit_sill, fit_nugget, verbose = verbose)
        if (!is.null(model_fit)) {
          vgm_list[[counter]] = model_fit
          SSerr_list = c(SSerr_list, attr(model_fit, 
                                          "SSErr"))
        }
        counter = counter + 1
      }
    }
  }
  strange_entries = sapply(vgm_list, function(v) any(c(v$psill, 
                                                       v$range) < 0) | is.null(v))
  if (any(strange_entries)) {
    if (verbose) {
      print(vgm_list[strange_entries])
      cat("^^^ ABOVE MODELS WERE REMOVED ^^^\n\n")
    }
    warning("Some models where removed for being either NULL or having a negative sill/range/nugget, \n\tset verbose == TRUE for more information")
    SSerr_list = SSerr_list[!strange_entries]
    vgm_list = vgm_list[!strange_entries]
  }
  if (verbose) {
    cat("Selected:\n")
    print(vgm_list[[which.min(SSerr_list)]])
    cat("\nTested models, best first:\n")
    tested = data.frame(`Tested models` = sapply(vgm_list, 
                                                 function(x) as.character(x[2, 1])), kappa = sapply(vgm_list, 
                                                                                                    function(x) as.character(x[2, 4])), SSerror = SSerr_list)
    tested = tested[order(tested$SSerror), ]
    print(tested)
  }
  result = list(exp_var = experimental_variogram, var_model = vgm_list[[which.min(SSerr_list)]], 
                sserr = min(SSerr_list))
  class(result) = c("autofitVariogram", "list")
  return(result)
}

'R' 카테고리의 다른 글

딥로또 R 버전  (0) 2020.02.10
R 스케줄링  (0) 2020.01.19
[ggplot2] 시각화 정리  (0) 2019.12.08
[R][SQL] RMariaDB 외부 접속 설정하기  (0) 2019.11.29
[공간정보오픈플렛폼]위경도 변환, 주소 변환  (0) 2019.11.27

단순선형회귀분석 중 최소제곱법에 대하여 포스팅 하려고 한다.

 

이해를 돕고자 적다보니 표현이 다소 불편 할 수도 있다. 전공자는 스킵하면 되겠다.

 

두개의 변수X와 Y의 자료가 있고 이를 통해 이들간에 선형적인 관계를 알려고 한다. 

 

이를 가장 잘 설명할 수 있는 직선은 무엇일까? 에 대한 해답 중 하나로 

 

최소제곱법이 이에 해당한다.

 

최소제곱법은 관측값과 예측값의 오차를 최소로 하는 직선을 찾는 것을 목표로 한다.

 

우선 고등학교 때 배웠던 직선의 방정식을 생각해보자.

 

$$ y=ax+b$$의 형태를 가지고 있다.

 

즉, 최소제곱법은 실제 측정된 y값과 x에 대한 a와 b로 계산된 y값의 차이가 최소가 되는 직선을 의미한다.

 

직선에 방정식으로 x값에 의해 생성된 y를 아래와 같이 표기하겠다.

$$\hat{y}$$

 

 

 

우리가 최소화 하여야 하는 것을 다시한번 정의해보자.

 

관측된 x들이 다음과 같다고 하자.

$$X=\{x_1, x_2, ... , x_n\}$$

 

그러면 이 때 관측된 다른 변수 Y는 다음과 같이 나타내보자.

$$Y=\{y_1,y_2,..., y_n\}$$

 

우리는 x의 i 시점에 대해 예측한 y값과 y의 오차 합을 최소화 하는 것이 목표이다.

이를 수식으로 나타내면 다음과 같다.

$$\hat{y_i}-y_i$$

이처럼 우리는 모형에서 최종적으로 최소화 하고자 하는 함수를 cost function이라고 하며, 연산에서 최소화 하고자 하는 함수를 loss function이라 부른다.

 

$$\sum [\hat{y_i}-y_i]$$

을 최소화 하는 것이 목표다. 

 

이를 어떻게 계산할까?

 

우리는 고등학교 때 배운 미분이라는 개념을 가지고 오려고 한다.

 

위의 값이 최소가 되는 절편과 기울기를 구하는게 목표이므로, 이를 편미분을 통해 계산하는 것이다.

 

우리가 찾으려하는 식은 다음과 같다.

$$\hat{y_i}=\beta_0+\beta_1 x_i+e$$

 

그렇다면 최소화 하고자 하는 값은 이를 편의상 다음과 같이 나타내겠다.

 

$$S=\sum{[y_i-\hat{y_i}] ^2}$$

 

절편에 대하여 편미분해보자.

$$\frac{\partial{S}}{\partial{\beta_0}}=2 \times \sum{[y_i-\beta_0-\beta_1 x_i]}[-1]=-2\sum{y_i-\beta_0-\beta_1 x_i}$$

$$\frac{\partial{S}}{\partial{\beta_0}}=0 \rightarrow -2\sum{y_i-\beta_0-\beta_1 x_i}=0 \rightarrow \sum{y_i}=\sum{\beta_0}+\sum{\beta_1 x_i} \rightarrow \sum{y_i}= n \beta_0+\sum{\beta_1 x_i}$$

 

이제 기울기에 대하여 편미분해보자.

$$\frac{\partial{S}}{\partial{\beta_1}}=2 \times \sum{[y_i-\beta_0-\beta_1 x_i]}[-x_i]=-2\sum{x_i[y_i-\beta_0-\beta_1 x_i]}$$

$$\frac{\partial{S}}{\partial{\beta_1}}=0 \rightarrow -2\sum{x_i[y_i-\beta_0-\beta_1 x_i]}=0 \rightarrow \sum{x_i y_i}=\sum{\beta_0 x_i}+\sum{\beta_1 [x_i]^2}$$

 

절편을 편미분하여 구한 수식에 다음을 곱하여보자.

$$\sum x_i$$ 

 

$$\rightarrow \sum {x_i}[n \beta_0+\sum{x_i \beta_1}]=\sum{x_i}\sum{y_i}$$

방금 구한 식을 기울기에 대하여 편미분한 수식에 서 빼보자.

 

$$\beta_1[[\sum{x_i}]^2-n \sum{x_{i}^2}]=\sum x_i \sum y_i - n\sum x_i y_i$$

 

$$\beta_1=\frac{\sum x_i \sum y_i -n \sum x_i y_i}{[[\sum{x_i}]^2 -n \sum{x_i^2}]}$$

 

$$\sum x_i=n\bar{x}$$

따라서 분모는 다음과 같이 나온다.

$$n^2 \bar{x}^2-n \sum{x_i}^2=n [n \bar{x}^2 - \sum{x_i}^2]$$

$$=n(2n \bar{x}^2 - n\bar{x}^2-\sum{x_i}^2=n[2\bar{x}\sum{x_i}-\sum{\bar{x}^2}-\sum{x_i}^2]=n\sum{[x_i-\bar{x}]}$$

 

분자는 다음과 같다.

$$\sum x_i \sum y_i -n \sum x_i y_i =[n \bar{x}][n \bar{y}] -n \sum x_i y_i$$

$$=n[n\bar{x}\bar{y} -\sum x_i y_i ]=n[2n\bar{x}\bar{y}-n\bar{x}\bar{y}-\sum x_i y_i $$

$$=n[n[\sum x_i\bar{y} +\sum y_i\bar{x}]-\sum{\bar{x}\bar{y}}-\sum x_i y_i$$

$$=n\sum[x_i-\bar{x}][y_i-\bar{y}]$$

 

따라서 기울기는 

$$\beta_1=\frac{\sum{[x_i-\beta{x}][y_i-\bar{y}]}}{\sum{[x_i-\bar{x}]}^2}=\frac{S_xy}{S_xx}$$

이를 대입해 절편을 구하면

$$\beta_0=\bar{y}-\beta_1\bar{x}$$

 

우연변동 : 일정한 수준에서 머물며 random한 노이즈를 가지는 경우를 의미

$$\hat{Y_t} \alpha +e_t$$

 

계절변동 : 주기적으로 변화를 나타내는 경우를 의미하며, 이 주기는 f에 의해 조절 됨

$$\hat{Y_t}=\alpha +\beta_1 \sin \frac{2\pi t}{f}+\beta_2 \cos \frac{2\pi t}{f}+e_t [ f는 주기]$$

 

추세변동 : 시간에 따라 증가하거나 감소하는 경향을 보이는 시계열 자료의 형태

$$\hat{Y_t}=T_t+e_t$$

$$\hat{Y_t}=\alpha+\beta t+e_t$$

$$\hat{Y_t}=\alpha+\beta_1 t+\beta_2 t +e_t$$

 

순환변동 : 1년 이상의 장기적인 계절성을 띄는 시계열 자료의 형태

$$\hat{Y_t}=C_t+e_t$$

 

1차 차분

$$ \nabla Y_t=Y_t -Y_{t-1}$$

 

2차 차분

$$ \nabla^2 Y_t= \nabla y_t - \nabla y_{t-1}$$

 

계절변동차분

$$\nabla_{12} Y_t=\nabla Y_t - \nabla Y_{t-12}$$

 

Box Cox 변환 : 독립성과 등분산성을 동시에 만족시키기 위해 고안된 방법. 시계열 자료의 변환에 자주 사용됨.

 

$$f(x:\lambda) = \frac{x^\lambda -1}{\lambda} [ \lambda \ne 0]$$

$$f(x:0)=log(x) [\lambda=0]$$

 

 

 

 

 

 

'통계 > time series' 카테고리의 다른 글

조금 더 빠른 시계열 예측  (0) 2020.06.08

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

확인

DTW는 두 개의 시간적 순서가 있는 벡터 간에 유사도를 평가하는 방법이다. 이 말을 쉽게 얘기하자면 우리는 예측값에 대해 정확히 알면 좋긴하나 현실적으로 제한적일 때 경향성이라도 비슷하게 잘 맞추는 알고리즘이 무엇인가 평가하고자 한다. 하지만  성능평가 지표로 사용하는 RMSE, MAE 등의 경우 예측값에 지현 현상이 일어 났을 때 단순히 예측값과 해당 시점의 관측값 간의 차이만을 평가하므로 적합한 평가지표가 아닐 수 있다. 이러한 경우 유사도 개념을 활용하게 되는데 유사도는 거리의 반대의 개념이라고 생각하면 좀 더 이해하기 쉽다.

 

그렇다면 DTW는 어떠한 알고리즘으로 구성 되어 있을까?

1. 두 개의 시계열 간의 거리를 모두 구하는 과정

2. 가장 가까운 거리를 구하기 위해 이를 누적합 하는 과정

3. 가장 가까운 거리간에 매칭하는 과정

 

이렇게 3가지로 구성이 된다.

 

예를 들어보자. 

 

시계열 예측값이 다음과 같이 존재한다고 하자.

 

x=c(1, 1, 2, 3, 3, 2)

y=c(1, 2, 3, 3, 2, 1)

 

이제 각각의 거리의 절대값에 대한 행렬을 구해보자 

 

       1  1  2  3  3  2

1     0  0  1  2  2  1

2     1  1  0  1  1  0

3     2  2  0  0  1

3     2  2  1  0  0  1

2     1  1  0  1  1  0

1     0  0  1  2  2  1

 

위와 같이 두개의 시계열 간의 거리의 절대값을 구하였다면 누적합을 구해보자.

주대각성분(현재 0, 1, 1 , 0 ,1 ,1 에 해당하는 (m, m)행렬의 대각선 성분)을 기준으로 i>j이면 행으로 누적합을 j>i이면 열로 누적합을 진행한다.

 

       1  1  2  3  3  2

1     0  0  1  3  5  6

2     1  1 0   1  2  2

3     3  3  1  0  0  1

3     5  5  2  0  1

2     6  6  2  1  1  0

1     6  6  3  3  3  1

 

아래는 R에 존재하는 DTW이다. 

#====library(dtw)====#
x=c(1,1,2,3,3,2)
y=c(1,2,3,3,2,1)
mydtw = dtw(y,x, keep.internals=T)
mydtw$costMatrix

 

맨 마지막 m,m 성분을 DTW값이라 한다. 

 

이렇게 구한 값을 이제 m,m부터 인접한 가장 작은 값과 매칭하자. 

 

그러면 매칭이 되는 값들을 이어 시각화 하면 다음과 같은 그림이 나타난다.

 

이는 DTW 상으로 가장 가까운 거리를 의미한다.

이를 기반으로 성능을 평가한다면 패턴 인식에 대한 성능평가지표로 RMSE나 MAE보다 좀 더 우수한 성능 평가 지표로 사용 될 수 있다 생각 된다.

 

참고 : http://hamait.tistory.com/862 

 

파이썬 코딩으로 말하는 데이터 분석 - 10. DTW (Dynamic time wrapping)

데이터 분석에 대한 기본적인 감과 덤으로 파이썬 코딩에 대한 감을 익히기 위한 강좌입니다. 개발자는 코드로 이해하는게 가장 빠른 길이며, 오래 기억하는 길이라 믿습니다. 순서 1. 통계 - 카�

hamait.tistory.com

 

'머신러닝' 카테고리의 다른 글

calibration Curve  (0) 2020.08.19
보루타(boruta algorithm)  (0) 2020.08.09
성능평가지표  (0) 2020.04.26
과적합이 좋지 못한 이유?  (0) 2020.01.20
정형데이터마이닝 - 비지도학습  (0) 2019.07.04