Стартовая линия

Мой единственный опыт программирования за пределами одного класса, который я посещал в старшей школе, был моим временем в школе Lambda. Lambda School — это учебный лагерь по науке о данных/кодированию, где они моделируют реальную рабочую среду в отрасли, чтобы подготовить вас к карьере в области разработки программного обеспечения. Во время моего пребывания в Lambda School нам поручили создать приложение, которое, по сути, возвращает городские показатели пользователю после того, как он введет местоположение города. Нашей целью было создать универсальный ресурс, чтобы пользователи могли получать самую точную информацию о городе. Вот тут-то и появляется CitySpire; наше приложение вернет прогнозируемые арендные ставки на следующие 12 месяцев, уровень преступности в этом месте (разделенный на насильственные преступления и преступления против собственности), показатель пешеходной доступности в этом месте, численность населения и стоимость жизни в этом месте в сравнении. к среднему по стране. У меня было много опасений, связанных с этим, поскольку есть много способов решить эту проблему, и многое может пойти не так во время работы над этим. Одна из таких проблем заключалась в том, чтобы решить, какую модель я буду использовать для прогнозов. В конце концов я выбрал предварительно обученную модель с использованием модели Prophet из библиотеки FBprophet, а не обучал модель с нуля. Преимущество в этом заключается в том, что Prophet уже адаптирован к сезонным изменениям и очень устойчив к значениям NaN.

Проблемы

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



Еще одной проблемой для нас было использование модели Prophet из библиотеки FBProphet. Как команда, мы решили использовать Pipenv для наших переменных среды, так как все были знакомы с ним, и его можно легко реплицировать на любой локальной машине. Проблема, однако, в том, что библиотека FBProphet вообще не поддерживает пипсы. Поскольку я принял решение использовать модель Prophet для нашего проекта, у меня был выбор. Либо я найду способ заставить Prophet работать локально с моей стороны и создать временную паузу, либо мне придется обучать новую модель с нуля и полностью отказаться от модели Prophet. В обоих подходах были как положительные, так и отрицательные стороны. Если бы мне пришлось обучать модель с нуля, мне пришлось бы сжимать и очищать наши наборы данных еще больше просто потому, что у нас было довольно значительное количество значений NaN в данных, с которыми должна работать модель. Преимущество этого в том, что это позволяет всем в моей команде использовать эту модель, не опасаясь пропажи пакетов из конкретной библиотеки.



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

# Make sure you update all your base packages beforehand first.
conda update --all
conda install -c anaconda ephem
conda install -c conda-forge pystan
conda install -c conda-forge fbprophet

Фактическое создание зазора немного сложнее, чем 3 строки кода. Мне пришлось переформатировать наш набор данных, чтобы модель Prophet могла использовать данные для генерации прогнозов. Затем мне пришлось взять наши прогнозы и объединить их с нашим исходным набором данных, чтобы мы могли отображать цены на аренду за текущий год, а также за следующие 12 месяцев. Весь процесс занял около 5–6 часов, при этом большая часть времени была потрачена на то, чтобы модель обрабатывала данные и генерировала прогнозы.

from fbprophet import Prophet
for x in range(2263):
    df1 = rent3.loc[rent3['index'] == x][['ds', 'yhat']]
    df2 = rent3.loc[rent3['index'] == x][['RegionID', 'RegionName', 'SizeRank', 'MsaName']]
    df1.columns = ['ds','y']
    df1['ds'] = pd.to_datetime(df1['ds'])
    m = Prophet(interval_width=.95)
    m.fit(df1)
    future = m.make_future_dataframe(freq='MS', periods=12)
    forecast = m.predict(future)
    predictions = forecast[['ds', 'yhat']]
    predictions['yhat'] = predictions.yhat.round()
    predictions['RegionID'] = df2['RegionID'].iloc[0]
    predictions['RegionName'] = df2['RegionName'].iloc[0]
    predictions['SizeRank'] = df2['SizeRank'].iloc[0]
    predictions['MsaName'] = df2['MsaName'].iloc[0]
    predictions = predictions[['RegionID', 'RegionName', 'SizeRank', 'MsaName', 'ds', 'yhat']]
    predictions.to_csv('zip_predictions.csv', mode='a', index=False)

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

def fetch_zip_rent():
# List of all months in 2020 and 2021
rent_dates = [‘2020–01–01’, ‘2020–02–01’, ‘2020–03–01’, ‘2020–04–01’, ‘2020–05–01’, ‘2020–06–01’, ‘2020–07–01’, ‘2020–08–01’, ‘2020–09–01’, ‘2020–10–01’, ‘2020–11–01’, ‘2020–12–01’, ‘2021–01–01’, ‘2021–02–01’, ‘2021–03–01’, ‘2021–04–01’, ‘2021–05–01’, ‘2021–06–01’, ‘2021–07–01’, ‘2021–08–01’, ‘2021–09–01’, ‘2021–10–01’, ‘2021–11–01’, ‘2021–12–01’]
# First attempt to fetch 1 record from fetch_zip_rent table with only ZIPcode values
SQL = f’’’SELECT “{‘“, “‘.join(rent_dates)}” FROM zip_rent WHERE “RegionName” = ‘{ZIPcode}’;’’’ results = list(conn.execute(SQL)) if len(results) == 1: return {key: value for key, value in list(zip(rent_dates, results[0]))}
# Next attempt to fetch 1 record from zip_rent table with only City and State values
SQL = f’’’SELECT “{‘“, “‘.join(rent_dates)}” FROM zip_rent WHERE “MsaName” = ‘{city+”, “+state}’;’’’ results = list(conn.execute(SQL)) if len(results) == 1: return {key: value for key, value in list(zip(rent_dates, results[0]))}
# Finally attempt to fetch 1 record from zip_rent table with City and State and ZIPcode values
SQL = f’’’SELECT “{‘“, “‘.join(rent_dates)}” FROM zip_rent WHERE “MsaName” = ‘{city+”, “+state}’ AND “RegionName” = ‘{ZIPcode}’’;’’’ if len(results) == 1: return {key: value for key, value in list(zip(rent_dates, results[0]))}
# If the above fails then return None
return None

Продукт

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

· Арендные ставки (текущие и будущие)

· Уровень преступности (насильственные и имущественные преступления)

· Численность населения

· Оценка проходимости

· Стоимость жизни

· Карта

· Вкладка «Избранное»

На данный момент наше приложение работает и предоставляет потенциальным пользователям самые важные показатели в любом месте в США. Однако в нашем приложении еще есть много возможностей для улучшения. Модель Пророка, которая использовалась для создания прогнозов, может быть оптимизирована еще больше, чтобы давать еще более точные результаты. Мы также можем реализовать дополнительные функции, такие как качество воздуха и количество случаев COVID в каждом месте. Технические проблемы, которые я вижу для их реализации, будут аналогичны тем, с которыми мы сталкивались до сих пор в начале создания этого приложения. Такие вещи, как трудности с поиском подходящих данных, очисткой и проектированием данных, чтобы они соответствовали нашей модели, а также с обеспечением того, чтобы у вас были правильные переменные среды для вашего приложения. Некоторые отзывы, которые я получил от коллег, побудили меня улучшить документацию. Таким образом, им будет легче понять, чего я пытаюсь достичь, что поможет в дальнейшем масштабировании. Этот проект научил меня многому и дал приблизительное представление о том, чего ожидать в полевых условиях. Хотя в этом задании я был главным инженером по машинному обучению, я узнал, что входит в создание функционального приложения от начала до конца. Это был ценный опыт, и команда, с которой я работал, была действительно исключительной.