Введение

В этой лабораторной работе мы продолжим изучение методов выбора признаков, используя пакеты caret, FSelector, arules и Boruta.

1.Изучение методов выбора признаков в CARET

Установить пакет CARET, выполнить команду names(getModelInfo()), ознакомиться со списком доступных методов выбора признаков. Выполните графический разведочный анализ данных с использование функции featurePlot() для набора данных из справочного файла пакета CARET:

x <- matrix(rnorm(50*5),ncol=5)

y <- factor(rep(c(“A”, “B”), 25))

Сохранить полученные графики в *.jpg файлы. Сделать выводы.

# Установите пакет caret, если он еще не установлен
if(!requireNamespace("caret", quietly = TRUE)) {
  install.packages("caret")
}

# Загрузите пакет caret
library(caret)
## Загрузка требуемого пакета: ggplot2
## Загрузка требуемого пакета: lattice
# Выполните команду names(getModelInfo()) и ознакомьтесь со списком доступных методов выбора признаков
model_names <- names(getModelInfo())
print(model_names)
##   [1] "ada"                 "AdaBag"              "AdaBoost.M1"        
##   [4] "adaboost"            "amdai"               "ANFIS"              
##   [7] "avNNet"              "awnb"                "awtan"              
##  [10] "bag"                 "bagEarth"            "bagEarthGCV"        
##  [13] "bagFDA"              "bagFDAGCV"           "bam"                
##  [16] "bartMachine"         "bayesglm"            "binda"              
##  [19] "blackboost"          "blasso"              "blassoAveraged"     
##  [22] "bridge"              "brnn"                "BstLm"              
##  [25] "bstSm"               "bstTree"             "C5.0"               
##  [28] "C5.0Cost"            "C5.0Rules"           "C5.0Tree"           
##  [31] "cforest"             "chaid"               "CSimca"             
##  [34] "ctree"               "ctree2"              "cubist"             
##  [37] "dda"                 "deepboost"           "DENFIS"             
##  [40] "dnn"                 "dwdLinear"           "dwdPoly"            
##  [43] "dwdRadial"           "earth"               "elm"                
##  [46] "enet"                "evtree"              "extraTrees"         
##  [49] "fda"                 "FH.GBML"             "FIR.DM"             
##  [52] "foba"                "FRBCS.CHI"           "FRBCS.W"            
##  [55] "FS.HGD"              "gam"                 "gamboost"           
##  [58] "gamLoess"            "gamSpline"           "gaussprLinear"      
##  [61] "gaussprPoly"         "gaussprRadial"       "gbm_h2o"            
##  [64] "gbm"                 "gcvEarth"            "GFS.FR.MOGUL"       
##  [67] "GFS.LT.RS"           "GFS.THRIFT"          "glm.nb"             
##  [70] "glm"                 "glmboost"            "glmnet_h2o"         
##  [73] "glmnet"              "glmStepAIC"          "gpls"               
##  [76] "hda"                 "hdda"                "hdrda"              
##  [79] "HYFIS"               "icr"                 "J48"                
##  [82] "JRip"                "kernelpls"           "kknn"               
##  [85] "knn"                 "krlsPoly"            "krlsRadial"         
##  [88] "lars"                "lars2"               "lasso"              
##  [91] "lda"                 "lda2"                "leapBackward"       
##  [94] "leapForward"         "leapSeq"             "Linda"              
##  [97] "lm"                  "lmStepAIC"           "LMT"                
## [100] "loclda"              "logicBag"            "LogitBoost"         
## [103] "logreg"              "lssvmLinear"         "lssvmPoly"          
## [106] "lssvmRadial"         "lvq"                 "M5"                 
## [109] "M5Rules"             "manb"                "mda"                
## [112] "Mlda"                "mlp"                 "mlpKerasDecay"      
## [115] "mlpKerasDecayCost"   "mlpKerasDropout"     "mlpKerasDropoutCost"
## [118] "mlpML"               "mlpSGD"              "mlpWeightDecay"     
## [121] "mlpWeightDecayML"    "monmlp"              "msaenet"            
## [124] "multinom"            "mxnet"               "mxnetAdam"          
## [127] "naive_bayes"         "nb"                  "nbDiscrete"         
## [130] "nbSearch"            "neuralnet"           "nnet"               
## [133] "nnls"                "nodeHarvest"         "null"               
## [136] "OneR"                "ordinalNet"          "ordinalRF"          
## [139] "ORFlog"              "ORFpls"              "ORFridge"           
## [142] "ORFsvm"              "ownn"                "pam"                
## [145] "parRF"               "PART"                "partDSA"            
## [148] "pcaNNet"             "pcr"                 "pda"                
## [151] "pda2"                "penalized"           "PenalizedLDA"       
## [154] "plr"                 "pls"                 "plsRglm"            
## [157] "polr"                "ppr"                 "pre"                
## [160] "PRIM"                "protoclass"          "qda"                
## [163] "QdaCov"              "qrf"                 "qrnn"               
## [166] "randomGLM"           "ranger"              "rbf"                
## [169] "rbfDDA"              "Rborist"             "rda"                
## [172] "regLogistic"         "relaxo"              "rf"                 
## [175] "rFerns"              "RFlda"               "rfRules"            
## [178] "ridge"               "rlda"                "rlm"                
## [181] "rmda"                "rocc"                "rotationForest"     
## [184] "rotationForestCp"    "rpart"               "rpart1SE"           
## [187] "rpart2"              "rpartCost"           "rpartScore"         
## [190] "rqlasso"             "rqnc"                "RRF"                
## [193] "RRFglobal"           "rrlda"               "RSimca"             
## [196] "rvmLinear"           "rvmPoly"             "rvmRadial"          
## [199] "SBC"                 "sda"                 "sdwd"               
## [202] "simpls"              "SLAVE"               "slda"               
## [205] "smda"                "snn"                 "sparseLDA"          
## [208] "spikeslab"           "spls"                "stepLDA"            
## [211] "stepQDA"             "superpc"             "svmBoundrangeString"
## [214] "svmExpoString"       "svmLinear"           "svmLinear2"         
## [217] "svmLinear3"          "svmLinearWeights"    "svmLinearWeights2"  
## [220] "svmPoly"             "svmRadial"           "svmRadialCost"      
## [223] "svmRadialSigma"      "svmRadialWeights"    "svmSpectrumString"  
## [226] "tan"                 "tanSearch"           "treebag"            
## [229] "vbmpRadial"          "vglmAdjCat"          "vglmContRatio"      
## [232] "vglmCumulative"      "widekernelpls"       "WM"                 
## [235] "wsrf"                "xgbDART"             "xgbLinear"          
## [238] "xgbTree"             "xyf"
# Подготовьте данные из справочного файла пакета CARET:
x <- matrix(rnorm(50*5),ncol=5)
y <- factor(rep(c("A", "B"), 25))

# Получаем путь к рабочему столу
desktop_path <- file.path(Sys.getenv("USERPROFILE"), "Desktop")

# Создадим графики отдельно для каждой пары признаков
for (i in 1:ncol(x)) {
  for (j in 1:ncol(x)) {
    if (i != j) {
      # Создайте имя файла для графика
      filename <- file.path(desktop_path, paste0("featurePlot_", i, "_", j, ".jpg"))

      # Создайте график scatterplot
      plot(x[,i], x[,j], col=ifelse(y=="A", "red", "blue"),
           xlab=paste("Признак", i), ylab=paste("Признак", j),
           main=paste("Признаки", i, "vs", j))
      legend("topright", legend=levels(y), col=c("red", "blue"), pch=1)

      # Откройте графическое устройство JPEG
      jpeg(filename, width = 800, height = 600)

      # Повторно создайте график scatterplot для сохранения в файл
      plot(x[,i], x[,j], col=ifelse(y=="A", "red", "blue"),
           xlab=paste("Признак", i), ylab=paste("Признак", j),
           main=paste("Признаки", i, "vs", j))
      legend("topright", legend=levels(y), col=c("red", "blue"), pch=1)

      # Закройте графическое устройство JPEG
      dev.off()

      # Выведите сообщение о создании файла
      cat("График сохранен в файл:", filename, "\n")
    }
  }
}

## График сохранен в файл: C:\Users\lexus/Desktop/featurePlot_1_2.jpg

## График сохранен в файл: C:\Users\lexus/Desktop/featurePlot_1_3.jpg

## График сохранен в файл: C:\Users\lexus/Desktop/featurePlot_1_4.jpg

## График сохранен в файл: C:\Users\lexus/Desktop/featurePlot_1_5.jpg

## График сохранен в файл: C:\Users\lexus/Desktop/featurePlot_2_1.jpg

## График сохранен в файл: C:\Users\lexus/Desktop/featurePlot_2_3.jpg

## График сохранен в файл: C:\Users\lexus/Desktop/featurePlot_2_4.jpg

## График сохранен в файл: C:\Users\lexus/Desktop/featurePlot_2_5.jpg

## График сохранен в файл: C:\Users\lexus/Desktop/featurePlot_3_1.jpg

## График сохранен в файл: C:\Users\lexus/Desktop/featurePlot_3_2.jpg

## График сохранен в файл: C:\Users\lexus/Desktop/featurePlot_3_4.jpg

## График сохранен в файл: C:\Users\lexus/Desktop/featurePlot_3_5.jpg

## График сохранен в файл: C:\Users\lexus/Desktop/featurePlot_4_1.jpg

## График сохранен в файл: C:\Users\lexus/Desktop/featurePlot_4_2.jpg

## График сохранен в файл: C:\Users\lexus/Desktop/featurePlot_4_3.jpg

## График сохранен в файл: C:\Users\lexus/Desktop/featurePlot_4_5.jpg

## График сохранен в файл: C:\Users\lexus/Desktop/featurePlot_5_1.jpg

## График сохранен в файл: C:\Users\lexus/Desktop/featurePlot_5_2.jpg

## График сохранен в файл: C:\Users\lexus/Desktop/featurePlot_5_3.jpg

## График сохранен в файл: C:\Users\lexus/Desktop/featurePlot_5_4.jpg

Выводы о featurePlot

  • Слабая разделимость: В целом, признаки демонстрируют слабую разделимость между классами A и B. Ящичковые диаграммы сильно перекрываются, что затрудняет четкое разделение классов.

  • Feature4 и Feature5 потенциально полезны: Feature4 и Feature5 могут внести некоторый вклад в классификацию, но в сочетании с другими признаками или более сложными моделями.

  • Feature1, Feature2 и Feature3 - низкая информативность: Feature1, Feature2 и Feature3, вероятно, не будут полезны для классификации в текущем виде.

2. Определение важности признаков с использованием FSelector

С использование функций из пакета Fselector [2] определить важность признаков для решения задачи классификации. Использовать набор data(iris). Сделать выводы.

не удалось установить и запустить пакет FSelector. Вместо него используется пакет Caret с похожим функционалом

#Установите пакет caret, если он еще не установлен
if(!requireNamespace("caret", quietly = TRUE)) {
  install.packages("caret")
}

# Загрузите пакет caret
library(caret)

# Подготовьте данные
data(iris)
dataset <- iris

control <- trainControl(method="cv", number=10)
model <- train(Species ~ ., data=dataset[,c(1:5)], method="rf", trControl=control, importance=TRUE)
print(model)
## Random Forest 
## 
## 150 samples
##   4 predictor
##   3 classes: 'setosa', 'versicolor', 'virginica' 
## 
## No pre-processing
## Resampling: Cross-Validated (10 fold) 
## Summary of sample sizes: 135, 135, 135, 135, 135, 135, ... 
## Resampling results across tuning parameters:
## 
##   mtry  Accuracy   Kappa
##   2     0.9600000  0.94 
##   3     0.9600000  0.94 
##   4     0.9533333  0.93 
## 
## Accuracy was used to select the optimal model using the largest value.
## The final value used for the model was mtry = 2.
importance <- varImp(model)
print(importance)
## rf variable importance
## 
##   variables are sorted by maximum importance across the classes
##              setosa versicolor virginica
## Petal.Width  67.031     100.00    91.204
## Petal.Length 59.390      94.33    76.212
## Sepal.Length 11.481      15.92    16.659
## Sepal.Width   7.226       0.00     6.922
plot(importance)

Выводы о FSelector

  • Petal.Length и Petal.Width - наиболее важные признаки для классификации видов Iris: Эти два признака имеют значительно более высокую важность по сравнению с Sepal.Length и Sepal.Width для всех трех видов Iris (setosa, versicolor и virginica).

  • Sepal.Length и Sepal.Width имеют относительно низкую важность: Эти признаки вносят меньший вклад в разделение видов Iris по сравнению с длиной и шириной лепестков. Особенности важности признаков для каждого вида: Для Iris setosa, как Petal.Length так и Petal.Width сильно отделяют от других видов, о чем свидетельствуют высокие значения важности.

  • Sepal.Length и Sepal.Width имеют низкую важность. Для Iris versicolor и Iris virginica Petal.Length и Petal.Width по-прежнему важны, но разница в важности между этими признаками и Sepal.Length/Sepal.Width менее выражена, чем для Iris setosa. Это указывает на то, что для различения versicolor и virginica требуется больше информации о размерах чашелистиков.

  • Длина и ширина лепестков - ключевые различители: Размеры лепестков, вероятно, являются наиболее визуально различимыми особенностями, которые помогают в идентификации этих видов Iris. Данные подтверждают эту визуальную гипотезу.

3. Дискретизация непрерывных переменных с помощью arules

С использованием функции discretize() из пакета arules выполните преобразование непрерывной переменной в категориальную [3] различными методами: «interval» (равная ширина интервала), «frequency» (равная частота), «cluster» (кластеризация) и «fixed» (категории задают границы интервалов). Используйте набор данных iris. Сделайте выводы

# Установите пакет arules, если он еще не установлен
if(!requireNamespace("arules", quietly = TRUE)) {
  install.packages("arules")
}

# Загрузите пакет arules
library(arules)
## Загрузка требуемого пакета: Matrix
## 
## Присоединяю пакет: 'arules'
## Следующие объекты скрыты от 'package:base':
## 
##     abbreviate, write
# Подготовьте данные
data(iris)
dataset <- iris

# Определите непрерывные переменные, которые будем дискретизировать
continuous_vars <- c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width")

# Определите различные методы дискретизации
methods <- c("interval", "frequency", "cluster", "fixed")

# Задайте границы интервалов для метода "fixed" (пример)
# Важно подобрать эти границы на основе понимания данных
fixed_breaks <- c(0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, Inf)

# Создайте функцию для дискретизации переменной с заданным методом
discretize_variable <- function(data, variable, method, breaks = NULL) {
  if (method == "fixed") {
    if (is.null(breaks)) {
      stop("Необходимо указать границы интервалов для метода 'fixed'")
    }
    #Определим labels вручную
    labels = character()
    for (i in 1:(length(breaks)-1)) {
      labels = append(labels,paste0("(",breaks[i],", ",breaks[i+1],"]"))
    }
    discretized_var <- discretize(data[[variable]], method = method, breaks = breaks, labels=labels)
  } else {
    discretized_var <- discretize(data[[variable]], method = method)
  }
  return(discretized_var)
}

# Создайте функцию для анализа результатов дискретизации
analyze_discretization <- function(data, variable, discretized_var, method) {
  # Выведите таблицу частот для каждой категории
  print(table(discretized_var))
  # Посчитайте количество уникальных категорий
  num_categories <- length(unique(discretized_var))
  cat("Количество уникальных категорий:", num_categories, "\n")

  # Создайте гистограмму
  hist(as.numeric(discretized_var),  # Преобразуем в числовой формат для гистограммы
       main = paste("Гистограмма для", variable, "(Метод:", method, ")"),
       xlab = "Категории",
       ylab = "Частота",
       col = "lightblue",
       border = "black",
       breaks = num_categories) # Указываем количество интервалов
}

# Примените дискретизацию к каждой переменной каждым методом и проанализируйте результаты
for (variable in continuous_vars) {
  cat("----------------------------------------\n")
  cat("Переменная:", variable, "\n")
  for (method in methods) {
    cat("  Метод:", method, "\n")
    if (method == "fixed") {
      discretized_var <- discretize_variable(dataset, variable, method, breaks = fixed_breaks)
    } else {
      discretized_var <- discretize_variable(dataset, variable, method)
    }
    analyze_discretization(dataset, variable, discretized_var, method) # Передаём имя переменной
  }
}
## ----------------------------------------
## Переменная: Sepal.Length 
##   Метод: interval 
## discretized_var
## [4.3,5.5) [5.5,6.7) [6.7,7.9] 
##        52        70        28 
## Количество уникальных категорий: 3

##   Метод: frequency 
## discretized_var
## [4.3,5.4) [5.4,6.3) [6.3,7.9] 
##        46        53        51 
## Количество уникальных категорий: 3

##   Метод: cluster 
## discretized_var
##  [4.3,5.33) [5.33,6.27)  [6.27,7.9] 
##          46          53          51 
## Количество уникальных категорий: 3

##   Метод: fixed 
## discretized_var
## (0, 4.5] (4.5, 5] (5, 5.5] (5.5, 6] (6, 6.5] (6.5, 7] (7, 7.5] (7.5, 8] 
##        4       18       30       31       32       22        7        6 
## (8, Inf] 
##        0 
## Количество уникальных категорий: 8

## ----------------------------------------
## Переменная: Sepal.Width 
##   Метод: interval 
## discretized_var
##   [2,2.8) [2.8,3.6) [3.6,4.4] 
##        47        88        15 
## Количество уникальных категорий: 3

##   Метод: frequency 
## discretized_var
##   [2,2.9) [2.9,3.2) [3.2,4.4] 
##        47        47        56 
## Количество уникальных категорий: 3

##   Метод: cluster 
## discretized_var
##    [2,2.75) [2.75,3.29)  [3.29,4.4] 
##          33          74          43 
## Количество уникальных категорий: 3

##   Метод: fixed 
## discretized_var
## (0, 4.5] (4.5, 5] (5, 5.5] (5.5, 6] (6, 6.5] (6.5, 7] (7, 7.5] (7.5, 8] 
##      150        0        0        0        0        0        0        0 
## (8, Inf] 
##        0 
## Количество уникальных категорий: 1

## ----------------------------------------
## Переменная: Petal.Length 
##   Метод: interval 
## discretized_var
##    [1,2.97) [2.97,4.93)  [4.93,6.9] 
##          50          54          46 
## Количество уникальных категорий: 3

##   Метод: frequency 
## discretized_var
##   [1,2.63) [2.63,4.9)  [4.9,6.9] 
##         50         49         51 
## Количество уникальных категорий: 3

##   Метод: cluster 
## discretized_var
##    [1,2.85) [2.85,4.89)  [4.89,6.9] 
##          50          49          51 
## Количество уникальных категорий: 3

##   Метод: fixed 
## discretized_var
## (0, 4.5] (4.5, 5] (5, 5.5] (5.5, 6] (6, 6.5] (6.5, 7] (7, 7.5] (7.5, 8] 
##       79       25       18       17        7        4        0        0 
## (8, Inf] 
##        0 
## Количество уникальных категорий: 6

## ----------------------------------------
## Переменная: Petal.Width 
##   Метод: interval 
## discretized_var
## [0.1,0.9) [0.9,1.7) [1.7,2.5] 
##        50        52        48 
## Количество уникальных категорий: 3

##   Метод: frequency 
## discretized_var
## [0.1,0.867) [0.867,1.6)   [1.6,2.5] 
##          50          48          52 
## Количество уникальных категорий: 3

##   Метод: cluster 
## discretized_var
##  [0.1,0.792) [0.792,1.71)   [1.71,2.5] 
##           50           54           46 
## Количество уникальных категорий: 3

##   Метод: fixed 
## discretized_var
## (0, 4.5] (4.5, 5] (5, 5.5] (5.5, 6] (6, 6.5] (6.5, 7] (7, 7.5] (7.5, 8] 
##      150        0        0        0        0        0        0        0 
## (8, Inf] 
##        0 
## Количество уникальных категорий: 1

Выводы о дискретизации

Общие наблюдения для всех переменных и методов:

Для методов interval, frequency и cluster количество уникальных категорий всегда равно 3. Это связано с тем, что эти методы по умолчанию разбивают данные на заданное число интервалов (в данном случае, вероятно, по умолчанию используется 3 интервала). Метод fixed позволяет задать произвольные границы интервалов, что приводит к разному количеству категорий в зависимости от выбранных границ. Переменная Sepal.Length:

Метод interval создает интервалы примерно равной ширины (около 1.2 единицы длины чашелистика). Метод frequency создает интервалы, в которых находится примерно одинаковое количество наблюдений (около 50). Метод cluster находит интервалы на основе кластеризации данных. Метод fixed с заданными границами позволяет детально анализировать распределение переменной по различным диапазонам значений. Обратите внимание на количество наблюдений в интервалах (0, 4.5], (4.5, 5] и т.д. Переменная Sepal.Width:

Методы interval, frequency и cluster показывают, что большинство значений Sepal.Width находятся в интервале [2.8, 3.6). Метод fixed показывает, что все значения Sepal.Width попадают в интервал (0, 4.5]. Это связано с тем, что используемые границы интервалов не подходят для этой переменной (они слишком широкие). Нужно изменить границы интервалов для метода fixed, чтобы получить более полезную информацию. Переменная Petal.Length:

Методы interval, frequency и cluster показывают равномерное распределение Petal.Length по трем интервалам. Метод fixed показывает более детальное распределение. Большинство значений (79) находятся в интервале (0, 4.5]. Переменная Petal.Width:

Результаты для Petal.Width аналогичны результатам для Petal.Length. Для метода fixed опять все значения попадают в первый интервал (0, 4.5], что требует корректировки границ интервалов.

4. Выбор признаков с помощью Boruta

Установите пакет Boruta и проведите выбор признаков для набора данных data(“Ozone”) [4, 5, 6]. Построить график boxplot, сделать выводы.

# Установите пакет mlbench, если он еще не установлен
if(!requireNamespace("mlbench", quietly = TRUE)) {
  install.packages("mlbench")
}

# Загрузите пакет mlbench
library(mlbench)

# Загрузите пакет Boruta, если он еще не установлен
if(!requireNamespace("Boruta", quietly = TRUE)) {
  install.packages("Boruta")
}

# Загрузите пакет Boruta
library(Boruta)

# Подготовьте данные
data("Ozone", package = "mlbench") #Явно указываем, что данные находятся в пакете mlbench
ozone <- na.omit(Ozone)  # Удаляем строки с NA

# Выполните выбор признаков с помощью Boruta
set.seed(123) # Для воспроизводимости результатов
boruta_output <- Boruta(V9 ~ ., data = ozone, mcAdj=TRUE)

# Выведите результаты
print(boruta_output)
## Boruta performed 15 iterations in 1.132909 secs.
##  11 attributes confirmed important: V1, V10, V11, V12, V13 and 6 more;
##  1 attributes confirmed unimportant: V3;
# Получите подтвержденные признаки
confirmed_attributes <- getSelectedAttributes(boruta_output, withTentative = FALSE)
cat("Подтвержденные признаки:", paste(confirmed_attributes, collapse = ", "), "\n")
## Подтвержденные признаки: V1, V2, V4, V5, V6, V7, V8, V10, V11, V12, V13
# Визуализируйте результаты с помощью boxplot
plot(boruta_output, main = "Важность признаков (Boruta)", xaxt = "n") # Убираем стандартные метки оси x
#Добавим свои
axis(side = 1, #Горизонтальная ось
     at = 1:ncol(ozone[, -1]), #Позиции меток (сколько столбцов без целевой)
     labels = colnames(ozone[, -1]), #Имена столбцов
     las = 2, #Поворот меток (2 - перпендикулярно оси)
     cex.axis = 0.7) #Размер шрифта

Выводы о Boruta

Подтвержденные важные признаки (Definite): Признаки V6, V7, V8, V9, V10, V11, V12 и V13 были признаны важными. Об этом свидетельствует их зеленый цвет и высокое расположение boxplot’ов. Значимость этих признаков растет в этом порядке. Наибольшую значимость демонстрирует признак V13. Подтвержденные незначимые признаки (Rejected): Признаки V2 и V3 были признаны незначимыми для модели, о чем говорит их красный цвет и низкое положение соответствующих boxplot’ов. Предварительные (Tentative) признаки (такие, которые требуют уточнения): Признаки V4 и V5 отмечены синим цветом. Boruta не смог однозначно определить их важность на текущем этапе. Возможно, для принятия окончательного решения потребуется дополнительный анализ или больше итераций алгоритма. Общие выводы:

Алгоритм Boruta выявил четкую группу важных признаков (V6-V13) для предсказания целевой переменной. Эти признаки, вероятно, играют ключевую роль в моделировании данных. Признаки V2 и V3, вероятно, не вносят существенного вклада в предсказание целевой переменной и могут быть исключены из модели для ее упрощения и повышения обобщающей способности. Для признаков V4 и V5 требуется дополнительное исследование, чтобы определить, следует ли их включать в модель или исключить.

Заключение

В этой лабораторной работе мы продолжили изучение методов выбора признаков, используя различные пакеты R. Полученные результаты позволяют сравнить различные подходы к выявлению наиболее важных признаков для задач классификации и прогнозирования.