之前一直在想一个问题:我可以用Softmax回归做多分类问题(判断图中是猫还是狗还是大象),但如果是多标签呢?(同时要判断图中衣服的款式、颜色和大小)这个问题一直留在我心中,我也去找了多标签分类/回归的推导,但是仍然不知道如何通过代码实现这个多标签预测问题。
这次在做多标签预测时,发现了sklearn库竟然是可以直接支持多标签预测及指标衡量的!不管我们有多少个不同独立的labels,都可以通过sklearn将多个标签包裹在其中,进行一次性的训练,并得到最终的损失/精度指标。
要使用的就是:sklearn中的multioutput,如果你要实现的是分类,那么使用MultiOutputClassifier,如果实现的是回归,那么使用MultiOutputRegressor
下面以多标签回归及不支持多标签的XGBoost模型为例,给出多标签训练预测的实现过程:
(只是写了多标签的关键代码,其他部分根据读者具体场景编写——包括数据读入、数据清洗、数据集划分等)
from sklearn.multioutput import MultiOutputRegressor
import pandas as pd
data = pd.read_csv(...)
target = pd.read_csv(...)
combine_features = pd.concat([data['scene'], data['accuracy'], data['whois_orgname'], data['as_name']], axis=1)
loc_result = pd.concat([target['lon'], target['lat']], axis=1) # 注意是两个相互独立的输出标签
multi_xgb = MultiOutputRegressor(XGBRegressor(max_depth=15, learning_rate=0.1, n_estimators=160, silent=False))
# 封装多标签输出
multi_xgb.fit(combine_features, loc_result)
mse = mean_squared_error(loc_result, multi_xgb.predict(combine_features))
print('(Lon and Lat) Train MSE: %.5f' % mse)
刚开始实验时,我是通过组合的特征对两个标签进行逐一训练,得到两个MSE指标值(lon和lat)。之后用sklearn.multioutput对两个标签进行封装训练,虽然训练过程中我观察到XGBoost仍然是启动了两次,但是最终得到一个唯一的MSE指标值(lon-lat)。可以发现,不管是在train集还是test集上,lon-lat的MSE均在单独的lon和lat的MSE之间。
最后总结一下这个多输出标签预测的核心代码:
multi_output_model = MultiOutputRegressor(model(parameters_set)) # 将普通的模型封装在sklearn的多标签类中
multi_output_model.fit(x_train, y_train)
mse = mean_squared_error(x_test, y_test)
参考资料:xgboost进行多输出回归预测