1 Введение

В данной лабораторной работе рассматриваются: 1. Графический разведочный анализ данных средствами пакета caret. 2. Определение важности признаков для задачи классификации с использованием пакета FSelector. 3. Дискретизация непрерывных признаков различными методами с помощью пакета arules. 4. Выбор признаков методом Boruta.

2 1. Графический разведочный анализ данных с использованием CARET

2.1 1.1 Установка и подключение пакета

if (!require(caret)) install.packages("caret", dependencies = TRUE)
library(caret)

2.2 1.2 Получение списка доступных моделей

model_names <- names(getModelInfo())
length(model_names)
## [1] 239
head(model_names, 50)
##  [1] "ada"            "AdaBag"         "AdaBoost.M1"    "adaboost"      
##  [5] "amdai"          "ANFIS"          "avNNet"         "awnb"          
##  [9] "awtan"          "bag"            "bagEarth"       "bagEarthGCV"   
## [13] "bagFDA"         "bagFDAGCV"      "bam"            "bartMachine"   
## [17] "bayesglm"       "binda"          "blackboost"     "blasso"        
## [21] "blassoAveraged" "bridge"         "brnn"           "BstLm"         
## [25] "bstSm"          "bstTree"        "C5.0"           "C5.0Cost"      
## [29] "C5.0Rules"      "C5.0Tree"       "cforest"        "chaid"         
## [33] "CSimca"         "ctree"          "ctree2"         "cubist"        
## [37] "dda"            "deepboost"      "DENFIS"         "dnn"           
## [41] "dwdLinear"      "dwdPoly"        "dwdRadial"      "earth"         
## [45] "elm"            "enet"           "evtree"         "extraTrees"    
## [49] "fda"            "FH.GBML"

2.3 1.3 Подготовка данных

set.seed(123)

x <- matrix(rnorm(50 * 5), ncol = 5)
colnames(x) <- paste0("X", 1:5)
x <- as.data.frame(x)

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

str(x)
## 'data.frame':    50 obs. of  5 variables:
##  $ X1: num  -0.5605 -0.2302 1.5587 0.0705 0.1293 ...
##  $ X2: num  0.2533 -0.0285 -0.0429 1.3686 -0.2258 ...
##  $ X3: num  -0.71 0.257 -0.247 -0.348 -0.952 ...
##  $ X4: num  0.788 0.769 0.332 -1.008 -0.119 ...
##  $ X5: num  2.199 1.312 -0.265 0.543 -0.414 ...
table(y)
## y
##  A  B 
## 25 25

2.4 1.4 Построение графиков и сохранение в PNG

2.4.1 1.4.1 Boxplot

png("figures/featureplot_box.png", width = 1600, height = 1200, res = 200)
featurePlot(
  x = x,
  y = y,
  plot = "box",
  auto.key = list(columns = 2)
)
dev.off()
## png 
##   2

2.4.2 1.4.2 Density plot

png("figures/featureplot_density.png", width = 1600, height = 1200, res = 200)
featurePlot(
  x = x,
  y = y,
  plot = "density",
  auto.key = list(columns = 2)
)
dev.off()
## png 
##   2

2.5 1.5 Вставка сохраненных изображений в отчет

2.5.1 Boxplot

2.5.2 Density plot

2.6 1.6 Выводы по заданию 1

Команда names(getModelInfo()) позволяет получить список моделей, доступных в пакете caret. Это показывает, что пакет содержит большое количество алгоритмов для задач классификации и регрессии.

С помощью функции featurePlot() были построены графики для искусственно сгенерированных данных. Поскольку признаки создавались случайным образом, выраженного разделения между классами A и B не наблюдается. На boxplot-м и density-графиках распределения признаков двух классов во многом пересекаются. Следовательно, такие признаки не являются информативными для качественной классификации.

3 2. Определение важности признаков для набора iris с помощью FSelector

3.1 2.1 Установка и подключение пакета

if (!require(FSelector)) install.packages("FSelector", dependencies = TRUE)
library(FSelector)

3.2 2.2 Загрузка данных iris

data(iris)
str(iris)
## 'data.frame':    150 obs. of  5 variables:
##  $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
##  $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
##  $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
##  $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
##  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
summary(iris)
##   Sepal.Length    Sepal.Width     Petal.Length    Petal.Width   
##  Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100  
##  1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300  
##  Median :5.800   Median :3.000   Median :4.350   Median :1.300  
##  Mean   :5.843   Mean   :3.057   Mean   :3.758   Mean   :1.199  
##  3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800  
##  Max.   :7.900   Max.   :4.400   Max.   :6.900   Max.   :2.500  
##        Species  
##  setosa    :50  
##  versicolor:50  
##  virginica :50  
##                 
##                 
## 

3.3 2.3 Оценка важности признаков

importance_iris <- information.gain(Species ~ ., data = iris)
importance_iris <- importance_iris[order(-importance_iris$attr_importance), , drop = FALSE]
importance_iris
##              attr_importance
## Petal.Width        0.9554360
## Petal.Length       0.9402853
## Sepal.Length       0.4521286
## Sepal.Width        0.2672750

3.4 2.4 Построение столбчатой диаграммы важности признаков

vals <- importance_iris$attr_importance
names(vals) <- rownames(importance_iris)

png("figures/iris_importance.png", width = 1600, height = 1200, res = 200)
barplot(
  vals,
  main = "Важность признаков для набора iris",
  ylab = "Information Gain",
  las = 2
)
dev.off()
## png 
##   2

3.5 2.5 Вставка графика в отчет

3.6 2.6 Выводы по заданию 2

Для набора данных iris была рассчитана важность признаков с помощью функции information.gain() из пакета FSelector. В результате признаки были ранжированы по степени их влияния на классификацию вида ириса.

Наиболее важными являются признаки с наибольшим значением attr_importance. Обычно наибольший вклад в задачу классификации вносят признаки, связанные с размерами лепестков (Petal.Length и Petal.Width), так как именно они лучше всего разделяют виды ирисов. Менее значимыми оказываются признаки чашелистиков. Следовательно, для построения модели классификации в первую очередь следует использовать наиболее информативные признаки.

4 3. Дискретизация непрерывной переменной с помощью arules::discretize()

4.1 3.1 Установка и подключение пакета

if (!require(arules)) install.packages("arules", dependencies = TRUE)
library(arules)

4.2 3.2 Выбор непрерывной переменной

x_cont <- iris$Sepal.Length
summary(x_cont)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   4.300   5.100   5.800   5.843   6.400   7.900

4.3 3.3 Дискретизация различными методами

4.3.1 Метод interval

disc_interval <- discretize(x_cont, method = "interval", categories = 3)
table(disc_interval)
## disc_interval
## [4.3,5.5) [5.5,6.7) [6.7,7.9] 
##        52        70        28

4.3.2 Метод frequency

disc_frequency <- discretize(x_cont, method = "frequency", categories = 3)
table(disc_frequency)
## disc_frequency
## [4.3,5.4) [5.4,6.3) [6.3,7.9] 
##        46        53        51

4.3.3 Метод cluster

disc_cluster <- discretize(x_cont, method = "cluster", categories = 3)
table(disc_cluster)
## disc_cluster
##  [4.3,5.42) [5.42,6.39)  [6.39,7.9] 
##          52          56          42

4.3.4 Метод fixed

disc_fixed <- discretize(
  x_cont,
  method = "fixed",
  breaks = c(-Inf, 5.5, 6.5, Inf),
  labels = c("small", "medium", "large")
)
table(disc_fixed)
## disc_fixed
##  small medium  large 
##     52     63     35

4.4 3.4 Сравнительная таблица

disc_result <- data.frame(
  Original = x_cont,
  Interval = disc_interval,
  Frequency = disc_frequency,
  Cluster = disc_cluster,
  Fixed = disc_fixed
)

head(disc_result, 15)
##    Original  Interval Frequency     Cluster  Fixed
## 1       5.1 [4.3,5.5) [4.3,5.4)  [4.3,5.42)  small
## 2       4.9 [4.3,5.5) [4.3,5.4)  [4.3,5.42)  small
## 3       4.7 [4.3,5.5) [4.3,5.4)  [4.3,5.42)  small
## 4       4.6 [4.3,5.5) [4.3,5.4)  [4.3,5.42)  small
## 5       5.0 [4.3,5.5) [4.3,5.4)  [4.3,5.42)  small
## 6       5.4 [4.3,5.5) [5.4,6.3)  [4.3,5.42)  small
## 7       4.6 [4.3,5.5) [4.3,5.4)  [4.3,5.42)  small
## 8       5.0 [4.3,5.5) [4.3,5.4)  [4.3,5.42)  small
## 9       4.4 [4.3,5.5) [4.3,5.4)  [4.3,5.42)  small
## 10      4.9 [4.3,5.5) [4.3,5.4)  [4.3,5.42)  small
## 11      5.4 [4.3,5.5) [5.4,6.3)  [4.3,5.42)  small
## 12      4.8 [4.3,5.5) [4.3,5.4)  [4.3,5.42)  small
## 13      4.8 [4.3,5.5) [4.3,5.4)  [4.3,5.42)  small
## 14      4.3 [4.3,5.5) [4.3,5.4)  [4.3,5.42)  small
## 15      5.8 [5.5,6.7) [5.4,6.3) [5.42,6.39) medium

4.5 3.5 Выводы по заданию 3

Функция discretize() позволяет преобразовать непрерывную переменную в категориальную несколькими способами.

Метод interval делит весь диапазон значений на интервалы одинаковой ширины.
Метод frequency формирует интервалы так, чтобы в каждом было примерно одинаковое число наблюдений.
Метод cluster выполняет группировку значений на основе их близости.
Метод fixed использует заранее заданные пользователем границы интервалов.

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

5 4. Выбор признаков методом Boruta для набора Ozone

5.1 4.1 Установка и подключение пакетов

if (!require(Boruta)) install.packages("Boruta", dependencies = TRUE)
if (!require(mlbench)) install.packages("mlbench", dependencies = TRUE)

library(Boruta)
library(mlbench)

5.2 4.2 Загрузка данных Ozone

data("Ozone", package = "mlbench")
str(Ozone)
## 'data.frame':    366 obs. of  13 variables:
##  $ V1 : Factor w/ 12 levels "1","2","3","4",..: 1 1 1 1 1 1 1 1 1 1 ...
##  $ V2 : Factor w/ 31 levels "1","2","3","4",..: 1 2 3 4 5 6 7 8 9 10 ...
##  $ V3 : Factor w/ 7 levels "1","2","3","4",..: 4 5 6 7 1 2 3 4 5 6 ...
##  $ V4 : num  3 3 3 5 5 6 4 4 6 7 ...
##  $ V5 : num  5480 5660 5710 5700 5760 5720 5790 5790 5700 5700 ...
##  $ V6 : num  8 6 4 3 3 4 6 3 3 3 ...
##  $ V7 : num  20 NA 28 37 51 69 19 25 73 59 ...
##  $ V8 : num  NA 38 40 45 54 35 45 55 41 44 ...
##  $ V9 : num  NA NA NA NA 45.3 ...
##  $ V10: num  5000 NA 2693 590 1450 ...
##  $ V11: num  -15 -14 -25 -24 25 15 -33 -28 23 -2 ...
##  $ V12: num  30.6 NA 47.7 55 57 ...
##  $ V13: num  200 300 250 100 60 60 100 250 120 120 ...
summary(Ozone)
##        V1            V2      V3           V4              V5      
##  1      : 31   1      : 12   1:52   Min.   : 1.00   Min.   :5320  
##  3      : 31   2      : 12   2:52   1st Qu.: 5.00   1st Qu.:5700  
##  5      : 31   3      : 12   3:52   Median : 9.00   Median :5770  
##  7      : 31   4      : 12   4:53   Mean   :11.53   Mean   :5753  
##  8      : 31   5      : 12   5:53   3rd Qu.:16.00   3rd Qu.:5830  
##  10     : 31   6      : 12   6:52   Max.   :38.00   Max.   :5950  
##  (Other):180   (Other):294   7:52   NA's   :5       NA's   :12    
##        V6               V7              V8              V9       
##  Min.   : 0.000   Min.   :19.00   Min.   :25.00   Min.   :27.68  
##  1st Qu.: 3.000   1st Qu.:49.00   1st Qu.:51.00   1st Qu.:49.73  
##  Median : 5.000   Median :65.00   Median :62.00   Median :57.02  
##  Mean   : 4.869   Mean   :58.48   Mean   :61.91   Mean   :56.85  
##  3rd Qu.: 6.000   3rd Qu.:73.00   3rd Qu.:72.00   3rd Qu.:66.11  
##  Max.   :11.000   Max.   :93.00   Max.   :93.00   Max.   :82.58  
##                   NA's   :15      NA's   :2       NA's   :139    
##       V10            V11             V12             V13       
##  Min.   : 111   Min.   :-69.0   Min.   :27.50   Min.   :  0.0  
##  1st Qu.: 890   1st Qu.:-10.0   1st Qu.:51.26   1st Qu.: 70.0  
##  Median :2125   Median : 24.0   Median :62.24   Median :110.0  
##  Mean   :2591   Mean   : 17.8   Mean   :60.93   Mean   :123.3  
##  3rd Qu.:5000   3rd Qu.: 45.0   3rd Qu.:70.52   3rd Qu.:150.0  
##  Max.   :5000   Max.   :107.0   Max.   :91.76   Max.   :500.0  
##  NA's   :15     NA's   :1       NA's   :14

5.3 4.3 Удаление пропусков

ozone_data <- na.omit(Ozone)
dim(ozone_data)
## [1] 203  13

5.4 4.4 Применение метода Boruta

set.seed(123)
boruta_model <- Boruta(V4 ~ ., data = ozone_data, doTrace = 0)
boruta_fixed <- TentativeRoughFix(boruta_model)
boruta_stats <- attStats(boruta_fixed)

boruta_stats
##        meanImp  medianImp     minImp     maxImp  normHits  decision
## V1   9.5563296  9.7071000  8.4255686 10.7247899 1.0000000 Confirmed
## V2   1.1557680  1.1576551 -0.2474598  2.7423660 0.1666667  Rejected
## V3  -0.9877372 -0.7333367 -3.4162909  0.3794342 0.0000000  Rejected
## V5   9.2426781  9.2313179  8.1108460 10.5140883 1.0000000 Confirmed
## V6   0.9886679  1.3615721 -1.1013954  1.9852132 0.0000000  Rejected
## V7  11.7026875 11.5169965 10.5127703 13.4896943 1.0000000 Confirmed
## V8  17.1647491 17.2255744 16.0336735 18.5525852 1.0000000 Confirmed
## V9  19.2281405 19.0627349 17.5889826 20.9190449 1.0000000 Confirmed
## V10  9.8662368  9.7266893  8.6477478 11.3131795 1.0000000 Confirmed
## V11 11.8977619 11.8484607 10.9347533 13.6520570 1.0000000 Confirmed
## V12 14.6326841 14.6095338 13.5595253 16.0775580 1.0000000 Confirmed
## V13  9.4438214  9.5489762  8.1005306 10.7881019 1.0000000 Confirmed

5.5 4.5 Построение boxplot и сохранение в PNG

png("figures/boruta_ozone_boxplot.png", width = 1800, height = 1200, res = 200)
plot(boruta_fixed, las = 2, cex.axis = 0.8, main = "Boruta: важность признаков для Ozone")
dev.off()
## png 
##   2

5.6 4.6 Вставка графика в отчет

5.7 4.7 Выводы по заданию 4

Метод Boruta позволяет определить, какие признаки действительно важны для предсказания целевой переменной. Алгоритм сравнивает реальные признаки с искусственно созданными теневыми признаками и на этой основе принимает решение о значимости.

В результате анализа признаки делятся на подтвержденные значимые (Confirmed), отклоненные (Rejected) и иногда промежуточные (Tentative). Построенный boxplot наглядно показывает распределение важности признаков. Те признаки, которые стабильно превосходят теневые, считаются действительно полезными для модели.

6 Общий вывод

В ходе лабораторной работы были изучены основные методы анализа данных и отбора признаков в языке R.

С помощью пакета caret был выполнен графический разведочный анализ данных, и показано, что случайно сгенерированные признаки плохо разделяют классы.
С помощью пакета FSelector была определена важность признаков для задачи классификации на наборе iris.
С помощью функции discretize() из пакета arules были рассмотрены различные способы перевода непрерывной переменной в категориальную.
С помощью алгоритма Boruta был выполнен отбор признаков для набора Ozone.

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

7 Заключение

Все результаты лабораторной работы были собраны в единый файл формата R Markdown. Итоговый отчет может быть скомпилирован в HTML и опубликован на RPubs.

8 Список использованных пакетов