机器学习笔记-线性回归之sklearn.SGDRegressor

机器学习笔记-线性回归之sklearn.SGDRegressor

本文主要内容

记录分析github机器学习项目practicalAI中线性回归04_Linear_Regression的内容分析心得,线性回归的原理和梯度下降相关的内容,请参考上一篇博客或者自行查阅资料。
机器学习笔记-线性回归之梯度下降

什么是sklearn?

sklearn即scikit-learn,是基于Python语言封装的一个机器学习的库,里面有很多现成的算法供我们调用。

SGDRegressor

SGDRegressor是使用随机梯度下降进行线性回归的,随机梯度下降是不将所有样本都进行计算后再更新参数,而是选取一个样本,计算后就更新参数。
上一篇文章中,我们将所有样本数据都计算完成后再更新参数的方法叫做批量梯度下降(BGD)

代码实现

numpy和pandas获取数据的解释在上一篇文章中也有,看注释也行,不再重复赘述。
主要的方式就是,先用train_test_split将数据随机分类成训练数据和测试数据,然后使用StandardScaler类,fit方法将数据标准化,获取平均值和方差,标准差。
然后用同一标准(x的缩放方式x_scaler和y的缩放方式y_scaler)对训练数据和测试数据标准化,具体标准化函数是
x ^ = x − x ˉ σ \hat x =\frac{x-\bar x}{\sigma} x^=σxxˉ
x ^ \hat x x^ 表示新的x值 x ˉ \bar x xˉ表示平均数 σ \sigma σ表示标准差
SGDRegressor的参数设定为squared_loss,默认参数也是这个,意思是损失函数使用方差的形式,大概是这样的,内部实际实现有所不同。
J ( θ 0 , θ 1 . . . θ n ) = 1 2 ∑ i = 0 n ( h θ ( x i ) − y i ) 2 \\J(\theta_0,\theta_1...\theta_n)=\frac{1}{2}\sum_{i=0}^n (h_\theta(x_i) -y_i)^2 J(θ0,θ1...θn)=21i=0n(hθ(xi)yi)2
penalty表示损失函数的惩罚函数,这里我们用的是none,表示不使用惩罚函数
还有很多其他参数可以调试,详情可以参考官方文档
初始化SGDRegressor之后,使用fit函数将数据传递进去,然后调用predict函数即可获得数据标准化之后对应的模拟结果,然后反向计算出标准化之前的输出结果即可完成数据模拟操作。计算原理可在代码注释中查看。

初学机器学习,有不对的地方欢迎讨论。
欢迎到github查看其它机器学习相关的代码。

#使用sklearn进行线性回归计算
import numpy as np
import pandas as pd
from argparse import Namespace

args = Namespace(
    seed = 1234,
    data_file = 'sample_data.csv',
    num_samples = 100,
    train_size = 0.75,
    test_size = 0.25,
    num_epochs = 100,
)
#设置随机数开始的整数值,保证我们的实验数据是一致的
np.random.seed(args.seed)

def generate_data(num_samples):
    X = np.array(range(num_samples))
    random_noise = np.random.uniform(-10,10,size = num_samples)
    y = 3.65 * X + 10 + random_noise
    return X,y
#得到我们需要的x,y数据
X,y = generate_data(args.num_samples)
#将x,y合并,并转置,然后存储为DataFrame,方便后续操作
data = np.vstack([X,y]).T
df = pd.DataFrame(data,columns = ['x','y'])

from sklearn.linear_model.stochastic_gradient import SGDRegressor
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

#得到分类后的测试数据和训练数据,
x_train,x_test,y_train,y_test = train_test_split(df['x'].values.reshape(-1,1)
    ,df['y'], test_size=args.test_size,random_state=args.seed)
#StandardScaler用于标准化数据集
#fit方法计算用于以后缩放的mean和std,默认参数情况下,mean是平均数
#std是标准差,就是所有数减去其平均值的平方和,所得结果除以该组数之个数(或个数减一,即变异数),再把所得值开根号,所得之数就是这组数据的标准差
x_scaler = StandardScaler().fit(x_train)
y_scaler = StandardScaler().fit(y_train.values.reshape(-1,1))

#transform: 执行数据标准化
#测试数据和预测数据的标准化的方式要和训练数据标准化的方式一样, 必须用同一个scaler来进行transform
#数据标准化公式,每个数据均是  (x - 平均值)/标准差
standardized_x_train = x_scaler.transform(x_train)
standardized_y_train = y_scaler.transform(y_train.values.reshape(-1,1)).ravel()
standardized_x_test = x_scaler.transform(x_test)
standardized_y_test = y_scaler.transform(y_test.values.reshape(-1,1)).ravel()

#loss:要是用的损失函数,默认是squared_loss,方差拟合
#penalty:使用的惩罚
lm = SGDRegressor(loss='squared_loss', penalty='none', max_iter=args.num_epochs)
#使用梯度下降模型
lm.fit(X=standardized_x_train,y=standardized_y_train)
#predict:进行数据预测
#scaler.var_是方差,np.sqrt(y_scaler.var_)就是标准差,y_scaler.scale_也是标准差,是一样的
#实际输出结果就是 (模拟的输出结果 * 标准差) + 平均数 和标准化过程刚好相反 
pred_train = (lm.predict(standardized_x_train) * y_scaler.scale_) + y_scaler.mean_
pred_test = (lm.predict(standardized_x_test) * np.sqrt(y_scaler.var_)) + y_scaler.mean_

#测试我们自己的数据
X_infer = np.array((0, 1, 2), dtype=np.float32)
standardized_X_infer = x_scaler.transform(X_infer.reshape(-1, 1))
pred_infer = (lm.predict(standardized_X_infer) * np.sqrt(y_scaler.var_)) + y_scaler.mean_
print (pred_infer)

# Unstandardize coefficients 
#lm.coef_是生成函数系数  lm.intercept_是生成函数的截距
#进行数据标准化之后,都接近于1,此时x,y均缩小了一定倍数,所以此处还原倍数
#相当于原来是 y = a * x  缩放成了  (y - y_scaler.mean_)/y_scale.scale_ = lm.coef_ * ((x - x_scaler.mean_) / x_scaler.scale_) + lm.intercept_
# y = lm.coef_ * ((x - x_scaler.mean_) / x_scaler.scale_) * y_scale.scale_ + lm.intercept_ * y_scale.scale_ + y_scaler.mean_
# y = lm.coef_ * (y_scaler.scale_/x_scaler.scale_) * (x - x_scaler.mean_) + lm.intercept_ * y_scale.scale_ + y_scaler.mean_
# y = lm.coef_ * (y_scaler.scale_/x_scaler.scale_) * x - lm.coef_ * (y_scaler.scale_/x_scaler.scale_) * x_scaler.mean_ + lm.intercept_ * y_scale.scale_ + y_scaler.mean_
#所以真实的a和lm.coef_的倍数关系就是 a = lm.coef_ * (y_scaler.scale_/x_scaler.scale_)
#真是的b和lm.intercept_的关系是 b = lm.coef_ * (y_scaler.scale_/x_scaler.scale_) * x_scaler.mean_ + lm.intercept_ * y_scale.scale_ + y_scaler.mean_
#也就是 b = a * x_scaler.mean_ + lm.intercept_ * y_scale.scale_ + y_scaler.mean_
coef = lm.coef_ * (y_scaler.scale_/x_scaler.scale_)
intercept = lm.intercept_ * y_scaler.scale_ + y_scaler.mean_ - np.sum(coef*x_scaler.mean_)
print (coef) # ~3.65
print (intercept) # ~10
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值