Этот отчет показывает ход и результаты выполнения лабораторной работы №4 по дисциплине «Анализ данных».
Тема лабораторной работы: «Способы подготовки исходных данных».
В работе рассматриваются способы обработки пропущенных значений,
удаления выбросов, удаления дубликатов, заполнения пропусков с помощью
пакетов caret и mice, а также пример анализа
мультиколлинеарности.
Перед запуском отчета необходимо один раз установить нужные пакеты в консоли RStudio:
install.packages("caret")
install.packages("mice")
install.packages("car")
Подключим необходимые библиотеки:
library(caret)
library(mice)
library(car)
Сформировать собственный датасет с помощью функции c(),
в котором содержатся числовые данные и значения NA.
my_data <- c(10, 20, NA, 30, 40, NA, 50)
my_data
## [1] 10 20 NA 30 40 NA 50
Был создан числовой вектор my_data, содержащий обычные
числовые значения и пропущенные значения NA. Такой набор
данных можно использовать для демонстрации способов поиска и обработки
пропусков.
Провести очистку данных с использованием функции is.na()
и вывести «чистый» датасет.
na_positions <- is.na(my_data)
na_positions
## [1] FALSE FALSE TRUE FALSE FALSE TRUE FALSE
clean_data <- my_data[!na_positions]
clean_data
## [1] 10 20 30 40 50
Функция is.na() позволяет определить, в каких позициях
находятся пропущенные значения. После этого с помощью логической
индексации были удалены элементы NA.
В результате был получен очищенный вектор, содержащий только числовые
значения: 10, 20, 30,
40, 50.
Сгенерировать таблицу данных с числовыми и текстовыми столбцами с
помощью функции c(). Очистить данные с помощью функции
complete.cases().
my_table <- data.frame(
numbers = c(1, 2, 3, NA, 5),
text = c("A", NA, "C", "D", "E")
)
my_table
## numbers text
## 1 1 A
## 2 2 <NA>
## 3 3 C
## 4 NA D
## 5 5 E
clean_table <- my_table[complete.cases(my_table), ]
clean_table
## numbers text
## 1 1 A
## 3 3 C
## 5 5 E
Функция complete.cases() определяет строки, в которых
нет пропущенных значений. С ее помощью из таблицы были удалены строки,
содержащие NA.
В результате остались только полностью заполненные строки таблицы.
Проанализировать датасет airquality с пропусками. С
использованием функции preProcess() из пакета
caret заполнить пропуски предсказанными значениями: средним
и медианой.
data(airquality)
head(airquality)
## Ozone Solar.R Wind Temp Month Day
## 1 41 190 7.4 67 5 1
## 2 36 118 8.0 72 5 2
## 3 12 149 12.6 74 5 3
## 4 18 313 11.5 62 5 4
## 5 NA NA 14.3 56 5 5
## 6 28 NA 14.9 66 5 6
colSums(is.na(airquality))
## Ozone Solar.R Wind Temp Month Day
## 37 7 0 0 0 0
airquality_mean <- airquality
airquality_mean$Ozone[is.na(airquality_mean$Ozone)] <-
mean(airquality$Ozone, na.rm = TRUE)
airquality_mean$Solar.R[is.na(airquality_mean$Solar.R)] <-
mean(airquality$Solar.R, na.rm = TRUE)
head(airquality_mean)
## Ozone Solar.R Wind Temp Month Day
## 1 41.00000 190.0000 7.4 67 5 1
## 2 36.00000 118.0000 8.0 72 5 2
## 3 12.00000 149.0000 12.6 74 5 3
## 4 18.00000 313.0000 11.5 62 5 4
## 5 42.12931 185.9315 14.3 56 5 5
## 6 28.00000 185.9315 14.9 66 5 6
colSums(is.na(airquality_mean))
## Ozone Solar.R Wind Temp Month Day
## 0 0 0 0 0 0
preproc_median <- preProcess(airquality, method = "medianImpute")
airquality_median <- predict(preproc_median, airquality)
head(airquality_median)
## Ozone Solar.R Wind Temp Month Day
## 1 41.0 190 7.4 67 5 1
## 2 36.0 118 8.0 72 5 2
## 3 12.0 149 12.6 74 5 3
## 4 18.0 313 11.5 62 5 4
## 5 31.5 205 14.3 56 5 5
## 6 28.0 205 14.9 66 5 6
colSums(is.na(airquality_median))
## Ozone Solar.R Wind Temp Month Day
## 0 0 0 0 0 0
В исходном датасете airquality были обнаружены пропуски
в столбцах Ozone и Solar.R.
При заполнении средним значением все пропущенные значения заменяются средним арифметическим соответствующего столбца. Такой способ простой, но он чувствителен к выбросам.
При заполнении медианой пропуски заменяются медианным значением. Этот способ часто является более устойчивым, так как медиана меньше зависит от выбросов.
После обработки в обоих вариантах пропущенные значения были устранены.
Сгенерировать два числовых набора данных и добавить в них выбросы. С
использованием функции boxplot() обнаружить выбросы и
удалить их.
set1 <- c(1, 2, 3, 4, 123)
set2 <- c(10, 20, 30, 40, 250)
boxplot(set1, main = "Set 1")
boxplot(set2, main = "Set 2")
outliers_set1 <- boxplot.stats(set1)$out
outliers_set2 <- boxplot.stats(set2)$out
outliers_set1
## [1] 123
outliers_set2
## [1] 250
clean_set1 <- set1[!set1 %in% outliers_set1]
clean_set2 <- set2[!set2 %in% outliers_set2]
clean_set1
## [1] 1 2 3 4
clean_set2
## [1] 10 20 30 40
В первом наборе данных выбросом является значение 123, а
во втором наборе данных выбросом является значение 250.
С помощью функции boxplot() выбросы были визуально
обнаружены, а с помощью boxplot.stats() были получены их
значения. После удаления выбросов остались очищенные наборы данных.
Сгенерировать таблицу данных, в которой дублируются строки. Удалить
строки с использованием функций unique() и
duplicated(). Сравнить результаты.
dup_table <- data.frame(
col1 = c(1, 2, 3, 3, 2, 1),
col2 = c("A", "B", "C", "C", "B", "A")
)
dup_table
## col1 col2
## 1 1 A
## 2 2 B
## 3 3 C
## 4 3 C
## 5 2 B
## 6 1 A
unique_table <- unique(dup_table)
unique_table
## col1 col2
## 1 1 A
## 2 2 B
## 3 3 C
no_dup_table <- dup_table[!duplicated(dup_table), ]
no_dup_table
## col1 col2
## 1 1 A
## 2 2 B
## 3 3 C
Функция unique() сразу возвращает таблицу без
повторяющихся строк. Это простой и удобный способ быстро удалить
дубликаты.
Функция duplicated() показывает, какие строки являются
повторными. В сочетании с логическим отрицанием ! она
позволяет оставить только первые вхождения строк.
Оба способа дали одинаковый итоговый результат, но
duplicated() дает больше контроля над процессом отбора
строк.
Обработать пропуски в данных с использованием пакета
mice.
data(airquality)
imp <- mice(
airquality,
m = 2,
maxit = 10,
method = "pmm",
seed = 123,
printFlag = FALSE
)
airquality_mice <- complete(imp)
head(airquality)
## Ozone Solar.R Wind Temp Month Day
## 1 41 190 7.4 67 5 1
## 2 36 118 8.0 72 5 2
## 3 12 149 12.6 74 5 3
## 4 18 313 11.5 62 5 4
## 5 NA NA 14.3 56 5 5
## 6 28 NA 14.9 66 5 6
head(airquality_mice)
## Ozone Solar.R Wind Temp Month Day
## 1 41 190 7.4 67 5 1
## 2 36 118 8.0 72 5 2
## 3 12 149 12.6 74 5 3
## 4 18 313 11.5 62 5 4
## 5 6 273 14.3 56 5 5
## 6 28 186 14.9 66 5 6
colSums(is.na(airquality_mice))
## Ozone Solar.R Wind Temp Month Day
## 0 0 0 0 0 0
Пакет mice используется для обработки пропущенных
значений методом множественной импутации. В отличие от простой замены
пропусков средним или медианой, метод mice учитывает связь
между переменными.
В данном случае использовался метод pmm. После обработки
все пропуски в датасете были заполнены.
Преимущество подхода mice заключается в том, что он
позволяет получить более реалистичные значения, так как учитывает
структуру исходных данных.
Разобрать пример с мультиколлинеарностью.
set.seed(123)
x1 <- rnorm(100)
x2 <- x1 * 2 + rnorm(100, 0, 0.1)
y <- 3 * x1 + 2 * x2 + rnorm(100)
data_mc <- data.frame(y, x1, x2)
head(data_mc)
## y x1 x2
## 1 -1.8666005 -0.56047565 -1.1919919
## 2 -0.2474527 -0.23017749 -0.4346666
## 3 10.5964748 1.55870831 3.0927474
## 4 0.9672443 0.07050839 0.1062625
## 5 0.3003505 0.12928774 0.1634136
## 6 11.5202025 1.71506499 3.4256272
cor_matrix <- cor(data_mc)
cor_matrix
## y x1 x2
## y 1.0000000 0.9882897 0.9887106
## x1 0.9882897 1.0000000 0.9985963
## x2 0.9887106 0.9985963 1.0000000
model <- lm(y ~ x1 + x2, data = data_mc)
summary(model)
##
## Call:
## lm(formula = y ~ x1 + x2, data = data_mc)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.8730 -0.6607 -0.1245 0.6214 2.0798
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.13507 0.09614 1.405 0.163
## x1 2.39060 1.97748 1.209 0.230
## x2 2.23811 0.98995 2.261 0.026 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.9513 on 97 degrees of freedom
## Multiple R-squared: 0.9779, Adjusted R-squared: 0.9774
## F-statistic: 2144 on 2 and 97 DF, p-value: < 2.2e-16
vif(model)
## x1 x2
## 356.4434 356.4434
В примере были созданы две переменные x1 и
x2, между которыми существует очень сильная связь.
Переменная x2 была специально сформирована на основе
x1, поэтому между ними возникает мультиколлинеарность.
Корреляционная матрица показывает, что признаки x1 и
x2 сильно коррелируют друг с другом. После построения
линейной регрессии был рассчитан показатель VIF.
VIF показывает, насколько увеличивается дисперсия
коэффициента из-за мультиколлинеарности. Чем выше значение
VIF, тем сильнее проблема мультиколлинеарности.
В данном примере значения VIF получились очень высокими,
поэтому можно сделать вывод, что между признаками есть сильная
мультиколлинеарность.
Всю представленную работу собрать в единый отчет с формулировкой задания, кодом и скриншотами выполнения.
Работа была оформлена в виде единого файла RMarkdown. В отчете представлены формулировки заданий, программный код, результаты выполнения и выводы.
После выполнения команды Knit можно получить HTML-файл
отчета. Далее его можно опубликовать на RPubs.
Для публикации необходимо нажать кнопку Publish, выбрать
сервис RPubs, указать название и описание публикации, после
чего скопировать полученную ссылку.
В результате выполнения лабораторной работы были закреплены навыки предварительной подготовки данных в языке R.
Были рассмотрены следующие операции:
NA;complete.cases();mice;VIF.Лабораторная работа показала, что подготовка исходных данных является важным этапом анализа. От качества очистки данных зависит корректность дальнейших расчетов и выводов.