c++多元线性回归_五种优化算法实现多元线性回归
生活随笔
收集整理的這篇文章主要介紹了
c++多元线性回归_五种优化算法实现多元线性回归
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
實現多元線性回歸的要求及假設條件:
'''線性回歸的假設條件:1、樣本獨立,即每個預測樣本之間沒有依賴關系;2、殘差e要服從正態分布,即y_true-y_pred的殘差需要服從高斯分布;3、特征之間獨立,即特征之間需要獨立,如果不獨立(共線性)會造成系數權重之和為單特征權重且權重方差較大,同時會造成模型預測結果震蕩,不穩定;4、樣本數需要大于特征數,如果特征數量大于樣本數量,通過最小二乘法無法求矩陣的逆,通過其他優化方式得到的最優結果非唯一解,造成模型偏差較大;5、殘差e要求方差齊性,即殘差不隨觀測變量的變化而變化;6、自變量與因變量之間呈線性關系;使用最小二乘法、梯度下降、隨機梯度下降、PSO粒子群算法及牛頓法實現多元線性回歸,數據集使用如下數據集from sklearn import datasetsdata=datasets.load_diabetes()
'''
整體源代碼,如有幫助,歡迎star:
https://github.com/suixintech/ML_Coding/edit/master/LinearRegression.py
本代碼主要通過五種常見的方法實現多元線性回歸,包含常見的最小二乘法、梯度下降、隨機梯度下降、pso粒子群優化算法以及牛頓法實現,具體推導這里不做過多講解,以實現代碼為主;
一、所引用的庫
from contextlib import contextmanager from time import strftime import time import numpy as np from sklearn import datasets import warnings warnings.filterwarnings('ignore')@contextmanager def timeSchedule(message: str):""" Time Schedule""" print('[INFO {}][{}] Start ...'.format(strftime('%Y-%m-%d %H:%M:%S'), message))start_time = time.time()yieldprint('[INFO {}][{}] End ...'.format(strftime('%Y-%m-%d %H:%M:%S'), message))print('[INFO {}][{}] Cost {:.2f} s'.format(strftime('%Y-%m-%d %H:%M:%S'), message, time.time() - start_time))二、最小二乘法
class LinearRegressionLSM:'''線性回歸-最小二乘法''' def __init__(self):self.x,self.y=datasets.load_diabetes()['data'],datasets.load_diabetes()['target']def fit(self):self.x=np.insert(self.x,0,1,axis=1)self.x_=np.linalg.inv(self.x.T.dot(self.x))return self.x_.dot(self.x.T).dot(self.y)def predict(self,x):w=self.fit()w=w.reshape(-1,1)return np.sum(w.T*x,axis=1)三、梯度下降
class LinearRegressionGD:'''線性回歸-梯度下降''' def __init__(self):self.data=datasets.load_diabetes()self.x, self.y= datasets.load_diabetes()['data'], datasets.load_diabetes()['target']self.w=np.zeros((self.x.shape[1],1))self.b=np.array([0.0])self.step=200000def costFunction(self,theta0,theta1,x,y):ddd=((np.sum(theta1.T*x,axis=1)+theta0)-y)**2J=np.sum(ddd,axis=0)return J/(2*x.shape[0])def partTheta0(self,theta0,theta1,x,y):h=theta0+np.sum(theta1.T*x,axis=1)diff=h-ypartial=diff.sum()/x.shape[0]return partialdef partTheta1(self,theta0,theta1,x,y):partials=[]for i in range(x.shape[1]):h=theta0+np.sum(theta1.T*x,axis=1)diff=(h-y)*x[:,i]partial=diff.sum()/x.shape[0]partials.append(partial)return np.array(partials).reshape(x.shape[1],1)def fit(self,x,y,aph=0.01):theta0, theta1=self.b,self.wcounter=0c=self.costFunction(theta0,theta1,x,y)costs=[c]c1=c+10err=0.00000001while (np.abs(c-c1)>err) and (counter<self.step):c1=cupdate_theta0=aph*self.partTheta0(theta0,theta1,x,y)update_theta1=aph*self.partTheta1(theta0,theta1,x,y)theta0-=update_theta0theta1-=update_theta1c=self.costFunction(theta0,theta1,x,y)costs.append(c)counter+=1return theta0,theta1,counterdef predict(self,x):w0,w1,c=self.fit(self.x,self.y)return (np.sum(w1.T*x,axis=1)+w0).sum()四、隨機梯度下降
class LinearRegressionSGD:'''線性回歸-隨機梯度下降''' def __init__(self):self.data = datasets.load_diabetes()self.x, self.y =datasets.load_diabetes()['data'], datasets.load_diabetes()['target']self.w = np.zeros((self.x.shape[1], 1))self.b = np.array([0.0])def costFunction(self,theta0,theta1,x,y):h=((theta0+np.sum(theta1.T*x,axis=1))-y)**2J=np.sum(h,axis=0)/2return Jdef partTheta0(self,theta0,theta1,x,y):h=theta0+np.sum(theta1.T*x,axis=1)diff=(h-y)return diffdef partTheta1(self,theta0,theta1,x,y):partials=[]h=theta0+np.sum(theta1.T*x,axis=1)for i in range(x.shape[0]):diff=(h-y)*x[i]partials.append(diff)return np.array(partials).reshape(x.shape[0],1)def fit(self):#初始化第1個樣本點的損失函數值c=self.costFunction(self.b,self.w,self.x[0],self.y[0])partTheta0=self.bpartTheta1=self.w#遍歷所有樣本點,計算對應損失函數值step=0aph=0.01#參與計算的總樣本數totalstep=10000for i in range(1,self.x.shape[0]):step+=1c1=cx,y=self.x[i,:],self.y[i]updateTheta0=self.partTheta0(partTheta0,partTheta1,x,y)updateTheta1=self.partTheta1(partTheta0,partTheta1,x,y)partTheta0-=aph*updateTheta0partTheta1-=aph*updateTheta1c=self.costFunction(partTheta0,partTheta1,x,y)if np.abs(c-c1)<=0.000000001 and step<totalstep:return partTheta0,partTheta1,iif step>=totalstep:return partTheta0,partTheta1,stepreturn partTheta0, partTheta1, stepdef predict(self,x):#訓練所有樣本點的結果w0, w1,step= self.fit()#進行預測return (np.sum(w1.T * x, axis=1) + w0).sum()五、牛頓法(注意與最小二乘法的數學推導區別)
class LinearRegressionNM:'''線性回歸-牛頓法''' def __init__(self):self.data = datasets.load_diabetes()self.x, self.y =datasets.load_diabetes()['data'], datasets.load_diabetes()['target']#插入數據1self.x=np.insert(self.x,0,1,axis=1)def computeHessianinv(self,x):#注意區別與最小二乘法之間的推導區別return np.linalg.inv(x.T.dot(x))def fit(self):return self.computeHessianinv(self.x).dot(self.x.T).dot(self.y)def predict(self,x):w=self.fit()return w[0]+np.sum(w[1:].T*x,axis=1)六、pso粒子群優化算法
class LiearRegressionPSO:'''線性回歸-PSO粒子群算法''' def __init__(self):self.data = datasets.load_diabetes()self.x, self.y = datasets.load_diabetes()['data'], datasets.load_diabetes()['target']self.w = 0.8self.c1 = 2self.c2 = 2self.r1 = 0.5self.r2 = 0.5self.pN = 30 #粒子數量self.dim = 11 #參數個數self.max_iter = 2000 # 最大迭代次數self.X = np.zeros((self.pN, self.dim)) #粒子位置self.V = np.zeros((self.pN, self.dim)) #粒子速度self.pbest = np.zeros((self.pN, self.dim)) #粒子最佳解self.gbest = np.zeros((1, self.dim)) #全局最優解self.p_fit = np.zeros(self.pN)#粒子最佳適應值self.fit = 100000000 #全局適應值初始值#損失函數,適應函數def costFunction(self,x):h=np.sum(x.T*np.insert(self.x,0,1,axis=1),axis=1)-self.ydiff=h**2return diff.sum()/self.x.shape[0]#粒子群初始化def initPopulation(self):for i in range(self.pN):for j in range(self.dim):self.X[i][j] = np.random.uniform(0, 1)self.V[i][j] = np.random.uniform(0, 1)self.pbest[i] = self.X[i]cost = self.costFunction(self.X[i])self.p_fit[i] = costif (cost < self.fit):self.fit = costself.gbest = self.X[i]def fitModel(self):#初始化粒子群self.initPopulation()costVale=[]for i in range(self.max_iter):for j in range(self.pN):cost=self.costFunction(self.X[j])if (cost<self.p_fit[j]):self.pbest[j]=self.X[j]self.p_fit[j]=costif (self.p_fit[j]<self.fit):self.gbest=self.X[j]self.fit=self.p_fit[j]for k in range(self.pN):self.V[k]=self.w*self.V[k]+self.c1*self.r1*(self.pbest[k]-self.X[k])+self.c2*self.r2*(self.gbest-self.X[k])self.X[k]=self.X[k]+self.V[k]costVale.append(self.fit)return self.gbest,costValedef predict(self,x):w,cost=self.fitModel()return w[0]+np.sum(w[1:].reshape(-1,1).T*x,axis=1)歡迎關注專欄~
總結
以上是生活随笔為你收集整理的c++多元线性回归_五种优化算法实现多元线性回归的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python求向量与x轴的夹角_2020
- 下一篇: 单片机声光电子琴程序流程图_基于单片机的