I'm having trouble with convergence of this R-code translated to Python: statsmodels.GLM gives correct result
import numpy as np
import pandas as pd
from scipy.special import expit # overflow encountered in exp
import statsmodels.api as sm
from matplotlib import pyplot as plt
# data
y= np.array([2,3,6,7,8,9,10,12,15], dtype = np.float)
x= np.array([1,1,1,1,1,1,1,1,1,-1, -1, 0, 0, 0, 0, 1, 1, 1], dtype = np.float).reshape(2,9).T # with intercept in 1st col
data= pd.DataFrame({"y": y, "intercept": x[:,0], "x": x[:,1]})
print(data)
# for glm function
x1= np.array([-1, -1, 0, 0, 0, 0, 1, 1, 1], dtype = np.float)
_x1 = sm.add_constant(x1, prepend=False)
_y = y[:, np.newaxis]
########################
## GLM
#######################
# implement-poisson-regression
from statsmodels.genmod.cov_struct import (Exchangeable, Independence,Autoregressive)
from statsmodels.genmod.families import Poisson
ind= ind = Independence()
fam= sm.families.links.log() ## Log-Linear Regression, also known as Poisson Regression
##data.endog DV, data.exog IV
poisson_model = sm.GLM( _y, _x1, cov_struct=ind, family = Poisson(link= fam))
poisson_results = poisson_model.fit( atol=1e-8) # attach_wls=True,
print(poisson_results.summary())
##print(poisson_results.params)
###########
# https://www.statsmodels.org/devel/examples/notebooks/generated/glm.html
# Plot yhat vs y:
from statsmodels.graphics.api import abline_plot
yhat = poisson_results.mu
fig, ax = plt.subplots()
ax.scatter(yhat, _y)
line_fit = sm.OLS(_y, sm.add_constant(yhat, prepend=True)).fit()
abline_plot(model_results=line_fit, ax=ax)
ax.set_title('Model Fit Plot')
ax.set_ylabel('Observed values')
ax.set_xlabel('Fitted values');
plt.show()
sklearn gives different betas - is the problem in log_scaling_preprocessing because of the nature of lambda param ? still cannot achieve correct coef=0.6698 & intercept=1.8893
#######################
## SKLEARN
#######################
from sklearn import linear_model
regr = linear_model.PoissonRegressor(tol= 1e-8)
regr.fit(data[[ "x"]], data.y)
print("\nPoissonRegressor")
print(regr.score(data[[ "x"]], data.y))
print("coef_ ", regr.coef_)
print("intercept_ ", regr.intercept_)
but the main problem from the above-linked article is hand-coded Newton-Raphson algorithm , as it seems to diverge, not converge, though being coded like in linked R-code -- where is my mistake in translating the logics to Python ?? Whether w_matrix should be calculated in the other way ?
def poisson_Newton_Raphson(x,y,b_init,tol=1e-8):
change = np.inf
b_old = b_init
while(change > tol) :
eta = x @ b_old # linear predictor
w = np.diag(expit(eta))
temp = x.T @ w @ x # ?? np.linalg.inv(x.T @ w @ x)
b_new = b_old + (temp @ x.T @ (y-expit(eta)))
change= np.linalg.norm(b_old - b_new, 2)
## print(change)
b_old = b_new
print(b_old)
return b_new
res= poisson_Newton_Raphson(x, y, np.zeros(2))
print(res)
how to make all 3 codes give the same results ?? (correct in GLM_example)
P.S. alternative -- anyway, my w-matrix seems to be errorness - how to correct it ?
P.P.S. Poisson Regression to model either counts or frequencies, e.g. for a non-constant λ, Poisson distribution has its variance equal to its mean, as lambda grows large the Poisson looks more and more like a normal distribution, to interpret
P.P.P.S. glm-Course_001, n.b. choice of distribution
All the methods you listed give exactly the same results. Here is a display: