# XGBoost vs LightGBM 2026: Gradient Boosting และคำถามสัมภาษณ์ Data Science > เชี่ยวชาญ XGBoost และ LightGBM สำหรับการสัมภาษณ์งาน data science เปรียบเทียบอัลกอริทึม gradient boosting เรียนรู้ hyperparameter tuning และฝึกคำถามสัมภาษณ์พร้อมตัวอย่างโค้ด - Published: 2026-09-17 - Updated: 2026-09-17 - Author: Anthony Fillion-Maillet - Tags: xgboost, lightgbm, gradient-boosting, machine-learning, data-science-interview - Reading time: 9 min --- XGBoost และ LightGBM ยังคงเป็นการ implement gradient boosting ที่มีประสิทธิภาพมากที่สุดสำหรับข้อมูลแบบตารางในปี 2026 โดยสามารถเอาชนะ deep learning ได้อย่างสม่ำเสมอบนชุดข้อมูลที่มีโครงสร้าง ทั้งสองไลบรารีมีการพัฒนาอย่างมาก โดย XGBoost 2.1 และ LightGBM 4.5 ได้แนะนำการปรับปรุงการเร่งความเร็ว GPU และการจัดการ categorical features ที่ดีขึ้น > **เคล็ดลับการสัมภาษณ์** > > เมื่อถูกถามว่า "ทำไมถึงใช้ XGBoost แทน neural network?" ให้เน้นย้ำว่า gradient boosting จัดการข้อมูลแบบตารางที่มีตัวอย่างน้อยกว่าได้อย่างมีประสิทธิภาพมากกว่า ต้องการ feature engineering น้อยกว่า และมี feature importance ในตัว Neural network เก่งในข้อมูลที่ไม่มีโครงสร้าง (ภาพ ข้อความ เสียง) แต่ประสบปัญหากับ heterogeneous tabular features ## ความแตกต่างระหว่าง Gradient Boosting กับ Random Forests Gradient boosting และ Random Forests ต่างใช้ decision trees แต่แนวทางการฝึกแตกต่างกันโดยพื้นฐาน Random Forests ฝึก trees อย่างอิสระและขนานกัน จากนั้นเฉลี่ยการทำนาย Gradient boosting ฝึก trees ตามลำดับ โดยแต่ละ tree แก้ไขข้อผิดพลาดของ ensemble ก่อนหน้า สูตรทางคณิตศาสตร์ช่วยชี้แจงความแตกต่างนี้ ในการวนรอบ `m` gradient boosting จะ fit tree ใหม่ `h_m(x)` ให้กับ negative gradient ของ loss function เทียบกับการทำนายของ ensemble ปัจจุบัน สำหรับ squared error loss negative gradient นี้เท่ากับ residuals ```python # gradient_boosting_demo.py import numpy as np from sklearn.tree import DecisionTreeRegressor def gradient_boosting_from_scratch(X, y, n_estimators=100, learning_rate=0.1, max_depth=3): """Simplified gradient boosting for regression to illustrate the algorithm.""" # Initialize predictions with the mean (minimizes squared error) predictions = np.full(len(y), y.mean()) trees = [] for _ in range(n_estimators): # Compute negative gradient (residuals for MSE loss) residuals = y - predictions # Fit a tree to the residuals tree = DecisionTreeRegressor(max_depth=max_depth) tree.fit(X, residuals) trees.append(tree) # Update predictions with shrinkage (learning rate) predictions += learning_rate * tree.predict(X) return trees, y.mean() ``` การพึ่งพาตามลำดับนี้ทำให้ gradient boosting ฝึกช้ากว่า Random Forests แต่โดยทั่วไปจะแม่นยำกว่าบนชุดข้อมูลเดียวกัน ## สถาปัตยกรรม XGBoost และพารามิเตอร์หลัก [XGBoost](https://xgboost.readthedocs.io/en/stable/) (eXtreme Gradient Boosting) ได้แนะนำการเพิ่มประสิทธิภาพหลายอย่างที่ทำให้ gradient boosting ใช้งานได้จริงในระดับขนาดใหญ่ ไลบรารีนี้ใช้ regularized objective function ที่รวม loss กับ L1 และ L2 penalties บน leaf weights ลด overfitting โดยไม่ต้องทำ cross-validation อย่างกว้างขวาง ```python # xgboost_classification.py import xgboost as xgb from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split # Generate synthetic classification data X, y = make_classification(n_samples=10000, n_features=20, n_informative=10, random_state=42) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # XGBoost with commonly tuned hyperparameters model = xgb.XGBClassifier( n_estimators=500, # Number of boosting rounds max_depth=6, # Maximum tree depth (controls complexity) learning_rate=0.1, # Shrinkage factor (eta in XGBoost docs) subsample=0.8, # Row sampling ratio per tree colsample_bytree=0.8, # Column sampling ratio per tree reg_alpha=0.1, # L1 regularization on leaf weights reg_lambda=1.0, # L2 regularization on leaf weights tree_method='hist', # Histogram-based algorithm (faster) early_stopping_rounds=50, # Stop if no improvement after 50 rounds random_state=42 ) model.fit( X_train, y_train, eval_set=[(X_test, y_test)], # Validation set for early stopping verbose=False ) print(f"Best iteration: {model.best_iteration}") print(f"Test accuracy: {model.score(X_test, y_test):.4f}") ``` พารามิเตอร์ `tree_method='hist'` ควรได้รับความสนใจ Histogram-based tree building ทำการ quantize continuous features เป็น discrete bins ลดการใช้หน่วยความจำและเร่งการค้นหา split XGBoost 2.0+ ใช้วิธีนี้เป็นค่าเริ่มต้น ## LightGBM: การเติบโตแบบ Leaf-Wise และการจัดการ Categorical [LightGBM](https://lightgbm.readthedocs.io/en/stable/) (Light Gradient Boosting Machine) จาก Microsoft ได้แนะนำนวัตกรรมสองอย่างที่มักทำให้เร็วกว่า XGBoost: การเติบโต tree แบบ leaf-wise และ Gradient-based One-Side Sampling (GOSS) Decision trees แบบดั้งเดิมเติบโตทีละ level โดยแยก nodes ทั้งหมดในความลึกที่กำหนดก่อนที่จะไปลึกขึ้น LightGBM เติบโตแบบ leaf-wise โดยแยก leaf ที่มีศักยภาพ gain สูงสุดเสมอ แนวทางไม่สมมาตรนี้สร้าง trees ที่ซับซ้อนกว่าด้วย splits น้อยกว่า มักจะถึง training loss ที่ต่ำกว่าเร็วกว่า ```python # lightgbm_with_categorical.py import lightgbm as lgb import pandas as pd import numpy as np from sklearn.model_selection import train_test_split # Create dataset with categorical features np.random.seed(42) df = pd.DataFrame({ 'category_a': np.random.choice(['low', 'medium', 'high'], 10000), 'category_b': np.random.choice(['type1', 'type2', 'type3', 'type4'], 10000), 'numeric_1': np.random.randn(10000), 'numeric_2': np.random.randn(10000), 'target': np.random.randint(0, 2, 10000) }) # Convert to categorical dtype (LightGBM reads this automatically) df['category_a'] = df['category_a'].astype('category') df['category_b'] = df['category_b'].astype('category') X = df.drop('target', axis=1) y = df['target'] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # LightGBM handles categorical features natively model = lgb.LGBMClassifier( n_estimators=500, max_depth=-1, # No limit (leaf-wise growth controls complexity) num_leaves=31, # Maximum leaves per tree (key LightGBM param) learning_rate=0.1, subsample=0.8, colsample_bytree=0.8, min_child_samples=20, # Minimum samples in a leaf reg_alpha=0.1, reg_lambda=1.0, random_state=42, verbose=-1 ) model.fit( X_train, y_train, eval_set=[(X_test, y_test)], callbacks=[lgb.early_stopping(50, verbose=False)] ) print(f"Best iteration: {model.best_iteration_}") print(f"Test accuracy: {model.score(X_test, y_test):.4f}") ``` การจัดการ categorical แบบ native ของ LightGBM เหนือกว่า one-hot encoding สำหรับ features ที่มี cardinality สูง อัลกอริทึมค้นหา splits ที่เหมาะสมที่สุดข้าม categorical values โดยไม่ต้องสร้าง sparse matrices ## XGBoost vs LightGBM: การเปรียบเทียบในทางปฏิบัติ การเลือกระหว่าง XGBoost และ LightGBM ขึ้นอยู่กับลักษณะของชุดข้อมูลและข้อจำกัด นี่คือการเปรียบเทียบโดยตรงตาม benchmarks และประสบการณ์จริง: | ด้าน | XGBoost 2.1 | LightGBM 4.5 | |------|-------------|---------------| | ความเร็วการฝึก | ช้ากว่าบนชุดข้อมูลขนาดใหญ่ | เร็วกว่า 2-5 เท่าด้วย GOSS | | การใช้หน่วยความจำ | สูงกว่า | ต่ำกว่า (histogram binning) | | Categorical features | ต้องการ encoding | รองรับแบบ native | | การเติบโตของ tree | Level-wise (ค่าเริ่มต้น) | Leaf-wise | | รองรับ GPU | CUDA, วิธี histogram | CUDA, รองรับ native | | ความเสี่ยง overfitting | ต่ำกว่า (level-wise) | สูงกว่า (leaf-wise, tune `num_leaves`) | | ชุดข้อมูลขนาดเล็ก (<10k แถว) | มักดีกว่า | เทียบเท่า | | ชุดข้อมูลขนาดใหญ่ (>1M แถว) | ช้ากว่า | เหมาะสมกว่า | สำหรับงาน [feature engineering](/blog/data-science/feature-engineering-machine-learning-techniques-interview-2026) ที่เวลาการฝึกมีความสำคัญ ข้อได้เปรียบด้านความเร็วของ LightGBM จะสำคัญมากในระหว่างการทดลองแบบวนซ้ำ ## กลยุทธ์ Hyperparameter Tuning สำหรับการสัมภาษณ์ ผู้สัมภาษณ์มักถามวิธีการ tune โมเดล gradient boosting แนวทางที่มีโครงสร้างแสดงถึงความคิดเชิงระบบมากกว่า random grid search ```python # hyperparameter_tuning.py import optuna import xgboost as xgb from sklearn.model_selection import cross_val_score from sklearn.datasets import make_classification X, y = make_classification(n_samples=5000, n_features=20, n_informative=10, random_state=42) def objective(trial): """Optuna objective for XGBoost hyperparameter optimization.""" params = { # Start with learning rate and n_estimators 'learning_rate': trial.suggest_float('learning_rate', 0.01, 0.3, log=True), 'n_estimators': trial.suggest_int('n_estimators', 100, 1000), # Tree complexity (most important for bias-variance tradeoff) 'max_depth': trial.suggest_int('max_depth', 3, 10), 'min_child_weight': trial.suggest_int('min_child_weight', 1, 10), # Regularization (reduce overfitting) 'reg_alpha': trial.suggest_float('reg_alpha', 1e-8, 10.0, log=True), 'reg_lambda': trial.suggest_float('reg_lambda', 1e-8, 10.0, log=True), # Sampling (stochastic gradient boosting) 'subsample': trial.suggest_float('subsample', 0.5, 1.0), 'colsample_bytree': trial.suggest_float('colsample_bytree', 0.5, 1.0), 'tree_method': 'hist', 'random_state': 42 } model = xgb.XGBClassifier(**params) scores = cross_val_score(model, X, y, cv=5, scoring='roc_auc') return scores.mean() study = optuna.create_study(direction='maximize') study.optimize(objective, n_trials=50, show_progress_bar=True) print(f"Best ROC-AUC: {study.best_value:.4f}") print(f"Best params: {study.best_params}") ``` ลำดับความสำคัญของการ tuning มีความสำคัญ: learning rate และจำนวน estimators ก่อน จากนั้นความซับซ้อนของ tree (`max_depth`, `num_leaves`) ตามด้วย regularization แล้วอัตราส่วน sampling ลำดับนี้สะท้อนวิธีที่พารามิเตอร์ส่งผลต่อ bias-variance tradeoff ## คำถามสัมภาษณ์ทั่วไปเกี่ยวกับ Gradient Boosting การสัมภาษณ์ data science ทดสอบทั้งความเข้าใจทางทฤษฎีและทักษะการ debug ในทางปฏิบัติ คำถามเหล่านี้ปรากฏบ่อยในการสัมภาษณ์ที่บริษัทที่ทำงานกับข้อมูลแบบตาราง **ถาม: ทำไม gradient boosting ถึง overfit ง่ายกว่า Random Forests?** Gradient boosting ฝึกตามลำดับ โดยแต่ละ tree fit ข้อผิดพลาดของ ensemble อย่างชัดเจน Trees ระยะหลังสามารถจดจำ noise ใน residuals ได้ Random Forests ฝึก trees อย่างอิสระบนตัวอย่าง bootstrap และการเฉลี่ยลด variance Regularization (learning rate, subsampling, ข้อจำกัด tree) ช่วยลดปัญหานี้ใน gradient boosting **ถาม: อะไรทำให้ XGBoost ให้ผลลัพธ์ที่แตกต่างกันบนข้อมูลเดียวกัน?** ความไม่แน่นอนมาจากสามแหล่ง: row subsampling (`subsample`), column subsampling (`colsample_bytree`) และการสร้าง histogram แบบขนาน การตั้ง `random_state` แก้ไขสองอย่างแรก สำหรับความสามารถในการทำซ้ำที่แน่นอน ให้ตั้ง `n_jobs=1` ด้วย แม้ว่าจะทำให้การฝึกช้าลง **ถาม: จัดการ class imbalance ใน XGBoost อย่างไร?** สามแนวทางที่ใช้ได้: 1. `scale_pos_weight`: ตั้งเป็น `(negative_count / positive_count)` สำหรับ binary classification 2. `sample_weight`: ส่ง instance weights ไปยัง `fit()` 3. Resampling: SMOTE หรือ random undersampling ก่อนการฝึก แนวทาง `scale_pos_weight` แก้ไข loss function และรักษาการกระจายข้อมูลดั้งเดิม มักเป็นที่นิยมมากกว่า resampling **ถาม: เมื่อไหร่ควรเลือก CatBoost แทน XGBoost หรือ LightGBM?** [CatBoost](https://catboost.ai/en/docs/) เก่งเมื่อชุดข้อมูลมี categorical features จำนวนมากที่มี cardinality สูง และเมื่อการลด overfitting ด้วยการ tuning น้อยที่สุดเป็นสิ่งสำคัญ Ordered boosting และโครงสร้าง tree แบบสมมาตรทำให้มันทนต่อ overfitting บนชุดข้อมูลขนาดเล็กได้ดีกว่า ข้อแลกเปลี่ยนคือการฝึกช้ากว่า LightGBM สำหรับพื้นฐานการจำแนกประเภทเพิ่มเติม ดู [โมดูลการจำแนกประเภท supervised learning](/technologies/data-science/interview-questions/ml-supervised-classification) ## Feature Importance และความสามารถในการตีความโมเดล การอธิบายการทำนายมีความสำคัญในอุตสาหกรรมที่ถูกควบคุมและสร้างความไว้วางใจกับผู้มีส่วนได้ส่วนเสีย ทั้ง XGBoost และ LightGBM ให้ feature importance ในตัว แต่การตีความต้องระมัดระวัง ```python # feature_importance.py import xgboost as xgb import matplotlib.pyplot as plt from sklearn.datasets import make_classification X, y = make_classification(n_samples=5000, n_features=20, n_informative=10, random_state=42) feature_names = [f'feature_{i}' for i in range(20)] model = xgb.XGBClassifier(n_estimators=100, random_state=42) model.fit(X, y) # Three importance types available importance_types = ['weight', 'gain', 'cover'] for imp_type in importance_types: importance = model.get_booster().get_score(importance_type=imp_type) print(f"\n{imp_type.upper()} importance (top 5):") sorted_imp = sorted(importance.items(), key=lambda x: x[1], reverse=True)[:5] for feat, score in sorted_imp: print(f" {feat}: {score:.2f}") ``` - **Weight**: จำนวนครั้งที่ feature ปรากฏใน splits ข้าม trees ทั้งหมด - **Gain**: การปรับปรุงเฉลี่ยใน objective function เมื่อ feature ถูกใช้สำหรับ splitting - **Cover**: จำนวนตัวอย่างเฉลี่ยที่ได้รับผลกระทบจาก splits บน feature นี้ Gain มักให้การวัด importance ที่มีความหมายมากที่สุด เนื่องจากเกี่ยวข้องโดยตรงกับการปรับปรุงโมเดล อย่างไรก็ตาม features ที่มีความสัมพันธ์กันอาจมี importance ที่ถูกประเมินต่ำเกินไป เนื่องจากโมเดลอาจ split บนอย่างใดอย่างหนึ่ง สำหรับการตีความเชิงสาเหตุ SHAP values ([มีให้ผ่านไลบรารี shap](https://shap.readthedocs.io/en/latest/)) ให้การระบุ feature ที่สอดคล้องและมีพื้นฐานทางทฤษฎีต่อการทำนาย ## ข้อพิจารณาในการ Deploy บน Production การ deploy โมเดล gradient boosting นำมาซึ่งปัญหาเรื่อง latency และ serialization ที่แตกต่างจากการฝึก ```python # model_serialization.py import xgboost as xgb import json # Train a model model = xgb.XGBClassifier(n_estimators=100, random_state=42) model.fit(X_train, y_train) # Save in XGBoost's native binary format (recommended for production) model.save_model('model.ubj') # Universal Binary JSON format # Load for inference loaded_model = xgb.XGBClassifier() loaded_model.load_model('model.ubj') # For model versioning, save with metadata metadata = { 'version': '1.0.0', 'trained_at': '2026-09-17', 'features': feature_names, 'best_iteration': model.best_iteration } with open('model_metadata.json', 'w') as f: json.dump(metadata, f) ``` Inference latency ขึ้นอยู่กับความลึกและจำนวน tree สำหรับแอปพลิเคชัน real-time ที่มีข้อกำหนด latency เข้มงวด (ต่ำกว่า 10ms) ให้พิจารณา: - ลด `n_estimators` ด้วย learning rate ที่สูงขึ้น - จำกัด `max_depth` ไว้ที่ 4-5 - ใช้เมธอด `predict()` ด้วย `iteration_range` เพื่อใช้ trees น้อยลง ## ประเด็นสำคัญสำหรับการสัมภาษณ์ XGBoost และ LightGBM - Gradient boosting ฝึก trees ตามลำดับบน residuals ไม่เหมือน Random Forests ที่ฝึกแบบขนานและเฉลี่ย - XGBoost เพิ่ม L1/L2 regularization ใน objective function ลด overfitting โดยไม่ต้อง cross-validation อย่างกว้างขวาง - LightGBM ใช้การเติบโตแบบ leaf-wise และ GOSS sampling ทำให้เร็วกว่า 2-5 เท่าบนชุดข้อมูลขนาดใหญ่ - การจัดการ categorical แบบ native ใน LightGBM เหนือกว่า one-hot encoding สำหรับ features ที่มี cardinality สูง - Tune ตามลำดับ: learning rate, ความซับซ้อนของ tree, regularization, อัตราส่วน sampling - `scale_pos_weight` จัดการ class imbalance โดยแก้ไข loss function รักษาการกระจายดั้งเดิม - Feature importance ตาม gain วัดการปรับปรุงโมเดลจริง แต่ features ที่มีความสัมพันธ์กันอาจดูมีความสำคัญน้อยกว่า - สำหรับ production ใช้รูปแบบ `.ubj` และพิจารณาลดจำนวน tree สำหรับแอปพลิเคชันที่ไวต่อ latency --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/th/blog/data-science/xgboost-lightgbm-gradient-boosting-interview-2026