Crack Data Science Интервью

Статистическое моделирование в R с кодом - Часть 1

Интервью Ace Data Science

Это первая часть двойного сообщения о статистическом моделировании. Если у вас нет, ознакомьтесь со второй частью:



Статистическое моделирование в Python, часть 2
Самая важная часть любого собеседования по науке о данных! todatascience.com



Вступление

За последние несколько месяцев я получил несколько собеседований по Data Science от ведущих технологических компаний. Почти все интервьюеры просили меня провести статистическое моделирование реального бизнес-сценария, на что я не произвел впечатления.

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

До сегодняшнего дня я потратил сотни часов на изучение симуляторов и подготовку к следующим техническим собеседованиям.

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

Определение

В реальном мире все происходит случайно, и существует бесконечное количество возможностей. Мы можем наблюдать только часть, но не все возможности.

Моделирование очень удобно и предлагает быстрый обзор распределения возможностей, соответствующих реальным результатам. Изучая смоделированные результаты, мы получаем представление о реальном мире.

Генерация случайных чисел

Давайте начнем с самого простого кода и перейдем к более сложным сценариям.

Команда runif (x, min = a, max = b) генерирует x значений в диапазоне от a до b.

library(dplyr)
set.seed(2)
runif(25,min=0,max=10)

Функция set.seed () устанавливает начальное число для генератора случайных чисел R, чтобы мы получали одинаковые значения при каждом запуске кода. В противном случае мы получим другие результаты. Попробуйте сами.

Чтобы получить целые числа, мы используем функцию round следующим образом:

runif(25,min=0,max=10) %>% 
  round(.,digits = 0)

Здесь канал % ›% происходит из пакета magrittr и позволяет писать более чистые и легко понятные код. На простой английский это слово можно перевести как «then».

На английском языке две приведенные выше строки кода означают:

  1. генерировать 25 чисел в диапазоне от 0 до 10
  2. затем (% ›%), округлите число до ближайшего целого.

Попробуйте, что произойдет, если вы настроите цифры = 1.

Другой способ создания случайного числа - с помощью функции sample:

> sample(x, size, replace=TRUE, prob=NULL)
  • x: вектор или положительное целое число
  • размер: неотрицательное целое число, дающее количество элементов на выбор
  • replace: образец с заменой или нет?
  • проблема: вектор вероятностных весов для получения элементов выбираемого вектора

(Пожалуйста, обратитесь к документации R для получения дополнительной информации, ссылка)

Быстрый пример.

set.seed(24)
sample(seq(1,10),8)

Функция set.seed () делает результат воспроизводимым.

Приведенный выше код генерирует случайную выборку из 8 чисел из последовательности [1,10]. Как видите, мы не устанавливаем правила замены и вероятности выбора.

По умолчанию R устанавливает для замены значение FALSE и принимает равные вероятности выбора.

x = 1:10
sample(x,replace=TRUE)

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

Помимо чисел, мы можем выбирать слова следующим образом:

set.seed(1)
sample(letters,18)

Равная и неравная вероятность выбора

# Сценарий 1: равная вероятность

Мы генерируем случайную выборку размером 10 из последовательности [1,5] с равными вероятностями.

equal_prob_dist = sample(5,10000,prob=rep(0.1,5),replace=T)
hist(equal_prob_dist)

Если мы установим prob = rep (0.1,5), то числа от 1 до 5 будут одинаковыми, как показано на гистограмме выше.

# Сценарий 2 Неравная вероятность

Как выглядит распределение, если вероятности выбора не равны (например, загруженная игральная кость)?

Мы генерируем случайную выборку размером 10 из последовательности [1,5] с неравными вероятностями.

unequal_prob_dist = sample(5,10000,prob =c(0.1,0.25,0.4,0.25,0.1), replace=T)
hist(unequal_prob_dist)

Мы устанавливаем следующие правила вероятности выбора для последовательности:

1 & 5: 0.1
2 & 4: 0.25 
3: 0.4

Оказывается, номер 3 выбирается чаще всего, а номер 1 и 5 выбирают меньше всего.

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

Примеры наблюдений из фрейма данных

Для выборки наблюдений (строк) из фрейма данных или списка мы выбираем не строки напрямую, а индексы в объект.

head(mtcars)

# step 1: create an index vector for the elements/rows 
index <- seq_len(nrow(mtcars))
 
# step 2: sample the index vector
set.seed(12)
#to obtain a random sample of 10
sample_index <- sample(index,10)
# step 3: to show the sampled elements/rows 
mtcars[sample_index,]

Приложения

В этом разделе давайте немного попрактикуемся и решим реальные бизнес-сценарии.

Вопрос 1: Есть два шестигранных кубика. Если вы бросите их вместе, какова вероятность выпадения 7?

set.seed(1)
die = 1:6
# sample 10000 times with replacements for dice 1
die1 = sample(die,10000,replace = TRUE,prob=NULL)
# sample 10000 times with replacements for dice 2
die2= sample(die,10000,replace=TRUE,prob = NULL)
# the combined value of die_1 and die_2 
outcomes = die1+die2
# the probability of getting a 7
mean(outcomes == 7)

Точно так же мы можем использовать цикл for для той же цели.

set.seed(1)
for (i in 10000){
 die_1 = sample(die,prob=NULL,replace=TRUE)
 die_2 = sample(die,prob=NULL,replace=TRUE)
 die_sum = die_1+die_2
 print(mean(die_sum==7))
}

Эти два результата почти одинаковы.

Вопрос 2: у вас есть два кубика. Какова вероятность выпадения 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 и 13?

Вместо моделирования каждого результата есть более простой способ получить то, что нам нужно, с помощью sapply.

sapply(2:13,function(x) mean(outcomes==x))

Согласно документации R, функция sapply () является «удобной для пользователя версией и оболочкой lapply, по умолчанию возвращающей вектор, матрицу или, если simplify = "array", массив, если необходимо, путем применения simplify2array(). sapply(x, f, simplify = FALSE, USE.NAMES = FALSE) то же самое, что и lapply(x, f) ».

Вкратце, функция применяет функцию mean (results) к последовательности [2,13].

Вопрос к вам: какова вероятность выпадения 7, если у вас 3 кубика?

Вопрос 3. Создайте случайную выборку из 10000 значений, и сколько уникальных наблюдений будет включено? Сколько не включено?

set.seed(1)
n=10000
included_obs = length(unique(sample(1:n, replace = TRUE)))
included_obs
missing_obs = n-included_obs
missing_obs

После выборки мы используем unique () для нахождения отличительных наблюдений и length () для подсчета. В выборке из 10 тыс. Выбираются 6316 уникальных случаев, а из 3684 (10 тыс. - 6316) - нет.

В качестве дальнейшего примечания, причина, по которой мы получаем только 6316 из 10k, заключается в том, что мы производим выборку с заменами, и поэтому некоторые числа выбираются повторно. Другими словами, некоторые числа отбираются несколько раз.

Вопрос 4. Создайте матрицу размера m * n со случайными значениями 0 и 1.

(кредиты дискуссиям на R-bloggers, здесь)

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

Во-первых, мы можем использовать цикл for.

m <- 10
n <- 10
# create an empty matrix
m00 <- matrix(0,m,n)
for (i in 1:m) {
   for (j in 1:n) {
     m00[i,j] <- sample(c(0,1),1)
 }
}
m00

Здесь matrix (0, m, n) создает пустую матрицу размером m * n, а два цикла for определяют значения каждой ячейки.

В большинстве случаев цикл for в R может быть не самым эффективным решением, и мы будем использовать другие варианты, если размер выборки достаточно велик.

Имея это в виду, авторы используют второй метод, используя функцию apply ().

m <-10
n<-10
m0 <- matrix(0,m,n)
apply(m0,c(1,2),function(x) sample(c(0,1),1))

Пока все должно быть хорошо знакомо, кроме функции apply (). Он возвращает вектор / массив / список значений, полученных путем применения функции к полям массива или матрицы (исходное определение, ссылка).

Он имеет следующий вид:

> apply(x, margin, fun,…) 
  • x: массив или матрица
  • margin: вектор, дающий индексы, в которых будет применяться функция. Для матрицы 1 обозначает строки, а 2 обозначает столбцы. c (1,2) указывает строки и столбцы, где x имеет именованные dimnames, это может быть вектор символов, выбирающий имена измерений
  • веселье: функция, которую нужно применить

Вопрос 5: Подбросьте монетку 10 раз и смоделируйте процесс 10 000 раз. Покажите распределение количества появившихся голов.

# create an empty list 
total_heads = c()
# use a for loop to simulate coin-flipping 10 times 
# repeat it for 10,000 times
for (i in 1:10000){
 sum_heads = sum(round(runif(10,0,1)))
 total_heads = c(total_heads, sum_heads)
 }
hist(total_heads)

Здесь я объясню три строчки кода, а остальные не требуют пояснений.

  1. для (1 из 1: 1000). В отличие от других языков программирования, вы должны указать диапазон как 1: 10000.
  2. сумма (round (runif (10,0,1))). Это структурированный способ кодирования, который имеет три отдельные функции: runif () → round () → sum (). Сначала он запускает функцию runif (), а в последнюю - sum (). По сути, строки кода генерируют 10 случайных чисел от 0 до 1, округляют их до ближайшего целого числа (0 или 1) и, наконец, суммируют.
  3. total_heads = c (total_heads, sum_heads). Поскольку вначале total_heads является пустым списком, мы используем строку кода для присвоения значения sum_heads total_heads.

Спасибо за чтение!

Это вводная статья о статистическом моделировании, и мы рассмотрим более сложные темы в следующих публикациях.

Будьте на связи!

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



Нравится читать это?

Найдите меня в LinkedIn и Twitter.

Также ознакомьтесь с другими моими сообщениями об искусственном интеллекте и машинном обучении.