回归分析

线性回归

scikit-learn提供了广义线性模型模块sklearn.linear_model. 它定义线性模型为:
image.png
linear_model模块提供用于线性回归的类:

class sklearn.linear_model.LinearRegression(fit_intercept=True, normalize=False, copy_X=True, n_jobs=1)
  • 生成一个LinearRegression类的实例。
  • 使用该实例调用fit()方法来拟合数组 X, y
  • fit(X, y, sample_weight=None),其中X, y接收数组,分别代表训练集和目标。
  • 将线性模型的系数w存储在其成员变量coef_中。
  • 用户可通过访问coef_和intercept_观察拟合的方程中,各自变量的系数和截距。
  • 使用predict()方法能够预测一个新的样本的回归值:
  • predict(X),其中X是新的样本。
#ch7
#例7-1 读取第5章产生的1元线性回归数据,进行回归分析,可视化回归结果
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.linear_model import LinearRegression
#读取数据文件
path='D:/my_python/ch7/data/'
X = pd.read_csv(path+'1x_regression.csv',sep = ',',encoding = 'utf-8').values
plt.rcParams['font.sans-serif'] = 'SimHei'#设置字体为SimHei显示中文
plt.rcParams['axes.unicode_minus']=False#坐标轴刻度显示负号
plt.rc('font', size=14)#设置图中字号大小
plt.figure(figsize=(4, 3))
plt.title('原始数据散点图')
plt.xlabel('x')#添加横轴标签
plt.ylabel('y')#添加纵轴标签
#绘制原始数据散点图,观察其特征
plt.scatter(X[:,0], X[:,1])
plt.show()
lr = LinearRegression()#生成线性回归模型实例
#可视化
plt.figure(figsize=(4, 3))
lr.fit(X[:,0].reshape(-1,1), X[:,1].reshape(-1,1))#训练
#将原始数据与回归曲线画在一张图上
plt.scatter(X[:,0], X[:,1])
plt.plot(X[:,0], lr.predict(X[:,0].reshape(-1,1)), 'k-')
plt.title('原始数据与回归方程图')
plt.xlabel('x')#添加横轴标签
plt.ylabel('y')#添加纵轴标签
plt.show()
print('回归方程为:\n','y=',lr.coef_[0],'*x+',lr.intercept_[0])
for x in range(10):
print('x=',x,'时,y的预测值为:',lr.predict(x))

岭回归

scikit-learn的sklearn.linear_model模块提供了岭回归Ridge()类:

class sklearn.linear_model.Ridge(alpha=1.0, fit_intercept=True, normalize=False, copy_X=True, max_iter=None, tol=0.001, solver=’auto’, random_state=None)

其主要参数alpha即为上式中的我们所说的λ\lambda.
Ridge()类的主要属性有:
coef_ : 数组,形状为(n_features,)或(n_targets, n_features),表示权重向量。
intercept_ : 浮点数,表示截距。
n_iter_ : 数组,形状为(n_targets,),表示每个目标的迭代次数,可以是None。
Ridge()类的主要方法有:
fit(X, y[, sample_weight])——拟合岭回归模型。
get_params([deep])——获取估计器参数。
predict(X)——预测X中样本的回归值。
score(X, y[, sample_weight])——返回R^2决策系数的预测值。
set_params(**params)——设置估计器参数。

岭回归
#例7-4 生成具有共线性特征的分类数据集,以对各个特征设置系数,叠加噪声,生成回归目标,进行岭回归
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn import datasets
n_samples=100
#生成具有冗余特征(共线性)的分类样本集
X, y = datasets.make_classification(n_samples=n_samples, n_features=10,
n_informative=2, n_redundant=7,
n_classes=2)
import seaborn as sns
sns.pairplot(pd.DataFrame(X))
#为X的每个特征设置系数和截距
b,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9=3,-5,4,8,-9,-3,6,2,-1,3,7
noise=np.random.randn(n_samples)
#叠加噪声生成回归目标集
y=2*noise+b+a0*X[:,0]+a1*X[:,1]+a2*X[:,2]+a3*X[:,3]+a4*X[:,4]+\
a5*X[:,5]+a6*X[:,6]+a7*X[:,7]+a8*X[:,8]+a9*X[:,9]
from sklearn import linear_model
#可视化,绘制真实系数与回归分析系数对比图
plt.figure(figsize=(6,4))
plt.rc('font', size=14)#设置图中字号大小
plt.rcParams['font.sans-serif'] = 'SimHei'#设置字体为SimHei显示中文
plt.rcParams['axes.unicode_minus']=False#坐标轴刻度显示负号
plt.plot([b,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9],marker='o')#真实系数
label=[]#该行代码书本中没有,应添加
for alpha in [0.001,100,1000]:
ridge = linear_model.Ridge(alpha=alpha)
ridge.fit(X, y)#拟合模型
plt.plot(np.append(ridge.intercept_,ridge.coef_),marker='*')#拟合系数
np.append(label,np.str_(alpha))
plt.legend(['实际系数','alpha=0.001', 'alpha=100','alpha=1000'])
plt.xlim(-1,20)
plt.title('拟合系数与实际系数对比')
plt.xlabel('变量Xi')#添加横轴标签
plt.ylabel('变量Xi的系数')#添加纵轴标签
plt.show()

image.png

逻辑回归

实现方面,逻辑回归只是对对线性回归的计算结果加上了一个Sigmoid函数,将数值结果转化为了0到1之间的概率(数值越大,函数越逼近1;数值越小,函数越逼近0),根据这个概率预测样本的类别。
scikit-learn机器学习模块的sklearn.linear_model提供了逻辑回归类LogisticRegression()

class sklearn.linear_model.LogisticRegression(penalty=’l2’, dual=False, tol=0.0001, C=1.0, fit_intercept=True, intercept_scaling=1, class_weight=None, random_state=None, solver=’warn’, max_iter=100, multi_class=’warn’, verbose=0, warm_start=False, n_jobs=None)

penalty:惩罚项,str类型,可选参数为l1和l2,默认为l2。用于指定惩罚项中使用的规范。newton-cg、sag和lbfgs求解算法只支持l2规范。
multi_class:分类方式选择参数,str类型,可选参数为ovr和multinomial,默认为ovr。ovr即前面提到的one-vs-rest(OvR),而multinomial即前面提到的many-vs-many(MvM)。如果是二元逻辑回归,ovr和multinomial并没有任何区别,区别主要在多元逻辑回归上。
LogisticRegression()类的主要属性有:
classes_ : 数组, 形状为(n_classes, ),表示分类器的类标签列表。
coef_ : 数组, 形状为((1, n_features)或 (n_classes, n_features),表示决策函数中特征的系数。
intercept_ : 数组, 形状为(1,)或(n_classes,),表示决策函数的截距。
n_iter_ : 数组, 形状为(n_classes,)或(1, ),表示所有类的实际迭代次数。
LogisticRegression()类的主要方法有:
decision_function(X)——预测样本的置信度分数。
densify()——将系数矩阵转化为紧密数组的格式。
fit(X, y[, sample_weight])——对给定训练数据拟合模型。
get_params([deep]) ——获取估计器参数。
predict(X)——预测X中样本的类标签。
predict_log_proba(X)——估计概率对数。
predict_proba(X)——估计概率。
score(X, y[, sample_weight]) ——返回对测试集的平均分类准确率。
set_params(**params)——设置估计器参数。
sparsify() ——将系数矩阵转化为稀疏格式。

#逻辑回归
#例7-5 生成具有两个特征的二元分类样本,分类别绘制原始样本集散点图,
#使用样本集训练逻辑回归模型,用训练好的模型对样本集进行分类,观察分类结果
import numpy as np
from sklearn.datasets.samples_generator import make_blobs
#使用make_blobs生成centers个类的数据集X,X形状为(n_samples,n_features)
#指定每个类的中心位置,y返回类标签
centers = [(-2, 0), (2, 0)]
X, y = make_blobs(n_samples=500, centers=centers, n_features=2,
random_state=0)
#分类别可视化样本集
plt.rc('font', size=14)#设置图中字号大小
plt.rcParams['font.sans-serif'] = 'SimHei'#设置字体为SimHei显示中文
plt.rcParams['axes.unicode_minus']=False#坐标轴刻度显示负号
plt.figure(figsize=(6, 4))
plt.scatter(X[np.where(y==0),0],X[np.where(y==0),1],marker='o',c='r')
plt.scatter(X[np.where(y==1),0],X[np.where(y==1),1],marker='<',c='b')
plt.xlim(-5,5)
plt.ylim(-4,4)
plt.legend(['y=0','y=1'])
plt.title('使用make_blobs生成自定义中心的2类样本')#添加标题
plt.show()
from sklearn.linear_model import LogisticRegression
#训练逻辑回归模型
logi_reg = LogisticRegression(random_state=0, solver='lbfgs',
multi_class='multinomial').fit(X, y)
#使用训练好的模型预测X的每个样本类别
y_predict=logi_reg.predict(X)
#分类别可视化预测结果
plt.figure(figsize=(6, 4))
plt.scatter(X[np.where(y_predict==0),0],X[np.where(y_predict==0),1],marker='o',c='r')
plt.scatter(X[np.where(y_predict==1),0],X[np.where(y_predict==1),1],marker='<',c='b')
plt.xlim(-5,5)
plt.ylim(-4,4)
plt.legend(['y_predict=0','y_predict=1'])
plt.title('对X预测结果')#添加标题
plt.show()
#绘制预测错误样本
plt.figure(figsize=(6, 4))
plt.scatter(X[np.where(y_predict!=y),0],X[np.where(y_predict!=y),1],marker='x')
plt.title('预测错误的样本')#添加标题
plt.xlim(-5,5)
plt.ylim(-4,4)
plt.show()

多项式回归

scikit-learn对多项式回归没有提供直接的方法,而是在数据预处理模块sklearn.preprocessing提供了PolynomialFeatures()类。
该类将数据集变换为具有高次项特征的新的数据集,将原始问题转化为线性回归问题。
用户再使用线性回归方法对转化后的数据集进行训练,从而间接的进行多项式回归分析。
image.png
PolynomialFeatures()类将其转化为具有3个特征的线性回归问题,这三个特征分别是x, x2, 和一个值全为1的常量特征。
输出形状为(n_samples,3), 格式为[1, x,x2]的新的数据集。
这时,新的数据集将是一个线性回归问题。使用线性回归方法对其拟合,既可以得到回归模型。
对多特征、有更高次项的样本,PolynomialFeatures()类同样通过增加高次项特征的方法,将其转化为线性特征数据集。
要预测新值,也需要使用训练的PolynomialFeatures()模型将其转为线性数据集,然后使用训练的线性回归模型对转化后的数据集进行预测。
PolynomialFeatures()类的格式如下:

class sklearn.preprocessing.PolynomialFeatures(degree=2, interaction_only=False, include_bias=True)

参数degree接收整数,表示拟合目标中项的最高指数,默认为2。
PolynomialFeatures()类的主要参数如下:
powers_ : 数组,形状为(n_output_features, n_input_features),powers_[i, j]是第j个输入特征在第i个输出特征的指数。
n_input_features_ :输入特征的数量。
n_output_features_ : 输出的多项式特征的总数量。
PolynomialFeatures()类的主要方法如下:
fit(X[, y])——计算输出特征的数量。
fit_transform(X[, y])——拟合数据,并转化数据。
get_feature_names([input_features])——返回输出特征的名称。
get_params([deep])——获取估计器参数。
set_params(**params)——设置估计器参数。
transform(X)——将数据集转化为多项式特征。
先生成PolynomialFeatures()类的一个实例,然后使用fit()输出特征的数量再使用transform()将数据集转换为1次特征数据集(也可以使用fit_transform())拟合和转换数据,接着对转换后的数据进行线性回归。

单特征数据集多项式回归

#多项式回归
#例7-7 根据已知一元二次方程,生成非线性样本集,对样本集进行多项式回归分析。
import numpy as np
import matplotlib.pyplot as plt
n_samples=10
X=np.sort(np.random.uniform(-5,10,n_samples)).reshape(-1,1)#形状为1列(一个特征)
y = 1.5 * X**2 -5*X -10
plt.rcParams['font.sans-serif'] = 'SimHei'#设置字体为SimHei显示中文
plt.rcParams['axes.unicode_minus']=False#坐标轴刻度显示负号
plt.rc('font', size=14)#设置图中字号大小
plt.figure(figsize=(6, 4))
plt.scatter(X,y)
plt.title('原始样本集')#添加标题
plt.show()
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
poly = PolynomialFeatures(2)
poly.fit(X)#拟合多项式模型
X2=poly.transform(X)#使用拟合模型变换X
print('原始数据集X的形状为:\n',X.shape)
print('X转换为X2后的形状为:\n',X2.shape)
print('原始数据集X为:\n',X)
print('X转换为X2后为:\n',X2)
lin_reg = LinearRegression()#生成线性回归模型实例
lin_reg.fit(X2,y)#使用变换后的数据集拟合线性回归模型
#生成均匀分布、排序的测试集,排序便于绘制曲线
x_test=np.sort(np.random.uniform(-10,15,100))
#使用拟合的多项式模型变换测试集
x_test2=poly.transform(x_test.reshape(-1,1))
#使用拟合的线性回归模型预测变换后的测试集
y_test_predict=lin_reg.predict(x_test2)
plt.figure(figsize=(6, 4))
plt.plot(x_test,y_test_predict,linewidth=2,c='y')
plt.scatter(X,y)
plt.title('多项式回归结果')#添加标题
plt.legend(['n=2','原始样本'])
plt.show()

多特征数据集多项式回归

#二特征多项式回归
#例7-10 根据已知二元二次方程,生成非线性样本集,对样本集进行多项式回归分析。
import numpy as np
import matplotlib.pyplot as plt
n_samples=30
X1=np.random.uniform(-1,1,n_samples).reshape(-1,1)#形状为1列(一个特征)
X2=np.random.uniform(-1,1,n_samples).reshape(-1,1)#形状为1列(一个特征)
print('X1的形状为:',X1.shape)
print('X2的形状为:',X2.shape)
#生成矩阵,,以生成更多空间样本
X1, X2 = np.meshgrid(X1, X2)
y =X1**2+X2**2+0.3*np.random.randn(n_samples)#叠加噪声
print('生成矩阵后X1的形状为:',X1.shape)
print('生成矩阵后X2的形状为:',X2.shape)
print('y的形状为:',y.shape)
#导入3D绘图模块,绘制原始样本的3D散点图
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
fig = plt.figure()
ax = Axes3D(fig)
ax.scatter(X1, X2,y,c='y')
plt.title('原始样本集')
plt.show()
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
#将X1,X2转化为单列特征,横向合并
X=np.hstack((X1.reshape(-1,1),X2.reshape(-1,1)))
poly2 = PolynomialFeatures(2)#多项式拟合模型参数最高指数为2
poly2.fit(X)#拟合多项式模型
X_poly=poly2.transform(X)#使用拟合模型变换X
print('原始数据集X的形状为:',X.shape)
print('X转换为X_poly后的形状为:',X_poly.shape)
lin_reg2 = LinearRegression()#生成线性回归模型实例
lin_reg2.fit(X_poly,y.reshape(-1,1))#使用变换后的数据集拟合线性回归模型
#生成测试集,用于预测,并绘制拟合曲面
n_test_samples=100
x_test1=np.linspace(-1.1,1.1,n_test_samples)
x_test2=np.linspace(-1.1,1.1,n_test_samples)
print('x_test1的形状为:',x_test1.shape)
print('x_test2的形状为:',x_test2.shape)
lin_reg2 = LinearRegression()#生成线性回归模型实例
lin_reg2.fit(X_poly,y.reshape(-1,1))#使用变换后的数据集拟合线性回归模型
#生成测试集,用于预测,并绘制拟合曲面
n_test_samples=100
x_test1=np.linspace(-1.1,1.1,n_test_samples)
x_test2=np.linspace(-1.1,1.1,n_test_samples)
print('x_test1的形状为:',x_test1.shape)
print('x_test2的形状为:',x_test2.shape)
#将x_test1,x_test2再转换为单列(单特征)数组,并横向合并
X_test=np.hstack((x_test1.reshape(-1,1),x_test2.reshape(-1,1)))
X_test_poly=poly2.transform(X_test)#多项式特征变换
y_predict=lin_reg2.predict(X_test_poly)#线性回归模型预测
#利用预测结果绘制拟合曲面,绘制原始数据散点图
fig = plt.figure()
ax = Axes3D(fig)
#将x_test1,x_test2恢复为矩阵形式,绘制预测结果的曲面
ax.plot_surface(x_test1.reshape(-1,n_test_samples),
x_test2,y_predict.reshape(-1,n_test_samples),
color='b')
ax.scatter(X1, X2,y,c='y')#绘制原始数据
plt.title('原始样本集与拟合曲面')
plt.show()