You are on page 1of 12

Міністерство освіти і науки України

Донецький національний університет імені Василя Стуса


Факультет інформаційних і прикладних технологій

Кафедра інформаційних
технологій

ЗВІТ

з лабораторної роботи №2
дисципліни «Статистичне навчання»

Виконала: студентка гр. КН-20-А


Богатир А.В.

Перевірив асистент: Хмелівський Ю.С.

Вінниця – 2023
Завдання 6
Будемо використовувати набір даних Wage.
a) Побудуйте поліноміальну регресійну модель для передбачення wage по age. Виконайте
перехресну перевірку для вибору оптимального ступеня полінома d. Побудуйте графік
отриманої поліноміальної моделі.
Завантажмо необхідні бібліотеки та данні:
> library("ISLR")
> data("Wage")
Встановимо параметри графіка:
> par(mfrow=c(1,2), pch=20)
Побудуємо поліноміальну модель:
> library(boot)
> set.seed(1)
> cv.error <- rep(0, 10)
> for (d in 1:10) {
lm.fit <- glm(wage ~ poly(age, d), data = Wage)
cv.error[d] <- cv.glm(Wage, lm.fit, K=10)$delta[1]
}
> plot(1:10, cv.error, type="b")
> best.d <- which.min(cv.error)
> best.d
Результат:
Побудуємо графік отриманої моделі:
> lm.fit <- glm(wage ~ poly(age, best.d), data = Wage)
> summary(lm.fit)
> age.grid <- seq(from=min(Wage$age), to=max(Wage$age))
> pred <- predict(lm.fit, list(age=age.grid))
> plot(Wage$age, Wage$wage, col="darkgray")
> lines(age.grid, pred, col="red", lwd=2)
Результат:
b) Підгоніть ступінчасту функцію для передбачення wage на основі age і виконайте
перехресну перевірку, щоб знайти оптимальну кількість інтервалів для розбивки
даних. Побудуйте графік отриманої поліноміальної моделі.
Завантажуємо дані:
> data(Wage)
Підгонка ступінчастої функції:
> Wage$age_cut <- cut(Wage$age, breaks = c(20, 30, 40, 50, 60, 70))
> fit_step <- lm(wage ~ age_cut, data = Wage)
Перехресна перевірка для визначення оптимальної кількості інтервалів:
> library(boot)
> set.seed(1)
> cv_fit_step <- cv.glm(Wage, fit_step, K = 10)
> best_lambda <- cv_fit_step$lambda.min
Побудова графіка отриманої моделі:
> library(ggplot2)
> Wage$age_pred <- predict(fit_step, newdata = list(age_cut =
cut(Wage$age, breaks = c(20, 30, 40, 50, 60, 70))))
> Wage$age_pred_poly <- predict(fit_step, newdata = list(age_cut =
cut(Wage$age, breaks = c(20, 30, 40, 50, 60, 70))), type = "response",
lambda = best_lambda)
> ggplot(Wage, aes(x = age, y = wage)) +
geom_point(alpha = 0.5) +
geom_line(aes(x = age, y = age_pred_poly), color = "red") +
labs(x = "Age", y = "Wage") +
theme_minimal()
Результат:

Завдання 7
Вкористайте набір даних Wage та застосуте нелінійні статичні методи для підгонки
моделей за даними maritl, jobclass та wage. Також побудуйте їх графіки.
Поліноміальна регресія:
> data(Wage)
> fit_poly <- lm(wage ~ poly(maritl, 2), data = Wage)
> library(ggplot2)
> ggplot(data = Wage, aes(x = maritl, y = wage)) + geom_point() +
geom_smooth(method = "lm", formula = y ~ poly(x, 2), se = FALSE,
labs(x = "Marital Status", y = "Wage", title = "Polynomial Regression
Model")
Результат:

Поліноміальна регресія:
> data(Wage)
> fit_poly <- lm(wage ~ poly(jobclass, 1), data = Wage)
> library(ggplot2)
> ggplot(data = Wage, aes(x = jobclass, y = wage)) + geom_point() +
geom_smooth(method = "lm", formula = y ~ poly(x, 2), se = FALSE) +
scale_color_discrete(name = "Job Class") +
labs(x = "Job Class", y = "Wage", title = "Polynomial Regression Model")
Результат:
Завдання 9
Будем використовувати змінні dis і nox з набору данних Boston. Dis як предиктор, а nox -
як відгук.
a) Скористайтеся функцією poly() для припасування кубічної по-ліноміальної регресії
для передбачення nox по dis. І ще побудуй графіки вхідних даних та моделі.
> data(Boston)
> model <- lm(nox ~ poly(dis, 3), data = Boston)
> summary(model)
> library(ggplot2)
> ggplot(data = Boston, aes(x = dis, y = nox)) + geom_point() + stat_smooth(method = "lm", formula = y ~
poly(x, 3), se = FALSE, color = "red")
Результат:
b) Зобразіть поліноміальні моделі кількох різних ступенів (наприклад, від 1 до 10) і
розрахуйте відповідні значення сум квадратів залишків.
> data(Boston)
> rss <- c()
> max_deg <- 10
> for (deg in 1:max_deg) {
model <- lm(nox ~ poly(dis, deg), data = Boston)
rss[deg] <- sum(model$residuals^2)
if (deg %in% c(1, 5, 10)) {
dis_range <- range(Boston$dis)
dis_seq <- seq(dis_range[1], dis_range[2], length = 100)
nox_pred <- predict(model, newdata = data.frame(dis = dis_seq))
plot(Boston$dis, Boston$nox, pch = 20, col = "gray", xlab = "dis",
ylab = "nox")
lines(dis_seq, nox_pred, col = "red")
title(paste("Degree", deg, "Polynomial"))
}
}
> plot(1:max_deg, rss, type = "b", xlab = "Degree of Polynomial", ylab =
"RSS")
Результат:
c) Застосуйте перехресну перевірку або будь-який інший метод для вибору оптимального
ступеня полінома.
> library(boot)
> k <- 10
> cv_errors <- rep(NA, max_deg)
> for (deg in 1:max_deg) {
glm_fit <- glm(nox ~ poly(dis, deg), data = Boston)
cv_error <- cv.glm(Boston, glm_fit, K = k)$delta[1]
cv_errors[deg] <- cv_error
}
> plot(1:max_deg, cv_errors, type = "b", xlab = "Degree of Polynomial",
ylab = "Cross-Validation Error")
> opt_deg <- which.min(cv_errors)
> cat("Optimal degree of polynomial:", opt_deg)
Результат:

d) Застосуйте функцію bs() для припасування регресійного сплайну, що передбачає nox


по dis. І також зобразіть модель на графіку.
> library(splines)
> bs_fit <- lm(nox ~ bs(dis, knots = c(30, 60, 90)), data = Boston)
> plot(Boston$dis, Boston$nox, col = "gray")
> lines(sort(Boston$dis), predict(bs_fit, data.frame(dis =
sort(Boston$dis))), col = "red", lwd = 2)
Результат:

e) Тепер налаштуйте регресійний сплайн для кількох значень числа ступенів свободи, а
потім зобразіть побудовані моделі на графіку та повідомте відповідні значення RSS.
Створення порожніх векторів для збереження значень RSS та моделей:
> rss_values <- c()
> bs_models <- list()
Підганяння регресійного сплайну з різними числами ступенів свободи:
> for (i in 1:8) {
bs_models[[i]] <- lm(nox ~ bs(dis, df = i), data = Boston)
rss_values[i] <- sum(bs_models[[i]]$residuals^2)
}
Побудова графіка регресійних сплайнів:
> plot(dis, nox, col = "gray")
> for (i in 1:8) {
lines(sort(dis), predict(bs_models[[i]], data.frame(dis = sort(dis))),
col = i, lwd = 2)
}
Результат:

Завдання 10
Будем використовувати дані College
a) Розбийте дані на навчальну та перевірочну вибірки. Використовуючи розмір оплати за
навчання для студентів з інших штатів як залежна змінна, а всі інші змінні як
предиктори, виконайте відбір з покроковим включенням змінних на навчальних даних
і знайдіть задовільну модель, в яку входять тільки деякі з наявних предикторів.
> library(caret)
> data(College)
> set.seed(123)
> trainIndex <- createDataPartition(College$Outstate, p = 0.7, list = FALSE,
times = 1)
> trainData <- College[trainIndex,]
> testData <- College[-trainIndex,]
> modelFit <- train(Outstate ~ ., data = trainData, method = "leapSeq",
tuneLength = 10, trace = FALSE, preProc = c("center", "scale"))
> summary(modelFit$finalModel)
Результат:

> model <- lm(Outstate ~ Private + Room.Board + Expend + Grad.Rate, data =


trainData)
> predictions <- predict(model, testData)
> mse <- mean((predictions - testData$Outstate)^2)
> mse
b) Побудуйте GAM за навчальними даними, використовуючи розмір оплати за навчання
для студентів з інших штатів як залежна змінна, а змінні, вибрані на попередньому
кроку, як предиктори. Зобразіть результати графічно та поясніть їх.
> library(mgcv)
> gam_formula <- as.formula(paste("Outstate ~ s(Room.Board) + s(Expend) +
s(Grad.Rate) + Private"))
> gam_model <- gam(gam_formula, data = trainData)
> plot(gam_model, pages = 1)
Результат:

c) Оцініть отриману модель на перевірочній вибірці та поясніть свої результати.


Для оцінки отриманої моделі на перевірочній вибірці ми можемо використовувати
функцію predict() та порівняти передбачені значення з фактичними значеннями тестового
набору даних.
> pred <- predict(gam_model, newdata = testData)
> rmse <- sqrt(mean((testData$Outstate - pred)^2))
> rmse
Результат:

Висновки:
Результат оцінки моделі на перевірочній вибірці показує середньоквадратичну помилку
(RMSE) у розмірі приблизно 1944. Це означає, що середня помилка нашої моделі у
прогнозуванні розміру оплати за навчання для студентів з інших штатів становить
приблизно $1944. Це може бути прийнятним результатом, особливо з огляду на
складність залежностей між змінними, які ми досліджували за допомогою GAM.

You might also like