1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 线性回归—梯度下降python实现

线性回归—梯度下降python实现

时间:2018-12-25 03:09:06

相关推荐

线性回归—梯度下降python实现

import numpy as npimport pandas as pd

导入数据

data=pd.read_csv(r"F:\数据集\dataset\boston.csv")data.head()

编写线性回归-梯度下降类

class LinearRegression:"""使用python语言实现线性回归算法(梯度下降法)"""def __init__(self,alpha,times):"""初始化方法:Parameters:——————————alpha:float学习率,用来控制步长。(权重调整的幅度)times:int循环迭代的次数"""self.alpha=alphaself.times=timesdef fit(self,X,y):"""根据提供的训训练数据,对模型进行训练Parameters:____________X:类数组类型。形状:[样本数量,特征数量]待训练的样本特征属性。(特征矩阵)y:类数组类型。形状:[样本数量]目标值(标签信息)"""X=np.asarray(X)y=np.asarray(y)#创建权重的向量,初始值是0(或任何其他的值),长度要比特征数量多1个(多出的一个就是截距)self.w_=np.zeros(1+X.shape[1])#创建损失列表,用来保存每次迭代后的损失值。损失值计算:(预测值-真实值)的平方和除以2self.loss_=[]#进行循环,多次迭代。在每次迭代过程中,不断去调整权重值,是的损失值不断减小for i in range(self.times):#计算预测值y_hat=np.dot(X,self.w_[1:])+self.w_[0]#计算真实值与预测值之间的差距error=y-y_hat#将损失值加入到损失列表当中self.loss_.append(np.sum(error**2)/2)#根据差距调整权重w_,根据公式;调整为 权重(j)=权重(j)+学习率*sum((y-y_hat) *x(j))self.w_[0]+=self.alpha*np.sum(error)#注意理解下面这句self.w_[1:]+=self.alpha*np.dot(X.T,error)def predict(self,X):"""根据参数传递的样本,对样本数据进行预测。Parameters:_____________X:类数组类型,形状:[样本数量,特征数量]需要进行测试的样本Returns:___________result:数组类型预测的结果"""X=np.asarray(X)result=np.dot(X,self.w_[1:])+self.w_[0]return result

测试

发现效果并不理想

lr=LinearRegression(alpha=0.001,times=20)t=data.sample(len(data),random_state=0)train_X=t.iloc[:400,:-1]train_y=t.iloc[:400,-1]test_X=t.iloc[400:,:-1]test_y=t.iloc[400:,-1]lr.fit(train_X,train_y)result=lr.predict(test_X)display(np.mean((result-test_y)**2))

1.1804176210461773e+210

特征缩放(标准化)–编写标准化类

发现上面的效果并不好,甚至出现损失函数值越来越大的情况,究其原因,发现其各个特征的数量级相差较大,故进行特征缩放,使各个特征相差变小

class StandardScaler:"""该类对数据进行标准化处理"""def fit(self,X):"""根据传递的样本,计算每个特征列的均值与标准差。 Parameters:______________X:类数组类型训练数据,用来计算均值与标准差。"""X=np.array(X)#按列计算标准差self.std_=np.std(X,axis=0)#按列计算均值self.mean_=np.mean(X,axis=0)def transform(self,X):"""对给定的数据X ,进行标准化处理(将X 的每一列都变成标准正态分布的数据)Parameters:——————————————X:类数组类型带转换的数据Return:_________result:类数组类型。参数X转换成标准正态分布后的结果"""return (X-self.mean_)/self.std_def fit_transform(self,X):"""对数据进行训练,并转换,返回转换之后的结果。Parameters:____________X:类数组类型待转换的数据Return:————————————result:类数组类型参数X转换成标准正态分布后的结果。"""self.fit(X)return self.transform(X)

测试标准化类

发现效果好很多

# 为了避免由每个特征数量级的不同而带来的梯度下降过程中的影响#我们现在考虑对每个特征进行标准化处理lr=LinearRegression(0.0005,times=20)t=data.sample(len(data),random_state=0)train_X=t.iloc[:400,:-1]train_y=t.iloc[:400,-1]test_X=t.iloc[400:,:-1]test_y=t.iloc[400:,-1]#对数据进行标准化处理s=StandardScaler()train_X=s.fit_transform(train_X)test_X=s.fit_transform(test_X)s2=StandardScaler()train_y=s2.fit_transform(train_y)test_y=s2.fit_transform(test_y)lr.fit(train_X,train_y)result=lr.predict(test_X)display(np.mean((result-test_y)**2))

0.14911890500740144

可视化

#导入可视化库import matplotlib as mplimport matplotlib.pyplot as pltmpl.rcParams["font.family"]="SimHei"mpl.rcParams["axes.unicode_minus"]=False

1. 绘制预测值

plt.figure(figsize=(10,10))#绘制预测值plt.plot(result,"ro-",label="预测值")plt.plot(test_y.values,"go--",label="真实值")plt.title("线性回归预测--梯度下降")plt.xlabel("样本序号")plt.ylabel("房价")plt.legend()plt.show()

2.绘制累计误差值

# 绘制累计误差值plt.plot(range(1,lr.times+1),lr.loss_,"o-")

[<matplotlib.lines.Line2D at 0xa2b7870888>]

3.绘制 直线拟合 散点图

# 因为房价分析涉及多个维度,不方便进行可视化显示,为了实现可视化,我们只选取其中的一个维度(RM)#并画出直线,实现拟合lr=LinearRegression(alpha=0.0005,times=50)t=data.sample(len(data),random_state=0)#注意,下面不能写成train_X=t.iloc[:400,5],虽然这样同样是截取RM列,但是它是一个series类型(一维),而train_X本来是一个特征矩阵(二维)#所以要写成train_X=t.iloc[:400,5:6]形式,这样返回一个dataframe结构(二维) test_X同理train_X=t.iloc[:400,6:7]train_y=t.iloc[:400,-1]test_X=t.iloc[400:,6:7]test_y=t.iloc[400:,-1]#display(train_X)#对数据进行标准化处理s=StandardScaler()train_X=s.fit_transform(train_X)test_X=s.fit_transform(test_X)#display(train_X)s2=StandardScaler()train_y=s2.fit_transform(train_y)test_y=s2.fit_transform(test_y)lr.fit(train_X,train_y)result=lr.predict(test_X)display(np.mean(result-test_y**2))

-1.0000000000000002

plt.scatter(train_X["rm"],train_y)#查看方程系数lr.w_#构建方程y=-3.07531778e-16+6.54984608e-01*xx=np.arange(-5,5,0.1)#display(x)y=-3.07531778e-16+6.54984608e-01*xplt.plot(x,y,"r")#也可以这样做 ,但要注意,由于x是一维的,而predict(X)的参数是二维的,所以要用x.reshape(-1,1)将其转换为二维的形式#plt.plot(x,lr.predict(x.reshape(-1,1)),"r")

[<matplotlib.lines.Line2D at 0xa2b2775048>]

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。