基于決策樹模型的汽車價格預測分析

一、整體流程概覽

這份代碼實現了一個完整的機器學習預測流程,核心目標是通過汽車的各項特征預測其價格。整體流程分為 6 個主要步驟:

  1. 模擬生成汽車數據集(含價格標簽)
  2. 數據預處理(清洗、編碼、特征選擇)
  3. 探索性數據分析(可視化數據分布和關系)
  4. 基礎模型訓練與評估
  5. 網格搜索優化模型參數
  6. 特征重要性分析

使用的核心算法是決策樹回歸器DecisionTreeRegressor),因為它能很好地捕捉特征與價格之間的非線性關系,且結果易于解釋。

二、詳細代碼講解

1. 模擬生成汽車數據庫(generate_car_data函數)

這一步的目標是創建一個貼近真實的汽車數據集,包含影響價格的關鍵特征和目標變量(價格)。

def generate_car_data(n_samples=1000):np.random.seed(42)  # 固定隨機種子,確保結果可復現
  • np.random.seed(42):設置隨機種子,保證每次運行生成相同的數據,便于調試和結果復現。
    brands = {'luxury': ['Mercedes', 'BMW', 'Audi', 'Lexus'],'mid_range': ['Toyota', 'Honda', 'Ford', 'Volkswagen'],'economy': ['Hyundai', 'Kia', 'Chevrolet', 'Fiat']
    }# 品牌概率計算(總和為1)
    luxury_prob = 0.2  # 豪華品牌整體占比20%
    mid_range_prob = 0.5  # 中端品牌50%
    economy_prob = 0.3  # 經濟品牌30%# 每個品牌的概率 = 類別總概率 / 類別內品牌數量
    luxury_p = [luxury_prob / 4] * 4  # 4個豪華品牌,每個占5%
    mid_range_p = [mid_range_prob / 4] * 4  # 4個中端品牌,每個占12.5%
    economy_p = [economy_prob / 4] * 4  # 4個經濟品牌,每個占7.5%
    p = luxury_p + mid_range_p + economy_p  # 合并概率列表(總和=1)

  • 解決了之前的ValueError:通過按類別分配總概率,再平均到每個品牌,確保概率總和為 1。
  • 1.2 特征生成
    data = {'brand': np.random.choice(brands['luxury'] + brands['mid_range'] + brands['economy'],size=n_samples, p=p),'age': np.random.randint(0, 15, size=n_samples),  # 車齡0-14年'mileage': np.random.lognormal(4.5, 0.8, size=n_samples) + np.random.randint(0, 50, size=n_samples),  # 里程數(對數正態分布,模擬真實車輛里程)'engine_size': np.round(np.random.uniform(1.0, 4.5, size=n_samples), 1),  # 發動機排量1.0-4.5L'horsepower': np.random.randint(80, 350, size=n_samples),  # 馬力80-349匹'fuel_type': np.random.choice(['gasoline', 'diesel', 'hybrid', 'electric'], p=[0.6, 0.2, 0.15, 0.05]),  # 燃油類型(汽油車占比最高)'transmission': np.random.choice(['manual', 'automatic'], p=[0.3, 0.7]),  # 變速箱(自動擋占比70%)'maintenance_rating': np.round(np.random.normal(7, 1.5, size=n_samples)).clip(1, 10),  # 保養評分(1-10分,均值7分)'accident_count': np.random.choice([0, 1, 2, 3], p=[0.7, 0.2, 0.08, 0.02]),  # 事故次數(多數車輛無事故)'seats': np.random.choice([2, 4, 5, 7, 8], p=[0.1, 0.2, 0.5, 0.15, 0.05])  # 座位數(5座車最常見)
    }

  • 特征選擇貼合真實場景:車齡、里程數、發動機大小等均為影響汽車價格的關鍵因素。
  • 分布設計合理:例如多數車輛無事故(accident_count=0占 70%)、5 座車最常見(占 50%)。
  • 價格由 “基礎價格 + 調整因素” 構成,模擬真實定價邏輯:

    # 基礎價格(按品牌檔次)
    brand_base_price = {brand: 50000 for brand in brands['luxury']}  # 豪華品牌基礎價5萬
    brand_base_price.update({brand: 30000 for brand in brands['mid_range']})  # 中端3萬
    brand_base_price.update({brand: 15000 for brand in brands['economy']})  # 經濟1.5萬
    df['base_price'] = df['brand'].map(brand_base_price)# 價格調整因素(核心邏輯)
    df['price'] = df['base_price'] \* (1 - df['age'] / 20)  # 車齡增加,價格降低(每年貶值約5%)* (1 - np.log1p(df['mileage']) / 20)  # 里程增加,價格降低(對數衰減,符合真實折舊)* (1 + df['engine_size'] / 10)  # 發動機越大,價格越高* (1 + df['horsepower'] / 500)  # 馬力越大,價格越高* (1 + (df['fuel_type'] == 'electric')*0.2 + (df['fuel_type'] == 'hybrid')*0.1)  # 電動車加價20%,混動車加價10%* (1 + (df['transmission'] == 'automatic')*0.1)  # 自動擋加價10%* (1 + (df['maintenance_rating'] - 5)/50)  # 保養評分每高1分,價格高2%* (1 - df['accident_count']*0.1)  # 每發生一次事故,價格降10%# 添加隨機噪聲(模擬市場波動)
    df['price'] = df['price'] * np.random.normal(1, 0.1, size=n_samples)  # 10%以內的隨機波動
    1.3 價格生成邏輯(核心)
    # 基礎價格(按品牌檔次)
    brand_base_price = {brand: 50000 for brand in brands['luxury']}  # 豪華品牌基礎價5萬
    brand_base_price.update({brand: 30000 for brand in brands['mid_range']})  # 中端3萬
    brand_base_price.update({brand: 15000 for brand in brands['economy']})  # 經濟1.5萬
    df['base_price'] = df['brand'].map(brand_base_price)# 價格調整因素(核心邏輯)
    df['price'] = df['base_price'] \* (1 - df['age'] / 20)  # 車齡增加,價格降低(每年貶值約5%)* (1 - np.log1p(df['mileage']) / 20)  # 里程增加,價格降低(對數衰減,符合真實折舊)* (1 + df['engine_size'] / 10)  # 發動機越大,價格越高* (1 + df['horsepower'] / 500)  # 馬力越大,價格越高* (1 + (df['fuel_type'] == 'electric')*0.2 + (df['fuel_type'] == 'hybrid')*0.1)  # 電動車加價20%,混動車加價10%* (1 + (df['transmission'] == 'automatic')*0.1)  # 自動擋加價10%* (1 + (df['maintenance_rating'] - 5)/50)  # 保養評分每高1分,價格高2%* (1 - df['accident_count']*0.1)  # 每發生一次事故,價格降10%# 添加隨機噪聲(模擬市場波動)
    df['price'] = df['price'] * np.random.normal(1, 0.1, size=n_samples)  # 10%以內的隨機波動

  • 調整邏輯符合常識:車齡 / 里程越高,價格越低;配置越好(如自動擋、電動車),價格越高。
  • 1.4 缺失值模擬
    # 5%的里程數缺失,3%的保養評分缺失
    df.loc[np.random.choice(df.index, int(n_samples*0.05)), 'mileage'] = np.nan
    df.loc[np.random.choice(df.index, int(n_samples*0.03)), 'maintenance_rating'] = np.nan

  • 模擬真實數據中的缺失情況,為后續預處理做準備。
  • 2. 數據預處理

    預處理是將原始數據轉換為模型可輸入的格式,包括缺失值處理、分類變量編碼等。

    2.1 缺失值處理
    # 用中位數填充缺失值(比均值更穩健,不受極端值影響)
    car_data['mileage'] = car_data['mileage'].fillna(car_data['mileage'].median())
    car_data['maintenance_rating'] = car_data['maintenance_rating'].fillna(car_data['maintenance_rating'].median())

  • 選擇中位數填充:因為里程數等特征可能存在極端值(如少數車輛里程極高),中位數更能代表 “典型值”。
2.2 分類變量編碼

機器學習模型只能處理數值型特征,需將分類變量轉換為數字:

# 1. 品牌檔次編碼(有序分類:豪華>中端>經濟)
brand_category = {}
for cat, brands_list in brands.items():for brand in brands_list:brand_category[brand] = 2 if cat == 'luxury' else 1 if cat == 'mid_range' else 0
car_data['brand_category'] = car_data['brand'].map(brand_category)  # 豪華=2,中端=1,經濟=0# 2. 燃油類型獨熱編碼(無序分類:無大小關系)
fuel_dummies = pd.get_dummies(car_data['fuel_type'], prefix='fuel', drop_first=True)
# 生成fuel_diesel, fuel_hybrid, fuel_electric三列(參考類別為gasoline)
car_data = pd.concat([car_data, fuel_dummies], axis=1)# 3. 變速箱類型二值化(自動=1,手動=0)
car_data['transmission'] = (car_data['transmission'] == 'automatic').astype(int)
  • 有序分類(如品牌檔次)用數值編碼,保留 “高低” 關系;
  • 無序分類(如燃油類型)用獨熱編碼,避免模型誤解 “數值大小”(如不認為 diesel=1 比 gasoline=0 高級)。
2.3 特征與目標變量分離
X = car_data.drop(['price', 'brand', 'fuel_type'], axis=1)  # 特征變量(刪除價格和無用原始分類列)
y = car_data['price']  # 目標變量(預測的汽車價格)
3. 探索性數據分析(EDA)

通過可視化理解數據分布和特征關系,為建模提供依據。

3.1 價格分布
sns.histplot(car_data['price'], kde=True)  # 直方圖+核密度曲線
  • 作用:觀察價格的整體分布(是否正態、有無極端值),本例中價格呈多峰分布(因品牌檔次不同)。
3.2 相關性分析
correlation = car_data.select_dtypes(include=[np.number]).corr()  # 計算數值特征的相關系數
sns.heatmap(correlation, annot=True, cmap='coolwarm')  # 熱力圖可視化

  • 作用:查看特征與價格的相關性強度(如品牌檔次與價格正相關,車齡與價格負相關),驗證特征設計的合理性。
3.3 關鍵特征與價格關系
sns.scatterplot(x='age', y='price', data=car_data)  # 車齡與價格的散點圖
  • 作用:直觀觀察單個特征與價格的關系(如車齡增加,價格明顯下降)。
4. 模型訓練與評估

使用決策樹回歸器構建預測模型,并評估其性能。

4.1 數據集劃分
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
  • 將數據按 7:3 分為訓練集(用于模型訓練)和測試集(用于評估泛化能力)。
4.2 基礎模型訓練與評估
dt_reg = DecisionTreeRegressor(random_state=42)  # 初始化決策樹回歸器
dt_reg.fit(X_train, y_train)  # 訓練模型
y_pred = dt_reg.predict(X_test)  # 預測測試集# 評估指標
mse = mean_squared_error(y_test, y_pred)  # 均方誤差(衡量預測值與真實值的平均平方差)
rmse = np.sqrt(mse)  # 均方根誤差(還原為價格單位,更易解釋)
r2 = r2_score(y_test, y_pred)  # 決定系數(0-1,越接近1說明模型解釋力越強)
  • 基礎模型性能:R2≈0.82,說明模型能解釋 82% 的價格變異,初步效果較好。
4.3 交叉驗證
cv_scores = cross_val_score(dt_reg, X, y, cv=10, scoring='r2')  # 10折交叉驗證
  • 作用:避免單次劃分的偶然性,更穩健地評估模型性能(本例平均R2≈0.80)。
5. 模型調優(網格搜索)

決策樹容易過擬合,通過網格搜索尋找最優參數:

param_grid = {'max_depth': [None, 5, 10, 15, 20],  # 樹的最大深度(控制復雜度,避免過擬合)'min_samples_split': [2, 5, 10, 20],  # 分裂節點所需的最小樣本數'min_samples_leaf': [1, 2, 5, 10],  # 葉子節點的最小樣本數'max_features': ['auto', 'sqrt', 'log2'],  # 每次分裂考慮的特征數量'splitter': ['best', 'random']  # 特征分裂策略
}grid_search = GridSearchCV(estimator=DecisionTreeRegressor(random_state=42),param_grid=param_grid,cv=10,  # 10折交叉驗證scoring='r2',  # 優化目標:最大化R2n_jobs=-1  # 利用所有CPU核心加速
)
grid_search.fit(X_train, y_train)  # 執行網格搜索
  • 原理:遍歷所有參數組合,選擇交叉驗證性能最好的參數(grid_search.best_params_)。
  • 效果:優化后模型R2提升至≈0.88,預測精度顯著提高。
6. 特征重要性分析

決策樹的優勢之一是可解釋性,通過特征重要性判斷哪些因素對價格影響最大:

feature_importance = best_model.feature_importances_  # 每個特征的重要性得分(總和=1)
importance_df = pd.DataFrame({'特征': X.columns, '重要性': feature_importance}).sort_values('重要性', ascending=False)
  • 結果解讀:品牌檔次(≈35%)、車齡(≈25%)、里程數(≈15%)是影響價格的三大核心因素,與常識一致。

三、核心技術點總結

  1. 模擬數據生成:通過合理的概率分布和業務邏輯,生成貼近真實的數據集,解決數據獲取難題。
  2. 數據預處理:針對分類變量選擇合適的編碼方式(有序編碼 / 獨熱編碼),用中位數填充缺失值。
  3. 模型選擇:決策樹回歸器適合處理非線性關系,且結果可解釋。
  4. 參數調優:網格搜索自動尋找最優參數,平衡模型復雜度和泛化能力。
  5. 結果解釋:通過特征重要性分析,將模型結果轉化為可理解的業務洞察。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/93738.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/93738.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/93738.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

0基礎安卓逆向原理與實踐:第2章:編程基礎與工具鏈

第2章:編程基礎與工具鏈 2.1 Java編程基礎 2.1.1 Java語言特性 Java是安卓應用開發的主要語言,具有以下核心特性: mindmaproot((Java特性))面向對象封裝繼承多態抽象平臺無關字節碼JVM一次編譯到處運行內存管理自動垃圾回收堆棧管理引用類型安全性字節碼驗證安全管理器訪…

深入理解JVM內存結構:從字節碼執行到垃圾回收的全景解析

🧠 深入理解JVM內存結構:從字節碼執行到垃圾回收的全景解析 #JVM內存模型 #Java性能優化 #垃圾回收機制 #并發編程一、JVM內存結構全景圖二、線程共享區域詳解 2.1 堆(Heap)—— 對象生存的宇宙 存儲內容: 所有new創建…

用 C++ 構建高性能測試框架:從原型到生產實戰指南

用 C 構建高性能測試框架:從原型到生產實戰指南 ?C 測試框架的關鍵價值?:當你的測試需要每秒處理百萬級交易,微秒級延遲要求已成為常態時,Python GC 的暫停便是不可接受的奢侈。 本文將深入探討如何用 C 構建兼具靈活性和高性能…

【C語言16天強化訓練】從基礎入門到進階:Day 4

🔥個人主頁:艾莉絲努力練劍 ?專欄傳送門:《C語言》、《數據結構與算法》、C語言刷題12天IO強訓、LeetCode代碼強化刷題、洛谷刷題、C/C基礎知識知識強化補充、C/C干貨分享&學習過程記錄 🍉學習方向:C/C方向 ??人…

C語言:字符函數與字符串函數(1)

在編程的過程中,我們經常會遇到需要處理字符和字符串的情況,為了方便操作字符和字符串,C語言標準庫中提供了一系列庫函數,接下來我們就學習一下這些函數。 目錄 1. 字符分類函數 2. 字母轉換函數 3. strlen函數的使用和模擬實現…

數據結構與算法系列(大白話模式)小學生起點(一)

出身,并不重要 !!!!只要有恒心,有毅力,肯于付出與學習,皆會取得相應的成就!天道酬勤,天行健,君子當自強不息!道可道,非常道…

計算機視覺第一課opencv(二)保姆級教學

目錄 簡介 一、邊界填充 1.函數說明 2.案例分析 二、圖像運算 1.號運算 2.cv2.add()函數 3.圖像加權運算 三、閾值處理 四、圖像平滑處理 1.椒鹽噪聲 2.均值濾波(Mean Filtering) 3.方框濾波 4. 高斯濾波(Gaussian Filtering&am…

DINOv3

一、摘要 https://arxiv.org/pdf/2508.10104 自監督學習有望消除對人工數據標注的需求,使模型能夠輕松擴展到大規模數據集和更大規模的架構。由于不針對特定任務或領域進行定制,這種訓練范式具有從各種來源學習視覺表示的潛力,能夠使用單一…

??pytest+yaml+allure接口自動化測試框架

高薪必備!18K接口自動化測試框架落地全流程|零基礎到實戰通關前言# 自動化測試,是目前測試行業一項比較普遍的測試技術了,之前的以UI自動化測試為主,現在的以接口自動化測試為主,無論技術更迭,…

LeetCode每日一題,2025-8-20

統計全為1的正方形子矩陣 這題是正方形,比較簡單 暴力就是二維前綴和。 或者用dp,dp[i][j]表示以i,j為右下角的最大正方形的邊長,它由(i-1,j),(i,j-1),(i-1,j-1)三者共同決定,通過找規律可知,由三個的最小值…

在Excel啟動時直接打開多個Excel文件

如果我們這段時間每天都要打開幾個相同的Excel文件開展工作,可以把這幾個文件放到一個文件夾(如果原來就在不同的文件夾,就把快捷方式放到同一個文件夾),然后在Excel選項中設置啟動時打開這個文件夾中的文件即可。注&a…

對象存儲 COS 端到端質量系列 —— 終端網絡診斷工具

背景 在COS終端SDK的眾多功能中,文件上傳功能的使用頗為頻繁。鑒于此,提升文件上傳的成功率便顯得至關重要。眾多導致上傳失敗的因素里,由網絡問題引發的故障無疑是其中影響上傳成功率的關鍵因素之一,同時也是最難以把控的要素。…

Flask高效數據庫操作指南

Flask-SQLAlchemy 數據庫操作關于Flask數據庫Flask中沒有指定使用的數據庫,可以自由選擇不管你是使用關系型數據庫,還是非關系型數據庫都可以,不像django提供了orm 數據庫抽象層,可以直接采用對象的方式操作數據庫。但是為了開發效…

Camera相機人臉識別系列專題分析之十九:MTK ISP6S平臺FDNode原生代碼

【關注我,后續持續新增專題博文,謝謝!!!】 上一篇我們講了: 這一篇我們開始講: 目錄 一、問題背景 二、MTK ISP6S平臺FDNodeImp.cpp 2.1:原生代碼

S32K3 的圖形化配置和EB配置mcal差異

32K3系列的圖形化配置工具(如S32 Design Studio, S32DS)與EB配置工具(基于EB tresos Studio)在配置MCAL(Microcontroller Abstraction Layer)時存在關鍵差異,主要體現在工具環境、配置流程、代碼…

Meta 再次重組人工智能部門

每周跟蹤AI熱點新聞動向和震撼發展 想要探索生成式人工智能的前沿進展嗎?訂閱我們的簡報,深入解析最新的技術突破、實際應用案例和未來的趨勢。與全球數同行一同,從行業內部的深度分析和實用指南中受益。不要錯過這個機會,成為AI領…

在nodejs中 有哪些是 “假值“和怎么寫 “雙重否定”

1.在 Node.js(以及 JavaScript)中,以下值在布爾上下文(例如 if 語句、while 循環條件等)中被視為 “假值”:false:布爾類型的 false 值,這是最直接的假值。if (false) {console.log(…

車載軟件架構 --- 贏得汽車軟件開發競賽

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 做到欲望極簡,了解自己的真實欲望,不受外在潮流的影響,不盲從,不跟風。把自己的精力全部用在自己。一是去掉多余,凡事找規律,基礎是誠信;二是…

機器學習總復習

這段時間學習了 KNN,線性回歸,邏輯回歸,貝葉斯,聚類(K-means,DBSCAN),決策樹,集成學習(隨機森林,XGboost),SVM支持向量機,…

深入解析EventPoller:Disruptor的輪詢式事件處理機制

EventPoller 是什么?EventPoller 是 Disruptor 框架中一種 基于輪詢(poll-based) 的事件消費機制。它與我們更常見的 BatchEventProcessor(基于獨立的消費者線程)形成了對比。核心區別在于:BatchEventProce…