#_*_coding:utf-8_*_ #建造一个最简单的梯度下降 def regression(data,alpha,lamba): import numpy as np n=len(data[0])-1 #获取data第一个数据的长度 theta=np.zeros(n) #初始化theta 返回的是array([ 0., 0., 0., 0., 0.]) for times in range(100): for d in data: x=d[:-1] y=d[-1] g=np.dot(theta,x)-y theta=theta-alpha*g*x+lamba * theta print(times,theta) return theta # 构造一个完整的梯度下降算法 # 数据校验 def validate(X, Y): if len(X) != len(Y): raise Exception("参数异常") else: m = len(X[0]) for l in X: if len(l) != m: raise Exception("参数异常") if len(Y[0]) != 1: #检查y是否一个 raise Exception("参数异常") # 计算差异值 def calcDiffe(x, y, a): lx = len(x) la = len(a) if lx == la: result = 0 for i in range(lx): result += x[i] * a[i] #theta1*x1 return y - result elif lx + 1 == la: result = 0 for i in range(lx): result += x[i] * a[i] #theta0+theta1*x1 result += 1 * a[lx] # 加上常数项 return y - result else: raise Exception("参数异常") ## 要求X必须是List集合,Y也必须是List集合 alphas 是步长 threshold阈值 maxIter最大迭代次数 def fit(X, Y, alphas, threshold=1e-6, maxIter=200, addConstantItem=True): import math import numpy as np ## 校验 validate(X, Y) ## 开始模型构建 l = len(alphas) m = len(Y) n = len(X[0]) + 1 if addConstantItem else len(X[0]) # 样本的个数 是否要截距项 ,要就加一 B = [True for i in range(l)] # 模型的格式:控制最优模型 [True, True, True, True, True] ## 差异性(损失值) J = [np.nan for i in range(l)] # loss函数的值 [nan, nan, nan, nan, nan] # 1. 随机初始化0值(全部为0), a的最后一列为常数项 a = [[0 for j in range(n)] for i in range(l)] # theta,是模型的系数 [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] # 2. 开始计算 for times in range(maxIter): #最大迭代次数 for i in range(l): #alphas步长的总个数 if not B[i]: # 如果当前alpha的值已经计算到最优解了,那么不进行继续计算 continue ta = a[i] # theta,第i个模型的系数 for j in range(n): alpha = alphas[i] ts = 0 for k in range(m): if j == n - 1 and addConstantItem: # 计算差异值 真实值与预测值的差异 calcDiffe ts += alpha * calcDiffe(X[k], Y[k][0], a[i]) * 1 #迭代公式常数项 else: ts = ts + alpha * calcDiffe(X[k], Y[k][0], a[i]) * X[k][j] #迭代公式 t = ta[j] + ts ta[j] = t ## 计算完一个alpha值的0的损失函数 flag = True js = 0 #计算的是损失函数 for k in range(m): js += math.pow(calcDiffe(X[k], Y[k][0], a[i]), 2) #计算真实值与预测值的差值的平方 if js > J[i]: #如果当前的损失大于上一轮损失,就结束 flag = False break; if flag: #判断 true 表示本轮的结果比上次损失小,要保存结果 J[i] = js #保存损失 for j in range(n): a[i][j] = ta[j] #保存theta else: # 标记当前alpha的值不需要再计算了 B[i] = False ## 计算完一个迭代,当目标函数/损失函数值有一个小于threshold的结束循环 r = [0 for j in J if j <= threshold] if len(r) > 0: break # 如果全部alphas的值都结算到最后解了,那么不进行继续计算 r = [0 for b in B if not b] #看看达到阈值没有 if len(r) > 0: break; # 3. 获取最优的alphas的值以及对应的0值 min_a = a[0] min_j = J[0] min_alpha = alphas[0] for i in range(l): if J[i] < min_j: min_j = J[i] min_a = a[i] min_alpha = alphas[i] print("最优的alpha值为:", min_alpha) # 4. 返回最终的theta值 return min_a # 预测结果 def predict(X, a): Y = [] n = len(a) - 1 for x in X: result = 0 for i in range(n): result += x[i] * a[i] result += a[n] Y.append(result) return Y # 计算实际值和预测值之间的相关性 def calcRScore(y, py): if len(y) != len(py): raise Exception("参数异常") import math import numpy as np avgy = np.average(y) m = len(y) rss = 0.0 tss = 0 for i in range(m): rss += math.pow(y[i] - py[i], 2) tss += math.pow(y[i] - avgy, 2) r = 1.0 - 1.0 * rss / tss return r import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt import pandas as pd import warnings #仅用于提示,而不中断执行 import sklearn from sklearn.linear_model import LinearRegression,Ridge, LassoCV, RidgeCV, ElasticNetCV from sklearn.preprocessing import PolynomialFeatures #可以理解为专门生成多项式特征,并且多项式包含的是相互影响的特征集 from sklearn.pipeline import Pipeline #管道机制实现了对全部步骤的流式化封装和管理 from sklearn.linear_model.coordinate_descent import ConvergenceWarning #其实就是迭代了200次但是还是没达到最佳拟合,只需要在创建MLPRegressor的时候加一个 ## 设置字符集,防止中文乱码 mpl.rcParams['font.sans-serif']=[u'simHei'] mpl.rcParams['axes.unicode_minus']=False # warnings.filterwarnings(action = 'ignore', category=ConvergenceWarning) ## 创建模拟数据 np.random.seed(0) #random.seed(something)只能是一次有效 np.set_printoptions(linewidth=1000, suppress=True) # 当ndarray里面的存放的数据维度过大时, # 在控制台会出现不能将ndarray完全输出的情况, # 中间部分的结果会用省略号打印出来。 # 这时就需要用到numpy里面的set_printoptions()方法。 # set_printoptions(precision=None, # threshold=None, # edgeitems=None, # linewidth=None, # suppress=None, # nanstr=None, # infstr=None, # formatter=None) # precision:输出结果保留精度的位数 # threshold:array数量的个数在小于threshold的时候不会被折叠 # edgeitems:在array已经被折叠后,开头和结尾都会显示edgeitems个数 # formatter:这个很有意思,像python3里面str.format(),就是可以对你的输出进行自定义的格式化 N = 10 x = np.linspace(0, 6, N) + np.random.randn(N) #返回10个标准正态分布样本值。 y = 1.8*x**3 + x**2 - 14*x - 7 + np.random.randn(N) x.shape = -1, 1 y.shape = -1, 1 plt.figure(figsize=(12,6), facecolor='w') ## 模拟数据产生 x_hat = np.linspace(x.min(), x.max(), num=100) x_hat.shape = -1,1 ## 线性模型 model = LinearRegression() model.fit(x,y) y_hat = model.predict(x_hat) s1 = calcRScore(y, model.predict(x)) print(model.score(x,y)) ## 自带R^2输出 print ("模块自带实现===============") print ("参数列表:", model.coef_) print ("截距:", model.intercept_) ## 自模型 ma = fit(x,y,np.logspace(-4,-2,100), addConstantItem=True) y_hat2 = predict(x_hat, ma) s2 = calcRScore(y, predict(x,ma)) print ("自定义实现模型=============") print ("参数列表:", ma) ## 开始画图 plt.plot(x, y, 'ro', ms=10) plt.plot(x_hat, y_hat, color='#b624db', lw=2, label=u'Python模型,$R^2$:%.3f' % s1) plt.plot(x_hat, y_hat2, color='#6d49b6', lw=2, label=u'自己实现模型,$R^2$:%.3f' % s2) plt.legend(loc = 'upper left') plt.grid(True) plt.xlabel('X', fontsize=16) plt.ylabel('Y', fontsize=16) plt.suptitle(u'自定义的线性模型和模块中的线性模型比较', fontsize=22) plt.show() from sklearn.ensemble import GradientBoostingRegressor clf = GradientBoostingRegressor() y1 = y.ravel() clf.fit(x,y1) print ("自带梯度下降法R方:", clf.score(x,y1)) y_hat3=clf.predict(x_hat) s3=calcRScore(y, clf.predict(x)) # 开始画图 plt.plot(x, y, 'ro', ms=10) plt.plot(x_hat, y_hat, color='#b624db', lw=2, label=u'Python模型,$R^2$:%.3f' % s1) plt.plot(x_hat, y_hat2, color='#6d49b6', lw=2, label=u'自己实现模型,$R^2$:%.3f' % s2) plt.plot(x_hat, y_hat3, color='#6daaba', lw=2, label=u'自带梯度下降方法,$R^2$:%.3f' % s3) plt.legend(loc = 'upper left') plt.grid(True) plt.xlabel('X', fontsize=16) plt.ylabel('Y', fontsize=16) plt.suptitle(u'自定义的线性模型和模块中的线性模型比较', fontsize=22) plt.show()