顾老师新书《全栈软件测试工程师宝典》
https://item.m.jd.com/product/10023427978355.html
以前两本书的网上购买地址:
《软件测试技术实战设计、工具及管理》:
https://item.jd.com/34295655089.html
《基于Django的电子商务网站》:
https://item.jd.com/12082665.html
1.基本概念
直线是最基本的几何图形,一般的直线可以表达为:y = kx b,这里的k我们叫做斜率,b叫做截距(x=0的时候,y的值。即直线与y轴的交叉点)。线性回归方法即找出一条直线,使得各个点到这条直线上的误差最小。
现在让我们通过Python语言来画一条直线:y = 0.5 * x 3(这里斜率为0.5, 截距为3)。
代码语言:javascript复制# 导入NumPy库
import numpy as np
# 导入画图工具
import matplotlib.pyplot as plt
def Line_base():
x = np.linspace(-5,5,100)
y = 0.5 * x 3
plt.plot(x,y,c='green')
plt.title('Straight Line')
plt.show()
初中几何课我们就知道:两个点确定唯一的一条直线。现在我们通过sklearn的线性模型中的线性回归(LinearRegression)类来画出一条经过[2,3]和[3,4]的直线。
代码语言:javascript复制# 通过两个点([2,3]和[3,4])画出直线
from sklearn.linear_model import LinearRegression
def Line_base_by_two_point():
X = [[2],[3]]
y = [3,4]
# 用线性模型拟合这;两个点
lr =LinearRegression().fit(X,y)
# 画出通过两个点([2,3]和[3,4])直线
z = np.linspace(-5,5,20)
plt.scatter(X,y,s=80)
plt.plot(z,lr.predict(z.reshape(-1,1)),c='k')
plt.title('Straight Line')
plt.show()
我们可以通过LinearRegression().coef_[0]和LinearRegression().lr.intercept_来获取直线的斜率和截距,代码如下。
代码语言:javascript复制# 显示这条线的斜率和截距
print('y={:.3f}'.format(lr.coef_[0]),'x',' {:.3f}'.format(lr.intercept_))
输出
代码语言:javascript复制y=1.000 x 1.000
在这里斜率与截距都为1。
现在我们在[2,3]、[3,4]两个点基础上再加一个点[4,4],来看看画出来的图是什么情形。
代码语言:javascript复制# 画出通过三个点([2,3]、[3,4]和[4,4])直线
def Line_base_by_three_point():
X = [[2],[3],[4]]
y = [3,4,4]
# 用线性模型拟合这;两个点
lr =LinearRegression().fit(X,y)
# 画出通过三个点([2,3]、[3,4]和[4,4])直线
z = np.linspace(-5,5,20)
plt.scatter(X,y,s=80)
plt.plot(z,lr.predict(z.reshape(-1,1)),c='k')
plt.title('Straight Line')
plt.show()
# 显示这条线的斜率和截距
print('y={:.3f}'.format(lr.coef_[0]),'x',' {:.3f}'.format(lr.intercept_))
输出
代码语言:javascript复制y=0.500 x 2.167
这条折线不经过[2,3]、[3,4]和[4,4]三个点中任意一个点,但是使得这三个点到这条直线的距离保持最小,这就体现出了线性回归的意义。
到目前为止,点的个数仅仅为三个,数量是非常有限的,我们通过make_regression(n_samples=50…)来制造出50个样本数据,然后用LinearRegression来拟合一条我们需要的直线。
代码语言:javascript复制#导入make_regression数据集成生成器
from sklearn.datasets import make_regression
# 画出多个点的直线
def Line_base_by_multiple_point():
X,y =make_regression(n_samples=50,n_features=1,n_informative=1,noise=50,random_state=1)
# 使用线性模型进行拟合
reg = LinearRegression()
reg.fit(X,y)
# z 是我们生成的等差数列,用来画出线性模型
z =np.linspace(-3,3,200).reshape(-1,1)
plt.scatter(X,y,c='b',s=60)
plt.plot(z,reg.predict(z),c='k')
plt.title('LinearRegression')
plt.show()
# 显示这条线的斜率和截距
print('y={:.3f}'.format(reg.coef_[0]),'x',' {:.3f}'.format(reg.intercept_))
输出
代码语言:javascript复制y=79.525 x 10.922
这条直线的斜率为79.525,截距为10.922。到50个样本点的平均误差最小。
线性回归方法包括:最小二乘法、逻辑回归、支持向量机、岭回归和套索回归。下面我们进行一一介绍。
2.最小二乘法
2.1原理
我们判断一个西瓜的好坏,可以通过它的色泽、根蒂和敲声参数乘以它们的系数加上一个误差系数(b)来获得。
F好瓜(x) = w1 x色泽 w2x根蒂 w3 x敲声 b (1)
假设有m个西瓜,第一个西瓜的参数为:[x1色泽 ,x1根蒂 ,x1敲声],第二个西瓜的参数为:[x2色泽 ,x2根蒂 ,x2敲声],…,第m个西瓜的参数为:[xm色泽 ,xm根蒂 ,xm敲声],我们可以用一个矩阵来表示这m个西瓜。
X =[[x1色泽 ,x1根蒂 ,x1敲声]
[x2色泽 ,x2根蒂 ,x2敲声]
…
[xm色泽 ,xm根蒂 ,xm敲声]]
我们把色泽、根蒂和敲声系数表示为一个竖向量:
w=[[w色泽系数],
[w根蒂系数],
[w敲声系数]]
即
w=[[w1] ,
[w2] ,
[w3]]
这样上面式(1)可以表示为:F好瓜(x) = Xw b。
其中:
Xw= [[x1色泽w1 x1根蒂w2 x1敲声w3]
[x2色泽w1 x2根蒂w2 x2敲声w3]
…
[xm色泽w1 xm根蒂w2 xm敲声w3]]
假设每个瓜的实际值为Y,
y = w=[[y1] ,
[y2] ,
…
[ym]]
实际值与计算值差的平方(即方差)为:(Xw-y)2,我们现在知道要求这个方差最小的系数w是多少?我们可以采用(Xw-y)2对w取导数=0的方法来获得这个w。对w求导为:-2XT (y-Xw),使-2XT (y-Xw)=0,得到w的最优解:w = (XTX)-1XTy。
2.2 sklearn.linear_model
sklearn.linear_model的LinearRegression类就是用最小二乘法来实现回归的。
代码语言:javascript复制# 导入数据划分模块、分为训练集和测试集
from sklearn.model_selection import train_test_split
def Line_for_sklearn_data():
X,y =make_regression(n_samples=100,n_features=2,n_informative=2,random_state=8)
X_train,X_test,y_train,y_test = train_test_split(X, y,random_state=8,test_size=0.3)#测试集占30%
lr =LinearRegression().fit(X,y)
print('lr.coef_: {} '.format(lr.coef_[:]))
print('reg.intercept_:{}'.format(lr.intercept_))
print('训练集得分:{}'.format(lr.score(X_train,y_train)))
print('测试集得分: {}'.format(lr.score(X_test,y_test)))
输出
代码语言:javascript复制lr.coef_: [82.06262736 7.73658023]
reg.intercept_: -8.881784197001252e-16
训练集得分: 1.0
测试集得分: 1.0
由于有两个参数,线性回归方程:y = 82.06262736x1 7.73658023x2-8.8e-16。另外由于使用make_regression产生的数据没有噪音,所以评分(score)是1.00,非常好。但是不雅开心得太早,我们使用sklearn datasets中的diabetes来进行线性回归,评分(score)就没有那么高了。
代码语言:javascript复制from sklearn import datasets
#用线性回归对sklearn数据进行分析
def useing_sklearn_datasets_for_LinearRegression():
X,y =datasets.load_diabetes().data,datasets.load_diabetes().target
X_train,X_test,y_train,y_test = train_test_split(X, y,random_state=8,test_size=0.3)
lr = LinearRegression().fit(X_train,y_train)
print('斜率: {} '.format(lr.coef_[0))
print('截距: {:.3f}'.format(lr.intercept_))
print('糖尿病训练集得分:{:.3f}'.format(lr.score(X_train,y_train)))
print('糖尿病测试集得分: {:.3f}'.format(lr.score(X_test,y_test)))
输出
代码语言:javascript复制斜率: [12.8821982 -280.25543507 525.99221876 407.85755317 -1120.30092255 698.91189157 234.67105524 208.41900324 816.01470258 114.97615609]
截距: 152.535
糖尿病训练集得分: 0.535
糖尿病测试集得分: 0.454
由于有10个斜率,与糖尿病数据有10个特征一致,训练集得分: 0.535,测试集得分: 0.454,显然这个数据是非常低的。我们再来看sklearn datasets对波士顿房价的回归。
代码语言:javascript复制Boston =datasets.load_boston()
X,y =Boston.data,Boston.target
X_train,X_test,y_train,y_test= train_test_split(X, y)
lr =LinearRegression().fit(X_train,y_train)
print('斜率: {} '.format(lr.coef_[:]))
print('截距: {}'.format(lr.intercept_))
print('波士顿房价训练集得分:{:.3f}'.format(lr.score(X_train,y_train)))
print('波士顿房价测试集得分:{:.3f}'.format(lr.score(X_test,y_test)))
输出
代码语言:javascript复制斜率: [-9.68961053e-02 4.87033096e-02-2.55499190e-02 3.92145072e 00 -1.52816098e 01 4.23762130e 00 -1.84848509e-02-1.56942479e 00 2.79115671e-01 -1.13985910e-02 -9.27575541e-01 1.05878888e-02-4.14823758e-01]
截距: 32.06878785459298
波士顿房价训练集得分: 0.743
波士顿房价测试集得分: 0.716
可见使用最小线性回归的性能还是比较小的。
2.3 StatsModels
Sklearn提供了最小二乘法的数据和算法,StatsModels也提供了最小二乘法的数据和算法。在StatsModels中最小二乘法又可以分为普通最小二乘法(OLS)、加权最小二乘法(WLS)、广义最小二乘法(GLS)和具有相关误差的可行最小二乘法。下面代码使用普通最小二乘法(OLS)来实现。
代码语言:javascript复制# 导入StatsModels的API库,C:Usersxiang>pip3 install statsmodels
import statsmodels.api as sm
#StatsModels 库
# y = w^x e(e 误差,符合均值为0的正态分布)
def StatsModels_linear_regression():
# 前四行训练构造函数,自变量x 因变量y
# 通过自变量x准备数据,将1~10 数据分割成20份
x = np.linspace(0,10,20)
# 向数组中添加一列,构成20组x
X = sm.add_constant(x)
ratio = np.array([1,10]) #ratio:比例
# 使回归方程的系数点乘x数据集,构成因变量y
#numpy.random.normal(loc=0.0, scale=1.0, size=None)
# loc:float,概率分布的均值,对应着整个分布的中心center
# scale: 概率分布的标准差,对应于分布的宽度,scale越大越矮胖,scale越小,越瘦高
# size: 输出的shape,默认为None,只输出一个值
# np.random.randn(size)所谓标准正太分布(μ=0, σ=1),对应于np.random.normal(loc=0, scale=1, size)
y = np.dot(X,ratio) np.random.normal(size=20)
# 执行OLS模型
testmodel = sm.OLS(y,X)
# 使用fit方法启动模型训练
results = testmodel.fit()
print("results.params:n",results.params,"nresults.summary():n",results.summary())
输出
results.params: | |||||||||
---|---|---|---|---|---|---|---|---|---|
[ 0.99796725 10.01634513] | |||||||||
results.summary(): | |||||||||
OLS Regression Results | |||||||||
Dep. Variable: | y | R-squared: | 0.999 | ||||||
Model: | OLS | Adj. R-squared: | 0.999 | ||||||
Method: | Least Squares | F-statistic: | 1.734e 04 | ||||||
Date: | Wed, 23 Dec 2020 | Prob (F-statistic): | 2.58e-28 | ||||||
Time: | 17:31:25 | Log-Likelihood: | -27.965 | ||||||
No. Observations: | 20 | AIC: | 59.93 | ||||||
Df Residuals: | 18 | BIC: | 61.92 | ||||||
Df Model: | 1 | ||||||||
Covariance Type: | nonrobust | ||||||||
coef | std err | t | P>|t| | [0.025 | 0.975] | ||||
const | 0.9980 | 0.445 | 2.243 | 0.038 | 0.063 | 1.933 | |||
x1 | 10.0163 | 0.076 | 131.668 | 0.000 | 9.857 | 10.176 | |||
Omnibus: | 1.628 | Durbin-Watson: | 1.619 | ||||||
Prob(Omnibus): | 0.443 | Jarque-Bera (JB): | 0.363 | ||||||
Skew: | -0.004 | Prob(JB): | 0.834 | ||||||
Kurtosis: | 3.660 | Cond. No. | 11.5 | ||||||
Notes:[1] Standard Errors assume that the covariance matrix of the errors is correctly specified. |
中文译文:
结果参数: | |||||||||
---|---|---|---|---|---|---|---|---|---|
[ 0.99796725 10.01634513] | |||||||||
结果描述: | |||||||||
OLS Regression Results | |||||||||
深度变量: | y | 判定系数: | 0.999 | ||||||
模型: | OLS | 平均判定系数: | 0.999 | ||||||
方法: | Least Squares | F统计量: | 1.734e 04 | ||||||
日期: | Wed, 23 Dec 2020 | 试验(F统计量): | 2.58e-28 | ||||||
时间: | 17:31:25 | 对数似然: | -27.965 | ||||||
观察号: | 20 | AIC: | 59.93 | ||||||
Df剩余 | 18 | BIC: | 61.92 | ||||||
Df模型: | 1 | ||||||||
协方差类型: | nonrobust | ||||||||
系数 | 标准误差 | t | P>|t| | [0.025 | 0.975] | ||||
const | 0.9980 | 0.445 | 2.243 | 0.038 | 0.063 | 1.933 | |||
x1 | 10.0163 | 0.076 | 131.668 | 0.000 | 9.857 | 10.176 | |||
综合: | 1.628 | Durbin-Watson: | 1.619 | ||||||
问题(综合): | 0.443 | Jarque-Bera (JB): | 0.363 | ||||||
偏斜: | -0.004 | 试验(JB): | 0.834 | ||||||
峰度系数: | 3.660 | 条件编号 | 11.5 | ||||||
注:[1] 标准误差假设误差的协方差矩阵被正确指定。 |
从中可以看出斜率为9.9462,截距为0.8117。我们用OLS分别对波士顿房价和糖尿病进行模拟。
代码语言:javascript复制from sklearn import datasets
def StatsModels_linear_regression_for_sklearn_dataset():
#Load Boston
Boston =datasets.load_boston()
X,y =Boston.data[:,5].reshape(-1,1),Boston.target.reshape(-1,1)
testmodel =sm.OLS(y,X)
results =testmodel.fit()
print("results.params(Boston):n",results.params,"nresults.summary(Boston):n",results.summary())
#Load diabetes
X,y = datasets.load_diabetes().data,datasets.load_diabetes().target
testmodel =sm.OLS(y,X)
results =testmodel.fit()
print("results.params(diabetes):n",results.params,"nresults.summary(diabetes):n",results.summary())
获得参数概要
代码语言:javascript复制results.params(Boston):
[3.6533504]
R-squared (uncentered): 0.901
results.params(diabetes):
[ -10.01219782 -239.81908937 519.83978679 324.39042769-792.18416163 476.74583782 101.04457032 177.06417623 751.27932109 67.62538639]
R-squared(uncentered): 0.106
由此可见对波士顿房价还是比较好的(0.901),而对于糖尿病就太不好了(0.106)。
现在我们用OLS、WLS、GLS来对波士顿房价进行评估。
代码语言:javascript复制def StatsModels_linear_regression_for_all_model():
#Load Boston
Boston =datasets.load_boston()
X,y =Boston.data[:,5].reshape(-1,1),Boston.target.reshape(-1,1)
testmodel =sm.OLS(y,X)
results =testmodel.fit()
print("OLS:n",results.params,"nOLS:n",results.summary())
Boston =datasets.load_boston()
X,y =Boston.data[:,5].reshape(-1,1),Boston.target.reshape(-1,1)
testmodel =sm.WLS(y,X)
results =testmodel.fit()
print("WLS:n",results.params,"nWLS:n",results.summary())
Boston =datasets.load_boston()
X,y =Boston.data[:,5].reshape(-1,1),Boston.target.reshape(-1,1)
testmodel =sm.GLS(y,X)
results =testmodel.fit()
print("GLS:n",results.params,"nGLS:n",results.summary())
使用这三种方法x均为3.6533504,精度均为0.901。
—————————————————————————————————
顾老师课程欢迎报名
软件安全测试
https://study.163.com/course/courseMain.htm?courseId=1209779852&share=2&shareId=480000002205486
接口自动化测试
https://study.163.com/course/courseMain.htm?courseId=1209794815&share=2&shareId=480000002205486
DevOps 和Jenkins之DevOps
https://study.163.com/course/courseMain.htm?courseId=1209817844&share=2&shareId=480000002205486
DevOps与Jenkins 2.0之Jenkins
https://study.163.com/course/courseMain.htm?courseId=1209819843&share=2&shareId=480000002205486
Selenium自动化测试
https://study.163.com/course/courseMain.htm?courseId=1209835807&share=2&shareId=480000002205486
性能测试第1季:性能测试基础知识
https://study.163.com/course/courseMain.htm?courseId=1209852815&share=2&shareId=480000002205486
性能测试第2季:LoadRunner12使用
https://study.163.com/course/courseMain.htm?courseId=1209980013&share=2&shareId=480000002205486
性能测试第3季:JMeter工具使用
https://study.163.com/course/courseMain.htm?courseId=1209903814&share=2&shareId=480000002205486
性能测试第4季:监控与调优
https://study.163.com/course/courseMain.htm?courseId=1209959801&share=2&shareId=480000002205486
Django入门
https://study.163.com/course/courseMain.htm?courseId=1210020806&share=2&shareId=480000002205486
啄木鸟顾老师漫谈软件测试
https://study.163.com/course/courseMain.htm?courseId=1209958326&share=2&shareId=480000002205486