Python二手车价格预测(二)—— 模型训练及可视化
系列文章目錄
一、Python數(shù)據(jù)分析-二手車數(shù)據(jù)獲取用于機器學(xué)習(xí)二手車價格預(yù)測
二、Python二手車價格預(yù)測(一)—— 數(shù)據(jù)處理
文章目錄
- 系列文章目錄
- 前言
- 一、明確任務(wù)
- 二、模型訓(xùn)練
- 1.引入庫
- 2.讀入數(shù)據(jù)
- 3.評價指標
- 4.線性回歸
- 5.K近鄰
- 6.決策樹回歸
- 7.隨機森林
- 8.XGBoost
- 9.集成模型Voting
- 10.Tensorflow神經(jīng)網(wǎng)絡(luò)
- 11.各模型結(jié)果
- 三、重要特征篩選
- 結(jié)語
前言
? ? ? ? 前面分享了二手車數(shù)據(jù)獲取的內(nèi)容,又對獲取的原始數(shù)據(jù)進行了數(shù)據(jù)處理,相關(guān)博文可以訪問上面鏈接。許多朋友私信我問會不會出模型,今天模型baseline來了!允許我拋磚引玉,有什么地方描述的不恰當或者有問題,請各位朋友們評論指正!
一、明確任務(wù)
? ? ? ? 一般的預(yù)測任務(wù)分為回歸任務(wù)和分類任務(wù),二手車的價格是一個連續(xù)值,因此二手車價格預(yù)測是一個回歸任務(wù)。
? ? ? ? 回歸任務(wù)的模型有很多,如:線性回歸、K近鄰(KNN)、嶺回歸、多層感知機、決策樹回歸、極限樹回歸、隨機森林、梯度提升樹……
? ? ? ? 諸多模型中有一部分模型是通過多個弱學(xué)習(xí)器集成起來的模型,像隨機森林、Voting等,它們具有更強的學(xué)習(xí)能力,集成多個單一學(xué)習(xí)器得到最終結(jié)果,一般集成模型的預(yù)測效果表現(xiàn)都很良好。
為了給大家提供一個二手車價格預(yù)測的baseline,我將選取幾個經(jīng)典模型進行訓(xùn)練。
二、模型訓(xùn)練
1.引入庫
代碼如下:
# 寫在前面,大家可以關(guān)注一下微信公眾號:吉吉的機器學(xué)習(xí)樂園 # 可以通過后臺獲取數(shù)據(jù),不定期分享Python,Java、機器學(xué)習(xí)等相關(guān)內(nèi)容import pandas as pd import numpy as np import matplotlib.pyplot as plt from matplotlib.pyplot import MultipleLocator import sys import seaborn as sns import warnings warnings.filterwarnings("ignore") plt.rcParams['font.sans-serif'] = ['SimHei'] # 用來正常顯示中文標簽 plt.rcParams['axes.unicode_minus'] = False # 用來正常顯示負號 pd.set_option('display.max_rows', 100,'display.max_columns', 1000,"display.max_colwidth",1000,'display.width',1000)from sklearn.metrics import * from sklearn.linear_model import * from sklearn.neighbors import * from sklearn.svm import * from sklearn.neural_network import * from sklearn.tree import * from sklearn.ensemble import * from xgboost import * import lightgbm as lgb import tensorflow as tf from tensorflow.keras import layers from sklearn.preprocessing import * from sklearn.ensemble import RandomForestRegressor as RFR from sklearn.model_selection import *2.讀入數(shù)據(jù)
代碼如下:
# final_data.xlsx 是上一次分享最后數(shù)據(jù)處理后的 data = pd.read_excel("final_data.xlsx", na_values=np.nan# 將數(shù)據(jù)劃分輸入和結(jié)果集 X = data[ data.columns[1:] ] y_reg = data[ data.columns[0] ]# 切分訓(xùn)練集和測試集, random_state是切分數(shù)據(jù)集的隨機種子,要想復(fù)現(xiàn)本文的結(jié)果,隨機種子應(yīng)該一致 x_train, x_test, y_train, y_test = train_test_split(X, y_reg, test_size=0.3, random_state=42)3.評價指標
? ? ? ? 平均絕對誤差的英文全稱為 Mean Absolute Error,也稱之為 L1 范數(shù)損失。是通過計算預(yù)測值和真實值之間的距離的絕對值的均值,來衡量預(yù)測值與真實值之間的距離。計算公式如下:
? ? ? ? 均方誤差英文全稱為 Mean Squared Error,也稱之為 L2 范數(shù)損失。通過計算真實值與預(yù)測值的差值的平方和的均值來衡量距離。計算公式如下:
? ? ? ? 均方根誤差的英文全稱為 Root Mean Squared Error,代表的是預(yù)測值與真實值差值的樣本標準差。計算公式如下:
? ? ? ? 決定系數(shù)評估的是預(yù)測模型相對于基準模型(真實值的平均值作為預(yù)測值)的好壞程度。計算公式如下:
-
最好的模型預(yù)測的 R2 的值為 1,表示預(yù)測值與真實值之間是沒有偏差的;
-
但是最差的模型,得到的 R2 的值并不是 0,而是會得到負值;
-
當模型的 R2 值為負值,表示模型預(yù)測結(jié)果比基準模型(均值模型)表現(xiàn)要差;
-
當模型的 R2 值大于 0,表示模型的預(yù)測結(jié)果比使用均值預(yù)測得到的結(jié)果要好。
定義評價指標函數(shù):
# 評價指標函數(shù)定義,其中R2的指標可以由模型自身得出,后面的score即為R2 def evaluation(model):ypred = model.predict(x_test)mae = mean_absolute_error(y_test, ypred)mse = mean_squared_error(y_test, ypred)rmse = sqrt(mse)print("MAE: %.2f" % mae)print("MSE: %.2f" % mse)print("RMSE: %.2f" % rmse)return ypred4.線性回歸
代碼如下:
model_LR = LinearRegression() model_LR.fit(x_train, y_train) print("params: ", model_LR.get_params()) print("train score: ", model_LR.score(x_train, y_train)) print("test score: ", model_LR.score(x_test, y_test)) predict_y = evaluation(model_LR)輸出結(jié)果:
params: {'copy_X': True, 'fit_intercept': True, 'n_jobs': None, 'normalize': False} train score: 0.823587700962806 test score: 0.7654427047191524 MAE: 1.97 MSE: 25.90 RMSE: 5.09我們可以將 y_test 轉(zhuǎn)換為 numpy 的 array 形式,方便后面的繪圖。
test_y = np.array(y_test)由于數(shù)據(jù)量較多,我們?nèi)☆A(yù)測結(jié)果和真實結(jié)果的前50個數(shù)據(jù)進行繪圖。
plt.figure(figsize=(10,10)) plt.title('線性回歸-真實值預(yù)測值對比') plt.plot(predict_y[:50], 'ro-', label='預(yù)測值') plt.plot(test_y[:50], 'go-', label='真實值') plt.legend() plt.show()
上圖中,綠色點為真實值,紅色點為預(yù)測值,當兩點幾乎重合時,說明模型的預(yù)測結(jié)果十分接近。
5.K近鄰
代碼如下:
model_knn = KNeighborsRegressor() model_knn.fit(x_train, y_train) print("params: ", model_knn.get_params()) print("train score: ", model_knn.score(x_train, y_train)) print("test score: ", model_knn.score(x_test, y_test)) predict_y = evaluation(model_knn)輸出結(jié)果:
params: {'algorithm': 'auto', 'leaf_size': 30, 'metric': 'minkowski', 'metric_params': None, 'n_jobs': None, 'n_neighbors': 5, 'p': 2, 'weights': 'uniform'} train score: 0.8701966571367806 test score: 0.7886892618747352 MAE: 1.35 MSE: 23.33 RMSE: 4.83繪圖:
plt.figure(figsize=(10,10)) plt.title('KNN-真實值預(yù)測值對比') plt.plot(predict_y[:50], 'ro-', label='預(yù)測值') plt.plot(test_y[:50], 'go-', label='真實值') plt.legend() plt.show()6.決策樹回歸
代碼如下:
model_dtr = DecisionTreeRegressor(max_depth = 5, random_state=30) model_dtr.fit(x_train, y_train) print("params: ", model_dtr.get_params()) print("train score: ", model_dtr.score(x_train, y_train)) print("test score: ", model_dtr.score(x_test, y_test)) predict_y = evaluation(model_dtr)? ? ? ? 在這里,決策樹學(xué)習(xí)器加入了一個 max_depth 的參數(shù),這個參數(shù)限定了樹的最大深度,設(shè)置這個參數(shù)的主要原因是為了防止模型過擬合
輸出結(jié)果:
params: {'criterion': 'mse', 'max_depth': 5, 'max_features': None, 'max_leaf_nodes': None, 'min_impurity_decrease': 0.0, 'min_impurity_split': None, 'min_samples_leaf': 1, 'min_samples_split': 2, 'min_weight_fraction_leaf': 0.0, 'presort': False, 'random_state': 30, 'splitter': 'best'} train score: 0.8339532311129941 test score: 0.7857733129009127 MAE: 2.16 MSE: 18.37 RMSE: 4.29如果不限定樹的最大深度會發(fā)生什么呢?
model_dtr = DecisionTreeRegressor(random_state=30) model_dtr.fit(x_train, y_train) print("params: ", model_dtr.get_params()) print("train score: ", model_dtr.score(x_train, y_train)) print("test score: ", model_dtr.score(x_test, y_test)) predict_y = evaluation(model_dtr)輸出結(jié)果:
params: {'criterion': 'mse', 'max_depth': None, 'max_features': None, 'max_leaf_nodes': None, 'min_impurity_decrease': 0.0, 'min_impurity_split': None, 'min_samples_leaf': 1, 'min_samples_split': 2, 'min_weight_fraction_leaf': 0.0, 'presort': False, 'random_state': 30, 'splitter': 'best'} train score: 0.999999225529954 test score: 0.8673942873037808 MAE: 1.16 MSE: 14.64 RMSE: 3.83獲得樹的最大深度:
model_dtr.get_depth()輸出結(jié)果:
38? ? ? ? 我們發(fā)現(xiàn),在不限定樹的最大深度時,決策樹模型的訓(xùn)練得分(R2)為:0.999999225529954,但測試得分僅為:0.8673942873037808。
? ? ? ? 這就是模型過擬合,在訓(xùn)練數(shù)據(jù)上的表現(xiàn)非常良好,當用未訓(xùn)練過的測試數(shù)據(jù)進行預(yù)測時,模型的泛化能力不足,導(dǎo)致測試結(jié)果不理想。
? ? ? ? 感興趣的同學(xué)可以自行查閱關(guān)于決策樹剪枝的過程。
繪圖:
plt.figure(figsize=(10,10)) plt.title('決策樹回歸-真實值預(yù)測值對比') plt.plot(predict_y[:50], 'ro-', label='預(yù)測值') plt.plot(test_y[:50], 'go-', label='真實值') plt.legend() plt.show()7.隨機森林
代碼如下:
model_rfr = RandomForestRegressor(random_state=30) model_rfr.fit(x_train, y_train) print("params: ", model_rfr.get_params()) print("train score: ", model_rfr.score(x_train, y_train)) print("test score: ", model_rfr.score(x_test, y_test)) predict_y = evaluation(model_rfr)輸出結(jié)果:
params: {'bootstrap': True, 'criterion': 'mse', 'max_depth': None, 'max_features': 'auto', 'max_leaf_nodes': None, 'min_impurity_decrease': 0.0, 'min_impurity_split': None, 'min_samples_leaf': 1, 'min_samples_split': 2, 'min_weight_fraction_leaf': 0.0, 'n_estimators': 10, 'n_jobs': None, 'oob_score': False, 'random_state': 30, 'verbose': 0, 'warm_start': False} train score: 0.9873589573962257 test score: 0.9004628017201377 MAE: 0.88 MSE: 10.99 RMSE: 3.32繪圖:
plt.figure(figsize=(10,10)) plt.title('隨機森林-真實值預(yù)測值對比') plt.plot(predict_y[:50], 'ro-', label='預(yù)測值') plt.plot(test_y[:50], 'go-', label='真實值') plt.legend() plt.show()8.XGBoost
? ? ? ? XGboost是華盛頓大學(xué)博士陳天奇創(chuàng)造的一個梯度提升(Gradient Boosting)的開源框架。至今可以算是各種數(shù)據(jù)比賽中的大殺器,被大家廣泛地運用。
代碼如下:
model_xgbr = XGBRegressor(n_estimators = 200, max_depth=5, random_state=1024) model_xgbr.fit(x_train, y_train) print("params: ", model_xgbr.get_params()) print("train score: ", model_xgbr.score(x_train, y_train)) print("test score: ", model_xgbr.score(x_test, y_test)) predict_y = evaluation(model_xgbr)輸出結(jié)果:
params: {'objective': 'reg:squarederror', 'base_score': 0.5, 'booster': 'gbtree', 'colsample_bylevel': 1, 'colsample_bynode': 1, 'colsample_bytree': 1, 'gamma': 0, 'gpu_id': -1, 'importance_type': 'gain', 'interaction_constraints': '', 'learning_rate': 0.300000012, 'max_delta_step': 0, 'max_depth': 5, 'min_child_weight': 1, 'missing': nan, 'monotone_constraints': '()', 'n_estimators': 200, 'n_jobs': 0, 'num_parallel_tree': 1, 'random_state': 1024, 'reg_alpha': 0, 'reg_lambda': 1, 'scale_pos_weight': 1, 'subsample': 1, 'tree_method': 'exact', 'validate_parameters': 1, 'verbosity': None} train score: 0.9897272945187993 test score: 0.8923618501911923 MAE: 0.88 MSE: 11.88 RMSE: 3.45繪圖:
plt.figure(figsize=(10,10)) plt.title('XGBR-真實值預(yù)測值對比') plt.plot(predict_y[:50], 'ro-', label='預(yù)測值') plt.plot(test_y[:50], 'go-', label='真實值') plt.legend() plt.show()9.集成模型Voting
? ? ? ? Voting可以簡單理解為將各個模型的結(jié)果加權(quán)平均,也是使用較多的一種集成模型。
代碼如下:
model_voting = VotingRegressor(estimators=[('model_LR', model_LR),('model_knn', model_knn), ('model_dtr', model_dtr),('model_rfr', model_rfr),('model_xgbr', model_xgbr)]) model_voting.fit(x_train, y_train) # print("params: ", model_voting.get_params()) print("train score: ", model_voting.score(x_train, y_train)) print("test score: ", model_voting.score(x_test, y_test)) predict_y = evaluation(model_voting)輸出結(jié)果:
train score: 0.9572901767964346 test score: 0.8964163648799375 MAE: 1.08 MSE: 11.44 RMSE: 3.38繪圖:
plt.figure(figsize=(10,10)) plt.title('集成模型voting-真實值預(yù)測值對比') plt.plot(predict_y[:50], 'ro-', label='預(yù)測值') plt.plot(test_y[:50], 'go-', label='真實值') plt.legend() plt.show()10.Tensorflow神經(jīng)網(wǎng)絡(luò)
使用Tensorflow前需要安裝,本文使用的是tensorflow2.0.0版本。
為了使模型快速收斂,首先需要將數(shù)據(jù)標準化。
代碼如下:
scaler = StandardScaler() x_train_scaled = scaler.fit_transform(x_train) x_test_scaled = scaler.transform(x_test)train_x = np.array(x_train_scaled) test_x = np.array(x_test_scaled) train_y = np.array(y_train) test_y = np.array(y_test)# 1、模型初始化 model_tf = tf.keras.Sequential()# 2、添加隱藏層,并設(shè)置激活函數(shù),這里我們用relu model_tf.add(layers.Dense(128, activation='relu')) model_tf.add(layers.Dense(64, activation='relu')) model_tf.add(layers.Dense(8, activation='relu')) model_tf.add(layers.Dense(4, activation='relu')) model_tf.add(layers.Dense(1, activation='relu'))# 3、初始化輸入的shape,189為輸入的189維特征 model_tf.build(input_shape =(None,189))# 4、編譯模型 model_tf.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),loss=tf.keras.losses.mean_squared_error,metrics=['mse', 'mae'])# 5、模型訓(xùn)練 history = model_tf.fit(train_x, train_y, epochs=200, batch_size=128,validation_split = 0.2, #從測試集中劃分80%給訓(xùn)練集validation_freq = 1) #測試的間隔次數(shù)為1# 獲取模型訓(xùn)練過程 model_tf.summary()輸出結(jié)果:
模型訓(xùn)練損失情況:
模型MAE:
plt.figure(figsize=(8,5)) plt.plot(range(1, len(mae) + 1), mae, label = 'mae') plt.plot(range(1, len(val_mae) + 1), val_mae, label = 'val_mae') plt.title('mean_absolute_error') plt.xlabel('Epochs') plt.ylabel('error') plt.legend() plt.show()
模型MSE:
模型評估:
輸出結(jié)果:
MAE: 0.94 MSE: 24.03 RMSE: 4.9011.各模型結(jié)果
| 線性回歸 | 1.97 | 25.9 | 5.09 | 0.82 | 0.76 |
| KNN | 1.35 | 23.3 | 4.83 | 0.87 | 0.78 |
| 決策樹 | 2.09 | 23.9 | 4.89 | 0.84 | 0.78 |
| 隨機森林 | 0.88 | 10.99 | 3.32 | 0.98 | 0.90 |
| XGBoost | 0.88 | 11.88 | 3.45 | 0.98 | 0.89 |
| Voting | 1.08 | 11.44 | 3.38 | 0.95 | 0.89 |
| 神經(jīng)網(wǎng)絡(luò) | 0.94 | 24.0 | 4.90 | 0.98 | 0.78 |
? ? ? ? 從上表可以看出,隨機森林模型的整體表現(xiàn)最好。當然,這不代表最優(yōu)結(jié)果,因為上述7種模型都沒有進行調(diào)參優(yōu)化,經(jīng)過調(diào)參后的各個模型效果還有可能提升。
三、重要特征篩選
? ? ? ? 為了提升模型效果也可以對數(shù)據(jù)做特征篩選,這里可以通過相關(guān)系數(shù)分析法,將影響二手車售價的特征與售價做相關(guān)系數(shù)計算,pandas包很方便的集成了算法,并且可以通過seaborn、matplotlib等繪圖包將相關(guān)系數(shù)用熱力圖的方式可視化。
# 這里的列取final_data中,除0-1和獨熱編碼形式的數(shù)據(jù) corr_cols = list(data.columns[:28]) + list(data.columns[43:49]) test_data = data[corr_cols] test_data_corr = test_data.corr() price_corr = dict(test_data_corr.iloc[0]) price_corr = sorted(price_corr.items(), key=lambda x: abs(x[1]), reverse=True) # 輸出按絕對值排序后的相關(guān)系數(shù) print(price_corr)輸出結(jié)果,除"售價"外,共有33個特征:
[('售價', 1.0),('新車售價', 0.7839935301900343),('最大功率(kW)', 0.7117612690884588),('最大馬力(Ps)', 0.7110554212212731),('最大扭矩(N·m)', 0.696952631401139),('最高車速(km/h)', 0.5419965777866631),('排量(mL)', 0.5330405118740592),('排量(L)', 0.5308107362792799),('整備質(zhì)量(kg)', 0.49194473580917225),('官方0-100km/h加速(s)', -0.48176542342318535),('寬度(mm)', 0.4714397275896106),('軸距(mm)', 0.46166756230018036),('氣缸數(shù)(個)', 0.4454272911508132),('油箱容積(L)', 0.437777686409757),('后輪距(mm)', 0.38050056092464896),('長度(mm)', 0.3713764530321577),('前輪距(mm)', 0.3620381932871346),('最大扭矩轉(zhuǎn)速(rpm)', -0.3350318499883131),('注冊日期差(天)', -0.2737947095245184),('出廠日期差(天)', -0.2598892184068559),('工信部綜合油耗(L/100km)', 0.21117598576704852),('行駛里程', -0.15837809707633024),('最大功率轉(zhuǎn)速(rpm)', -0.14929627599693607),('行李廂容積(L)', 0.1303796302281349),('每缸氣門數(shù)(個)', 0.08610716158708019),('壓縮比', 0.0820485577972737),('車門數(shù)', -0.05405277879497536),('高度(mm)', 0.04866102899154555),('商業(yè)險過期日期差(天)', -0.047366786391213236),('交強險過期日期差(天)', -0.04465347803879652),('車船稅過期日期差(天)', -0.03694367077131783),('載客/人', -0.03234487106605593),('最小離地間隙(mm)', 0.027822359248097703),('座位數(shù)', 0.016036623933084658)]繪制熱力圖:
price_corr_cols = [ r[0] for r in price_corr ] price_data = test_data_corr[price_corr_cols].loc[price_corr_cols] plt.figure(figsize=(15, 10)) plt.title("相關(guān)系數(shù)熱力圖") ax = sns.heatmap(price_data, linewidths=0.5, cmap='OrRd', cbar=True) plt.show()
? ? ? ? 為了驗證相關(guān)系數(shù)分析出來的重要特征是否對模型有效,我們將模型效果最好的隨機森林模型的前33個重要特征輸出。
輸出結(jié)果:
('新車售價', 0.5435) ('最大馬力(Ps)', 0.0928) ('注冊日期差(天)', 0.077) ('最大扭矩(N·m)', 0.0547) ('最大功率(kW)', 0.05) ('行駛里程', 0.0406) ('出廠日期差(天)', 0.0187) ('高度(mm)', 0.0128) ('駐車制動類型_手剎', 0.0107) ('最大功率轉(zhuǎn)速(rpm)', 0.0098) ('寬度(mm)', 0.007) ('軸距(mm)', 0.0059) ('工信部綜合油耗(L/100km)', 0.0052) ('最大扭矩轉(zhuǎn)速(rpm)', 0.0043) ('長度(mm)', 0.0042) ('助力類型_電動助力', 0.0041) ('后輪距(mm)', 0.0038) ('整備質(zhì)量(kg)', 0.0038) ('擋位個數(shù)_5', 0.0035) ('行李廂容積(L)', 0.0027) ('最高車速(km/h)', 0.0026) ('官方0-100km/h加速(s)', 0.0026) ('油箱容積(L)', 0.0026) ('前輪距(mm)', 0.0024) ('壓縮比', 0.0023) ('排量(mL)', 0.0021) ('排量(L)', 0.0019) ('上坡輔助', 0.0015) ('日間行車燈', 0.0013) ('商業(yè)險過期日期差(天)', 0.0013) ('最小離地間隙(mm)', 0.0012) ('擋位個數(shù)_6', 0.0012) ('交強險過期日期差(天)', 0.0011)? ? ? ? 將相關(guān)系數(shù)分析出來的重要特征集合與隨機森林的前33個重要特征取交集,并輸出有多少個重復(fù)的特征。
f1_list = [] f2_list = []for i in range(33):f1_list.append(feature_important[i][0])for i in range(1, 34):f2_list.append(price_corr[i][0])cnt = 0 for i in range(33):if f1_list[i] in f2_list:print(f1_list[i])cnt += 1 print("共有"+str(cnt)+"個重復(fù)特征!")輸出結(jié)果:
新車售價 最大馬力(Ps) 注冊日期差(天) 最大扭矩(N·m) 最大功率(kW) 行駛里程 出廠日期差(天) 高度(mm) 最大功率轉(zhuǎn)速(rpm) 寬度(mm) 軸距(mm) 工信部綜合油耗(L/100km) 最大扭矩轉(zhuǎn)速(rpm) 長度(mm) 后輪距(mm) 整備質(zhì)量(kg) 行李廂容積(L) 最高車速(km/h) 官方0-100km/h加速(s) 油箱容積(L) 前輪距(mm) 壓縮比 排量(mL) 排量(L) 商業(yè)險過期日期差(天) 最小離地間隙(mm) 交強險過期日期差(天) 共有27個重復(fù)特征!? ? ? ? 結(jié)果表明,相關(guān)系數(shù)分析出來的重要特征對模型的效果是有效的。數(shù)據(jù)分析的魅力就在于通過統(tǒng)計學(xué)習(xí)的方法,能在模型訓(xùn)練前得到有價值的信息,甚至能挖掘出意想不到的結(jié)論。
? ? ? ? 在我看來,模型預(yù)測結(jié)果的好壞,最重要的是數(shù)據(jù)預(yù)處理,其次是特征工程和特征篩選,而模型及調(diào)參只是找到一個無限接近正確答案的工具。
結(jié)語
? ? ? ? 數(shù)據(jù)分析、數(shù)據(jù)挖掘以及模型訓(xùn)練還有很多沒有學(xué)到的,我也只是將我個人學(xué)習(xí)理解到的東西展現(xiàn)出來,為朋友們拋磚引玉,希望朋友們在我的baseline方法中,創(chuàng)造更完美的答案。
總結(jié)
以上是生活随笔為你收集整理的Python二手车价格预测(二)—— 模型训练及可视化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MUMU模拟器设置网络
- 下一篇: JS基础 将字符串数组用|或其他符号分割