1 Цель работы

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

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

2.1 1.1. Пакет caret

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

Для просмотра доступных моделей используется функция getModelInfo().

library(caret)
library(FSelector)
library(arules)
library(Boruta)

set.seed(123)

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

model_list <- names(getModelInfo())
head(model_list, 30)
##  [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"

Количество доступных моделей:

length(model_list)
## [1] 239

2.2 1.2. Формирование исходного набора данных

В соответствии с условием задания создадим матрицу из 50 наблюдений и 5 признаков.

x <- matrix(rnorm(50 * 5), ncol = 5)
y <- factor(rep(c("A", "B"), 25))

colnames(x) <- paste0("X", 1:5)

head(x)
##               X1          X2          X3         X4         X5
## [1,] -0.56047565  0.25331851 -0.71040656  0.7877388  2.1988103
## [2,] -0.23017749 -0.02854676  0.25688371  0.7690422  1.3124130
## [3,]  1.55870831 -0.04287046 -0.24669188  0.3322026 -0.2651451
## [4,]  0.07050839  1.36860228 -0.34754260 -1.0083766  0.5431941
## [5,]  0.12928774 -0.22577099 -0.95161857 -0.1194526 -0.4143399
## [6,]  1.71506499  1.51647060 -0.04502772 -0.2803953 -0.4762469

Количество объектов каждого класса:

table(y)
## y
##  A  B 
## 25 25

2.3 1.3. Графический анализ с использованием featurePlot()

С помощью функции featurePlot() построим попарные диаграммы рассеяния признаков.

Сначала сохраним график в JPG-файл.

jpeg(
  filename = "featurePlot_pairs.jpg",
  width = 1800,
  height = 1800,
  res = 200
)

featurePlot(
  x = x,
  y = y,
  plot = "pairs"
)

dev.off()
## png 
##   2

Отобразим график в отчёте:

featurePlot(
  x = x,
  y = y,
  plot = "pairs"
)

Также построим графики плотности распределения признаков и сохраним их в JPG-файл.

jpeg(
  filename = "featurePlot_density.jpg",
  width = 1800,
  height = 1400,
  res = 200
)

featurePlot(
  x = x,
  y = y,
  plot = "density",
  scales = list(
    x = list(relation = "free")
  )
)

dev.off()
## png 
##   2

Отобразим графики плотности в отчёте:

featurePlot(
  x = x,
  y = y,
  plot = "density",
  scales = list(
    x = list(relation = "free")
  )
)

2.4 1.4. Вывод

В ходе первого задания был выполнен графический разведочный анализ набора данных из 50 наблюдений и 5 признаков.

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

Так как исходные значения были случайно сгенерированы из нормального распределения, выраженного разделения классов A и B на графиках не наблюдается.

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

3.1 2.1. Набор данных iris

Для определения важности признаков используется стандартный набор данных iris.

data(iris)
head(iris)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
## 3          4.7         3.2          1.3         0.2  setosa
## 4          4.6         3.1          1.5         0.2  setosa
## 5          5.0         3.6          1.4         0.2  setosa
## 6          5.4         3.9          1.7         0.4  setosa

Общая статистическая информация:

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  
##                 
##                 
## 

Названия переменных:

names(iris)
## [1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width"  "Species"

Набор данных iris содержит четыре числовых признака: Sepal.Length, Sepal.Width, Petal.Length и Petal.Width. Целевой переменной является Species.

3.2 2.2. Определение важности признаков

Для оценки важности признаков используется метод Information Gain.

ig <- information.gain(
  Species ~ .,
  data = iris
)

ig
##              attr_importance
## Sepal.Length       0.4521286
## Sepal.Width        0.2672750
## Petal.Length       0.9402853
## Petal.Width        0.9554360

Отсортируем признаки по убыванию важности:

ig_sorted <- ig[order(-ig[[1]]), , drop = FALSE]

ig_sorted
##              attr_importance
## Petal.Width        0.9554360
## Petal.Length       0.9402853
## Sepal.Length       0.4521286
## Sepal.Width        0.2672750

3.3 2.3. График важности признаков

barplot(
  ig_sorted[[1]],
  names.arg = rownames(ig_sorted),
  main = "Важность признаков по Information Gain",
  xlab = "Признак",
  ylab = "Важность",
  las = 2
)

3.4 2.4. Вывод

Метод Information Gain позволяет определить, насколько каждый признак информативен для определения класса объекта.

Полученное ранжирование показывает, какие признаки наиболее полезны для классификации объектов набора iris. Наиболее информативными обычно являются признаки, характеризующие размеры лепестков.

4 Задание 3. Дискретизация непрерывной переменной

4.1 3.1. Исходные данные

Для дискретизации используется непрерывная переменная Sepal.Length из набора данных iris.

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

4.2 3.2. Метод interval

Метод interval разбивает диапазон значений на интервалы одинаковой ширины.

iris_interval <- discretize(
  x_iris,
  method = "interval",
  categories = 3
)
## Warning in discretize(x_iris, method = "interval", categories = 3): Parameter
## categories is deprecated. Use breaks instead! Also, the default method is now
## frequency!
table(iris_interval)
## iris_interval
## [4.3,5.5) [5.5,6.7) [6.7,7.9] 
##        52        70        28

4.3 3.3. Метод frequency

Метод frequency формирует категории с приблизительно одинаковым количеством наблюдений.

iris_frequency <- discretize(
  x_iris,
  method = "frequency",
  categories = 3
)
## Warning in discretize(x_iris, method = "frequency", categories = 3): Parameter
## categories is deprecated. Use breaks instead! Also, the default method is now
## frequency!
table(iris_frequency)
## iris_frequency
## [4.3,5.4) [5.4,6.3) [6.3,7.9] 
##        46        53        51

4.4 3.4. Метод cluster

Метод cluster выполняет дискретизацию на основе кластеризации значений.

iris_cluster <- discretize(
  x_iris,
  method = "cluster",
  categories = 3
)
## Warning in discretize(x_iris, method = "cluster", categories = 3): Parameter
## categories is deprecated. Use breaks instead! Also, the default method is now
## frequency!
table(iris_cluster)
## iris_cluster
##  [4.3,5.33) [5.33,6.27)  [6.27,7.9] 
##          46          53          51

4.5 3.5. Метод fixed

При использовании метода fixed границы интервалов задаются пользователем.

iris_fixed <- discretize(
  x_iris,
  method = "fixed",
  breaks = c(4.3, 5.4, 6.5, 7.9)
)

table(iris_fixed)
## iris_fixed
## [4.3,5.4) [5.4,6.5) [6.5,7.9] 
##        46        69        35

4.6 3.6. Сравнение результатов

discretization_result <- data.frame(
  Original = x_iris,
  Interval = iris_interval,
  Frequency = iris_frequency,
  Cluster = iris_cluster,
  Fixed = iris_fixed
)

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

4.7 3.7. Вывод

В ходе третьего задания непрерывная переменная Sepal.Length была преобразована в категориальную четырьмя способами.

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

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

5 Задание 4. Отбор признаков с помощью Boruta

5.1 4.1. Набор данных Ozone

Для выполнения задания используется набор данных Ozone.

if (!requireNamespace("mlbench", quietly = TRUE)) {
  stop(
    "Для выполнения задания 4 необходимо установить пакет mlbench. ",
    "Выполните в консоли R: install.packages('mlbench')"
  )
}

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   NAs    :5       NAs    :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  
##                   NAs    :15      NAs    :2       NAs    :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  
##  NAs    :15     NAs    :1       NAs    :14

Удалим строки, содержащие пропущенные значения:

Ozone_clean <- na.omit(Ozone)

dim(Ozone_clean)
## [1] 203  13

5.2 4.2. Формирование категориальной целевой переменной

Для применения Boruta в задаче классификации сформируем категориальную переменную на основе медианного значения концентрации озона.

ozone_median <- median(Ozone_clean$V4)

Ozone_clean$ozone_class <- factor(
  ifelse(
    Ozone_clean$V4 >= ozone_median,
    "High",
    "Low"
  )
)

table(Ozone_clean$ozone_class)
## 
## High  Low 
##  108   95

Исходную переменную ozone исключим из списка признаков.

ozone_data <- Ozone_clean[
  ,
  setdiff(names(Ozone_clean), "V4")
]

str(ozone_data)
## 'data.frame':    203 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",..: 5 6 7 8 9 12 13 14 15 16 ...
##  $ V3         : Factor w/ 7 levels "1","2","3","4",..: 1 2 3 4 5 1 2 3 4 5 ...
##  $ V5         : num  5760 5720 5790 5790 5700 5720 5760 5780 5830 5870 ...
##  $ V6         : num  3 4 6 3 3 3 6 6 3 2 ...
##  $ V7         : num  51 69 19 25 73 44 33 19 19 19 ...
##  $ V8         : num  54 35 45 55 41 51 51 54 58 61 ...
##  $ V9         : num  45.3 49.6 46.4 52.7 48 ...
##  $ V10        : num  1450 1568 2631 554 2083 ...
##  $ V11        : num  25 15 -33 -28 23 9 -44 -44 -53 -67 ...
##  $ V12        : num  57 53.8 54.1 64.8 52.5 ...
##  $ V13        : num  60 60 100 250 120 150 40 200 250 200 ...
##  $ ozone_class: Factor w/ 2 levels "High","Low": 2 2 2 2 2 2 2 2 2 2 ...

5.3 4.3. Отбор признаков Boruta

set.seed(123)

boruta_model <- Boruta(
  ozone_class ~ .,
  data = ozone_data,
  doTrace = 0
)

boruta_model
## Boruta performed 99 iterations in 2.517292 secs.
##  9 attributes confirmed important: V1, V10, V11, V12, V13 and 4 more;
##  2 attributes confirmed unimportant: V3, V6;
##  1 tentative attributes left: V2;

5.4 4.4. Результаты отбора признаков

boruta_stats <- attStats(boruta_model)
boruta_stats
##          meanImp  medianImp       minImp     maxImp  normHits  decision
## V1   0.527820582 0.52673908  0.464166850 0.58819891 1.0000000 Confirmed
## V2   0.108899476 0.11140582 -0.002062672 0.24203424 0.4141414 Tentative
## V3  -0.002365002 0.01146640 -0.065534702 0.03673776 0.0000000  Rejected
## V5   0.496486423 0.49474689  0.436704013 0.58892617 1.0000000 Confirmed
## V6   0.033439729 0.03094937 -0.061311663 0.13041460 0.0000000  Rejected
## V7   0.583246145 0.58147708  0.496733201 0.68851283 1.0000000 Confirmed
## V8   0.920008697 0.92353584  0.807444434 1.04277559 1.0000000 Confirmed
## V9   0.746108167 0.74904350  0.668899070 0.81078945 1.0000000 Confirmed
## V10  0.428106615 0.42910216  0.315777636 0.49989416 1.0000000 Confirmed
## V11  0.610045934 0.61291192  0.506182653 0.70091731 1.0000000 Confirmed
## V12  0.703997619 0.70495727  0.633350834 0.78104290 1.0000000 Confirmed
## V13  0.382070133 0.38501117  0.299333053 0.46957763 1.0000000 Confirmed

Подтверждённые признаки:

boruta_stats[
  boruta_stats$decision == "Confirmed",
  ,
  drop = FALSE
]
##       meanImp medianImp    minImp    maxImp normHits  decision
## V1  0.5278206 0.5267391 0.4641668 0.5881989        1 Confirmed
## V5  0.4964864 0.4947469 0.4367040 0.5889262        1 Confirmed
## V7  0.5832461 0.5814771 0.4967332 0.6885128        1 Confirmed
## V8  0.9200087 0.9235358 0.8074444 1.0427756        1 Confirmed
## V9  0.7461082 0.7490435 0.6688991 0.8107894        1 Confirmed
## V10 0.4281066 0.4291022 0.3157776 0.4998942        1 Confirmed
## V11 0.6100459 0.6129119 0.5061827 0.7009173        1 Confirmed
## V12 0.7039976 0.7049573 0.6333508 0.7810429        1 Confirmed
## V13 0.3820701 0.3850112 0.2993331 0.4695776        1 Confirmed

5.5 4.5. График Boruta

plot(
  boruta_model,
  las = 2
)

5.6 4.6. Boxplot

Построим boxplot распределения концентрации озона для двух сформированных классов.

boxplot(
  V4 ~ ozone_class,
  data = Ozone_clean,
  main = "Распределение концентрации озона по классам",
  xlab = "Класс",
  ylab = "Концентрация озона"
)

5.7 4.7. Вывод

Алгоритм Boruta используется для определения информативности признаков относительно целевой переменной.

В результате работы алгоритма признаки получают один из статусов: Confirmed, Rejected или Tentative.

График Boruta позволяет визуально сравнить важность признаков и выделить наиболее информативные характеристики.

Boxplot показывает распределение концентрации озона для двух сформированных групп и позволяет визуально оценить различия между ними.

6 Общий вывод

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

С помощью пакета caret был выполнен графический разведочный анализ с использованием функции featurePlot().

С помощью пакета FSelector была определена важность признаков набора данных iris методом Information Gain.

С использованием функции discretize() пакета arules выполнена дискретизация непрерывной переменной четырьмя методами: interval, frequency, cluster и fixed.

Для набора данных Ozone был применён алгоритм Boruta для определения информативности признаков. Дополнительно был построен boxplot для анализа распределения концентрации озона по сформированным классам.

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