在 Airbnb 使用機器學習預測房源的價格

在 Airbnb 使用機器學習預測房源的價格

位於希臘愛琴海伊莫洛維裏的一個 Airbnb 民宿的美好風景html

簡介

數據產品一直是 Airbnb 服務的重要組成部分,不過咱們很早就意識到開發一款數據產品的成本是很高的。例如,個性化搜索排序可讓客戶更容易發現中意的房屋,智能訂價可讓房東設定更具競爭力的價格。然而,須要許多數據科學家和工程師付出許多時間和精力才能作出這些產品。前端

最近,Airbnb 機器學習的基礎架構進行了改進,使得部署新的機器學習模型到生產環境中的成本下降了許多。例如,咱們的 ML Infra 團隊構建了一個通用功能庫,這個庫讓用戶能夠在他們的模型中應用更多高質量、通過篩選、可複用的特徵。數據科學家們也開始將一些自動化機器學習工具歸入他們的工做流中,以加快模型選擇的速度以及提升性能標準。此外,ML Infra 還建立了一個新的框架,能夠自動將 Jupyter notebook 轉換成 Airflow pipeline 能接受的格式。python

在本文中,我將介紹這些工具是如何協同運做來加快建模速度,從而下降開發 LTV 模型(預測 Airbnb 民宿價格)整體成本的。react

什麼是 LTV?

LTV 全稱 Customer Lifetime Value,意爲「客戶終身價值」,是電子商務、市場公司中很流行的一種概念。它定義了在將來一個時間段內用戶預期爲公司帶來的收益,一般以美圓爲單位。android

在一些例如 Spotify 或者 Netflix 之類的電子商務公司裏,LTV 一般用於制定產品訂價(例如訂閱費等)。而在 Airbnb 之類的市場公司裏,知曉用戶的 LTV 將有助於咱們更有效地分配營銷渠道的預算,更明確地根據關鍵字作在線營銷報價,以及作更好的類目細分。ios

咱們能夠根據過去的數據來計算曆史值,固然也能夠進一步使用機器學習來預測新登記房屋的 LTV。git

LTV 模型的機器學習工做流

數據科學家們一般比較熟悉和機器學習任務相關的東西,例如特徵工程、原型製做、模型選擇等。然而,要將一個模型原型投入生產環境中須要的是一系列數據工程技術,他們可能對此不太熟練。github

不過幸運的是,咱們有相關的機器學習工具,能夠將具體的生產部署工做流從機器學習模型的分析創建中分離出來。若是沒有這些神奇的工具,咱們就沒法輕鬆地將模型應用於生產環境。下面將經過 4 個主題來分別介紹咱們的工做流以及各自用到的工具:apache

  • 特徵工程:定義相關特徵
  • 原型設計與訓練:訓練一個模型原型
  • 模型選擇與驗證:選擇模型以及調參
  • 生產部署:將選擇好的模型原型投入生產環境使用

特徵工程

使用工具:Airbnb 內部特徵庫 — Zipline後端

任何監督學習項目的第一步都是去找到會影響到結果的相關特徵,這一個過程被稱爲特徵工程。例如在預測 LTV 時,特徵能夠是某個房源房屋在接下來 180 天內的可以使用天數所佔百分比,或者也能夠是其與同市場其它房屋訂價的差別。

在 Airbnb 中,要作特徵工程通常得從頭開始寫 Hive 查詢語句來建立特徵。可是這個工做至關無聊,並且須要花費不少時間。由於它須要一些特定的領域知識和業務邏輯,也所以這些特徵 pipeline 並不容易共享或複用。爲了讓這項工做更具可擴展性,咱們開發了 Zipline —— 一個訓練特徵庫。它能夠提供不一樣粒度級別(例如房主、客戶、房源房屋及市場級別)的特徵。

這個內部工具「多源共享」的特性讓數據科學家們能夠在過去的項目中找出大量高質量、通過審查的特徵。若是沒有找到但願提取的特徵,用戶也能夠寫一個配置文件來建立他本身須要的特徵:

source: {
  type: hive
  query:""" SELECT id_listing as listing , dim_city as city , dim_country as country , dim_is_active as is_active , CONCAT(ds, ' 23:59:59.999') as ts FROM core_data.dim_listings WHERE ds BETWEEN '{{ start_date }}' AND '{{ end_date }}' """
  dependencies: [core_data.dim_listings]
  is_snapshot: true
  start_date: 2010-01-01
}
features: {
  city: "City in which the listing is located."
  country: "Country in which the listing is located."
  is_active: "If the listing is active as of the date partition."
}複製代碼

在構建訓練集時,Zipline 將會找出訓練集所須要的特徵,自動的按照 key 將特徵組合在一塊兒並填充數據。在構造房源 LTV 模型時,咱們使用了一些 Zipline 中已經存在的特徵,還本身寫了一些特徵。模型總共使用了 150 多個特徵,其中包括:

  • 位置:國家、市場、社區以及其它地理特徵
  • 價格:過夜費、清潔費、與類似房源的價格差別
  • 可用性:可過夜的總天數,以及房主手動關閉夜間預訂的佔比百分數
  • 是否可預訂:預訂數量及過去 X 天內在夜間訂房的數量
  • 質量:評價得分、評價數量、便利設施

實例數據集

在定義好特徵以及輸出變量以後,就能夠根據咱們的歷史數據來訓練模型了。

原型設計與訓練

使用工具:Python 機器學習庫scikit-learn

之前面的訓練集爲例,咱們在作訓練前先要對數據進行一些預處理:

  • 數據插補:咱們須要檢查是否有數據缺失,以及它是否爲隨機出現的缺失。若是不是隨機現象,咱們須要弄清楚其根本緣由;若是是隨機缺失,咱們須要填充空缺數據。
  • 對分類進行編碼:一般來講咱們不能在模型裏直接使用原始的分類,由於模型並不能去擬合字符串。當分類數量比較少時,咱們能夠考慮使用 one-hot encoding 進行編碼。若是分類數量比較多,咱們就會考慮使用 ordinal encoding, 按照分類的頻率計數進行編碼。

在這一步中,咱們還不知道最有效的一組特徵是什麼,所以編寫可快速迭代的代碼是很是重要的。如 Scikit-LearnSpark 等開源工具的 pipeline 結構對於原型構建來講是很是方便的工具。Pipeline 可讓數據科學家們設計藍圖,指定如何轉換特徵、訓練哪個模型。更具體來講,能夠看下面咱們 LTV 模型的 pipeline:

transforms = []

transforms.append(
    ('select_binary', ColumnSelector(features=binary))
)

transforms.append(
    ('numeric', ExtendedPipeline([
        ('select', ColumnSelector(features=numeric)),
        ('impute', Imputer(missing_values='NaN', strategy='mean', axis=0)),
    ]))
)

for field in categorical:
    transforms.append(
        (field, ExtendedPipeline([
            ('select', ColumnSelector(features=[field])),
            ('encode', OrdinalEncoder(min_support=10))
            ])
        )
    )

features = FeatureUnion(transforms)複製代碼

在高層設計時,咱們使用 pipeline 來根據特徵類型(如二進制特徵、分類特徵、數值特徵等)來指定不一樣特徵中數據的轉換方式。最後使用 FeatureUnion 簡單將特徵列組合起來,造成最終的訓練集。

使用 pipeline 開發原型的優點在於,它可使用 data transforms 來避免繁瑣的數據轉換。總的來講,這些轉換是爲了確保數據在訓練和評估時保持一致,以免將原型部署到生產環境時出現的數據不一致。

另外,pipeline 還能夠將數據轉換過程和訓練模型過程分開。雖然上面代碼中沒有,但數據科學家能夠在最後一步指定一種 estimator(估值器)來訓練模型。經過嘗試使用不一樣的估值器,數據科學家能夠爲模型選出一個表現最佳的估值器,減小模型的樣本偏差。

模型選擇與驗證

使用工具:各類自動機器學習框架

如上一節所述,咱們須要肯定候選模型中的哪一個最適合投入生產。爲了作這個決策,咱們須要在模型的可解釋性與複雜度中進行權衡。例如,稀疏線性模型的解釋性很好,但它的複雜度過低了,不能很好地運做。一個足夠複雜的樹模型能夠擬合各類非線性模式,可是它的解釋性不好。這種狀況也被稱爲誤差(Bias)和方差(Variance)的權衡

上圖引用自 James、Witten、Hastie、Tibshirani 所著《R 語言統計學習》

在保險、信用審查等應用中,須要對模型進行解釋。由於對模型來講避免無心排除一些正確客戶是很重要的事。不過在圖像分類等應用中,模型的高性能比可解釋更重要。

因爲模型的選擇至關耗時,咱們選擇採用各類自動機器學習工具來加速這個步驟。經過探索大量的模型,咱們最終會找到表現最好的模型。例如,咱們發現 XGBoost (XGBoost) 明顯比其餘基準模型(好比 mean response 模型、嶺迴歸模型、單一決策樹)的表現要好。

上圖:咱們經過比較 RMSE 能夠選擇出表現更好的模型

鑑於咱們的最初目標是預測房源價格,所以咱們很舒服地在最終的生產環境中使用 XGBoost 模型,比起可解釋性它更注重於模型的彈性。

生產部署

使用工具:Airbnb 本身寫的 notebook 轉換框架 — ML Automator

如開始所說,構建生產環境工做流和在筆記本上構建一個原型是徹底不一樣的。例如,咱們如何進行按期的重訓練?咱們如何有效地評估大量的實例?咱們如何創建一個 pipeline 以隨時監視模型性能?

在 Airbnb,咱們本身開發了一個名爲 ML Automator 的框架,它能夠自動將 Jupyter notebook 轉換爲 Airflow 機器學習 pipeline。該框架專爲熟悉使用 Python 開發原型,但缺少將模型投入生產環境經驗的數據科學家準備。

ML Automator 框架概述(照片來源:Aaron Keys)

  • 首先,框架要求用戶在 notebook 中指定模型的配置。該配置將告訴框架如何定位訓練數據表,爲訓練分配多少計算資源,以及如何計算模型評價分數。
  • 另外,數據科學家須要本身寫特定的 fittransform 函數。fit 函數指定如何進行訓練,而 transform 函數將被 Python UDF 封裝,進行分佈式計算(若是有須要)。

下面的代碼片斷展現了咱們 LTV 模型中的 fittransform 函數。fit 函數告訴框架須要訓練 XGBoost 模型,同時轉換器將根據咱們以前定義的 pipeline 轉換數據。

def fit(X_train, y_train):
    import multiprocessing
    from ml_helpers.sklearn_extensions import DenseMatrixConverter
    from ml_helpers.data import split_records
    from xgboost import XGBRegressor

    global model

    model = {}
    n_subset = N_EXAMPLES
    X_subset = {k: v[:n_subset] for k, v in X_train.iteritems()}
    model['transformations'] = ExtendedPipeline([
                ('features', features),
                ('densify', DenseMatrixConverter()),
            ]).fit(X_subset)

    # 並行使用轉換器
    Xt = model['transformations'].transform_parallel(X_train)

    # 並行進行模型擬合
    model['regressor'] = XGBRegressor().fit(Xt, y_train)

def transform(X):
    # return dictionary
    global model
    Xt = model['transformations'].transform(X)
    return {'score': model['regressor'].predict(Xt)}複製代碼

一旦 notebook 完成,ML Automator 將會把訓練好的模型包裝在 Python UDF 中,並建立一個以下圖所示的 Airflow pipeline。數據序列化、按期重訓練、分佈式評價等數據工程任務都將被載入到平常批處理做業中。所以,這個框架顯著下降了數據科學家將模型投入生產的成本,就像有一位數據工程師在與科學家一塊兒工做同樣!

咱們 LTV 模型在 Airflow DAG 中的圖形界面,運行於生產環境中

Note:除了模型生產化以外,還有一些其它項目(例如跟蹤模型隨着時間推移的性能、使用彈性計算環境建模等)咱們沒有在這篇文章中進行介紹。這些都是正在進行開發的熱門領域。

經驗與展望

過去的幾個月中,咱們的數據科學家們與 ML Infra 密切合做,產生了許多很好的模式和想法。咱們相信這些工具將會爲 Airbnb 開發機器學習模型開闢新的範例。

  • 首先,顯著地下降了模型的開發成本:經過組合各類不一樣的獨立工具的優勢(Zipline 用於特徵工程、Pipeline 用於模型原型設計、AutoML 用於模型選擇與驗證,以及最後的 ML Automator 用於模型生產化),咱們大大減短了模型的開發週期。
  • 其次,notebook 的設計下降了入門門檻:還不熟悉框架的數據科學家能夠當即獲得大量的真實用例。在生產環境中,能夠確保 notebook 是正確、自解釋、最新的。這種設計模式受到了新用戶的好評。
  • 所以,團隊將更願意關注機器學習產品的 idea:在本文撰寫時,咱們還有其它幾支團隊在採用相似的方法探索機器學習產品的 idea:爲檢查房源隊列進行排序、預測房源是否會增長合夥人、自動標註低質量房源等等。

咱們對這個框架和它帶來的新範式的將來感到無比的興奮。經過縮小原型與生產環境間的差距,咱們可讓數據科學家和數據工程師更多去追求端到端的機器學習項目,讓咱們的產品作得更好。


想使用或者一塊兒開發這些機器學習工具嗎?咱們正在尋找 能幹的你加入咱們的數據科學與分析團隊


特別感謝參與這項工做的Data Science&ML Infra團隊的成員:Aaron Keys, Brad Hunter, Hamel Husain, Jiaying Shi, Krishna Puttaswamy, Michael Musson, Nick Handel, Varant Zanoyan, Vaughn Quoss 等人。另外感謝 Gary Tang, Jason Goodman, Jeff Feng, Lindsay Pettingill 給本文提的意見。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOSReact前端後端產品設計 等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索