快速入门Python机器学习(五)

2022-05-22 10:28:17 浏览数 (1)

5 线性回归

Sklearn类的线性回归以sklearn.linear_model.LinearRegression为基础,以sklearn.linear_model.Ridge(岭回归)、sklearn.linear_model.Lasso(套索回归)和sklearn.linear_model.ElasticNet(弹性网络)为优化。

我们首先来看一下如何通过Python画一条直线。

画出y = 0.5 × x 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()

画出经过[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()
    # 显示这条线的斜率和截距
   print('y={:.3f}'.format(lr.coef_[0]),'x',' {:.3f}'.format(lr.intercept_))

输出:

代码语言:javascript复制
y=1.000 x  1.000

可以看到,斜率与截距均为1.000。

我们加入第三个点[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  0.500

斜率为0.500,截距为0.500。

该直线到这三个点偏差最小,正如前面所说的,线性回归方法即找出一条直线,使得各个点到这条直线上的误差最小。

接下来介绍一下LinearRegression。

表达式

代码语言:javascript复制
sklearn.linear_model.LinearRegression(*, fit_intercept=True, normalize=False, copy_X=True, n_jobs=None, positive=False)

属性

属性

解释

coef_

array of shape (n_features, ) or (n_targets, n_features)。训练后的输入端模型系数,如果label有两个,即y值有两列。那么是一个2D的array

intercept_

float or array of shape (n_targets,).线性模型中的独立项(截距)。如果fit_intercept=False,则设置为0.0

rank_

Int.矩阵X的秩。仅在X稠密时可用。

singular_

array of shape (min(X, y),) . X的奇异值。仅在X为稠密时可用。

方法

fit(X, y[, sample_weight])

拟合线性模型。

get_params([deep])

获取此估计器的参数。

predict(X)

用线性模型预测。

score(X, y[, sample_weight])

返回预测的确定系数R2。

set_params(**params)

设置此估计器的参数。

这里,特别介绍一下score方法

score (X, y, sample_weight=None)

返回给定测试数据和标签的平均精确度。在多标签分类中,这是子集精度,这是一个苛刻的度量标准,因为您需要为每个样本准确地预测每个标签集。

输入

X:array-like, shape = (n_samples, n_features)。样本。

y :array-like, shape = (n_samples) or (n_samples, n_outputs)。真的X标签。

sample_weight:array-like, shape = [n_samples], optional。测试权重。

输出

代码语言:javascript复制
score :float。R2平均精度self.predict(X) wrt. y.

比如:

代码语言:javascript复制
clf.score(X_train,y_train)))
clf.score(X_test,y_test)))

5.1 用make_regression数据(无噪音)进行线性回归

代码语言:javascript复制
def LinearRegression_for_make_regression():
       myutil = util()
       X,y = make_regression(n_samples=100,n_features=1,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)
       clf = LinearRegression().fit(X,y)
       print('lr.coef_: {} '.format(clf.coef_[:]))
       print('reg.intercept_: {}'.format(clf.intercept_))
       print('训练集得分: {:.2%}'.format(clf.score(X_train,y_train)))
       print('测试集得分: {:.2%}'.format(clf.score(X_test,y_test)))

输出

代码语言:javascript复制
lr.coef_: [63.7840862] 
reg.intercept_: 4.440892098500626e-15
训练集得分: 100.00%
测试集得分: 100.00%

由于有两个参数,线性回归方程:

代码语言:javascript复制
y = 63.7840862X 4.440892098500626×10-15。

由于数据集没有噪声,所以score为100.00%。

在util类定义方法show_pic和draw_line

代码语言:javascript复制
       #显示图片
        def show_pic(self,title):
              plt.rcParams['font.sans-serif']=['SimHei']
              plt.rcParams['axes.unicode_minus']=False
              plt.suptitle(title)
              plt.show()
       
       #画拟合线
       def draw_line(self,X,y,clf,title):
              Z = np.linspace(-3,3,100)
              plt.scatter(X,y,c='b',s=60)
              try:
                     plt.plot(Z,clf.predict(Z.reshape(-1,1)),c='k')
              except Exception as e:
                     print("不支持画线")
              self.show_pic(title)

在上面代码后面加入:

代码语言:javascript复制
    myutil = util()
    title = "make_regression LinearRegression()回归线(无噪音)"
    myutil.draw_line(X[:,0],y,clf,title)

得到如下图。

很显然,拟合度相当好。

最后调用util类中的学习曲线方法。

代码语言:javascript复制
myutil.plot_learning_curve(LinearRegression(),X,y,title)
myutil.show_pic(title)

5.2 用make_regression数据(有噪音)进行线性回归

代码语言:javascript复制
#加入噪音
def LinearRegression_for_make_regression_add_noise():
       myutil = util()
       X,y = make_regression(n_samples=100,n_features=1,n_informative=2,noise=50,random_state=8)
       X_train,X_test,y_train,y_test = train_test_split(X, y, random_state=8,test_size=0.3)
       clf = LinearRegression().fit(X,y)
       print('lr.coef_: {} '.format(clf.coef_[:]))
       print('reg.intercept_: {}'.format(clf.intercept_))
       print('训练集得分: {:.2%}'.format(clf.score(X_train,y_train)))
       print('测试集得分: {:.2%}'.format(clf.score(X_test,y_test)))

输出

代码语言:javascript复制
lr.coef_: [68.77648945]
reg.intercept_: 1.2498738851984426
训练集得分: 70.18%
测试集得分: 64.27%

有两个参数,线性回归方程:

代码语言:javascript复制
y = 68.77648945X 1.2498738851984426

由于数据集有噪声,所以score 不为100.00%.

画出拟合线和得分图。

代码语言:javascript复制
myutil = util()
title = "make_regression LinearRegression()回归线(有噪音)"
myutil.draw_line(X[:,0],y,clf,title)
代码语言:javascript复制
myutil.plot_learning_curve(LinearRegression(),X,y,title)
myutil.show_pic(title)

得分是非常低的。

5.3 用糖尿病数据进行线性回归

代码语言: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复制
斜率: [11.5106203   -282.51347161   534.20455671   401.73142674 -1043.89718398   634.92464089  186.43262636   204.93373199   762.47149733    91.9460394 ]
截距: 152.562
糖尿病训练集得分: 53.04%
糖尿病测试集得分: 45.93%

可见用这个方法来拟合糖尿病数据是非常差的。画出得分图。

代码语言:javascript复制
title = "make_regression 糖尿病数据"
myutil.plot_learning_curve(LinearRegression(),X,y,title)
myutil.show_pic(title)

由于这里的直线是10维的,所以不能画出拟合曲线。

5.4 用波士顿房价数据进行线性回归

代码语言: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('波士顿房价训练集得分: {:.2%}'.format(lr.score(X_train,y_train)))
print('波士顿房价测试集得分: {:.2%}'.format(lr.score(X_test,y_test)))

输出

代码语言:javascript复制
斜率: [-1.14130415e-01  4.97830423e-02  4.15213771e-02  2.76156785e 00 -1.77723628e 01  3.89701303e 00 -1.08133797e-02 -1.54389831e 00  3.25856015e-01 -1.49890955e-02 -8.77878878e-01  7.79144087e-03 -4.97358277e-01]
截距: 36.38609891153045
波士顿房价训练集得分: 74.86%
波士顿房价测试集得分: 71.54%

画出得分图。

代码语言:javascript复制
title = "make_regression 波士顿房价数据"
myutil.plot_learning_curve(LinearRegression(),X,y,title)
myutil.show_pic(title)

同样这里的直线不是2维的,所以不能画出拟合曲线。

0 人点赞