Мои личные заметки из класса машинного обучения. Эти примечания будут и дальше обновляться и улучшаться по мере того, как я продолжаю просматривать курс, чтобы по-настоящему понять его. Большое спасибо Джереми и Рэйчел, которые дали мне возможность учиться.

Уроки: 1234567891011 12

Видео / Блокнот

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

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

for df in (joined,joined_test):
    df["CompetitionMonthsOpen"] = df["CompetitionDaysOpen"]//30
    df.loc[df.CompetitionMonthsOpen>24, "CompetitionMonthsOpen"]= 24
joined.CompetitionMonthsOpen.unique()
array([24,  3, 19,  9,  0, 16, 17,  7, 15, 22, 11, 13,  2, 23, 12,  4, 10,  1, 14, 20,  8, 18,  6, 21,  5])

Давай продолжим работать над этим. Потому что то, что происходит в этой записной книжке, вероятно, будет применяться к большинству наборов данных временных рядов, с которыми вы работаете. Как мы уже говорили, хотя здесь мы использовали df.apply, это то, где он запускает фрагмент кода Python над каждой строкой, и это ужасно медленно. Таким образом, мы делаем это только в том случае, если не можем найти векторную функцию pandas или numpy, которая может сделать это сразу для всего столбца. Но в данном случае я не смог найти способ преобразовать год и номер недели в дату без использования произвольного Python.

Также стоит помнить об этой идее лямбда-функции. Каждый раз, когда вы пытаетесь применить функцию к каждой строке чего-либо или к каждому элементу тензора, если векторизованной версии еще нет, вам придется вызывать что-то вроде DataFrame.apply, которое будет запускать функцию, которую вы передаете каждому элемент. По сути, это карта в функциональном программировании, поскольку очень часто функцию, которую вы хотите передать ей, вы просто используете один раз, а затем выбросите. Этот лямбда-подход очень распространен. Итак, эта лямбда создает функцию только для того, чтобы указать df.apply, что использовать.

for df in (joined,joined_test):
    df["Promo2Since"] = pd.to_datetime(df.apply(lambda x: Week(
        x.Promo2SinceYear, x.Promo2SinceWeek).monday(), 
            axis=1).astype(pd.datetime))
    df["Promo2Days"] = df.Date.subtract(df["Promo2Since"]).dt.days

Мы могли бы написать это и по-другому [3:16]. Следующие две ячейки - это одно и то же:

Один из подходов - определить функцию (create_promo2since(x)), а затем передать ее по имени, или другой - определить функцию на месте с помощью лямбда. Так что, если вам неудобно создавать и использовать лямбда, полезно попрактиковаться, а поиграться с df.apply - хороший способ попрактиковаться.

Продолжительность [4:32]

Давайте поговорим об этом разделе длительностей, который на первый взгляд может показаться немного конкретным, но на самом деле это не так. Что мы собираемся сделать, так это посмотреть на три поля: “Promo”, “StateHoliday”, “SchoolHoliday”

Итак, в основном у нас есть таблица:

  • для каждого магазина на каждую дату, есть ли в этом магазине промо-акция на эту дату
  • есть ли школьные каникулы в этом районе этого магазина в этот день?
  • есть ли в этом регионе государственный праздник для этого магазина в этот день?

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

Таким образом, основная идея здесь заключается в том, что когда у нас есть события в нашем временном ряду, мы хотим создать два новых столбца для каждого события [7:20]:

  1. Сколько времени пройдет до следующего раза, когда это событие произойдет.
  2. Сколько времени прошло с того момента, когда это событие произошло в последний раз.

Другими словами, сколько времени до следующего государственного праздника, сколько времени прошло с предыдущего государственного праздника. Так что это не то, что мне известно как библиотека или что-то в этом роде. Итак, я написал здесь от руки.

def get_elapsed(fld, pre):
    day1 = np.timedelta64(1, 'D')
    last_date = np.datetime64()
    last_store = 0
    res = []

    for s,v,d in zip(df.Store.values,df[fld].values, 
                     df.Date.values):
        if s != last_store:
            last_date = np.datetime64()
            last_store = s
        if v: last_date = d
        res.append(((d-last_date).astype('timedelta64[D]') / day1))
    df[pre+fld] = res

Что очень важно, мне нужно делать это по магазинам. Итак, я хочу сказать для этого магазина, когда в этом магазине была последняя промо-акция (то есть сколько времени прошло с момента последней промо-акции), например, сколько времени пройдет до следующей промо-акции.

Вот что я собираюсь сделать. Я собираюсь создать небольшую функцию, которая будет принимать имя поля, и я собираюсь передать ее каждому из Promo, затем StateHoliday, а затем SchoolHoliday. Так что давайте, например, устроим школьные каникулы. Итак, мы говорим, что поле - это школьные каникулы, а затем говорим get_elapsed('SchoolHoliday', 'After'). Итак, позвольте мне показать вам, что это будет делать. Мы собираемся в первую очередь отсортировать по магазину и дате. Теперь, когда мы пройдемся по этому циклу, мы перейдем к циклу внутри магазина. Итак, магазин №1: первое января, второе января, третье января и так далее.

fld = 'SchoolHoliday'
df = df.sort_values(['Store', 'Date'])
get_elapsed(fld, 'After')
df = df.sort_values(['Store', 'Date'], ascending=[True, False])
get_elapsed(fld, 'Before')

Проходя цикл по каждому магазину, мы в основном собираемся сказать, является ли этот ряд школьным праздником или нет [8:56]. Если это школьные каникулы, мы будем отслеживать переменную с именем last_date, которая говорит, что это последняя дата, когда мы видели школьные каникулы. Итак, мы собираемся добавить к нашему результату количество дней, прошедших с последних школьных каникул.

Важность использования zip [9:26]

Есть несколько интересных особенностей. Один из них - использование zip. На самом деле я мог бы написать это намного проще, написав for row in df.iterrows():, а затем взять нужные поля из каждой строки. Оказывается, это в 300 раз медленнее той версии, которая у меня есть. По сути, перебор DataFrame и извлечение определенных полей из строки связано с большими накладными расходами. Что намного быстрее, так это перебор массива numpy. Итак, если вы возьмете серию (например, df.Store) и добавите после нее .values, это захватит numpy массив этой серии.

Итак, вот три массива numpy. Один - это идентификаторы магазина, второй - какой fld (в данном случае школьный праздник) и какая дата. Итак, теперь я хочу пройтись по первому, второму и третьему спискам каждого из этих списков. И это действительно очень распространенный образец. Мне нужно делать что-то подобное практически в каждой записной книжке, которую я пишу. И способ сделать это - с помощью zip. Итак, zip означает цикл по каждому из этих списков по одному. Затем здесь мы можем взять элемент из первого списка, второго списка и третьего списка:

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

Итак, мы будем перебирать каждый магазин, каждый школьный праздник и каждую дату [11:34].

Вопрос: перебирает ли он все возможные комбинации каждого из этих [11:44]? Нет. Просто 111, 222 и т. Д.

Итак, в этом случае мы в основном хотим сказать: давайте возьмем первый магазин, первые школьные каникулы и первое свидание. Итак, для магазина 1, первое января, школьные каникулы были правдой или ложью. Так что, если это школьные каникулы, я буду отслеживать этот факт, сказав, что последний раз я видел школу в этот день, и добавлю, сколько времени прошло с последних школьных каникул. И если идентификатор магазина отличается от идентификатора последнего магазина, то теперь я получил совершенно новый магазин, и в этом случае мне нужно в основном все сбросить.

Вопрос: Что будет с первыми точками, которых у нас не было в последний отпуск [12:39]? Ага, поэтому я просто установил здесь произвольную начальную точку (np.datetime64()), и в итоге, я не могу вспомнить, самая большая или самая маленькая возможная дата. Возможно, вам впоследствии потребуется заменить это отсутствующим значением или нулями. Однако хорошо то, что благодаря ReLU нейронной сети очень легко отсекать экстремальные значения. Так что в этом случае я не сделал с этим ничего особенного. В итоге я получил эти отрицательные отметки времени миллиарда, и он все еще работал нормально.

Следующее, что нужно отметить, - это множество вещей, которые мне нужно сделать как с обучающим, так и с тестовым набором [13:35]. Итак, в предыдущем разделе я фактически добавил этот цикл, в котором для каждого из обучающих DataFrame и тестовых DataFrame я выполняю следующие действия:

Каждую ячейку я сделал для каждого фрейма данных:

Далее следует целая серия ячеек, которые я хочу запустить в первую очередь для обучающего набора и для набора тестов. В этом случае, как я это сделал, у меня здесь две разные ячейки: одна, которая устанавливает df как обучающий набор, вторая, которая устанавливает его как тестовый набор.

Я использую это так: я запускаю только первую ячейку (то есть пропускаю df=test[columns]), затем я запускаю все ячейки под ней, поэтому все это выполняется с обучающим набором. Затем я возвращаюсь и запускаю вторую ячейку, затем проверяю все ячейки под ней. Таким образом, этот ноутбук не предназначен для работы сверху вниз. Но он предназначен для работы именно таким образом. Я упомянул об этом, потому что это может быть полезным трюком. Вы, конечно, можете поместить все это в функцию, в которую вы передаете фрейм данных, и вызывать ее один раз с тестовым набором, один раз с обучающим набором. Но мне нравится немного поэкспериментировать, более интерактивно смотреть на каждый шаг по мере продвижения. Таким образом, это простой способ запустить что-либо в разных фреймах данных, не превращая это в функцию.

Если я сортирую по хранилищу и по дате, то это отслеживает, когда что-то произошло в последний раз [15:11]. Итак, d — last_date, таким образом, в конечном итоге сообщит мне, сколько дней прошло с последних школьных каникул:

Итак, теперь, если я отсортирую дату по убыванию и вызову ту же самую функцию, тогда она скажет, сколько времени до следующего праздника:

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

Сделайте это к государственному празднику, сделайте это для промо, вот и все:

fld = 'StateHoliday'
df = df.sort_values(['Store', 'Date'])
get_elapsed(fld, 'After')
df = df.sort_values(['Store', 'Date'], ascending=[True, False])
get_elapsed(fld, 'Before')
fld = 'Promo'
df = df.sort_values(['Store', 'Date'])
get_elapsed(fld, 'After')
df = df.sort_values(['Store', 'Date'], ascending=[True, False])
get_elapsed(fld, 'Before')

Функция прокрутки [16:11]

Следующее, что мы здесь рассмотрим, - это функции прокрутки. Вращение в пандах - это то, как мы создаем то, что мы называем оконными функциями. Допустим, у меня были такие данные. Что я мог сделать, так это сказать: «Хорошо, давайте создадим окно примерно в 7 дней».

Тогда я мог бы взять средние продажи за это семидневное окно. Тогда я мог бы сделать то же самое здесь, взять средние продажи за это семидневное окно.

Итак, если сделать это для каждой точки и объединить эти средние, вы получите скользящую среднюю:

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

Pandas позволяет вам создавать оконные произвольные оконные функции, используя эту прокрутку здесь:

bwd = df[['Store']+columns].sort_index().groupby("Store"
                  ).rolling(7, min_periods=1).sum()
fwd = df[['Store']+columns].sort_index(ascending=False
                  ).groupby("Store").rolling(7, min_periods=1).sum()

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

Я должен упомянуть [19:20], если вы перейдете на страницу временных рядов на Pandas, слева будет длинный список индексов. Там много, потому что Уэс МакКинни, создавший это, изначально занимался торговлей хедж-фондами, я полагаю. И его работа была посвящена временным рядам. Так что я думаю, что изначально Pandas был очень сосредоточен на временных рядах, и все же это, пожалуй, самая сильная часть Pandas. Так что, если вы играете с вычислениями временных рядов, вы определенно должны попытаться изучить этот API целиком. И есть много концептуальных элементов, связанных с отметками времени, смещениями даты, передискретизацией и тому подобным, чтобы вы могли понять. Но оно того стоит, потому что в противном случае вы будете писать эти вещи вручную в виде циклов. Это займет у вас намного больше времени, чем использование того, что уже делает Pandas. И, конечно же, Pandas сделает это за вас в сильно оптимизированном векторизованном коде C, тогда как ваша версия будет работать в цикле на Python. Так что определенно стоит, если вы работаете с временными рядами, изучить полный API временных рядов Pandas. Они примерно так же сильны, как и любой другой API временных рядов.

Хорошо, в конце всего этого вы можете увидеть те значения отправной точки, которые я упомянул [20:56] - немного крайние значения. Итак, вы можете видеть здесь, 17 сентября, в магазине 1 было 13 дней после последних школьных каникул. 16-е было 12, 11, 10 и так далее.

В настоящее время мы проводим акцию. Вот это за день до рекламной акции:

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

Категорический или непрерывный [21:46]

Итак, теперь мы сделали это, у нас есть много столбцов в нашем наборе данных, поэтому мы разделили их на категориальные и непрерывные столбцы. Мы поговорим об этом подробнее в разделе обзора, но это все, для чего я собираюсь создать встраивание:

И contin_vars - это все, что я собираюсь добавить прямо в модель. Так, например, у нас есть CompetitionDistance, так что это расстояние до ближайшего конкурента, максимальная температура, и у нас есть категориальное значение DayOfWeek. Итак, здесь у нас максимальная температура, может быть, около 22,1, потому что в Германии используют температуру по Цельсию, у нас есть расстояние до ближайшего конкурента, может быть, 321,7 км. Затем у нас есть день недели, может быть, суббота - 6. Итак, первые два числа войдут прямо в наш вектор, который мы будем вводить в нашу нейронную сеть. Мы увидим это через некоторое время, но на самом деле мы нормализуем их, но более или менее. Но этой категориальной переменной мы не являемся. Нам нужно пройти через вложение. Таким образом, у нас будет некоторая матрица вложения 7 на 4 (например, вложение размерности 4). Таким образом, это будет искать 6-й ряд, чтобы получить обратно четыре элемента. Таким образом, день недели 6 превратится в вектор длины 4, который затем будет добавлен сюда.

Вот как будут работать наши непрерывные и категориальные переменные.

Затем все наши категориальные переменные превратят их в категориальные переменные Pandas так же, как мы делали это до [24:21]:

for v in cat_vars: 
    joined[v] = joined[v].astype('category').cat.as_ordered()

Затем мы собираемся применить те же сопоставления к тестовой выборке. Если суббота равна 6 в обучающем наборе, это apply_cats гарантирует, что суббота также будет 6 в тестовом наборе:

apply_cats(joined_test, joined)

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

for v in contin_vars:
    joined[v] = joined[v].fillna(0).astype('float32')
    joined_test[v] = joined_test[v].fillna(0).astype('float32')

Итак, это еще один маленький трюк, который я использую.

idxs = get_cv_idxs(n, val_pct=150000/n)
joined_samp = joined.iloc[idxs].set_index("Date")
samp_size = len(joined_samp); samp_size
150000

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

samp_size = n
joined_samp = joined.set_index("Date")

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

Нормализация данных [25:51]

Теперь, когда у нас есть этот joined_samp, мы можем передать его в proc_df, как мы это делали раньше, чтобы получить зависимую переменную для работы с отсутствующими значениями. В этом случае мы передаем еще одну вещь - do_scale=True. Это вычтет среднее значение и разделит его на стандартное отклонение.

df, y, nas, mapper = proc_df(joined_samp, 'Sales', do_scale=True)
yl = np.log(y)

Причина в том, что наш первый слой - это просто матрица умножения. Итак, вот наш набор весов. И наш вход имеет что-то вроде 0,001 и что-то еще, например, 10⁶, тогда наша весовая матрица была инициализирована случайными числами от 0 до 1. Тогда в основном 10⁶ будет иметь градиенты, которые на 9 порядков больше, чем 0,001, что не годится для оптимизации. Итак, нормализуя все до среднего нулевого стандартного отклонения 1 для начала, это означает, что все градиенты будут иметь один и тот же масштаб.

Нам не нужно было делать это в случайных лесах, потому что в случайных лесах нас заботил только порядок сортировки. Нас совершенно не заботили ценности. Но с линейными моделями и вещами, которые построены из слоев линейных моделей, то есть нейронных сетей, мы очень заботимся о масштабе. Итак, do_scale=True нормализует наши данные для нас. Теперь, поскольку он нормализует наши данные для нас, он возвращает один дополнительный объект mapper, который является объектом, который содержит для каждой непрерывной переменной, какое среднее значение и стандартное отклонение было нормализовано. Причина в том, что нам придется использовать одно и то же среднее значение и стандартное отклонение на тестовом наборе, потому что нам нужно, чтобы наш тестовый набор и наш обучающий набор масштабировались точно таким же образом; в противном случае они будут иметь разные значения.

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

Вы заметите, что подавляющее большинство соревнований по регрессии на Kaggle используют либо среднеквадратичную ошибку в процентах, либо среднеквадратичную ошибку журнала в качестве метрики оценки [29:23]. Это потому, что в реальных задачах большую часть времени мы больше заботимся о соотношениях, чем о грубых различиях. Поэтому, если вы разрабатываете свой собственный проект, вполне вероятно, что вы захотите подумать об использовании журнала зависимой переменной.

Итак, затем мы создаем набор проверки, и, как мы узнали ранее, в большинстве случаев, если у вас есть проблема, связанная с компонентом времени, ваш набор проверки, вероятно, хочет быть самым последним периодом времени, а не случайным подмножеством [ 30:00 ]. Вот что я здесь делаю:

val_idx = np.flatnonzero(
    (df.index<=datetime.datetime(2014,9,17)) & 
    (df.index>=datetime.datetime(2014,8,1)))

Когда я закончил моделирование и нашел архитектуру и набор гиперпараметров, несколько эпох и все такое, что действительно хорошо работает, если я хочу сделать свою модель как можно лучше, я переучусь всему этому - включая набор для проверки. Теперь, по крайней мере, в настоящее время Fast AI предполагает, что у вас есть набор для проверки, поэтому мой хакерский обходной путь состоит в том, чтобы установить для моего набора проверки только один индекс, который является первой строкой:

val_idx=[0]

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

Вопрос: у меня есть вопрос относительно функции get_elapsed, который мы обсуждали ранее. В функции get_elapsed мы пытаемся узнать, через сколько дней до следующего праздника. Так что каждый год праздники более или менее фиксированы, например, 4 июля, 25 декабря будет праздник, и почти никаких изменений. Так что, не можем ли мы просто взглянуть на прошлые годы и просто получить список всех праздников, которые будут отмечаться в этом году [31:09]? Может быть. Я имею в виду, в данном случае, я полагаю, что это не так для Promo, и некоторые праздники меняются, например, Пасха. Таким образом, я могу написать один фрагмент кода, который будет работать для всех из них. И это не займет много времени. Если ваш набор данных был настолько большим, что это заняло слишком много времени, вы могли бы сделать это в течение одного года, а затем как бы как-то скопировать его. Но в данном случае в этом не было необходимости. И я всегда ценю свое время больше, чем компьютер, поэтому стараюсь делать все как можно проще.

Создание модели [32:31]

Итак, теперь мы можем создать нашу модель. Чтобы создать нашу модель, мы должны создать объект данных модели, как мы всегда делаем с Fast AI. Таким образом, объект данных столбчатой ​​модели - это просто объект данных модели, представляющий обучающий набор, набор проверки и дополнительный тестовый набор стандартных столбчатых структурированных данных.

md = ColumnarModelData.from_data_frame(PATH, val_idx, df, 
                    yl.astype(np.float32), cat_flds=cat_vars, 
                    bs=128, test_df=df_test)

Нам просто нужно указать, какие из переменных следует рассматривать как категориальные. Затем передайте наши фреймы данных.

Вот количество категорий для каждой из наших категориальных переменных. Таким образом, для каждой из наших матриц вложения это сообщает нам количество строк в этой матрице вложения. Затем мы определяем, какую размерность вложения мы хотим. Если вы выполняете обработку естественного языка, то количество измерений, которое вам нужно, чтобы уловить все нюансы того, что означает слово и как оно используется, было эмпирически установлено, что составляет около 600. Оказывается, когда вы делаете модели НЛП с встраиваемыми матрицами, которые меньше 600, вы не получите такого хорошего результата, как при размере 600. После 600 он, похоже, не сильно улучшится. Я бы сказал, что человеческий язык - одна из самых сложных вещей, которые мы моделируем, поэтому я не ожидал, что вы столкнетесь со многими, если вообще, категориальными переменными, которые нуждаются в встраиваемых матрицах с более чем 600 измерениями. С другой стороны, некоторые вещи могут иметь довольно простую причинно-следственную связь. Так, например, StateHoliday - может быть, если что-то праздничное, то это просто случай, например, "нормально" в магазинах в городе, есть какое-то поведение, в магазинах за городом, есть какое-то другое поведение и все. Может быть, это довольно простые отношения. Итак, в идеале, когда вы решаете, какой размер встраивания использовать, вы должны использовать свои знания о предметной области, чтобы решить, насколько сложны отношения и насколько велико встраивание мне нужно. На практике вы этого почти никогда не узнаете. Вы знаете это только потому, что, возможно, кто-то другой уже проводил это исследование и выяснил это, как в НЛП. Так что на практике вам, вероятно, потребуется использовать какое-то практическое правило, и, попробовав какое-то практическое правило, вы могли бы попробовать немного выше, немного ниже и посмотреть, что поможет. Так что это своего рода эксперимент.

cat_sz=[(c, len(joined_samp[c].cat.categories)+1) for c in cat_vars]
cat_sz
[('Store', 1116),
 ('DayOfWeek', 8),
 ('Year', 4),
 ('Month', 13),
 ('Day', 32),
 ('StateHoliday', 3),
 ('CompetitionMonthsOpen', 26),
 ('Promo2Weeks', 27),
 ('StoreType', 5),
 ('Assortment', 4),
 ('PromoInterval', 4),
 ('CompetitionOpenSinceYear', 24),
 ('Promo2SinceYear', 9),
 ('State', 13),
 ('Week', 53),
 ('Events', 22),
 ('Promo_fw', 7),
 ('Promo_bw', 7),
 ('StateHoliday_fw', 4),
 ('StateHoliday_bw', 4),
 ('SchoolHoliday_fw', 9),
 ('SchoolHoliday_bw', 9)]

Итак, вот мое практическое правило [35:45]. Мое практическое правило - посмотреть, сколько дискретных значений имеет категория (то есть количество строк в матрице вложения), и сделать размерность встраивания вдвое меньшей. Так что если . день недели, который является вторым, восемь строк и четыре столбца. Вот оно (c+1)//2 - количество столбцов, разделенное пополам. Но затем я говорю, что не нужно больше 50. Здесь вы можете увидеть для Store (первая строка), там 116 магазинов, размерность которых равна 50. Почему 50? Я не знаю. Похоже, что пока все работает нормально. Вы можете обнаружить, что вам нужно что-то немного другое. На самом деле, что касается конкурса продуктов питания в Эквадоре, я не пробовал играть с этим, но думаю, нам могут понадобиться вложения большего размера. Но есть с чем возиться.

emb_szs = [(c, min(50, (c+1)//2)) for _,c in cat_sz]
emb_szs
[(1116, 50),
 (8, 4),
 (4, 2),
 (13, 7),
 (32, 16),
 (3, 2),
 (26, 13),
 (27, 14),
 (5, 3),
 (4, 2),
 (4, 2),
 (24, 12),
 (9, 5),
 (13, 7),
 (53, 27),
 (22, 11),
 (7, 4),
 (7, 4),
 (4, 2),
 (4, 2),
 (9, 5),
 (9, 5)]

Вопрос. По мере того, как ваша мощность множества становится все больше и больше, вы создаете все более широкие и широкие матрицы встраивания. Разве вы не сильно рискуете переобучением, потому что, если вы выберете 70 параметров, модель никогда не сможет уловить все эти вариации, поскольку ваши данные на самом деле огромны [36:44]? Это отличный вопрос, поэтому позвольте мне напомнить вам мое золотое правило о разнице между современным машинным обучением и старым машинным обучением. В старом машинном обучении мы контролируем сложность за счет уменьшения количества параметров. В современном машинном обучении мы контролируем сложность за счет регуляризации. Итак, краткий ответ - нет. Меня не беспокоит переобучение, потому что я избегаю переобучения не за счет уменьшения количества параметров, а за счет увеличения отсева или увеличения снижения веса. Сказав это, нет смысла использовать больше параметров для конкретного вложения, чем мне нужно. Потому что регуляризация наказывает модель, предоставляя ей больше случайных данных или фактически штрафуя веса. Так что мы не будем использовать больше, чем нужно. Но это своего рода мое общее эмпирическое правило при проектировании архитектуры - быть щедрым в отношении количества параметров. В этом случае, если после некоторой работы мы почувствуем, что магазин на самом деле не так важен. Затем я мог бы вручную изменить это, чтобы уменьшить его. Или, если я действительно обнаружил, что здесь недостаточно данных, я либо переоснащаю, либо использую больше регуляризации, чем мне удобно, тогда вы можете вернуться. Но я всегда начинал с щедрости на параметры. В данном случае эта модель получилась довольно неплохой.

Хорошо, теперь у нас есть список кортежей, содержащий количество строк и столбцов каждой из наших матриц вложения [38:41]. И поэтому, когда мы вызываем get_learner для создания нашей нейронной сети, это первое, что мы передаем:

  • emb_szs: насколько велико каждое из наших вложений
  • len(df.columns)-len(cat_vars): сколько у нас непрерывных переменных
  • [1000,500]: сколько активаций создать для каждого слоя
  • [0.001,0.01]: какой дропаут использовать для каждого слоя
m = md.get_learner(emb_szs, len(df.columns)-len(cat_vars),
                   0.04, 1, [1000,500], [0.001,0.01], y_range=y_range)
m.summary()

Затем мы можем позвонить fit. Какое-то время мы подгоняемся и получаем что-то около отметки 0,1.

m.fit(lr, 1, metrics=[exp_rmspe])
[ 0.       0.01456  0.01544  0.1148 ]
m.fit(lr, 3, metrics=[exp_rmspe])
[ 0.       0.01418  0.02066  0.12765]                           
[ 1.       0.01081  0.01276  0.11221]                           
[ 2.       0.00976  0.01233  0.10987]
m.fit(lr, 3, metrics=[exp_rmspe], cycle_len=1)
[ 0.       0.00801  0.01081  0.09899]                            
[ 1.       0.00714  0.01083  0.09846]                            
[ 2.       0.00707  0.01088  0.09878]

Я попробовал запустить это на тестовом наборе и отправил его в Kaggle на прошлой неделе, и вот он [39:25]:

Частный балл .107, общественный балл .103. Так что давайте посмотрим, как это пойдет. Начнем с публичного:

340-е место из 3000. Это не очень хорошо. Давайте попробуем частную таблицу лидеров, которая составляет .107.

Ой, 5-е [40:30]. Так что, надеюсь, вы сейчас думаете о том, что скоро заканчиваются соревнования Kaggle, в которых я участвовал, и я потратил много времени, пытаясь добиться хороших результатов в общедоступной таблице лидеров. Интересно, было ли это хорошей идеей. Ответ - нет, это не так. Публичная таблица лидеров Kaggle не предназначена для замены вашего тщательно разработанного набора для проверки. Так, например, если вы проводите соревнование по айсбергам (какие из них - корабли, а какие - айсберги), то они фактически поместили около 4000 синтетических изображений в общедоступную таблицу лидеров и ни одного в частную таблицу лидеров. Так что это одна из действительно хороших вещей, которые проверяют вас на Kaggle: Создаете ли вы хороший набор для проверки и доверяете ли вы ему? Потому что, если вы доверяете своим отзывам в таблице лидеров больше, чем своим оценочным отзывам, вы можете оказаться на 350-м месте, когда думали, что находитесь на 5-м месте. В этом случае у нас на самом деле был довольно хороший набор для проверки, потому что, как вы можете видеть, он говорит где-то около 0,1, а на самом деле мы получили где-то около 0,1. Так что в данном случае публичная таблица лидеров в этом соревновании была совершенно бесполезна.

Вопрос. В связи с этим, насколько верхняя часть общедоступной таблицы лидеров фактически соответствует вершине частной таблицы лидеров? Потому что в задаче прогнозирования оттока есть примерно 4 человека, которые полностью превосходят всех остальных [42:07]. Это полностью зависит. Если они произвольно выбирают общедоступную и частную таблицу лидеров, это должно быть чрезвычайно показательным. Но могло и не быть. Таким образом, в этом случае человек, занявший второе место в публичной таблице лидеров, действительно выигрывал. Первое место в публичной таблице лидеров оказалось 7-м. Фактически, вы можете увидеть здесь маленькую зеленую штуку. Где еще этот парень прыгнул на 96 позиций.

Если бы мы вошли с помощью нейронной сети, которую только что рассматривали, мы бы перепрыгнули на 350 позиций. Так что это просто зависит от обстоятельств. Иногда они говорят вам, что общедоступная таблица лидеров была выбрана случайным образом. Иногда они говорят вам, что это не так. Как правило, вы должны выяснить это, посмотрев на корреляцию между результатами вашего набора для валидации и результатами общедоступной таблицы лидеров, чтобы увидеть, насколько хорошо они коррелированы. Иногда, если 2 или 3 человека намного опережают всех, они могли обнаружить какую-то утечку или что-то в этом роде. Часто это признак того, что есть какая-то уловка.

Итак, это Россманн, и это подводит нас к концу всего нашего материала.

Обзор [44:21]

Мы узнали два способа обучить модель. Один - с помощью построения дерева, а другой - с помощью SGD. Таким образом, подход SGD - это способ обучения модели, которая представляет собой линейную модель или набор линейных слоев с нелинейностями между ними. В то время как построение дерева, в частности, даст нам дерево. Затем построение дерева, мы можем комбинировать его с бэггингом, чтобы создать случайный лес, или с усилением, чтобы создать GBM, или с различными другими небольшими вариациями, такими как чрезвычайно рандомизированные деревья. Так что стоит напоминать себе о том, что эти штуки делают. Итак, давайте посмотрим на некоторые данные. Собственно, давайте посмотрим конкретно на категориальные данные. Итак, категориальные данные, есть несколько вариантов того, как могут выглядеть категориальные данные. Допустим, у нас есть почтовый индекс, поэтому у нас есть 94003 - это наш почтовый индекс. Тогда у нас есть продажи, скажем, 50. Для 94131 продажи 22 и так далее. Итак, у нас есть категориальная переменная. Есть несколько способов представить эту категориальную переменную. Можно было бы просто использовать номер. Может, для начала это было не число. Может, это был вовсе не номер. Может быть, категориальная переменная похожа на Сан-Франциско, Нью-Йорк, Мумбаи и Сидней. Но мы можем превратить его в число, просто произвольно решив дать им числа. В итоге получается число. Мы могли бы просто использовать такое произвольное число. Поэтому, если окажется, что почтовые индексы, численно расположенные рядом друг с другом, имеют несколько схожее поведение, тогда диаграмма сравнения почтовых индексов и продаж может выглядеть примерно так, например:

Или, наоборот, если два следующих друг за другом почтовых индекса не будут иметь схожего поведения при продажах, вы можете ожидать увидеть что-то похожее на это:

Вроде просто повсюду. Итак, есть две возможности. Итак, что бы сделал случайный лес, если бы мы просто закодировали zip таким образом, он скажет: хорошо, мне нужно найти мою единственную лучшую точку разделения - точку разделения, которая сделает две стороны как можно меньшими стандартными отклонениями. или математически эквивалентно иметь наименьшую среднеквадратичную ошибку. В этом случае он может выбрать здесь в качестве первой точки разделения, потому что с левой стороны одно среднее, а с другой стороны - другое среднее [48:07].

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

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

Во втором случае он может делать то же самое [49:25]. Он скажет: "Хорошо", это мой лучший первый разделитель, даже если нет никакой связи между одним почтовым индексом и его соседним почтовым индексом в числовом отношении. Мы все еще можем видеть здесь, если он разделится здесь, среднее значение с одной стороны, а среднее значение с другой стороны, вероятно, примерно здесь:

Тогда где он разделится дальше? Вероятно, здесь, потому что здесь среднее значение с одной стороны, а вот среднее значение с другой стороны.

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

С другой стороны [50:26], если мы делаем нейронную сеть или как простейшую версию, такую ​​как линейная регрессия или логистическая регрессия, лучшее, что она могла бы сделать, это то (выделено зеленым цветом), что совершенно бесполезно:

И то же самое с этим. Это будет так:

Таким образом, порядковый номер не будет полезным кодированием для линейной модели или чего-то, что объединяет линейные и нелинейные модели вместе. Поэтому вместо этого мы создаем одну горячую кодировку. Вот так:

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

Вопрос: В какой момент это становится слишком утомительным для вашей системы [51:36]? Практически никогда. Помните, что в реальной жизни нам не нужно создавать эту матрицу. Вместо этого мы можем просто иметь четыре коэффициента и просто выполнять поиск по индексу, который математически эквивалентен умножению на одно горячее кодирование. Так что это не проблема.

Стоит упомянуть [52:14]. Я знаю, что вас, ребята, научили более аналитическим решениям проблем. А в аналитических решениях, подобных линейной регрессии, вы не можете решить что-либо с такой степенью коллинеарности. Другими словами, вы знаете, что в Сиднее что-то есть, если это не Мумбаи, Нью-Йорк или Сан-Франциско. Другими словами, между четвертым из этих классов и тремя другими существует стопроцентная коллинеарность. Итак, если вы попытаетесь решить линейную регрессию таким образом аналитически, все развалится. Обратите внимание на SGD, у нас нет такой проблемы. Как и SGD, какое это дело? Мы просто делаем один шаг по производной. Это немного беспокоит, потому что, в конце концов, главная проблема коллинеарности состоит в том, что существует бесконечное количество одинаково хороших решений. Другими словами, мы могли бы увеличить все это слева и уменьшить это. Или уменьшите все это и увеличьте это. И они собираются уравновесить.

А когда существует бесконечно большое количество хороших решений, это означает, что на поверхности потерь много плоских участков, и их может быть труднее оптимизировать. Так что действительно простой способ избавиться от всех этих плоских пятен - добавить немного регуляризации. Итак, если мы добавили немного снижения веса, например, даже 1e-7, то это говорит о том, что они больше не все одинаково хороши, тот, который является лучшим, тот, где параметры самые маленькие и наиболее похожи друг на друга. , и это снова вернет его к хорошей функции потерь.

Вопрос: не могли бы вы пояснить, почему одно горячее кодирование не так утомительно [54:03]? Конечно. Если у нас есть один вектор с горячим кодированием и мы умножаем его на набор коэффициентов, то это то же самое, что просто сказать: давайте возьмем то, что есть. Другими словами, если бы мы сохранили это (1000) как ноль, 0100 как единицу, 0020 как двойку, то это было бы точно так же, как просто сказать эй, поищи это в массиве.

Поэтому мы называем эту версию вложением. Таким образом, вложение - это весовая матрица, которую можно умножить на одно горячее кодирование. И это всего лишь вычислительный ярлык. Но математически это то же самое.

Существует ключевое различие между решением модели линейного типа аналитически и с помощью SGD [55:03]. С SGD нам не нужно беспокоиться о коллинеарности и прочем, по крайней мере, не в такой степени. Затем разница между решением линейной, однослойной или многослойной модели с помощью SGD и дерева; дерево будет жаловаться на меньшее количество вещей. Так, в частности, вы можете просто использовать порядковые числа в качестве категориальных переменных, и, как мы узнали только что ранее, нам также не нужно беспокоиться о нормализации непрерывных переменных для дерева, но нам действительно нужно беспокоиться об этом для этих моделей, обученных SGD.

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

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

Вопрос: в интерпретаторе дерева мы смотрим на пути и их вклад в функции. В случае нейронной сети, то же самое и с активациями, я предполагаю, что вклад каждой активации на их пути [57:42]? Да, может быть. Я не знаю. Я не думал об этом. Продолжение вопроса: как мы можем сделать вывод об активациях? Джереми: будьте осторожны, произнося слово вывод, потому что люди обычно используют это слово специально для обозначения того же, что и прогноз времени теста. Вы имеете в виду модель допросить. Я не уверен. Мы должны подумать об этом. Фактически, Хинтон и один из его учеников только что опубликовали статью о том, как аппроксимировать нейронную сеть деревом именно по этой причине. Газету еще не читал.

Вопрос. В линейной регрессии и традиционной статистике мы сосредоточили внимание на статистической значимости изменений и тому подобном. Итак, когда вы думаете об интерпретаторе дерева или даже о диаграмме водопада, которая, я думаю, является просто визуализацией. Я думаю, где это подходит? Потому что мы можем видеть, да, это выглядит важным в том смысле, что вызывает большие изменения, но как мы узнаем, что это традиционно статистически значимое [58:43]? Так что большую часть времени меня не волнует традиционная статистическая значимость, и причина в том, что в настоящее время основной движущей силой статистической значимости является объем данных, а не их практическая значимость. И в настоящее время большинство построенных вами моделей содержат столько данных, что каждая крошечная деталь будет статистически значимой, но большинство из них не будет иметь практического значения. Поэтому мое основное внимание уделяется практическому значению, какое влияние оказывает размер этого влияния на ваш бизнес? Статистическая значимость была намного важнее, когда у нас было намного меньше данных для работы. Если вам действительно нужно знать статистическую значимость, потому что, например, у вас очень маленький набор данных, потому что его очень дорого маркировать или сложно собирать или что-то еще, или это набор медицинских данных для редкого заболевания, вы всегда можете получить статистическую значимость с помощью начальной загрузки это означает, что вы можете случайным образом передискретизировать свой набор данных несколько раз, обучить свою модель несколько раз, а затем вы сможете увидеть фактические вариации в прогнозах. Таким образом, с помощью начальной загрузки вы можете превратить любую модель в нечто, что дает вам доверительные интервалы. Есть статья Майкла Джордана, в которой есть методика, называемая мешок маленьких ботинок, которая на самом деле идет немного дальше и ее стоит прочитать, если вам интересно.

Вопрос: вы сказали, что нам не нужна одна матрица горячего кодирования, если вы выполняете случайные леса. Что будет, если мы это сделаем и насколько плохой может быть модель [1:00:46]? Мы действительно это сделали. Помните, что у нас был этот максимальный размер категории, и мы создали одну горячую кодировку, и причина, по которой мы это сделали, заключалась в том, что тогда важность нашей функции сообщала нам важность отдельных уровней и нашего графика частичной зависимости, мы могли включать отдельные уровни. Таким образом, это не обязательно ухудшает модель, это может улучшить ее, но, вероятно, не сильно ее изменит. В данном случае это почти не изменило. Продолжение вопроса. Мы также заметили на реальных данных, что если количество элементов выше, скажем, 50 уровней, и если вы выполните одно горячее кодирование, случайный лес будет работать очень плохо? Джереми: Да, именно так. Вот почему в Fast.AI у нас есть максимальный размер категории, потому что в какой-то момент ваши горячие закодированные переменные становятся слишком разреженными. Поэтому я обычно отключаю его на 6 или 7. Также потому, что, когда вы перестанете это делать, он становится менее полезным, потому что из-за важности функции будет слишком много уровней, на которые действительно стоит смотреть. Продолжение вопроса. Джереми: Да, все будет хорошо. Это похоже на то, как если количество элементов увеличивается слишком высоко, вы просто слишком сильно разбиваете свои данные в основном, и поэтому на практике ваша порядковая версия, вероятно, будет лучше.

Нет времени пересматривать все, но это ключевые концепции, а затем, вспоминая, что матрица вложения, которую мы можем использовать, вероятно, будет иметь более одного коэффициента, у нас фактически будет размерность нескольких коэффициентов, которые не будут полезно для большинства линейных моделей [1:02:42]. Но как только у вас есть многослойные модели, они создают представление вашей категории, которое намного богаче, и вы можете сделать с ним гораздо больше.

Этика и наука о данных [1:03:13]

"Силовая установка"

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

На самом деле я не собираюсь рассказывать вам, что это значит, потому что я не знаю [1:05:34]. Все, что я собираюсь сделать, - это рассказать вам о некоторых проблемах и заставить вас поверить в две вещи о них:

  1. Тебе следует заботиться.
  2. Это большие текущие проблемы.

Основная причина, по которой я хочу, чтобы вы заботились о вас, заключается в том, что я хочу, чтобы вы хотели быть хорошим человеком и показать вам, что отсутствие мыслей об этих вещах сделает вас плохим человеком. Но если вы не найдете это убедительным, я вам скажу. Было обнаружено, что Volkswagen жульничает в своих тестах на выбросы. За это был отправлен в тюрьму программист, реализовавший этот фрагмент кода. Они сделали именно то, что им сказали. Так что, если вы приходите сюда с мыслью: «Эй, я просто технарь, я просто сделаю то, что мне говорят, это моя работа». Я говорю вам, если вы сделаете это, вас могут отправить в тюрьму за то, что вам говорят, Итак: а) не делайте просто то, что вам говорят, потому что вы можете быть плохим человеком и б) вы можете пойти в тюрьму.

Второе, что нужно осознать, это в голове момент, когда вы встречаетесь с двадцатью людьми на работе, и вы все говорите о том, как вы собираетесь реализовать эту новую функцию, и все это обсуждают [1: 06:49 ]. И все такие: Мы могли бы сделать это, и вот способ моделирования, а затем мы можем реализовать это, и вот эти ограничения, и есть какая-то часть вас, которая думает, уверен ли я, что нам следует это делать? Сейчас не время думать об этом, потому что тогда действительно трудно подойти и сказать: Извините, я не уверен, что это хорошая идея. Вам действительно нужно заранее подумать о том, как бы вы справились с этой ситуацией. Поэтому я хочу, чтобы вы подумали об этих проблемах сейчас и поняли, что к тому времени, когда вы окажетесь в центре, вы можете даже не осознавать, что это происходит. Это будет просто встреча, как и любая другая, и группа людей будет обсуждать, как решить этот технический вопрос. Вы должны уметь распознавать, о, на самом деле это что-то с этическим подтекстом.

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

Так что инженеры, пытающиеся решать инженерные проблемы и создавать проблемы, не новость. В нацистской Германии IBM, группа, известная как Холлерит, Холлерит было первоначальным названием IBM, и оно происходит от человека, который фактически изобрел использование перфокарт для отслеживания переписи населения США. Первое в мире массовое широкомасштабное использование перфокарт для сбора данных. И это превратилось в IBM, поэтому на тот момент все еще называлось Hollerith. Итак, Холлерит продал систему перфокарт нацистской Германии, и каждая перфокарта имела такой код: Еврей, 8, цыган, 12, общая казнь за смерть газовой камерой, 6. Вот одна из этих карточек, описывающих правильный путь убить этих разных людей. Таким образом, швейцарский судья постановил, что техническая помощь IBM облегчила нацистам решение задач и совершение ими преступлений против человечности. Это привело к гибели около двадцати миллионов мирных жителей. Итак, согласно еврейской виртуальной библиотеке, из которой я получил эти фотографии и цитаты, они считают, что уничтожение еврейского народа стало еще менее важным из-за воодушевляющего характера технических достижений IBM, только усиливалось фантастической прибылью, которую нужно было получить. . Итак, это было давно, и, надеюсь, вы не перестанете работать в компаниях, которые способствуют геноциду. Но, возможно, вы [1:09:59].

Потому что, возможно, вы прямо сейчас зайдете в Facebook, которые способствуют геноциду. И я знаю людей в Facebook, которые делают это, и они понятия не имели, что делают это. Прямо сейчас, в Facebook, мусульманское население Мьянмы находится в эпицентре геноцида рохинджа. Младенцев выхватывают из рук матери и бросают в огонь, гибнут люди, сотни и тысячи беженцев. В интервью мьянманские генералы сказали, что мы так благодарны Facebook за то, что они сообщили нам о «фейковых новостях рохинджа», что эти люди на самом деле не люди, а животные. Facebook не ставил своей целью разрешить геноцид рохинджа в Мьянме, нет. Вместо этого они хотели увеличить количество кликов. Получается, что аналитики данных в Facebook научились их алгоритмам: если вы возьмете те вещи, которые интересуют людей, и накормите их немного более экстремальными версиями, вы на самом деле получите гораздо больше впечатлений, и проект менеджеры говорят максимизировать эти впечатления, и люди кликают, и это создает эту вещь. Так что потенциальные последствия необычны и глобальны. И это происходит буквально. Это октябрь 2017 года. Это происходит сейчас.

Вопрос: я просто хочу прояснить, что здесь происходило. Значит, это было содействие фейковым новостям или неточным СМИ [1:11:48]? Да, позвольте мне остановиться на этом подробнее. То, что произошло, произошло в середине 2016 года, когда Facebook уволил своих редакторов-людей. Итак, именно люди решили, как расположить вещи на вашей домашней странице. Этих людей уволили и заменили на алгоритмы машинного обучения. Итак, алгоритм машинного обучения, написанный такими специалистами по обработке данных, как вы, имел хорошие четкие метрики, и они пытались максимизировать свою точность прогнозов, и мы думаем, что если мы поставим это выше, чем это, мы получим больше кликов. Оказалось, что эти алгоритмы размещения вещей в ленте новостей Facebook имели тенденцию говорить: О, человеческая природа такова, что мы склонны нажимать на вещи, которые стимулируют наши взгляды, и поэтому похожи на более экстремальные версии того, что мы уже видели. Это отлично подходит для модели дохода Facebook, направленной на максимальное вовлечение, она хорошо смотрелась по всем их KPI. В то время в прессе появлялись негативные отзывы о том, что я не уверен, что материалы, которые Facebook сейчас помещает в свой раздел трендов, на самом деле настолько точны, но с точки зрения показателей, которые люди оптимизируют в Facebook, это выглядело потрясающий. Итак, еще в октябре 2016 года люди начали замечать серьезные проблемы.

Например, в Америке незаконно предлагать жилье людям определенной расы. Это незаконно, и все же новостная организация обнаружила, что Facebook делает именно это в октябре 2016 года. Опять же, не потому, что кто-то из этой команды по анализу данных сказал: «Давайте сделаем так, чтобы чернокожие не могли жить в хорошем районе». Но вместо этого они обнаружили, что их алгоритм автоматической кластеризации и сегментации обнаружил, что существует группа людей, которым не нравятся афроамериканцы, и если вы настроите на них таргетинг на такие виды рекламы, то они с большей вероятностью выберут такой тип жилья или что бы ни. Но интересно то, что даже после того, как об этом сказали трижды, Facebook все еще не исправил это. И это не просто технические проблемы. Это тоже экономические вопросы. Когда вы начинаете говорить о том, за что вам платят (то есть о рекламе), вы должны изменить способы их структурирования, чтобы вы знали, что используете больше людей, которые стоят денег, или менее агрессивно применяете свои алгоритмы для таргетинга на людей на основе от статуса группы меньшинств или чего-то еще, что может повлиять на доходы. Я говорю об этом потому, что в какой-то момент своей карьеры вы окажетесь в разговоре, в котором вы думаете: «Я не уверен, что это морально нормально», а человек, с которым вы разговариваете, думает в своей голове «это принесет нам много денег », вам никогда не удастся провести успешный разговор, потому что вы говорите о разных вещах. Поэтому, когда вы разговариваете с кем-то, кто может быть более опытным и более старшим, чем вы, и он может звучать так, как будто знает, о чем говорит, просто поймите, что их стимулы не обязательно будут сосредоточены на том, как так, чтобы я был хорошим человеком. . Как будто они не думают, как я могу быть плохим человеком, но, по моему опыту, чем больше времени вы проводите в отрасли, тем меньше вы теряете чувствительность к этим вещам, например, продвижение по службе и зарабатывание денег - не самое главное.

Так, например [1:15:45], у меня много друзей, которые очень хорошо разбираются в компьютерном зрении, и некоторые из них создали стартапы, которые кажутся почти ручными, чтобы помочь авторитарным правительствам контролировать своих граждан. Когда я спрашиваю своих друзей, не думали ли вы о том, как это можно использовать таким образом, они, как правило, обижаются, что я спрашиваю. Но я прошу вас подумать об этом. Где бы вы ни закончили работу, если вы в конечном итоге создадите стартап, инструменты можно использовать во благо или во зло. Поэтому я не говорю, что не стоит создавать отличные инструменты для отслеживания и обнаружения объектов на основе компьютерного зрения, потому что вы можете продолжить и создать гораздо лучший набор инструментов для роботов для хирургического вмешательства. Я просто говорю: осознавайте это, думайте об этом, говорите об этом.

Вот что меня увлекло [1:16:50]. На самом деле, это действительно крутая вещь, которую сделал meetup.com. Они думают об этом. Они действительно думали об этом. Они подумали, что вы знаете что, если бы мы построили систему совместной фильтрации, как мы узнали в классе, чтобы помочь людям решить, на какую встречу им пойти. Он может заметить, что в целом в Сан-Франциско мужчин на несколько больше, чем женщин, обычно посещают встречи технарей, и поэтому он может начать принимать решение рекомендовать встречи техников большему количеству мужчин, чем женщин. В результате все больше мужчин пойдет на встречи технарей, в результате чего, когда женщины будут приходить на встречи технарей, они будут как и все мужчины, я действительно не хочу ходить на встречи технарей. В результате алгоритм получит новые данные, говорящие о том, что мужчинам больше нравятся встречи технарей, поэтому он продолжает работу. Таким образом, небольшая часть этого первоначального толчка со стороны алгоритма может создать эту неконтролируемую петлю обратной связи. И, например, вы заканчиваете почти всеми мужскими встречами технарей. Так что такой вид цикла обратной связи - тонкий вопрос, о котором действительно хочется подумать, когда вы думаете о том, какое поведение я изменяю с помощью этого алгоритма, который я строю.

Еще один пугающий пример содержится в этой статье, где авторы описывают, как многие департаменты в США сейчас используют алгоритмы прогнозирования полицейских [1:18:18]. Так где же нам найти кого-нибудь, кто собирается совершить преступление? Итак, вы знаете, что алгоритм просто возвращает вам данные, которые вы ему предоставили. Так что, если ваше полицейское управление вообще занималось расовым профилированием в прошлом, то оно может предложить немного чаще, может быть, вам стоит отправиться в черные кварталы, чтобы проверить людей, совершающих преступления. В результате чего больше ваших полицейских направляются в районы для чернокожих, в результате чего они арестовывают больше чернокожих, в результате чего данные говорят, что районы для чернокожих менее безопасны. В результате алгоритм говорит полицейскому, может, стоит почаще бывать в черных кварталах и т. Д.

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

Итак, эта об алгоритмах социальных сетей - это на самом деле статья в New York Times, недавно опубликованная одной из моих подруг, Рене Деста, и она сделала кое-что удивительное [1:20:08]. Она создала вторую учетную запись Facebook, фальшивую. В то время она очень интересовалась движением против вакцинации, поэтому она начала следить за парочкой антивакссеров и посетила пару ссылок против вакцинации. И внезапно ее новостная лента начинает наполняться новостями, направленными против ваксера, а также другими вещами, такими как химические трассы, теории заговора глубинного государства и все такое прочее. Таким образом, она начинает нажимать на них, и чем больше она нажимала, тем более хардкорные и далеко идущие конспирологические материалы рекомендовал Facebook. Итак, теперь, когда Рене заходит в ту учетную запись Facebook, вся эта история полна злых, сумасшедших, далеко идущих заговоров. Это все, что она видит. Так что, если это был ваш мир, то для вас это постоянное напоминание и доказательство всего этого. Опять же, это своего рода циклическая обратная связь, которая в конечном итоге приводит генералам Мьянмы на их домашней странице в Facebook, что рохинджа - это животные, фальшивые новости и все остальное.

Во многом это также происходит из-за предвзятости [1:21:51]. Итак, давайте поговорим конкретно о предвзятости. Предвзятость в программном обеспечении для изображений возникает из-за предвзятости данных. И поэтому большинство людей, которых я знаю в алгоритмах компьютерного зрения, создающих мозг, в Google, очень немногие из них - цветные. Поэтому, когда они тренируют алгоритмы с фотографиями своих семей и друзей, они тренируют их с очень небольшим количеством цветных людей. Поэтому, когда FaceApp решила, что мы попробуем просмотреть множество фотографий в Instagram, чтобы увидеть, какие из них получили больше всего голосов, даже не осознавая этого, ответом были светлые лица. Поэтому они построили генеративную модель, чтобы сделать вас более горячими, и вот настоящие фотографии, а вот более горячая версия. Таким образом, более горячая версия более белая, без ноздрей и более европейского вида. Это не очень хорошо, мягко говоря. Опять же, я не думаю, что кто-то в FaceApp сказал: «Давайте создадим что-то, что заставит людей выглядеть более белыми. Они просто натренировали его на кучке образов людей, которые были вокруг них. И это также имеет серьезные коммерческие последствия. Им пришлось вытащить эту особенность. У них было огромное количество негативных ответов, как и следовало бы.

Другой пример. Google Фото создал этот фото-классификатор, самолеты, небоскребы, автомобили, градуировки и гориллы. Так что подумайте, как это выглядит для большинства людей. Большинство людей смотрят на это, они ничего не знают о машинном обучении, они говорят: «какого хрена кто-то в Google написал код, чтобы брать чернокожих и называть их гориллами». Вот как это выглядит. Мы знаем, что этого не произошло. Мы знаем, что произошло: команда специалистов по компьютерному зрению Google, у которых нет ни одного цветного человека или несколько человек, работающих в команде, построила классификатор, используя все фотографии, которые у них были, поэтому, когда система обнаружила человека с темной кожей это было похоже на то, что я в основном видел это раньше только среди горилл, поэтому я отнесу это к этой категории. Опять же, предвзятость в данных создает предвзятость в программном обеспечении, и опять же, коммерческие последствия были очень значительными. Google действительно получил от этого много плохого пиара, как и должно было. Это было фото, которое кто-то разместил в своей ленте в Твиттере. Они сказали, что посмотрите, что Google Фото только что решил сделать.

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

То же самое вы видите при обработке естественного языка [1:25:18]. Вот турецкий. О - это местоимение в турецком языке, которое не имеет пола. Нет он против нее. Но, конечно же, в английском языке у нас нет широко распространенного негендерного местоимения единственного числа, поэтому Google Translate преобразует его в это. Сейчас есть множество людей, которые увидели это в Интернете и буквально сказали ну и что? это правильно возвращает обычное использование в английском языке. Я знаю, как это обучается, это похоже на векторы слов Word2vec, он был обучен в корпусе новостей Google, корпусе книг Google, он просто говорит нам, как обстоят дела. С точки зрения, это совершенно верно. Предвзятые данные для создания этого предвзятого алгоритма - это фактические данные о том, как люди писали книги и газетные статьи на протяжении десятилетий. Но означает ли это, что это именно тот продукт, который вы хотите создать? Значит ли это, что вам нужно создать этот продукт? Именно потому, что конкретный способ обучения модели означает, что она в конечном итоге это делает, действительно ли это тот дизайн, который вам нужен? И можете ли вы подумать о потенциальных негативных последствиях и петлях обратной связи, которые это может создать? Если вас что-то беспокоит, то теперь, к счастью, у вас есть новая крутая инженерная проблема, над которой нужно поработать. Как мне создавать непредвзятые решения НЛП? И сейчас есть несколько стартапов, которые начинают этим заниматься и начинают зарабатывать деньги. Итак, это возможности для вас. Это похоже на то, что вот некоторые вещи, когда люди создают плохие социальные результаты из-за своих дерьмовых моделей. Вы можете пойти и построить что-нибудь получше. Другой пример систематической ошибки в векторах слов Word2vec - обзоры ресторанов, в которых мексиканские рестораны оцениваются хуже, потому что слово мексиканский чаще ассоциируется с криминальными словами в американской прессе и книгах. Опять же, это настоящая проблема.

Рэйчел действительно провела интересный анализ простых векторов слов Word2vec [1:27:46]. По сути, она вытащила их и посмотрела на эти аналогии, основываясь на некоторых исследованиях, которые проводились в другом месте. Как видите, векторные направления Word2vec показывают, что отец - врач, а мать - медсестра. Мужчина для программиста, как женщина для домохозяйки, и так далее. Так что действительно легко увидеть, что находится в этих векторах слов. Они имеют фундаментальное значение практически для всего программного обеспечения НЛП, которое мы используем сегодня.

Вот отличный пример [1:28:30]. ProPublica действительно проделала много хорошей работы в этой области. Многие судьи теперь имеют доступ к программному обеспечению для вынесения приговоров. Итак, программное обеспечение по вынесению приговора говорит судье, что это лицо, мы бы рекомендовали такой приговор. Конечно, судья не понимает машинного обучения, поэтому у него есть два варианта: либо делать то, что он говорит, либо полностью игнорировать его, и некоторые люди попадают в каждую категорию. Вот что происходит с теми, кто попадает в категорию делай то, что говорит. Для тех, кто был отнесен к категории повышенного риска, подмножество тех, кто был отнесен к категории повышенного риска, на самом деле оказалось, что не совершило повторного правонарушения, составляло примерно два процента белых и примерно половину афроамериканцев. Таким образом, почти в два раза чаще люди, которые не совершали повторных преступлений, были отмечены как лица с повышенным риском, если они афроамериканцы, и наоборот. Среди тех, кто был назван более низким уровнем риска, но на самом деле совершил повторное преступление, оказались около половины белых и только 28% афроамериканцев. Итак, это данные, о которых я хотел бы думать, что никто не собирается создавать что-то, что делает это. Но когда вы начинаете с предвзятых данных, и данные говорят, что белые и черные курят марихуану примерно с одинаковой скоростью, но черные сажают в тюрьмы, я думаю, примерно в 5 раз чаще, чем белые, характер системы правосудия в Америке. или, по крайней мере, на данный момент это не равно, это несправедливо. И поэтому данные, которые вводятся в модель машинного обучения, будут в основном поддерживать этот статус-кво. А потом из-за отрицательной обратной связи будет становиться все хуже и хуже.

Теперь я расскажу вам еще кое-что интересное об этом, на что указал исследователь Абэ Гонг [1:30:35]. Вот некоторые из задаваемых вопросов. Итак, возьмем один. Твоего отца когда-нибудь арестовывали? Ваш ответ на этот вопрос решит, будете ли вы взаперти и на какой срок. Как вы, как исследователь машинного обучения, думаете, что это может улучшить точность прогнозирования вашего алгоритма и дать вам лучший R²? Хорошо, но я не знаю. Может быть, это так. Вы попробуете, так что у меня есть R² получше. Значит ли это, что вам следует его использовать? Есть еще вопрос. Как ты думаешь, разумно ли посадить кого-нибудь на более длительный срок из-за того, кем был их отец? И тем не менее, это на самом деле примеры вопросов, которые мы прямо сейчас задаем правонарушителям, а затем помещаем в систему машинного обучения, чтобы решить, что с ними произойдет. Опять же, кто бы это ни разработал, он, по-видимому, был похож на лазер, сфокусированный на техническом совершенстве, получая максимальную площадь под кривой ROC, и я нашел эти отличные предсказатели, которые дали мне еще 0,02. И я думаю, не переставал думать, что это разумный способ решить, кто пойдет в тюрьму на более длительный срок.

Итак, сложив это вместе, вы можете увидеть, как это может становиться все более и более пугающим [1:32:03]. Мы возьмем такую ​​компанию, как Taser, и тазеры - это те устройства, которые в основном вызывают сильное поражение электрическим током, а тазеры отлично справляются с работой по созданию прочных отношений с некоторыми академическими исследователями, которые, кажется, говорят все, что они говорят им, до той степени, в которой сейчас Если вы посмотрите на данные, то окажется, что с большой вероятностью вы умрете, если попадете под электрошок. Это случается не необычно. И все же исследователи, которым они заплатили, чтобы разобраться в этом, постоянно возвращались и говорили: О нет, это не имеет никакого отношения к электрошокеру. Тот факт, что они умерли сразу после этого, не имел никакого отношения. Это было просто случайностью, всякое случается . Таким образом, эта компания сейчас владеет 80% рынка нательных камер. И они начали покупать компании, занимающиеся компьютерным зрением, искусственным интеллектом. И они собираются попробовать и теперь использовать эти видеозаписи с нательной камеры полиции, чтобы предвидеть преступную деятельность. Так что это значит? Это нормально, у меня теперь есть дисплей с дополненной реальностью, на котором написано: Убей этого человека, потому что он собирается сделать что-то плохое? Это вроде как тревожное направление, и поэтому я уверен, что никто из специалистов по анализу данных в Taser или в компаниях, которые они выкупили, не думает, будто это мир, в создании которого я хочу помочь, но они могут оказаться в нем или вы могли бы окажетесь в центре такого рода дискуссии, где речь не идет явно об этой теме, но есть часть вас, которая просто думает: Интересно, как это можно использовать. И я не знаю точно, что делать в этой ситуации, потому что вы можете спросить, и, конечно же, люди скажут нет-нет-нет. Так что же ты мог сделать? Вы можете попросить какое-то письменное обещание, вы можете решить уйти, вы можете начать исследование законности того, что сказать, например, о, я бы, по крайней мере, защищал свою правовую ситуацию. Я не знаю. Подумайте, как бы вы на это отреагировали.

Итак, это некоторые вопросы, которые Рэйчел придумала для размышлений [1:34:39]. Если вы хотите создать продукт для обработки данных или использовать модель, если вы строите модель машинного обучения, на это есть причина. Вы что-то пытаетесь сделать. Итак, какая предвзятость может быть в этих данных? Поскольку какая бы то ни было предвзятость в этих данных в конечном итоге приводит к предвзятости в ваших прогнозах, потенциально затем искажает действия, на которые вы влияете, потенциально затем искажает данные, которые вы возвращаете, и вы можете получить цикл обратной связи.

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

Можем ли мы провести аудит кода? Это открытый исходный код? Проверьте различную частоту ошибок в разных группах. Есть ли простое правило, которое мы могли бы использовать вместо этого, которое было бы легко интерпретируемым и понятным? А если что-то пойдет не так, есть ли у нас хороший способ с этим справиться?

Когда мы говорили с людьми об этом и многие люди приходили к Рэйчел и говорили, что меня беспокоит то, чем занимается моя организация, что мне делать [1:36:21]? Или меня просто беспокоит токсичное рабочее место, что мне делать? И очень часто Рэйчел говорит, не думала ли ты уйти? И они скажут, что я не хочу терять работу. Но на самом деле вы умеете программировать, вы примерно 0,3% населения. Если вы умеете программировать и заниматься машинным обучением, вы, вероятно, будете в числе 0,01% населения. Вы пользуетесь огромным спросом. На самом деле очевидно, что организация не хочет, чтобы вы чувствовали себя кем-то, кто может просто уйти и устроиться на другую работу, что не в их интересах. Но это абсолютно верно. Так что одна из вещей, с которой, я надеюсь, вы закончите этот курс, - это достаточно уверенности в себе, чтобы осознать, что у вас есть навыки, чтобы получить работу, и особенно после того, как вы получите свою первую работу, ваша вторая работа станет на порядок. Полегче. Так что это важно не только для того, чтобы вы почувствовали, что действительно способны действовать этично, но также важно понимать, если вы окажетесь в токсичной среде, что, к сожалению, довольно распространено. Есть много дерьмовых технологических культур / сред, особенно в районе залива. Если вы окажетесь в одной из таких сред, лучше всего выбраться к черту. И если у вас нет уверенности в себе, чтобы думать, что вы можете найти другую работу, вы можете попасть в ловушку. Так что это действительно важно. Очень важно знать, что вы покидаете эту программу с очень востребованными навыками, и особенно после того, как у вас есть первая работа, вы теперь являетесь человеком с востребованными навыками и опытом работы в этой области.

Вопрос: это довольно широкий вопрос, но что вам известно о том, что люди делают для устранения предвзятости в данных [1:38:41]? Знаете, сейчас это как бы спорная тема, и есть люди, пытающиеся использовать алгоритмический подход, при котором они в основном пытаются сказать, как мы можем выявить предвзятость и как бы вычесть ее. Но самые эффективные способы, которые я знаю, - это те, которые пытаются лечить на уровне данных. Так что начните с более разнообразной команды, в частности, в команду входят люди из гуманитарных наук, такие как социологи, психологи, экономисты, люди, которые понимают петли обратной связи и последствия для человеческого поведения, и они, как правило, оснащены хорошими инструментами для выявления и отслеживания таких проблем. А затем попробуйте включить решения в сам процесс. Но нет какого-то стандартного процесса, на который я мог бы указать вам и сказать, как его решить. Если такое есть, то мы еще не нашли. Чтобы понять проблемы и усердно работать над ними, нужна разнообразная команда умных людей - вот краткий ответ.

Комментарий: это обычное дело для всего класса. Если вам это интересно, я прочитал довольно классную книгу, Джереми, вы, наверное, слышали о ней, Оружие математического разрушения. Кэти О'Нил. Он охватывает много того же [1:40:09]. Да, спасибо за рекомендацию. Кэти великолепна. Еще у нее есть выступление на TED. Книгу дочитать не успела. Это так чертовски удручает. Я был просто как больше нет. Но да, очень хорошо.

Все в порядке. Вот и все. Спасибо всем. Для меня это было очень напряженно. Очевидно, это должно было быть чем-то, чем я поделился с Рэйчел. Так что я закончил тем, что сделал одно из самых трудных дел в своей жизни: я научил двух людей, конечно, самостоятельно, а также ухаживал за больной женой и имел малыша, а также прошел курс глубокого обучения. А также проделайте все это с новой библиотекой, которую я только что написал. Так что я с нетерпением жду возможности поспать. Но оно того стоило. Потому что ты был потрясающим. Я в восторге от того, как вы отреагировали на возможности, которые я вам дал, а также на отзывы, которые я вам дал. Поздравляю.

Уроки: 1234567891011 12