线性问题主要处理回归问题,回归问题即预测一个连续问题的数值。
计算决定系数(R-squared,也称为R²或系数决定)是衡量回归模型预测准确性的一个常用指标。R-squared值越接近1,表示模型的预测性能越好;如果R-squared值为0,则表示模型只是简单地预测了目标变量的平均值;如果R-squared值为负,则表示模型的表现甚至不如简单地预测目标变量的平均值。
import numpy as np import matplotlib.pyplot as plt if __name__=='__main__': x = np.array([1,2,4,6,8]) y = np.array([2,5,7,8,9]) x_mean = np.mean(x) y_mean = np.mean(y) denominator = 0.0 numerator = 0.0 for x_i, y_i in zip(x, y): numerator += (x_i - x_mean) * (y_i - y_mean) # 按照a的公式得到分子 denominator += (x_i - x_mean) ** 2 # 按照a的公式得到分母 a = numerator / denominator # 得到a b = y_mean - a * x_mean # 得到b y_predict = a * x + b plt.scatter(x,y,color='b') plt.plot(x,y_predict,color='r') plt.xlabel('管子的长度', fontproperties = 'simHei', fontsize = 15) #matplotlib
的plt.xlabel()
函数来设置 x 轴的标签时,指定了标签文本和字体大小 plt.ylabel('收费', fontproperties='simHei', fontsize=15) plt.show()
使用面向对象的思想实现对一元线性回归的算法的封装
def fit(self,x_train,y_train): assert x_train.ndim == 1, \ (截断?) #assert
语句用于测试一个条件,如果条件为假(False),则引发一个AssertionError
异常。这通常用于调试目的,以确保程序中的某些条件或假设始终为真。 "一元线性回归模型仅处理向量,而不能处理矩阵" x_mean = np.mean(x_train) y_mean = np.mean(y_train) denominator = 0.0 numerator = 0.0 for x_i, y_i in zip(x_train, y_train): numerator += (x_i - x_mean) * (y_i - y_mean) # 按照a的公式得到分子numerator += ...
:将上述乘积累加到numerator
变量中。 denominator += (x_i - x_mean) ** 2 # 按照a的公式得到分母 self.a_ = numerator / denominator # 得到a self.b_ = y_mean - self.a_ * x_mean # 得到b return self
预测
def predict (self, x_test_group):
return np.array([self._predict(x_test) for x_test in x_test_group])self._predict
函数:这个函数是类的私有方法,意味着它只能在类的内部被调用。
#对于输入向量合集中的每一个向量都进行一次预测,预测的具体实现被封装在_predict函数中。
def _predict(self,x_test):
return self.a_*x_test+self.b_#求取每一个输入的x_test已得到预测值的具体实现
import numpy as np from numpy import linalg class MLinearRegression: def __init__(self): self.coef_ = None #代表的是权重 self.interception_ = None #代表的是截距 self._theta = None #代表的是权重+截距_theta
:这是一个以单下划线开头的属性名。在Python中,这种命名约定通常用于表示该属性是“受保护的”或“内部使用的”,意味着它不应该被类的外部直接访问。然而,这只是一个命名约定,实际上Python并不强制这种访问控制_theta
属性的值设置为None
。None
是Python中的一个特殊值,表示“无”或“空” ''' 规范下代码,X_train代表的是矩阵X大写,y_train代表的是向量y小写 ''' def fit(self,X_train, y_train):#fit方法主要用来训练模型 assert X_train.shape[0] == y_train.shape[0], \ "训练集的矩阵行数与标签的行数保持一致" ones = np.ones((X_train.shape[0], 1)) X_b = np.hstack((ones, X_train)) # 将X矩阵转为第一列为1,其余不变的X_b矩阵 self._theta = linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y_train) self.interception_ = self._theta[0] self.coef_ = self._theta[1:] return self def predict(self,X_predict): ones = np.ones((X_predict.shape[0], 1)) X_b = np.hstack((ones, X_predict)) # 将X矩阵转为第一列为1,其余不变的X_b矩阵 使多元线性回归的公式看成是两个矩阵的运算,第一列恒为1点乘计算后的值是截距。 return X_b.dot(self._theta) #得到的就是预测值 def mean_squared_error(self, y_true, y_predict):均方误差 return np.sum((y_true - y_predict) ** 2) / len(y_true) def score(self,X_test,y_test): #使用r square y_predict = self.predict(X_test) return 1 - (self.mean_squared_error(y_test,y_predict) / (np.var(y_test)))
np.hstack()
是 NumPy 库中的一个函数,用于沿着水平方向(即沿着第二个轴,也就是列方向)堆叠数组序列。这个函数将多个数组在它们的第二个维度上拼接起来,要求所有输入数组的第一个维度(通常是行数)必须相同。
numpy.hstack(tup)
其中,tup
是一个元组(tuple),包含了要堆叠的数组。可以直接传递一个数组列表给 np.hstack()
,因为 Python 会自动将列表转换为元组。
python 复制代码 import numpy as np # 创建两个数组 a = np.array([[1, 2], [3, 4]]) b = np.array([[5, 6], [7, 8]]) # 水平堆叠 a 和 b c = np.hstack((a, b)) print(c) # [[1 2 5 6] [3 4 7 8]]
注意事项
- 所有输入数组的第一维(行数)必须相同。
- 如果输入数组不是二维的,
np.hstack()
会尝试将它们视为二维数组(即,如果它们是一维的,它们会被视为具有单个行或列的二维数组)。但是,这可能会导致意外的结果,特别是当一维数组被堆叠时。 - 对于更复杂的数据堆叠需求(比如沿着第一个轴堆叠),你可以使用
np.vstack()
(垂直堆叠)或np.concatenate()
(沿指定轴堆叠)等函数。 - 如果输入数组不是 NumPy 数组,但它们可以被解释为数组(比如列表的列表),则可能需要先使用
np.array()
或类似函数将它们转换为 NumPy 数组,然后再进行堆叠。
均方误差(Mean Squared Error,MSE)是一种常用的评估回归模型性能的指标。它计算了预测值与实际值之间差异的平方的平均值。均方误差越小,模型的预测效果越好。
计算步骤
- 计算预测值与实际值之间的差值:对于每个样本,计算预测值和实际值的差值 <br>
- 平方差值:对每个差值进行平方 <br>
- 求和:将所有平方差值相加 <br>
- 取平均:将求和结果除以样本数量 <br>
import numpy as np # 实际值 y_true = np.array([3, -0.5, 2, 7]) # 预测值 y_pred = np.array([2.5, 0.0, 2, 8]) # 计算均方误差 mse = np.mean((y_true - y_pred) ** 2) print("均方误差 (MSE):", mse)
逻辑回归模型
在线性回归的基础上加上Sigmoid函数对线性回归的结果进行压缩,令最终预测值在一个范围内,Sigmoid函数的作用将一个连续的数值压缩到一定范围内,通常把大于0.5归为1,小于0.5归为0,
梯度下降算法
import numpy as np import matplotlib.pyplot as plt if __name__ == '__main__': plot_x = np.linspace(-1, 6, 141) #从-1到6选取141个点 plot_y = (plot_x - 2.5) ** 2 – 1 #二次方程的损失函数 plt.scatter(plot_x[5], plot_y[5], color='r') #设置起始点,颜色为红色 plt.plot(plot_x, plot_y) # 设置坐标轴名称 plt.xlabel('theta', fontproperties='simHei', fontsize=15) plt.ylabel('损失函数', fontproperties='simHei', fontsize=15) plt.show() theta = 0.0 #初始点 theta_history = [theta] eta = 0.1 #步长 epsilon = 1e-8 #精度问题或者eta的设置无法使得导数为0 while True: gradient = dJ(theta) #求导数 last_theta = theta #先记录下上一个theta的值 theta = theta - eta * gradient #得到一个新的theta 用于更新模型参数以最小化某个损失函数,gradient
是损失函数关于theta
的梯度,即损失函数在theta
处的斜率或导数。 theta_history.append(theta) if(abs(J(theta) - J(last_theta)) < epsilon): break #当两个theta值非常接近的时候,终止循环 plt.plot(plot_x,J(plot_x),color='r') plt.plot(np.array(theta_history),J(np.array(theta_history)),color='b',marker='x') plt.show() #一开始的时候导数比较大,因为斜率比较陡,后面慢慢平缓了 print(len(theta_history)) #一共走了46步
学习率分析
linspace函数也用于生成具有指定数量的等间距样本的数组。
用python实现逻辑回归
import numpy as np class LogisticRegressionSelf: def __init__(self): """初始化Logistic regression模型""" self.coef_ = None #维度 self.intercept_ = None #截距 self._theta = None #sigmoid函数,私有化函数 def _sigmoid(self,x): y = 1.0 / (1.0 + np.exp(-x)) return y def fit(self,X_train,y_train,eta=0.01,n_iters=1e4): assert X_train.shape[0] == y_train.shape[0], '训练数据集的长度需要和标签长度保持一致' #计算损失函数 def J(theta,X_b,y): p_predcit = self._sigmoid(X_b.dot(theta))
-
X_b.dot(theta)
计算特征和参数的点积,得到一个线性组合。 float('inf')
,表示成本无穷大。
try: return -np.sum(y*np.log(p_predcit) + (1-y)*np.log(1-p_predcit)) / len(y) except: return float('inf') #求sigmoid梯度的导数 def dJ(theta,X_b,y): x = self._sigmoid(X_b.dot(theta)) return X_b.T.dot(x-y)/len(X_b) #模拟梯度下降 def gradient_descent(X_b,y,initial_theta,eta,n_iters=1e4,epsilon=1e-8): theta = initial_theta i_iter = 0 while i_iter < n_iters: gradient = dJ(theta,X_b,y) last_theta = theta theta = theta - eta * gradient i_iter += 1 if (abs(J(theta,X_b,y) - J(last_theta,X_b,y)) < epsilon): break return theta X_b = np.hstack([np.ones((len(X_train),1)),X_train]) initial_theta = np.zeros(X_b.shape[1]) #列向量 self._theta = gradient_descent(X_b,y_train,initial_theta,eta,n_iters) self.intercept_ = self._theta[0] #截距 self.coef_ = self._theta[1:] #维度 return self def predict_proba(self,X_predict): X_b = np.hstack([np.ones((len(X_predict), 1)), X_predict]) return self._sigmoid(X_b.dot(self._theta)) def predict(self,X_predict): proba = self.predict_proba(X_predict) return np.array(proba > 0.5,dtype='int')
标签:图像识别,predict,self,day5,学习,train,np,theta,mean From: https://www.cnblogs.com/candice1/p/18330324