簡體   English   中英

為什么在 sklearn.linear_model.QuantileRegressor 中安裝 model 然后在 R model 實現中需要更長的時間?

[英]Why its takes so much longer to fit model in sklearn.linear_model.QuantileRegressor then R model implementation?

首先我使用 R 實現分位數回歸,然后我使用具有相同分位數(tau)和 alpha=0.0(正則化常數)的 Sklearn 實現。 我得到相同的公式。 我嘗試了許多“求解器”,但運行時間仍然比 R 長得多。

運行時間:Scikit-learn model vs R model

例如:

示例:40672 個樣本

在 R model 中,默認方法是“br”,而在 Sklearn 中是“lasso”。 雖然我將 R 實現的方法更改為“套索”,但運行時間更短。

不同的方法

導入並創建數據:

import sklearn
print('sklearn version:', sklearn.__version__) # sklearn=1.0.1
import scipy
print('scipy version:', scipy.__version__) # scipy=1.7.2
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import time

from sklearn.linear_model import QuantileRegressor

from sklearn.base import BaseEstimator, RegressorMixin
from sklearn.metrics import r2_score
from sklearn.ensemble import BaggingRegressor
from rpy2.robjects.packages import importr
from rpy2.robjects import numpy2ri, pandas2ri

pandas2ri.activate() #activate conversion of Python pandas to R data structures
numpy2ri.activate() #activate conversion of Python numpy to R data structures

n_samples, n_features = 10000, 1
X = np.linspace(start=0.0,stop=2.0,num=n_samples).reshape((n_samples,n_features))
y = X+X*np.random.rand(n_samples,n_features)+1

X = pd.DataFrame(data=X, columns=['X'])
y = pd.DataFrame(data=y, columns=['y'])

Function 為 plot 數據(有或無線):

from typing import NoReturn, List
import matplotlib.lines as mlines

def ScatterPlot(X : np.ndarray, Y : np.ndarray, title : str = "Default", line_coef : List[int] = None)->NoReturn:
    print(line_coef)
    fig, ax = plt.subplots(figsize=(6, 6))
    ax.scatter(X, y, s=80, marker="P", c='green')
    xmin, xmax = ax.get_xbound()
    ymin, ymax = ax.get_ybound()
    plt.title(title)
    plt.xlabel("X")
    plt.ylabel("Y")
    ax.set(xlim=(xmin, xmax), ylim=(ymin, ymax))#, aspect='equal')
    ax.grid()
    if line_coef is not None:
        p1, p2 = [0, line_coef[0]], [1, sum(line_coef)] 
        ymax = p1[1] + (p2[1] - p1[1]) / (p2[0] - p1[0]) * (xmax - p1[0])
        ymin = p1[1] + (p2[1] - p1[1]) / (p2[0] - p1[0]) * (xmin - p1[0])
        ax.add_line(mlines.Line2D([xmin,xmax], [ymin,ymax], color='red'))
    plt.show()
    
ScatterPlot(X=X, Y=y)

Plot

獲取公式的函數:

def R_get_formula():
    return (str(coef_R[0]) + ' + ' + ' + '.join(
        ['{} * [{}]'.format(str(a), str(b)) for a, b in zip(coef_R[1:].tolist(), ['X'])]))    

def get_formula_from_sklearn(regressor):
    return (str(regressor.intercept_) + ' + ' + ' + '.join(
            ['{} * [{}]'.format(str(a), str(b)) for a, b in zip(regressor.coef_.tolist(), regressor.feature_names_in_)])) 

擬合數據並測試運行時間和公式:

tau=0.95

_quantreg = importr("quantreg")  #import quantreg package from R
################# QuantileRegression R #################
start = time.time()
model_R = _quantreg.rq(formula='{} ~ .'.format(y.columns[0]), tau=tau, data=pd.concat(
            [y.reset_index(drop=True), X.loc[y.index, :].reset_index(drop=True)], axis=1))
coef_R = numpy2ri.ri2py(model_R[0])
print('R tooks {} seconds to finish'.format(time.time()-start)) 
print("The formula is: {}".format(R_get_formula()))
print("Tau: {}".format(tau))
ScatterPlot(X=X, y=y, title="QuantileRegression - R",line_coef=coef_R)

################# QuantileRegression sklearn #################
start = time.time()
model_sklearn = QuantileRegressor(quantile=tau, alpha=0.0, solver='highs')
model_sklearn.fit(X, y)
print('Sklearn tooks {} seconds to finish'.format(time.time()-start)) 
print("The formula is: {}".format(get_formula_from_sklearn(model_sklearn)))
print("Tau: {}".format(tau))
ScatterPlot(X=X, y=y, title="QuantileRegression - sklearn",line_coef=[model_sklearn.intercept_] + list(model_sklearn.coef_))

R_model
sklearn_model

為什么在 sklearn 中安裝 model 然后在 R model 實現中需要更長的時間?

正如 Mauricio 在評論中所建議的,將求解器更改為 HiGHS solver="highs"在某些情況下有效(至少,它解決了我的問題)。 順便說一句,這可能需要安裝求解器。

參數的使用見這里

如果您的數據集稍大一些,則在他們的 Github 存儲庫中報告了一個問題

我已經在使用內點法的 Python 中實現了快速分位數回歸。 它還支持集群魯棒標准誤差。 請在此處查看: https://github.com/mozjay0619/pyqreg

在那里您會找到安裝說明和一些示例。 如果你最終使用它,請給鏈接一些信用(給回購一個星。我花了很長時間才做到這一點)干杯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM