-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Testing quantreg vs MLJLinearModels #147
Comments
Just tried it with MLJ, but it uses same setup. using CSV, DataFrames
dataset = CSV.read(download("http://freakonometrics.free.fr/rent98_00.txt"), DataFrame)
x0 = [ones(size(dataset,1)) Matrix(dataset[!,[:area, :yearc]])]
y0 = dataset[!,:rent_euro]
df_mlj = DataFrames.DataFrame([y0 x0],[:rent_euro, :intc, :area, :yearc])
ym, Xm = unpack(df_mlj, ==(:rent_euro), in([:intc, :area, :yearc])) #; rng=123
using MLJ
QuantileRegressor = @load QuantileRegressor pkg=MLJLinearModels
mach = fit!(machine(QuantileRegressor(;delta=0.3, fit_intercept=false, penalty=:none), Xm, ym))
fitted_params(mach) Fitted parameters:
This is might be no surprise, since these two from MLJ should be the same models. However, using # _ test with QuantileRegressions
using QuantileRegressions
ResultQR = qreg(@formula(rent_euro ~ area + yearc), df_mlj, .3) output: julia> ResultQR = qreg(@formula(rent_euro ~ area + yearc), df_mlj, .3)
StatsModels.TableRegressionModel{QuantileRegressions.QRegModel, Matrix{Float64}}
rent_euro ~ 1 + area + yearc
Coefficients:
─────────────────────────────────────────────────────────
Quantile Estimate Std.Error t value
─────────────────────────────────────────────────────────
(Intercept) 0.3 -5542.5 169.111 -32.7743
area 0.3 3.97813 0.0838414 47.4483
yearc 0.3 2.88723 0.085967 33.5854
───────────────────────────────────────────────────────── Thus, could you help with MLJ quantile regression estimation? Thank you. |
Hello! Thanks for the report. I investigated this a little bit and a core part of the problem seems to be around To debug this stuff (explaining here as it might be of interest to you), a good thing is to check the y = Vector(dataset[!,:rent_euro])
X = Matrix(dataset[!,[:area, :yearc]])
qr = QuantileRegression(0.3; penalty=:none)
qr2 = QuantileRegression(0.7; penalty=:none)
obj_qr = objective(qr, X, y)
obj_qr2 = objective(qr2, X, y)
mlj_beta = [
5.566200326965212,
0.07844799525061612,
-0.0005985624309847961
]
mlj_beta2 = fit(qr2, X, y)
obj_qr(mlj_beta) # 381_972
obj_qr(mlj_beta2) # 226_639
obj_qr2(mlj_beta) # 245_533
obj_qr2(mlj_beta2) # 380_221 this shows that As a note, if you compute the same objective functions with the coefs obtained via R you'd get
which makes sense. Note that the objective obtained with the MLJLM is still 10% worse than what you get with |
Thanks for your time looking at it. I understand that one should look at the objective, although, the data are quite trivial to solve and MLJ QuantileRegression should provide same results for coefficient even for non-standardised data, right? I have switched the Hope you will find it easily in the solver/setup of Quantile regression. tau2 = 0.7
mlj_qreg2 = MLJLinearModels.QuantileRegression(tau2; fit_intercept=true, scale_penalty_with_samples=false, penalty=:none)
mlj_beta2 = MLJLinearModels.fit(mlj_qreg2, Matrix(dataset[!,[:area, :yearc]]), dataset[!,:rent_euro]) Coefs: julia> mlj_beta2 = MLJLinearModels.fit(mlj_qreg2, Matrix(dataset[!,[:area, :yearc]]), dataset[!,:rent_euro])
3-element Vector{Float64}:
3.2583091596534843
0.07749778937937656
-0.0004959079331218055 |
to be clear (maybe I wasn't in my previous message) what I reported does show that there is an issue which should be fixed (the tau stuff) in the package. After fixing it you may still get pretty different results and this is not necessarily a bug (especially if the objective function at the two points is roughly the same). The point about standardising etc, has to do with how similar you can expect the objective function to be after interruption of two different solvers run with their stopping rules. If you have a nice convex function with two perfectly tuned solvers, they will/should converge to the same spot; what I'm saying here is that it almost certainly isn't the case here (even though the function is obviously convex). My point is just that even if everything is set properly with good defaults, you may end up stopping in an area which is not a minima but seems like one to the solver (e.g. a really flat valley). The parameters at that point may be completely different (including very different magnitude) from the ones you'd get with some other method (eg LP here). You get that all the time with neural nets for instance (though there the objective function is of course non convex). Standardising helps the objective function be "nicer" and can help reduce the gap between close-to-optimal points. |
Thanks for your comment. I do understand what you write about optimization. I wish this package and algorithm would converge to results close to the LP one since the computation here is much faster than JuMP's LP. Maybe it is the point of different results. I look forward to seeing how the optimization behaves when the thing with |
Ok so the issue with tau is fixed in #148 which is good. I'll merge and do a patch release. For the comparison of QR here's a couple of notes:
This just confirms the discussion we had earlier: in this instance, it looks like the method stops in a non-optimal zone. In fact passing What could be interesting is to check how well what you get from either method generalises (e.g. if you split the data 80/20, use 80 to train and predict on 20, how well does it do). I hope this clarifies what's going on and is a bit helpful! I'll close this now as I don't think there's anything left to fix in the package but feel free to reopen if you still have questions. |
* fix a doc typo * fixes following discussion around #147 --------- Co-authored-by: Anthony D. Blaom <[email protected]>
Just want to add that I appreciate the time spent by @luboshanus and @tlienart on this issue. |
* fix a doc typo * fixes following discussion around #147 * small adjustments + typo fixes * first pass at Gramian training for OLS (#146) * proof of concept * AbstractMatrix -> AVR * cleaner impl * endline * fix error type * construct kernels if not passed in * add test case for implicit gram construction * last endline * check for isempty instead of iszero * Prepare minor release with gramian training --------- Co-authored-by: Anthony D. Blaom <[email protected]> Co-authored-by: adienes <[email protected]>
Hi,
I was a bit force to implement/rewrite quantile regression as linear programming (LP) model because results obtained using this package compared to a MATLAB code I had from a paper were not same/similar. Matlab used LP and at first I did not want to code LP in Julia, so I took
MLJLinearModels
with its possibility of L1 penalty for quantile regression. Nonetheless, different results put me to rewrite quantile regression as LP, which I also wanted to compare with thisMLJLinearModels'
simpleNoPenalty
QuantileRegression
.Here is an example from stackoverflow using R and an example using MLJLinearModels:
Link: https://stats.stackexchange.com/questions/384909/formulating-quantile-regression-as-linear-programming-problem
This is simple quantile regression, on these data. Not LP model.
In R using
quantreg
:In Julia:
It might help with an idea of tests or comparison with
quantreg
. Could you please verify or help, what is the problem with results? Coefficients are at different scale and not only that. :)Thanks
The text was updated successfully, but these errors were encountered: