Наука о данных для стартапов: прогнозное моделирование

Шестая часть моей текущей серии о создании дисциплины data science в стартапе. Вы можете найти ссылки на все публикации во Введении и книгу, основанную на этой серии, на Amazon.

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

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

Типы прогнозных моделей

Модели машинного обучения обычно делятся на две категории: обучение с учителем и обучение без учителя. Для контролируемых проблем данные, используемые для соответствия модели, имеют определенные метки или целевые переменные. Например, если цель состоит в том, чтобы определить, какие пользователи в мобильной игре могут стать покупателями, мы можем использовать данные транзакций от прошлых пользователей в качестве меток, где 1 означает платного пользователя, а 0 означает бесплатного пользователя. Метка используется в качестве входных данных для контролируемого алгоритма, чтобы обеспечить обратную связь при подборе модели к набору обучающих данных. Алгоритмы классификации и регрессии - это два типа обучения с учителем. В задаче классификации цель состоит в том, чтобы предсказать вероятность результата, например, совершит ли пользователь мобильной игры покупку. Для регрессии цель состоит в том, чтобы предсказать непрерывную переменную, такую ​​как цена дома, с учетом описания различных характеристик.

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

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

Для стартапа вы, вероятно, начнете с моделей классификации и регрессии, которые часто называют классическими или поверхностными проблемами машинного обучения. Можно использовать множество различных подходов. Некоторые общие подходы к классификации - это логистическая регрессия, наивный байес, деревья решений и методы ансамбля, такие как случайные леса и XGBoost. Общие подходы к регрессии включают многие из тех же подходов, что и классификация, но вместо логистической регрессии используется линейная регрессия. Машины опорных векторов были популярны еще десять лет назад, когда я учился в аспирантуре, но теперь XGBoost кажется королем поверхностных задач обучения.

Важно знать, как реализуются различные алгоритмы, потому что, если вы хотите поставлять прогнозную модель как часть продукта, она должна быть надежной и масштабируемой. Как правило, при отгрузке товаров предпочтение отдается моделям с нетерпением, а не с ленивыми моделями. Активные модели - это подходы, которые генерируют набор правил как часть процесса обучения, например коэффициенты в модели линейной регрессии, в то время как ленивая модель генерирует набор правил во время выполнения. Например, модель ближайшего соседа (k-NN) - это ленивый подход. Ленивые методы часто полезны для создания систем онлайн-обучения, где модель часто обновляется новыми данными во время развертывания, но могут иметь проблемы с масштабируемостью.

Как оценивается эффективность прогнозной модели, зависит от типа решаемой задачи. Например, такие показатели, как средняя абсолютная ошибка (MAE), среднеквадратическая ошибка (RMSE) и коэффициенты корреляции, полезны для оценки регрессионных моделей, в то время как ROC-площадь под кривой (AUC), точность, отзыв и рост полезны. для задач классификации.

Обучение классификационной модели

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

Для начала нам нужно получить набор данных локально, который мы можем использовать в качестве входных данных для различных инструментов. В приведенном ниже коде R показано, как выбрать 100 тыс. Беременностей и сохранить фрейм данных в CSV. Этот запрос похож на запрос из прошлого сообщения, но я включил дополнительные ограничения в предложение where, чтобы избежать извлечения записей с отсутствующими (NA) значениями.

library(bigrquery)
project <- "your_project_id"
options(stringsAsFactors = FALSE)
sql <- "SELECT year, mother_age, father_age, gestation_weeks
 ,case when ever_born > 0 then ever_born else 0 end as ever_born
 ,case when mother_married then 1 else 0 end as mother_married
 ,weight_pounds
 ,case when plurality = 2 then 1 else 0 end as label
FROM `bigquery-public-data.samples.natality`
where plurality in (1, 2) and gestation_weeks between 1 and 90
  and weight_pounds between 1 and 20
order by rand() 
LIMIT 100000"
df <- query_exec(sql, project = project, use_legacy_sql = FALSE)
write.csv(df, "natality.csv", row.names = FALSE)

Одна из проблем с этим набором данных заключается в том, что в этом наборе данных гораздо больше отрицательных примеров, чем положительных. Только 2,4% беременностей в выборке данных имеют метку «1», что указывает на близнецов. Это означает, что нам нужно будет использовать другие показатели, помимо точности, чтобы оценить эффективность различных подходов. Точность не является хорошей метрикой для проблем с большим дисбалансом классов, таких как эта, потому что прогнозирование метки 0 для каждой записи приводит к точности 97,6%. Вместо этого мы будем использовать метрику кривой AUC для оценки различных моделей, поскольку она полезна для решения проблем с несбалансированными классами.

Еще одно соображение при оценке разных моделей - использование разных наборов данных для обучения, тестирования и удержания. Набор данных удержания удерживается до конца процесса обучения модели и используется только один раз для оценки. Наборы данных для обучения и тестирования можно использовать сколь угодно часто при построении и настройке модели. Такие методы, как 10-кратная перекрестная проверка, полезны для построения надежных оценок производительности модели. Обычно я использую этот подход при построении моделей, но для краткости он не рассматривается во всех приведенных ниже примерах.

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

На приведенной выше диаграмме показаны визуализации различных функций в наборе данных. Красные точки данных представляют собой положительные примеры (близнецы), а синие точки данных представляют отрицательные примеры (одиночки). Для объектов с сильным сигналом часто можно провести вертикальную линию, разделяющую большинство красных и синих точек данных. С этим набором данных дело обстоит иначе, и нам нужно будет объединить различные функции, чтобы создать хороший классификатор.

Я использовал Weka для изучения следующих алгоритмов и вычисления показателей AUC при 10-кратной перекрестной проверке:

  • Логистика: 0,892
  • Наивный Байес: 0,893
  • LogitBoost: 0,908

Самым эффективным алгоритмом из тех, что я исследовал, был LogitBoost. Этот алгоритм имеет ряд гиперпараметров, таких как количество итераций, которые можно настроить для дальнейшего повышения производительности модели. В Weka могут быть и другие алгоритмы, которые еще лучше работают с этим набором данных, но наше первоначальное исследование привело к многообещающим результатам.

Визуализация кривой ROC для модели логистической регрессии показана на рисунке выше. С помощью Weka также можно изучить важность различных функций в модели логистической регрессии. Вы можете напрямую проверить коэффициенты модели. Например, weight_pounds имеет наивысшее значение коэффициента 0,93. Также можно использовать средство ранжирования атрибутов InfoGain, чтобы определить, какие функции наиболее важны для этой задачи классификации. Weka обнаружила, что наиболее влиятельной характеристикой был weight_pounds (0,0415), за которым следовали gestation_weeks (0,0243).

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

BigML
Еще один инструмент, который я использовал в своем стартапе, - это BigML. Этот инструмент похож на Weka в том, что он предоставляет графический интерфейс (веб-интерфейс) для изучения различных типов моделей без необходимости кодирования. У инструмента меньше опций, чем у Weka, но есть более свежие модели, такие как DeepNets.

На изображении выше показан один из инструментов важности функций, предоставляемых BigML. Эти инструменты полезны для понимания того, какие функции полезны для прогнозирования результата. Я исследовал две разные модели с помощью BigML, в результате чего были получены следующие показатели AUC:

  • Логистика: 0,890
  • DeepNet: 0,902

Вместо 10-кратной перекрестной проверки я использовал одно разделение данных 80/20 для оценки различных моделей. Производительность моделей в BigML была аналогична Weka, но не совсем соответствовала производительности LogitBoost.

Помимо построения кривых ROC, как показано выше, BigML может строить другие полезные визуализации, такие как графики подъема. BigML также предоставляет полезные показатели классификации, такие как точность, отзыв и оценка F1.

R - Glmnet
Мы можем реализовать модель логистической регрессии, которую мы уже оценили, используя библиотеку glm в R. Функцию обобщенных линейных моделей можно применить к логистической регрессии, указав биномиальное семейство. как вход. Код R, который загружает CSV и обучает модель логистической регрессии, показан ниже.

df <- read.csv("Natality.csv")
fit <- glm(label ~ .,family=binomial(),data=df)
fit
library(Deducer)
rocplot(fit)

После подбора модели оператор fit выводит коэффициенты модели. Чтобы оценить производительность модели, я использовал библиотеку Deducer, которая включает функцию rocplot. Для этого базового подхода к подгонке модели я не выполнял перекрестной проверки. Результатом было значение AUC 0,890 для набора обучающих данных.

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

library(glmnet)
x <- sparse.model.matrix(label ~ ., data = df)
y <- as.factor(df$label)
fit = glmnet(x, y, family = "binomial")
plot(fit, xvar = "dev", label = TRUE)

По умолчанию для подбора обучающих данных используется модель «наименьших квадратов». На диаграмме ниже показано, как коэффициенты модели меняются по мере использования дополнительных факторов в качестве входных данных для модели. Первоначально в качестве входных данных используются только функции weight_pounds. Как только этот член начинает подвергаться штрафам, около значения -0,6, для модели рассматриваются дополнительные функции.

cvfit = cv.glmnet(x, y, family = "binomial", type.measure = "auc")
cat(paste("ROC:", max(cvfit$cvlo)))
plot(cvfit)

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

Python - scikit-learn
Еще один инструмент, о котором я хотел рассказать в этом разделе, - это scikit-learn, потому что он предоставляет стандартизированный способ исследования точности различных типов моделей. До сих пор я был сосредоточен на R для подгонки моделей и EDA, но инструменты Python, доступные через scikit-learn, довольно полезны.

# load the data set
import pandas as pd
df = pd.read_csv('./Natality.csv')
# build a random forest classifier 
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier()
x = df.drop('label', axis=1)
y = df['label']
rf.fit(x, y)
# evaluate the results 
from sklearn.metrics import roc_curve, auc
false_positive_rate, true_positive_rate, _ = roc_curve(y, rf.predict(x))
roc_auc = auc(false_positive_rate, true_positive_rate)
# plot the curve
import matplotlib.pyplot as plt
plt.plot(false_positive_rate, true_positive_rate, 
    'b', label='AUC = %0.2f'% roc_auc)
plt.legend(loc='lower right')
plt.show()

Приведенный выше код Python показывает, как читать во фрейме данных с помощью pandas, подбирать случайную модель леса с помощью sklearn, оценивать производительность модели и строить результаты, как показано на рисунке ниже. Для этой модели я не применял перекрестную проверку при оценке модели. Одним из преимуществ использования scikit-learn является то, что функции соответствия и оценки согласованы для разных алгоритмов, что упрощает изучение различных вариантов.

Кластеризация

Один из видов анализа, который полезен для стартапов, - это понимание того, существуют ли разные сегменты или группы пользователей. Общий подход к этому типу работы состоит в том, чтобы сначала идентифицировать кластеры в данных, назначать метки этим кластерам, а затем назначать метки новым записям на основе помеченных кластеров. В этом разделе показано, как выполнить этот тип процесса, используя данные из Обзора потребительских финансов Федеральной резервной системы за 2016 год.

Набор данных обследования обеспечивает разбивку активов для тысяч домашних хозяйств в США. Цель этого упражнения по кластеризации - определить, существуют ли разные типы состоятельных домохозяйств с чистой стоимостью более 1 миллиона долларов США. Полный код для загрузки данных и выполнения анализа представлен в этом Блокноте Jupyter. Предыдущий анализ с этим набором данных представлен в этом сообщении в блоге.

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

# filter on affluent households, and print the total number
affluent <- households[households$netWorth >= 1000000, ]
cat(paste("Affluent Households: ", floor(sum(affluent$weight))))
# plot a Factor Map of assets 
fviz_pca_var(PCA(affluent,  graph = FALSE), col.var="contrib",    
  gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"), repel = TRUE)+
  labs(title ="Affluent Households - Assets Factor Map")

Результаты, представленные ниже, показывают, что существует несколько различных групп активов, которые различаются в зависимости от состоятельных домохозяйств. Самый важный фактор - это справедливость бизнеса. Некоторые другие группы факторов включают инвестиционные активы (АКЦИИ, ОБЛИГАЦИИ) и активы в сфере недвижимости / пенсионные фонды.

Сколько кластеров использовать?
Теперь мы видим признаки того, что существуют разные типы миллионеров и что активы различаются в зависимости от сегмента чистой стоимости. Чтобы понять, как распределение активов различается по сегментам чистой стоимости, мы можем использовать кластерный анализ. Сначала мы идентифицируем кластеры среди богатых респондентов опроса, а затем применяем эти ярлыки ко всей совокупности респондентов опроса.

k <- 7
res.hc <- eclust(households[sample(nrow(households), 1000), ],
  "hclust", k = k, graph = FALSE) 
fviz_dend(res.hc, rect = TRUE, show_labels = FALSE)

Чтобы определить, сколько кластеров использовать, я создал дендрограмму кластера, используя приведенный выше фрагмент кода. Результатом является рисунок, показанный ниже. Я также варьировал количество кластеров k, пока не получилось наибольшее количество четко идентифицируемых кластеров.

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

clarax <- clara(affluent, k)
fviz_cluster(clarax, stand = FALSE, geom = "point", ellipse = F)

Чтобы сгруппировать зажиточные домохозяйства в уникальные группы, я использовал алгоритм CLARA. Визуализация различных кластеров показана ниже. Результаты аналогичны PCA и подходу с факторной картой, описанному выше.

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

groups <- clarax$clustering
results <- as.data.frame(t(aggregate(affluent,list(groups),mean)))  
results[2:18,]

Результаты этого блока кода показаны ниже. На основе этих результатов мы придумали следующие описания кластеров:

  • V1: Акции / Облигации - 31% активов, за которыми следуют домашние и паевые инвестиционные фонды.
  • V2: Диверсифицированный - 53% бизнес, 10% дом и 9% другая недвижимость
  • V3: Жилая недвижимость - 48% активов
  • V4: Паевые инвестиционные фонды - 50% активов
  • V5: Выход на пенсию - 48% активов
  • V6: Собственный капитал - 85% активов
  • V7: Коммерческая недвижимость - 59% активов

За исключением кластера V7, содержащего только 3% населения, большинство кластеров относительно одинаковы по размеру. Второй по величине кластер представляет 12% населения, а самый большой кластер представляет 20%. Вы можете использовать таблицу (группы), чтобы показать невзвешенные размеры совокупности кластеров.

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

# assign all of the households to a cluster 
groups <- knn(train = affluent, test = households, 
  cl = clarax$clustering, k = k, prob = T, use.all = T)
# figure out how many households are in each cluster 
clusters <- data.frame(
  c1 = ifelse(groups == 1, weights, 0), 
  ... 
  c7 = ifelse(groups == 7, weights, 0) 
)
# assign each household to a net worth cluster 
nw <- floor(2*log10(nwHouseholds))/2
results <- as.data.frame(t(aggregate(clusters,list(nw),sum)))
# compute the number of households that belong to each segment
results$V1 <- results$V1/sum(ifelse(nw == 4, weights, 0))
...
results$V11 <- results$V11/sum(ifelse(nw == 9, weights, 0))
# plot the results 
plot <- plot_ly(results, x = ~10^Group.1, y = ~100*c1, type = 'scatter', mode = 'lines', name = "Stocks") %>%
  add_trace(y = ~100*c2, name = "Diversified") %>%
  ...
  add_trace(y = ~100*c7, name = "Commercial R.E.") %>%
  layout(yaxis = list(title = '% of Households', ticksuffix = "%"),
     xaxis = list(title = "Net Worth ($)", type = "log"), 
     title  = "Cluster Populations by Net Worth")

Результаты этого процесса показаны на рисунке ниже. На диаграмме показаны некоторые очевидные и некоторые новаторские результаты: фонды домовладения и пенсионные фонды составляют большую часть активов небогатых домохозяйств, существует относительно равномерное сочетание кластеров около 2 млн долларов (без учета коммерческой недвижимости и акционерного капитала) и бизнеса. У сверхбогатых домашних хозяйств капитал преобладает над чистым капиталом, за ним следуют другие инвестиционные активы.

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

Заключение

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

В этом посте я показала четыре различных подхода к построению классификационных моделей для прогнозирования близнецов во время беременности. Я показал, как инструменты Weka и BigML на основе графического интерфейса можно использовать для оценки моделей логистической регрессии, ансамблевых моделей и глубоких сетей. Я также написал примеры сценариев для выполнения логистической регрессии с регуляризацией в R и случайных лесов в Python. Я завершил пост примером кластеризации, которая может быть полезна для выполнения задач сегментации для стартапа.

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