请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

【随机梯度下降法】X特征量对R2score的影响

老师对不起(>人<;),又要麻烦您了。

在上一次您给我指出数据未进行归一化,进行计算导致程序准确率低,我进行改正就愉快地进行测试了。
在调整m(X的训练量)和n(X的特征数量)参数测试效率的过程中,我惊讶地发现在n越来越大的情况下,准确率会极速下降,而sklearn算法则不会影响,我在想我们实现随机梯度下降法的方式是不是有些许问题,我的代码在n大于60左和从bobo老师那复制的代码在n变大了之后,准确率也都会急速下降,而sklearn则没影响,这个问题我解决不了,也不知道这个问题是否适合我这个阶段研究,不适合我就果断跳过先,


python代码

代码有点多
写出来冗杂,和上一个问题用的是一样的
https://coding.imooc.com/learn/questiondetail/274363.html

jupyter Notebook代码

准备工作

import numpy as np
import matplotlib.pyplot as plt
#这个是我写的线性回归的代码
from nike.LinearRegression import LinearRegression
#这个是从bobo老师哪里复制的线性回归的代码
from nike.LinearRegression import LinearRegression2

定义数据初始化函数

def init(m,n):
	#初始化数据
	np.random.seed(666)
	X = np.random.random(size=(m,n))
	true_theta = np.arange(X.shape[1]+1,dtype=float)
	
	X_b = np.concatenate([np.ones((len(X),1)),X],axis=1)
	#对y不加噪点,我觉得数据量可能有点大算的有点慢
	y = X_b.dot(true_theta)
	#归一化+分割数据
	from sklearn.preprocessing import StandardScaler
	from sklearn.model_selection import train_test_split

	X_train, X_test, y_train, y_test = train_test_split(X, y)
	
	standard = StandardScaler()
	standard.fit(X_train)
	X_train_standard = standard.transform(X_train)
	X_test_standard = standard.transform(X_test)
	return	X_train_standard, X_test_standard, y_train, y_test

绘制n与socre的曲线

#我自己写的代码
score_history=[]
reg1 = LinearRegression()
#将数据从1-100逐级递增,计算代码准确率并记录,用于绘制n与socre的图形
for i in range(1,120):
	X_train_standard, X_test_standard, y_train, y_test=init(1000,i)
	reg1.fit_sgd(X_train_standard, y_train)
    score_history.append(reg3.score(X_test_standard, y_test))
#绘制图形
plt.plot([i for i in range(len(score_history))],score_history)
plt.axis([0,100, -3,1.2])
plt.xlabel('n')
plt.ylabel('R2-Score value')
plt.show()

图片描述


#从bobo老师那里复制的代码
score_history=[]
reg2 = LinearRegression2()
#将数据从1-120逐级递增,计算代码准确率并记录,用于绘制n与socre的图形
for i in range(1,120):
	X_train_standard, X_test_standard, y_train, y_test=init(1000,i)
	reg2.fit_sgd(X_train_standard, y_train)
    score_history.append(reg2.score(X_test_standard, y_test))
#绘制图形
plt.plot([i for i in range(len(score_history))],score_history)
plt.axis([0,100, -3,1.2])
plt.xlabel('n')
plt.ylabel('R2-Score value')
plt.show()

图片描述


#机器学习sklearn
from sklearn.linear_model import SGDRegressor
score_history=[]
reg3 = SGDRegressor()
#将数据从1-120逐级递增,计算代码准确率并记录,用于绘制n与socre的图形
for i in range(1,120):
	X_train_standard, X_test_standard, y_train, y_test=init(1000,i)
	reg3.fit(X_train_standard, y_train)
    score_history.append(reg3.score(X_test_standard, y_test))
#绘制图形
plt.plot([i for i in range(len(score_history))],score_history)
plt.axis([0,100, -3,1.2])
plt.xlabel('n')
plt.ylabel('R2-Score value')
plt.show()

图片描述


正在回答

1回答

liuyubobobo 2022-08-26 03:12:48

更准确地说,不是我们的实现“有问题”,而是我们的实现可以更好。但是继续优化这个 SGD 的过程已经不是这个课程的目标了。


sklearn 中的 SGD 的原理和我们课程介绍的原理是一致的。但是在细节上,无论是“随机梯度方向的计算”,还是“学习率的自适应变换”,都更加复杂。可以参考这里的公式:https://scikit-learn.org/stable/modules/sgd.html#id5


其中 R 函数和 L 函数的定义参考这里:https://scikit-learn.org/stable/modules/sgd.html#mathematical-formulation


整体,sklearn 中的实现,是在使用一个复杂的公式,去更准确的使用一个数据点,去“估计”梯度最有可能的方向,而非像我们的实现中,简单地直接用这个点去计算梯度。


==========


至于为什么这个公式估计出的梯度更准确,虽然这个问题确实更多出现在机器学习领域,但整体,我倾向于认为这不是一个机器学习的问题,而更多的是一个数值分析的问题。


简单地说,我们要做的事情就是求解让某个公式最大化(或者最小化)对应的参数解。这个问题本身是脱离机器学习领域,而是一个纯粹的“数学问题”。但是解决这个数学问题要依靠计算机(因为可能没有公式解),所以这类问题在计算机领域都可以归入到“数值分析”的篮子里。


最简单的例子,sqrt(1234567),计算机是怎么求解出来的?这就是一个数值分析问题。但通常我们不会考虑这个问题。可是假设你现在遇到的问题,对 sqrt 的精度要求非常高,要求精确到小数点后 100 位,那么标准库中提供的 sqrt 就不能满足你的要求了。你就需要自己写一个算法计算 sqrt 了。大概就是这个意思。


至少在学习机器学习的初期,你可以不去管这些具体的计算过程,而更多的去关注模型的原理。如果以后继续深入机器学习,尤其是要改进机器学习的底层原理的时候(而非仅仅应用的话),可能会去关注这类“数值问题”(但要注意,机器学习算法的改进不仅仅包括这类数值的改进,原理的改进也很重要甚至在机器学习这个领域中,是更重要的。)。届时,可能你需要专门去学习一门课程(或者一个领域),叫“最优化”(Mathematical Optimization),这个领域会更多的去探讨如何能更快更好地去求解一个最优化的式子的解。(最优化其实也是一个大的领域,大多数人工智能专业的硕士生或者博士生一定要学的是“凸优化”。)


如果你想粗糙地了解一下这个领域,可以先看看这个 wiki 词条:https://en.wikipedia.org/wiki/Mathematical_optimization


但整体,在入门阶段,不需要特别深究这些具体的底层计算原理,更多的去掌握整个模型的作用原理。我们在课程汇总实现的代码,主要还是为了让大家了解模型原理的。但是在实践中,还是应该去使用专业的团队经过多年的积累实现的这些库的,这些库的实现通常都是现阶段最优解了(就像如果不出意外,我们应该调用标准库的 sqrt 函数,而非自己实现一个。但我们在学习的时候,要了解 sqrt 是什么意思,做了一件什么事儿。)


继续加油!:)

1 回复 有任何疑惑可以回复我~
  • 提问者 黄义舜 #1
    我当时实验的时候,在n特征量不大的时候,||我认为使用公式法最合适,但特征量大了,就很慢了。||我就想批量梯度下降适合用于没有直接数学解的模型假设,而小梯度下降则用于数据量和特征量很大的情况,但我自己实现的函数却在特征量100多不到就“倒下了”,我以为是我代码或者环境有问题。
    =======
    bobo老师这一段话和那两个文档,我可能得等到以后回过头再来消化了,谢谢bobo老师给了我一个学习的方向。
    回复 有任何疑惑可以回复我~ 2022-08-26 19:20:56
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信