跳至主要內容

    LightGBM 與 CatBoost:效率與類別特徵的取捨

    從直方圖、葉優先生長,到有順序的類別統計與 Boosting

    sunny 桑尼· · 42 MIN READ · 158 次瀏覽

    LightGBM 與 CatBoost:效率與類別特徵的取捨
    本文目錄

    同樣是逐輪加入決策樹,為什麼還需要不同的工具?讀過Boosting和XGBoost後,可以把這個問題拆成兩部分:找下一棵樹時,怎樣減少搜尋成本;遇到門市、商品類別等欄位時,怎樣利用資訊而不讓答案提前混進特徵。

    LightGBM很適合拿來理解直方圖搜尋與葉優先生長,CatBoost則讓我們看見類別統計和訓練順序的關係。兩者都能處理數值與類別特徵;這不是「數值用一套、類別用另一套」的硬性分類。本文先拆原理,再讓兩套工具對同一份合成資料實跑。

    LightGBM先縮小候選切點的搜尋範圍

    假設某個連續欄位有很多不同值。精細地逐一考慮相鄰值之間的切點,需要處理大量候選。直方圖方法先把連續值映射到有限個bin,再在bin的邊界上評估切分。

    這裡的直方圖不只是數人頭。沿用XGBoost篇的記法,每筆有損失的一階導數g與二階導數h;同一bin會累積這些訓練統計。以下是刻意縮小的教學例,並非套件輸出的內部bin:

    bin假想落入的值g總和h總和
    11.2、1.8−32
    22.1、2.912
    34.021

    如果試「bin 1在左,其餘在右」,就能取得左側G=−3、H=2,右側G=3、H=3,再放進相應的切分評分。試下一個bin邊界時,繼續累加即可。原本1.2和1.8之間的細緻切點已被合併,這正是減少搜尋與保留解析度之間的交換。

    建立直方圖仍需要讀取資料;不能把整個訓練時間直接說成只跟bin數有關。官方Features的成本拆解是:累積直方圖需要掃描資料,建好之後評估bin邊界的成本才跟bin數連動。父節點的直方圖也能減去一個子節點的直方圖,取得另一側的統計,減少重複累積。

    實作時通常把原始數值交給工具,讓工具處理內部分箱。不必先為每個數值欄位手工做one-hot。bin太少會失去細節;bin更多也不保證測試更準,仍需看記憶體、訓練時間與驗證表現。XGBoost也有hist方法,直方圖並非LightGBM獨有。

    葉優先生長:下一刀切在哪個葉?

    圖1|LightGBM文件用這張圖示意level-wise:生長進度沿深度向下推進。圖中沒有特徵條件,也沒有測試分數。來源:Microsoft Corporation/The LightGBM developers,Features,MIT;原圖未改,手機版另作分步編排。

    逐層生長先處理同一深度的節點。葉優先則在目前可以切分的葉中,選損失下降最有利的一個繼續切;因此可能在一條分支往下走了好幾步,另一側仍很淺。

    圖2|綠色突出示意中的部分葉,黑色末端節點也都是葉,圖示生長逐步集中於部分分支;不是每一層都必須全部展開。來源同圖1,MIT;原圖未改,手機版另作分步編排。示意圖沒有提供資料量或泛化成效。

    假想目前三個葉的最佳候選增益為8、3、1,葉優先會先處理增益8的葉。切完後,候選集合和增益要更新,不能直接把舊的8、3、1當成永遠不變的排行榜。

    在固定葉數的條件下,這種生長方式傾向更有效降低訓練損失,但也可能更積極地追逐小區域。小資料尤其要注意過擬合。num_leaves限制葉數,max_depth限制深度,min_child_samples限制葉的樣本條件;三者不是同一個旋鈕。設了max_depth,LightGBM仍採葉優先,並不因此改成逐層生長。

    還有一個容易混淆的名詞:CatBoost常用的對稱樹要求同一層所有節點使用同一個切分條件。單純「逐層」只描述生長順序,同層仍可能使用不同條件,所以圖1不能直接當成CatBoost對稱樹的充分定義。CatBoost也提供其他grow policy;下面範例會明確指定對稱樹。

    兩套工具都有類別處理,但處理方式不同

    門市A、B、C沒有天然的大小關係。若隨意編成1、2、3,再當一般連續欄位切「小於2.5」,便把任意代碼帶成了距離和順序。這是特徵工程需要先辨識的問題。

    LightGBM可以把欄位標成類別,在其類別切分機制下尋找類別集合的分割。官方概念說明以類別累積的梯度/Hessian排序,再搜尋分割;不是把類別代碼一律當連續數字,也不是所有情境都必須展開成one-hot。實際分割還受正則化與類別參數影響。

    CatBoost的重要方法之一則是target statistics:用類別與目標之間的訓練統計,把類別轉成可供樹使用的數值。這很有吸引力,也很容易洩漏。

    圖3|原簡報實體PDF第10頁、投影片5/21。指示函數只讓同類別的樣本進入分子和分母;求和包含目前這筆自己的目標。來源:Liudmila Prokhorenkova等五位作者/YANDEX LLC,2018 NIPS CatBoost官方簡報,Apache 2.0;裁去大片空白、保留標題、公式與原署名列,手機版單獨放大公式。

    如果每個客戶ID都只出現一次,用整份訓練資料對ID算目標平均,得到的特徵就等於該筆答案。模型看起來像學得很準,實際上只是答案換了一個欄位名稱。未來新客戶沒有這個答案,流程就接不上了。

    平滑可以減少小樣本極端值,但不會自動移除自己的答案

    圖4|原簡報實體PDF第13頁、投影片6/21。a控制先驗P的權重;分母多a,分子多aP。這是平滑,不代表公式已排除目前這筆的y。來源及授權同圖3;裁去空白、保留標題、公式與原署名列,手機版放大公式。

    把上圖換成比較好讀的記法:

    平滑類別統計 = (同類別的目標總和 + aP) / (同類別樣本數 + a)
    

    當樣本很少,先驗能避免估計直接跳到0或1。但只要目標總和還包含目前這筆,自己的答案就仍影響自己的特徵。平滑處理的是估計不穩定的一部分問題,不能替代資料洩漏檢查。

    先驗本身也有來源:不能拿保留測試集的標籤估計先驗,再宣稱測試資料完全沒參與訓練。接下來的小算例用固定P=0.5,讓這個條件清楚可見。

    Ordered target statistics:只用排序前面已出現的同類樣本

    圖5|原簡報實體PDF第21頁、投影片9/21。訓練第k筆時,Dₖ只包含排序比它早的資料;套用到測試資料時可使用訓練集合D的統計。D不包含測試標籤。來源及授權同圖3;裁去空白並保留原標題、敘述與署名列,手機版放大前綴定義,完整原敘述仍見桌機圖與本段。

    先排好訓練資料。對每筆樣本,用它之前、同類別的資料計算統計,再加入先驗。假設三筆都屬於A,排序後的目標依序是1、0、1,固定P=0.5、a=1:

    現在處理哪筆前面A的目標該筆取得的統計
    第1筆,y=1尚無(0+0.5)/(0+1)=0.5
    第2筆,y=01(1+0.5)/(1+1)=0.75
    第3筆,y=11、0(1+0.5)/(2+1)=0.5

    三筆的特徵分別是0.5、0.75、0.5。若改用全部三筆目標做平滑平均,三筆都會拿到(2+0.5)/(3+1)=0.625。兩者不同,原因在於每筆能看的資訊集合不同。

    這是用來理解概念的單一類別、單一排序算例;CatBoost實際還有多個排序、類別組合及不同統計設定,不是只執行這張三列表格。驗證與新資料的類別統計應由訓練流程取得,不能臨時把新資料真實y填進去。

    隨機排序也不會自動遵守真實時間。如果資料是每日預測、同一客戶重複出現或有群組關聯,外層資料切分仍要依時間/群組設計。工具內部有順序,不表示訓練、驗證與測試已經替你切對。

    Ordered Boosting:這次改的是計算殘差的模型

    圖6|第7筆用M₆而非已看過第7筆標籤的模型來產生平方誤差殘差。上標t−1指前一輪;下標6指排序前綴長度,兩種編號不是同一件事。來源:同作者群/YANDEX LLC,官方2018 NIPS資料夾comics.pdf單頁原圖,Apache 2.0;桌機與手機圖皆保留完整原圖。

    Ordered target statistics在問「這筆類別特徵可以用誰的標籤估計」;Ordered Boosting則在問「算這筆梯度/殘差時,使用的模型已經看過誰」。它們是相配的兩個環節,不能合成一句「類別不會洩漏,所以Boosting也不會偏」。

    以平方誤差為例,若第7筆的預測來自只用前6筆資料建立的前一輪模型,殘差可寫成:

    r₇ᵗ = y₇ − M₆ᵗ⁻¹(x₇)
    

    這仍會用到y₇作為本輪學習訊號;關鍵是相減的預測模型未先把y₇吸收進去。這個想法用來處理論文分析的prediction shift,不是保證所有資料都不過擬合、都無偏或都比Plain準。

    圖7|原始Algorithm 1:第4行先用前綴模型算各筆殘差,第6行再用不同長度的前綴資料學習更新。這是概念算法,不代表正式套件每一輪都把n個完整模型從零重訓。來源:同作者群/YANDEX LLC,官方2018 NIPS資料夾algorithm.png,Apache 2.0;原圖未改,手機版節錄第1–4行與第5–8行分開放大,移除右側空白,程式內容未改。

    CatBoost有Ordered與Plain等設定,Plain仍可使用ordered target statistics。本文實跑明確設boosting_type="Ordered",不把某個版本、裝置或任務的預設值說成永遠如此。原論文的實作也為前綴模型與樹結構計算做了優化,讀懂概念不等於已重現其整套工程。

    同一份含類別資料,實際跑兩次

    下面產生1,000筆虛構、彼此獨立的資料:兩個常態數值欄位,加上一個六種類別的欄位。目標是依指定公式隨機抽出的0/1,沒有真實客戶、營運成效或歷史資料的含義。

    共同切成600筆train、200筆valid、200筆test。只有valid用於early stopping,test在訓練與選輪數後才計算。LightGBM把欄位轉成pandas category,類別字典只由train建立;CatBoost保留原字串並指定cat_features。這次六種類別都在train出現。若未來有未知類別,範例的LightGBM轉換會將其設成缺失;CatBoost使用自身已學到的類別處理規則,兩者不能假定完全等價。

    實測環境為WSL、Python 3.10.12、NumPy 1.26.3、pandas 2.2.2、scikit-learn 1.5.1、LightGBM 4.4.0、CatBoost 1.2.5,CPU單執行緒。這是固定重現版本,並非宣稱最新版本。可在自己的獨立環境安裝這些版本後,將下方程式存成compare_categorical.py執行:

    python -m pip install numpy==1.26.3 pandas==2.2.2 scikit-learn==1.5.1 lightgbm==4.4.0 catboost==1.2.5
    python compare_categorical.py
    
    import numpy as np
    import pandas as pd
    import sklearn
    import lightgbm as lgb
    import catboost
    from catboost import CatBoostClassifier
    from sklearn.model_selection import train_test_split
    from sklearn.metrics import log_loss, roc_auc_score
    
    # Fictional independent rows; category effects and all labels are simulated.
    rng = np.random.default_rng(42)
    n = 1000
    x0, x1 = rng.normal(size=(2, n))
    group_id = rng.integers(0, 6, size=n)
    group_effect = np.array([-1.0, -0.5, 0.0, 0.3, 0.7, 1.0])
    score = 1.2 * x0 - 0.7 * x1 + group_effect[group_id]
    probability = 1.0 / (1.0 + np.exp(-score))
    y = rng.binomial(1, probability)
    X = pd.DataFrame({"x0": x0, "x1": x1,
                      "group": [f"g{k}" for k in group_id]})
    dev, test = train_test_split(np.arange(n), test_size=0.2,
                                 stratify=y, random_state=42)
    train, valid = train_test_split(dev, test_size=0.25,
                                   stratify=y[dev], random_state=42)
    
    # Fit the categorical vocabulary on train; unseen levels become missing here.
    levels = sorted(X.iloc[train]["group"].unique())
    X_lgb = X.copy()
    X_lgb["group"] = pd.Categorical(X_lgb["group"], categories=levels)
    light = lgb.LGBMClassifier(
        n_estimators=500, learning_rate=0.05, num_leaves=15,
        min_child_samples=20, reg_lambda=1.0,
        random_state=42, n_jobs=1, verbosity=-1,
        deterministic=True, force_col_wise=True,
    )
    light.fit(
        X_lgb.iloc[train], y[train],
        eval_set=[(X_lgb.iloc[valid], y[valid])],
        eval_metric="binary_logloss",
        callbacks=[lgb.early_stopping(30, verbose=False), lgb.log_evaluation(0)],
    )
    
    # Keep categorical strings; explicitly choose Ordered and symmetric trees.
    cat = CatBoostClassifier(
        iterations=500, learning_rate=0.05, depth=4, l2_leaf_reg=3.0,
        loss_function="Logloss", eval_metric="Logloss",
        boosting_type="Ordered", grow_policy="SymmetricTree",
        random_seed=42, thread_count=1, task_type="CPU",
        allow_writing_files=False, verbose=False,
    )
    cat.fit(
        X.iloc[train], y[train], cat_features=["group"],
        eval_set=(X.iloc[valid], y[valid]),
        early_stopping_rounds=30, use_best_model=True,
    )
    
    print(f"versions numpy={np.__version__} pandas={pd.__version__} "
          f"sklearn={sklearn.__version__} lightgbm={lgb.__version__} "
          f"catboost={catboost.__version__}")
    print(f"split train={len(train)} valid={len(valid)} test={len(test)}")
    print("train_levels=" + ",".join(levels))
    print(f"LightGBM selected_rounds={light.best_iteration_}")
    print(f"CatBoost best_iteration_zero_based={cat.best_iteration_} "
          f"retained_trees={cat.tree_count_}")
    for name, model, frame in [("LightGBM", light, X_lgb), ("CatBoost", cat, X)]:
        for split_name, indices in [("valid", valid), ("test", test)]:
            p = model.predict_proba(frame.iloc[indices])[:, 1]
            print(f"{name} {split_name} logloss={log_loss(y[indices], p):.6f} "
                  f"auc={roc_auc_score(y[indices], p):.6f}")
    baseline = np.full(len(test), y[train].mean())
    print(f"training_prior test logloss={log_loss(y[test], baseline):.6f}")
    
    # The fixed prior is a teaching choice, not estimated from the current label.
    labels = [1, 0, 1]
    prior, a = 0.5, 1.0
    ordered = [(sum(labels[:i]) + a * prior) / (i + a)
               for i in range(len(labels))]
    greedy = (sum(labels) + a * prior) / (len(labels) + a)
    print("ordered_toy=" + ",".join(f"{z:.6f}" for z in ordered))
    print(f"all_labels_smoothed={greedy:.6f}")
    

    輪數由驗證集選,測試集只回報一次

    實跑的選擇結果是LightGBM保留44輪;CatBoost的best_iteration_是從0開始的155,保留156棵樹。兩者最多都准許500輪、連續30輪未改善即停止;但每輪樹的結構、類別處理與計算不同,所以這不是相同算力預算的速度測試。

    模型valid log lossvalid AUCtest log losstest AUC
    LightGBM0.5967370.7486250.5222300.824932
    CatBoost0.5646700.7765280.5207840.827083

    只用train正類比例作固定機率預測,test log loss為0.693103。這讓我們知道兩套模型在這次合成資料上都學到了比常數預測更多的訊號。兩個模型的test差異很小,沒有多次切分、不確定性估計或相同搜尋成本控制,不能推出CatBoost普遍勝出;test比valid好也不奇怪,兩份有限樣本不必難度相同。

    Log loss檢查機率型輸出與答案的相符程度,AUC看排序,不是固定閾值下的accuracy,也不是已驗證機率校準。若要做實際決策,還要回到分類指標與閾值及業務成本。

    這份程式沒有手工預算全資料target encoding;類別統計由工具的訓練流程負責。不要為了加速,先用整份資料含test的y算類別均值,再把程式裡的字串欄位換掉;那會改變這次實驗最重要的前提。

    選工具之前,先保留可以比較的條件

    你遇到的問題先檢查什麼

    很多列、很多切點,記憶體或訓練時間吃緊
    直方圖參數、硬體、資料型態與實測資源;不只看模型名字
    類別很多、每類樣本少
    編碼是否洩漏、未知類別規則、平滑與類別組合的成本
    訓練很好,valid掉很多
    葉數、深度、每葉條件、正則化、資料切分與洩漏
    某套工具分數只好一點點
    相同資料切分、搜尋預算、重複評估與部署成本

    LightGBM可以從較小的葉數、合理每葉樣本條件開始;CatBoost則先確認哪些欄位真的是類別,以及是否需要Ordered設定。不要把同名depth或相同500輪當成公平成本的保證,也不要從小樣本範例推估百萬筆資料的速度。

    這一篇增加的是兩套工具的理解與可運行入口。接下來比較模型時,仍需要把搜尋空間、驗證規則與保留測試放在同一個實驗設計裡,才能知道較高的分數是否值得換掉現有方案。

    原始來源、配圖與授權

    技術脈絡取自LightGBM Features、LightGBM 4.4.0分類器API、CatBoost原論文、官方2018 NIPS簡報與原圖及CatBoost參數文件。查核日2026-10-31;現行線上文件與本篇固定實跑版本可能不同。LightGBM文件提及的其他工具歷史預設,不作今日所有版本的比較依據。

    圖1–2採LightGBM官方文件原圖,MIT,Copyright (c) Microsoft Corporation;Copyright (c) The LightGBM developers。圖3–7採CatBoost官方repository內的原始簡報/圖檔,Apache License 2.0,Copyright 2017–2026 YANDEX LLC;作者為Liudmila Prokhorenkova、Gleb Gusev、Aleksandr Vorobev、Anna Veronika Dorogush、Andrey Gulin。沒有把arXiv下載權當作轉載授權,也沒有採用另有網站使用限制的新聞文章圖片。

    本篇教學文字、bin小表格、三筆類別算例及合成分類程式為重新設計的教學材料;來源圖不表示作者為本篇背書。圖檔裁切、手機編排及封面修改逐項見各圖說與下列說明,完整授權附於文末。

    封面採圖2完整原圖等比縮放加白邊。手機圖1–2將各完整生長階段改成上下排列,省去階段間箭頭與重複英文底標;圖3–4放大完整公式;圖5放大完整前綴集合定義;圖6保留完整原圖;圖7保留第1–8行、移除標題/input與外側空白並分段排列。原始意義、數字與公式未改;原圖完整上下文見正文與來源連結。

    MIT-LightGBM 原始授權全文

    The MIT License (MIT)
    
    Copyright (c) Microsoft Corporation
    Copyright (c) The LightGBM developers
    
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
    
    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    SOFTWARE.
    

    Apache-2.0-CatBoost 原始授權全文

    Copyright 2017-2026 YANDEX LLC
    
                                   Apache License
                               Version 2.0, January 2004
                            http://www.apache.org/licenses/
    
       TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
    
       1. Definitions.
    
          "License" shall mean the terms and conditions for use, reproduction,
          and distribution as defined by Sections 1 through 9 of this document.
    
          "Licensor" shall mean the copyright owner or entity authorized by
          the copyright owner that is granting the License.
    
          "Legal Entity" shall mean the union of the acting entity and all
          other entities that control, are controlled by, or are under common
          control with that entity. For the purposes of this definition,
          "control" means (i) the power, direct or indirect, to cause the
          direction or management of such entity, whether by contract or
          otherwise, or (ii) ownership of fifty percent (50%) or more of the
          outstanding shares, or (iii) beneficial ownership of such entity.
    
          "You" (or "Your") shall mean an individual or Legal Entity
          exercising permissions granted by this License.
    
          "Source" form shall mean the preferred form for making modifications,
          including but not limited to software source code, documentation
          source, and configuration files.
    
          "Object" form shall mean any form resulting from mechanical
          transformation or translation of a Source form, including but
          not limited to compiled object code, generated documentation,
          and conversions to other media types.
    
          "Work" shall mean the work of authorship, whether in Source or
          Object form, made available under the License, as indicated by a
          copyright notice that is included in or attached to the work
          (an example is provided in the Appendix below).
    
          "Derivative Works" shall mean any work, whether in Source or Object
          form, that is based on (or derived from) the Work and for which the
          editorial revisions, annotations, elaborations, or other modifications
          represent, as a whole, an original work of authorship. For the purposes
          of this License, Derivative Works shall not include works that remain
          separable from, or merely link (or bind by name) to the interfaces of,
          the Work and Derivative Works thereof.
    
          "Contribution" shall mean any work of authorship, including
          the original version of the Work and any modifications or additions
          to that Work or Derivative Works thereof, that is intentionally
          submitted to Licensor for inclusion in the Work by the copyright owner
          or by an individual or Legal Entity authorized to submit on behalf of
          the copyright owner. For the purposes of this definition, "submitted"
          means any form of electronic, verbal, or written communication sent
          to the Licensor or its representatives, including but not limited to
          communication on electronic mailing lists, source code control systems,
          and issue tracking systems that are managed by, or on behalf of, the
          Licensor for the purpose of discussing and improving the Work, but
          excluding communication that is conspicuously marked or otherwise
          designated in writing by the copyright owner as "Not a Contribution."
    
          "Contributor" shall mean Licensor and any individual or Legal Entity
          on behalf of whom a Contribution has been received by Licensor and
          subsequently incorporated within the Work.
    
       2. Grant of Copyright License. Subject to the terms and conditions of
          this License, each Contributor hereby grants to You a perpetual,
          worldwide, non-exclusive, no-charge, royalty-free, irrevocable
          copyright license to reproduce, prepare Derivative Works of,
          publicly display, publicly perform, sublicense, and distribute the
          Work and such Derivative Works in Source or Object form.
    
       3. Grant of Patent License. Subject to the terms and conditions of
          this License, each Contributor hereby grants to You a perpetual,
          worldwide, non-exclusive, no-charge, royalty-free, irrevocable
          (except as stated in this section) patent license to make, have made,
          use, offer to sell, sell, import, and otherwise transfer the Work,
          where such license applies only to those patent claims licensable
          by such Contributor that are necessarily infringed by their
          Contribution(s) alone or by combination of their Contribution(s)
          with the Work to which such Contribution(s) was submitted. If You
          institute patent litigation against any entity (including a
          cross-claim or counterclaim in a lawsuit) alleging that the Work
          or a Contribution incorporated within the Work constitutes direct
          or contributory patent infringement, then any patent licenses
          granted to You under this License for that Work shall terminate
          as of the date such litigation is filed.
    
       4. Redistribution. You may reproduce and distribute copies of the
          Work or Derivative Works thereof in any medium, with or without
          modifications, and in Source or Object form, provided that You
          meet the following conditions:
    
          (a) You must give any other recipients of the Work or
              Derivative Works a copy of this License; and
    
          (b) You must cause any modified files to carry prominent notices
              stating that You changed the files; and
    
          (c) You must retain, in the Source form of any Derivative Works
              that You distribute, all copyright, patent, trademark, and
              attribution notices from the Source form of the Work,
              excluding those notices that do not pertain to any part of
              the Derivative Works; and
    
          (d) If the Work includes a "NOTICE" text file as part of its
              distribution, then any Derivative Works that You distribute must
              include a readable copy of the attribution notices contained
              within such NOTICE file, excluding those notices that do not
              pertain to any part of the Derivative Works, in at least one
              of the following places: within a NOTICE text file distributed
              as part of the Derivative Works; within the Source form or
              documentation, if provided along with the Derivative Works; or,
              within a display generated by the Derivative Works, if and
              wherever such third-party notices normally appear. The contents
              of the NOTICE file are for informational purposes only and
              do not modify the License. You may add Your own attribution
              notices within Derivative Works that You distribute, alongside
              or as an addendum to the NOTICE text from the Work, provided
              that such additional attribution notices cannot be construed
              as modifying the License.
    
          You may add Your own copyright statement to Your modifications and
          may provide additional or different license terms and conditions
          for use, reproduction, or distribution of Your modifications, or
          for any such Derivative Works as a whole, provided Your use,
          reproduction, and distribution of the Work otherwise complies with
          the conditions stated in this License.
    
       5. Submission of Contributions. Unless You explicitly state otherwise,
          any Contribution intentionally submitted for inclusion in the Work
          by You to the Licensor shall be under the terms and conditions of
          this License, without any additional terms or conditions.
          Notwithstanding the above, nothing herein shall supersede or modify
          the terms of any separate license agreement you may have executed
          with Licensor regarding such Contributions.
    
       6. Trademarks. This License does not grant permission to use the trade
          names, trademarks, service marks, or product names of the Licensor,
          except as required for reasonable and customary use in describing the
          origin of the Work and reproducing the content of the NOTICE file.
    
       7. Disclaimer of Warranty. Unless required by applicable law or
          agreed to in writing, Licensor provides the Work (and each
          Contributor provides its Contributions) on an "AS IS" BASIS,
          WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
          implied, including, without limitation, any warranties or conditions
          of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
          PARTICULAR PURPOSE. You are solely responsible for determining the
          appropriateness of using or redistributing the Work and assume any
          risks associated with Your exercise of permissions under this License.
    
       8. Limitation of Liability. In no event and under no legal theory,
          whether in tort (including negligence), contract, or otherwise,
          unless required by applicable law (such as deliberate and grossly
          negligent acts) or agreed to in writing, shall any Contributor be
          liable to You for damages, including any direct, indirect, special,
          incidental, or consequential damages of any character arising as a
          result of this License or out of the use or inability to use the
          Work (including but not limited to damages for loss of goodwill,
          work stoppage, computer failure or malfunction, or any and all
          other commercial damages or losses), even if such Contributor
          has been advised of the possibility of such damages.
    
       9. Accepting Warranty or Additional Liability. While redistributing
          the Work or Derivative Works thereof, You may choose to offer,
          and charge a fee for, acceptance of support, warranty, indemnity,
          or other liability obligations and/or rights consistent with this
          License. However, in accepting such obligations, You may act only
          on Your own behalf and on Your sole responsibility, not on behalf
          of any other Contributor, and only if You agree to indemnify,
          defend, and hold each Contributor harmless for any liability
          incurred by, or claims asserted against, such Contributor by reason
          of your accepting any such warranty or additional liability.
    
       END OF TERMS AND CONDITIONS
    
       APPENDIX: How to apply the Apache License to your work.
    
          To apply the Apache License to your work, attach the following
          boilerplate notice, with the fields enclosed by brackets "[]"
          replaced with your own identifying information. (Don't include
          the brackets!)  The text should be enclosed in the appropriate
          comment syntax for the file format. We also recommend that a
          file or class name and description of purpose be included on the
          same "printed page" as the copyright notice for easier
          identification within third-party archives.
    
       Copyright 2017 YANDEX LLC
    
       Licensed under the Apache License, Version 2.0 (the "License");
       you may not use this file except in compliance with the License.
       You may obtain a copy of the License at
    
           http://www.apache.org/licenses/LICENSE-2.0
    
       Unless required by applicable law or agreed to in writing, software
       distributed under the License is distributed on an "AS IS" BASIS,
       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       See the License for the specific language governing permissions and
       limitations under the License.
    

    留言0

    登入後就能留言。

    登入
    sunny 桑尼
    sunny 桑尼

    AI 資料科學 · 產品經理 · 蒙奇 D 桑尼

    專注於 AI 工具應用與資料科學教育,致力於讓每個人都能用 AI 提升工作效率。曾任職於科技業,現為全職教育創作者。

    讀更多文章 →想自己動手試?領免費 Starter Kit →