xlearn 预测错误给出与函数输出不同的 mse

xlearn predictions error give a different mse than output by the function

xlearn 预测函数给出的 mse 与您通过查看预测并自行计算得到的 mse 不同。这是执行此操作的代码;您可以通过克隆 xlearn repository 并在存储库 demo/regression/house_price 中复制以下代码来 运行 它

# Copyright (c) 2018 by contributors. All Rights Reserved.                                                                                                   
#                                                                                                                                                            
# 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.                                                                                                                             
                                                                                                                                                             
import xlearn as xl                                                                                                                                          
import pandas as pd                                                                                                                                          
from sklearn.metrics import mean_squared_error                                                                                                               
                                                                                                                                                             
# Training task                                                                                                                                              
                                                                                                                                                             
# param:                                                                                                                                                     
#  0. regression task                                                                                                                                        
#  1. learning rate: 0.2                                                                                                                                     
#  2. regular lambda: 0.002                                                                                                                                  
#  3. evaluation metric: mae                                                                                                                                 
fm_model = xl.create_linear()  # Use factorization machine                                                                                                   
fm_model.setTrain("./house_price_train.txt")    # Training data                                                                                              
fm_model.setValidate("./house_price_test.txt")  # Validation data                                                                                            
fm_model.disableNorm()                                                                                                                                       
# fm_model.setSigmoid()                                                                                                                                      
# fm_model.disableEarlyStop()                                                                                                                                
param = {'task':'reg', 'lr':0.0002,                                                                                                                          
        'lambda':0.00001, 'metric':'rmse', 'epoch':100}                                                                                                      
                                                                                                                                                             
# Start to train                                                                                                                                             
# The trained model will be stored in model.out                                                                                                              
print("here")                                                                                                                                                
fm_model.fit(param, './model.out')                                                                                                                           
fm_model.setTest("./house_price_test.txt")  # Test data                                                                                                      
                                                                                                                                                             
# Prediction task                                                                                                                                            
                                                                                                                                                             
# Start to predict                                                                                                                                           
# The output result will be stored in output.txt                                                                                                             
outs = fm_model.predict("./model.out", "./output.txt")                                                                                                       
true = pd.read_csv("./house_price_test.txt", sep='\t', header=None)[0]                                                                                       
# print(true)                                                                                                                                                
preds = pd.read_csv("./output.txt", header=None)[0]                                                                                                          
                                                                                                                                                             
# Calculate using sklearn                                                                                                                                    
print(mean_squared_error(true, preds))                                                                                                                       
# Self calculate                                                                                                                                             
sq = 0.0                                                                                                                                                     
for t, p in zip(true, preds):                                                                                                                                
    sq += (t - p) ** 2                                                                                                                                       
print(sq/len(true))                                                                                                                                          

如果将其保存为 min_eg.py,运行 则(安装 xlearn 后)为 python min_eg.py简直了。

这是您得到的输出:

有趣的是,您获得的 MSE 始终恰好是预测函数报告的 mse 的两倍。

非常感谢任何帮助;我想知道其他人是否遇到过同样的问题。

很多人使用 1/2 MSE 作为损失,因为它使导数“更容易”。鉴于他们使用的是“损失”而不是“MSE”或类似的词,我敢打赌这就是正在发生的事情。

为清楚起见,如果您的损失是

1/2n * [(y_1 - p_1)^2 + ... + (y_n - p_n)^2]

那么导数 (wrt p) 将是

-1/n * [(y_1 - p_1) + ... + (y_n - p_n)]

2 消失了,因为您最终乘以 2 的幂规则。

请原谅格式...我不知道如何在这里做数学。

正好是MSE / 2

长话短说:xlearn 库的 MSE 损失是,正如您提到的,MSE / 2

对您的用例进行一些取证,我可以确认 SquaredLoss 在核心库中的命名在其计算中有一个 *0.5 因子。

下面你可以按照我的步骤自己验证这个结论。

如何验证

第 1 步

站在 xlearn/src、运行 grep -r "The test loss is" *。它将指向 solver/inference.cc,行 62:

https://github.com/aksnzhy/xlearn/blob/master/src/solver/inference.cc#L62

哪里可以看到打印的数字是loss_object的GetLoss方法。

请注意,python 库只是此基础 C 代码库之上的包装器。

第 2 步

这object是一个失败的例子。两个定义的损失可以在文件夹 src/loss 下找到。它们是 cross-entropy 用于分类,squared loss 用于回归:

https://github.com/aksnzhy/xlearn/tree/master/src/loss

步骤 3.

最后,您可以在此处查看 header 和 squared loss 的执行情况:

你在哪里可以看到,虽然in the .h file它说损失是:

loss = sum_all_example( (y - pred) ^ 2 )

文件 .cc 中的实际实现在计算中有一个 *0.5 因素,都在 37 and 100.

行中

理论上的原因

这是机器学习中的常规做法,基于梯度下降法使用损失函数的导数这一事实。有了这个 1/2 因子使得导数在某种程度上更整洁,因为在推导时,2 的幂变成了一个 *2 因子,该因子被添加的 1/2 抵消了。另一方面,添加此 1/2 因素不会影响训练目的的指标,因为形状和最小值会保留。