используя nnet и пастернак
Искусственнаянейронная сеть – это тип модели прогнозирования, основанный на сильно взаимосвязанной сети "нейронов"/сети узлов.
Нейронная сеть с прямой связью содержит последовательность слоев нейронов/узлов. Каждый узел в слое связан со всеми узлами в предыдущем слое, через которые он получает информацию, и всем узлам следующего уровня, которым он отправляет информацию. Первый уровень — это входной уровень, где информация предиктора подается/принимается в сеть.
Затем у нас есть скрытые слои, и, наконец, мы получаем выходной слой/узел. С большим количеством слоев будут более высокие вычислительные затраты и сложность.
Обучение нейронной сети с прямой связью будет включать алгоритм оптимизации, такой как градиентный спуск, и функция потерь для измерения разницы между прогнозируемым выходом и фактическим выходом. Итеративно корректируя веса и смещения нейронной сети с помощью обратного распространения, сеть учится минимизировать потери/затраты и улучшать свои прогнозы.
Нейронные сети с прямой связью применялись для решения различных задач, таких как регрессия, классификация и распознавание образов.
Что я расскажу здесь
Я буду создавать нейронные сети как с библиотекой nnet, так и с библиотекой parsnip,используя эти данные.
Мы можем немного настроить модели, а затем посмотреть на некоторые метрики прогнозирования.
Я также распечатаю лучший прогноз и проведу некоторую визуализацию прогнозов!
Давайте начнем
моя установка: RStudio 2023.03.1 и версия R 4.2.2
knitr::opts_chunk$set(echo = TRUE) library(tidyverse) library(rsample) library(yardstick) library(nnet) library(parsnip) library(recipes) library(GGally) data <- read_csv("https://raw.githubusercontent.com/NicJC/Customers/main/Customers.csv")
Мы можем просмотреть данные и использовать библиотеку GGally для печати матричного графика:
library(GGally) ggpairs(data, mapping = ggplot2::aes(color = Gender), upper = list(continuous = wrap("density", alpha = 0.5), combo = "box_no_facet"))+ggplot2::labs(title = "Customers") + theme(axis.text.x = element_text(color="steelblue", size=10, angle=90), axis.text.y = element_text( color="steelblue", size=11))
Примечание. Я добавил эти размеры фигуры в фрагмент кода, касающийся размеров графика: fig.height=12 , fig.width=13 , fig.align=’center’
Давайте переименуем столбцы набора данных, чтобы было проще работать с метками столбцов:
data <- data %>% rename(Income = 'Annual Income ($)' , SpendingScore = 'Spending Score (1-100)' , WorkExperience = 'Work Experience' , FamilySize = 'Family Size') data %>% head(n=5)
Я использую rename из tidyverse / dplyr для переименования столбцов набора данных.
Посмотрим, есть ли пропущенные значения:
library(naniar) vis_miss(data)
Библиотека (naniar) дает хороший визуальный вывод пропущенных значений.
Затем мы можем посмотреть на типы данных:
data %>% str()
Теперь я могу разделить данные на Training и Test. Примечание. Я использую библиотеку (rsample) для разделения данных.
set.seed(1794) split <- initial_split(data, prop=4/5) Train <- training(split) Test <- testing(split)
Установите начальное значение для повторяемости.
Модели
Сначала мы используем библиотеку (nnet) для создания двух нейронных сетей.
Синтаксис:
Размер относится к скрытым узлам в скрытом слое, оптимальным выбором будет количество предикторов, деленное на 2.
linout = TRUE относится к переменной отклика y и производным функциям как к линейным или нет, что даст вам linout = FALSE.
set.seed(9713) Nnet1 <- nnet(Income ~ ., data = Train, linout=TRUE, size=3)
Проверим точность прогноза (используем библиотеку(аршин)):
pred1 <- Test %>% bind_cols(pred = predict(Nnet1, newdata=Test) %>% as.numeric()) pred1 %>% metrics(truth=Income, estimate=pred)
Это не выглядит хорошо!
Тюнинг
Теперь добавим несколько дополнительных параметров:
Аргумент decay управляет частотой обновления веса в алгоритме обратного распространения. Значение по умолчанию — ноль, но лучше выбрать значение 0,1, 0,01 или даже 0,001.
maxit = 1000 относится к максимальному количеству итераций, разрешенных для схождения.
Сходимость — это важный процесс в машинном обучении, с помощью которого параметры модели приближаются к набору оптимальных значений, которые минимизируют функцию потерь, с целью найти веса и смещения, которые дают минимально возможную функцию потерь.
Функция потерь – это мера, которая количественно определяет несоответствие между прогнозируемым результатом модели обучения и фактическим результатом.
set.seed(9713) Nnet2 <- nnet(Income ~ ., data = Train, linout=TRUE, size=4,decay=0.1 , maxit=1000)
Сошлись после 860 итераций.
Проверка точности:
pred2 <- Test %>% bind_cols(pred = predict(Nnet2, newdata=Test) %>% as.numeric()) pred2 %>% metrics(truth=Income, estimate=pred)
Так-то лучше! Чем меньше процент ошибок, тем лучше.
Теперь мы можем использовать parsnip для следующей нейронной сети:
set.seed(2694) spec <- mlp(mode="regression", engine="nnet", hidden_units=4, penalty=0.01, epochs = 1000) fit1 <- spec %>% fit(Income ~ ., data=Train) fit1 %>% extract_fit_engine() %>% pluck("convergence") pred3 <- fit1 %>% augment(new_data=Test) pred3 %>% metrics(truth=Income, estimate=.pred)
extract_fit_engine() %›% pluck("convergence") должен дать вам 0, если модель сошлась. В нашем случае здесь был произведен 0.
Это третье предсказание выглядит действительно хорошо!
Давайте посмотрим, как выглядят прогнозы:
Визуализации
Сначала я хочу создать гистограмму, чтобы сравнить доход с профессией.
pred3 %>% ggplot() + geom_bar(mapping = aes( x = Income , fill = Profession)) + coord_flip() + scale_x_binned() + labs( title = "Prediction of Income by Profession" , color = "Profession")
Теперь я хочу взглянуть на некоторые графики плотности:
pred3 %>% ggplot() + geom_density(mapping = aes( x = Income , col = Gender)) + facet_wrap(~Profession , scales='free') + labs(title = "Density plot of Income by profession and gender") + theme(axis.text.x = element_text(color="black", size=10, angle=90), axis.text.y = element_text( color="black", size=11))
Что вы думаете? Имеют ли визуализации смысл в отношении доходов и профессий?
Заключение
Нам нужно постоянно пробовать различные методологии настройки, чтобы получить лучшую модель. Я также думаю, что важно визуализировать результаты и посмотреть, соответствует ли результат тому, что мы ожидали, и имеют ли результаты смысл.
Надеюсь, статья вам понравилась и оказалась полезной.
Подписывайтесь на меня, чтобы не пропустить другие статьи о R, Julia, Python и прикладной статистике!
Если вы хотите зарегистрироваться на Medium, вы можете использовать мою реферальную ссылку, чтобы поддержать меня. Спасибо.
Если вас интересует классификация с помощью нейронных сетей, ознакомьтесь с моей статьей ниже: