I am trying to write a class LinearModel, representing a linear regression model. it gives an error for def predict
class LinearModel:
def __init__(self, X, y):
self.X = X
self.y = y
#X columns of 1s appended on its left,
X = np.vstack((np.ones((X.shape[0], )), X.T)).T
if len(self.X)!=len(y):
raise ("they are not similar")
def fit(self):
# stores this coefficient vector in the object.
Xt = np.transpose(X)
XtX = np.dot(Xt,X)
Xty = np.dot(Xt,y)
beta = np.linalg.solve(XtX,Xty)
self.fit = beta
def coef(self):
# raise an error if called before the model has been fitted
if not self.fit:
raise ValueError("Need to call the fit function first")
#returns βˆ.
return self.fit
def predict(self,X0=None): # Takes an optional argument X0
if not self.fit:
raise ValueError("Need to call the fit function first")
if X0==None:
X0 = X
X0 = np.vstack((np.ones((X0.shape[0], )), X0.T)).T
# where X0 is X0 with column of 1s added on its left.
prediction = self.fit * X0 # method should return X0 * βˆ
return prediction
X = np.array([[-1.34164079, -1.25675744], [-0.4472136, -0.48336824],
[0.4472136, 0.29002095], [1.34164079, 1.45010473]])
y = np.array([1, 3, 4, 6])
model = LinearModel(X, y)
model.fit()
print(model.coef())
print(model.predict())
edits
class LinearModel:
def __init__(self, X, y):
self.X = X
self.y = y
#X columns of 1s appended on its left,
X = np.vstack((np.ones((X.shape[0], )), X.T)).T
if len(self.X)!=len(y):
raise ("they are not similar")
self._is_fitted : bool = False
def fit(self):
Xt = np.transpose(X)
XtX = np.dot(Xt,X)
Xty = np.dot(Xt,y)
beta = np.linalg.solve(XtX,Xty)
beta_array = np.array(beta)
self.fit = beta_array
self._is_fitted = True
def coef(self):
# raise an error if called before the model has been fitted
if not self._is_fitted:
raise ValueError("Need to call the fit function first")
#returns βˆ
return self.fit
def predict(self,X0=None): # Takes an optional argument X0
if not self._is_fitted:
raise ValueError("Need to call the fit function first")
if X0==None:
X0 = X
X0 = np.vstack((np.ones((X0.shape[0], )), X0.T)).T
# where X0 is X0 with column of 1s added on its left.
prediction = np.multiply(X0, self.fit) # method should return X0 * βˆ
return prediction
X = np.array([[-1.34164079, -1.25675744], [-0.4472136, -0.48336824],
[0.4472136, 0.29002095], [1.34164079, 1.45010473]])
y = np.array([1, 3, 4, 6])
model = LinearModel(X, y)
model.fit()
print(model.coef())
print(model.predict())
it gives an error of ValueError: operands could not be broadcast together with shapes (4,3) (2,) meaning that I will have to to broadcasting to multiply 2 matrices. Can anymore suggest me how?
You can't use a method name as an attribute. Is self.fit
supposed to be a method to fit? Or the coefficients?
You can't test if that attribute (let's call it beta
) is assigned simply by saying if self.beta
or something similar. First of all, if it is not, you'll get an error for trying to read an unassigned variable. Secondly, and that is the error you get, if that beta
contains something that is neither True nor False, you'll get an error about Truth value. So, assign a value to beta
in the __init__
method. For example self.beta=None
. And then test if it is None
with if beta is None
.
All attributes access must be prefixed with self.
. You are using X
instead of self.X
more than once. Which means that those X
are the global one. The one to which you haven't added a column of 1
.
self.beta * X0
is not doing what you expect to do. *
is a member×member multiplication, not a matrix multiplication (and if it were a matrix multiplication it would be an illegal one). @
(or .dot
) is the matrix multiplication operator. And to multiply a 3×n matrix by a 3 elements vector, you need to do it the other way. So X0 @ self.beta
[Non fatal] There is a np.hstack
function, rather than vstack + double transpose
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.