• sklearn机器学习——day12


    回归是一种应用广泛的预测建模技术,这种技术的核心在于预测的结果是连续型变量。

    线性回归的任务,就是构造一个预测函数来映射输入的特征矩阵 和标签值 的线性关系,这个预测函数在不同的教 材上写法不同,可能写作 , ,或者 等等形式,但无论如何,这个预测函数的本质就是我们需要构建的 模型,而构造预测函数的核心就是找出模型的参数向量 。

    希望我们的预测结果和真实值差异越小越好

    最小二乘法求解多元线性回归的参数

    现在问题转换成了求解让RSS最小化的参数向量 ,这种通过最小化真实值和预测值之间的RSS来求解参数的方法叫 做最小二乘法。

     

     

     来做一次回归试试

    1. from sklearn.linear_model import LinearRegression as LR
    2. from sklearn.model_selection import train_test_split
    3. from sklearn.model_selection import cross_val_score
    4. from sklearn.datasets import fetch_california_housing as fch #加利福尼亚房屋价值数据集
    5. import pandas as pd
    6. housevalue = fch() #会需要下载,大家可以提前运行试试看
    7. X = pd.DataFrame(housevalue.data) #放入DataFrame中便于查看
    8. y = housevalue.target
    9. X.shape
    10. y.shape
    11. X.head()
    12. housevalue.feature_names
    13. X.columns = housevalue.feature_names
    14. """
    15. MedInc:该街区住户的收入中位数
    16. HouseAge:该街区房屋使用年代的中位数
    17. AveRooms:该街区平均的房间数目
    18. AveBedrms:该街区平均的卧室数目
    19. Population:街区人口
    20. AveOccup:平均入住率
    21. Latitude:街区的纬度
    22. Longitude:街区的经度
    23. """
    24. Xtrain, Xtest, Ytrain, Ytest = train_test_split(X,y,test_size=0.3,random_state=420)
    25. for i in [Xtrain, Xtest]:
    26. i.index = range(i.shape[0])
    27. Xtrain.shape
    28. #如果希望进行数据标准化,还记得应该怎么做吗?
    29. #先用训练集训练标准化的类,然后用训练好的类分别转化训练集和测试集
    30. reg = LR().fit(Xtrain, Ytrain)
    31. yhat = reg.predict(Xtest)
    32. yhat
    33. reg.coef_
    34. [*zip(Xtrain.columns,reg.coef_)]
    35. """
    36. MedInc:该街区住户的收入中位数
    37. HouseAge:该街区房屋使用年代的中位数
    38. AveRooms:该街区平均的房间数目
    39. AveBedrms:该街区平均的卧室数目
    40. Population:街区人口
    41. AveOccup:平均入住率
    42. Latitude:街区的纬度
    43. Longitude:街区的经度
    44. """
    45. reg.intercept_

     

    回归类模型的评估指标

     是否预测了正确的数值:

    1. from sklearn.metrics import mean_squared_error as MSE
    2. MSE(yhat,Ytest)
    3. y.max()
    4. y.min()
    5. cross_val_score(reg,X,y,cv=10,scoring="mean_squared_error")
    6. #为什么报错了?来试试看!
    7. import sklearn
    8. sorted(sklearn.metrics.SCORERS.keys())
    9. cross_val_score(reg,X,y,cv=10,scoring="neg_mean_squared_error")

     是否拟合了足够的信息:

     衡量的是1 - 我们的模型没 有捕获到的信息量占真实标签中所带的信息量的比例,所以, 越接近1越好

    1. #调用R2
    2. from sklearn.metrics import r2_score
    3. r2_score(yhat,Ytest)
    4. r2 = reg.score(Xtest,Ytest)
    5. r2

    多重共线性:岭回归与Lasso

    求 解系数 的式子和过程:

    多重共线性如果存在,则线性回归就无法使用最小二乘法来进行求解,或者求解就会出现偏差。幸运的是,不能存在 多重共线性,不代表不能存在相关性——机器学习不要求特征之间必须独立,必须不相关,只要不是高度相关或者精 确相关就好。

     

    岭回归

    是为了修复漏洞而设 计的(实际上,我们使用岭回归或者Lasso,模型的效果往往会下降一些,因为我们删除了一小部分信息 )

    在sklearn中,岭回归由线性模型库中的Ridge类来调用:

    就在加利佛尼亚房屋价值数据集上来验证一下这个说法:

    1. import numpy as np
    2. import pandas as pd
    3. from sklearn.linear_model import Ridge, LinearRegression, Lasso
    4. from sklearn.model_selection import train_test_split as TTS
    5. from sklearn.datasets import fetch_california_housing as fch
    6. import matplotlib.pyplot as plt
    7. housevalue = fch()
    8. X = pd.DataFrame(housevalue.data)
    9. y = housevalue.target
    10. X.columns = ["住户收入中位数","房屋使用年代中位数","平均房间数目"
    11. ,"平均卧室数目","街区人口","平均入住率","街区的纬度","街区的经度"]
    12. X.head()
    13. Xtrain,Xtest,Ytrain,Ytest = TTS(X,y,test_size=0.3,random_state=420)
    14. #数据集索引恢复
    15. for i in [Xtrain,Xtest]:
    16. i.index = range(i.shape[0])
    17. #使用岭回归来进行建模
    18. reg = Ridge(alpha=1).fit(Xtrain,Ytrain)
    19. reg.score(Xtest,Ytest)
    20. #交叉验证下,与线性回归相比,岭回归的结果如何变化?
    21. alpharange = np.arange(1,1001,100)
    22. ridge, lr = [], []
    23. for alpha in alpharange:
    24. reg = Ridge(alpha=alpha)
    25. linear = LinearRegression()
    26. regs = cross_val_score(reg,X,y,cv=5,scoring = "r2").mean()
    27. linears = cross_val_score(linear,X,y,cv=5,scoring = "r2").mean()
    28. ridge.append(regs)
    29. lr.append(linears)
    30. plt.plot(alpharange,ridge,color="red",label="Ridge")
    31. plt.plot(alpharange,lr,color="orange",label="LR")
    32. plt.title("Mean")
    33. plt.legend()
    34. plt.show()
    35. #细化一下学习曲线
    36. alpharange = np.arange(1,201,10)
    37. #模型方差如何变化?
    38. alpharange = np.arange(1,1001,100)
    39. ridge, lr = [], []
    40. for alpha in alpharange:
    41. reg = Ridge(alpha=alpha)
    42. linear = LinearRegression()
    43. varR = cross_val_score(reg,X,y,cv=5,scoring="r2").var()
    44. varLR = cross_val_score(linear,X,y,cv=5,scoring="r2").var()
    45. ridge.append(varR)
    46. lr.append(varLR)
    47. plt.plot(alpharange,ridge,color="red",label="Ridge")
    48. plt.plot(alpharange,lr,color="orange",label="LR")
    49. plt.title("Variance")
    50. plt.legend()
    51. plt.show()

     选取最佳的正则化参数取值

    使用岭迹图来判 断正则项参数的最佳取值

     

    岭迹图认 为,线条交叉越多,则说明特征之间的多重共线性越高。我们应该选择系数较为平稳的喇叭口所对应的 取值作为最 佳的正则化参数的取值。

    绘制岭迹图的方法非常简单,代码如下:

    1. import numpy as np
    2. import matplotlib.pyplot as plt
    3. from sklearn import linear_model
    4. #创造10*10的希尔伯特矩阵
    5. X = 1. / (np.arange(1, 11) + np.arange(0, 10)[:, np.newaxis])
    6. y = np.ones(10)
    7. #计算横坐标
    8. n_alphas = 200
    9. alphas = np.logspace(-10, -2, n_alphas)
    10. #建模,获取每一个正则化取值下的系数组合
    11. coefs = []
    12. for a in alphas:
    13. ridge = linear_model.Ridge(alpha=a, fit_intercept=False)
    14. ridge.fit(X, y)
    15. coefs.append(ridge.coef_)
    16. #绘图展示结果
    17. ax = plt.gca()
    18. ax.plot(alphas, coefs)
    19. ax.set_xscale('log')
    20. ax.set_xlim(ax.get_xlim()[::-1]) #将横坐标逆转
    21. plt.xlabel('正则化参数alpha')
    22. plt.ylabel('系数w')
    23. plt.title('岭回归下的岭迹图')
    24. plt.axis('tight')
    25. plt.show()

     Lasso处理多重共线性

    Lasso的损失函数表达式为:

     

     

    Lasso的核心作用:特征选择

    在sklearn中我们的Lasso使用的损失函数是:

     

    看lasso如何做特征选择:

    1. import numpy as np
    2. import pandas as pd
    3. from sklearn.linear_model import Ridge, LinearRegression, Lasso
    4. from sklearn.model_selection import train_test_split as TTS
    5. from sklearn.datasets import fetch_california_housing as fch
    6. import matplotlib.pyplot as plt
    7. housevalue = fch()
    8. X = pd.DataFrame(housevalue.data)
    9. y = housevalue.target
    10. X.columns = ["住户收入中位数","房屋使用年代中位数","平均房间数目"
    11. ,"平均卧室数目","街区人口","平均入住率","街区的纬度","街区的经度"]
    12. X.head()
    13. Xtrain,Xtest,Ytrain,Ytest = TTS(X,y,test_size=0.3,random_state=420)
    14. #恢复索引
    15. for i in [Xtrain,Xtest]:
    16. i.index = range(i.shape[0])
    17. #线性回归进行拟合
    18. reg = LinearRegression().fit(Xtrain,Ytrain)
    19. (reg.coef_*100).tolist()
    20. #岭回归进行拟合
    21. Ridge_ = Ridge(alpha=0).fit(Xtrain,Ytrain)
    22. (Ridge_.coef_*100).tolist()
    23. #Lasso进行拟合
    24. lasso_ = Lasso(alpha=0).fit(Xtrain,Ytrain)
    25. (lasso_.coef_*100).tolist()
    26. #岭回归进行拟合
    27. Ridge_ = Ridge(alpha=0.01).fit(Xtrain,Ytrain)
    28. (Ridge_.coef_*100).tolist()
    29. #Lasso进行拟合
    30. lasso_ = Lasso(alpha=0.01).fit(Xtrain,Ytrain)
    31. (lasso_.coef_*100).tolist()
    32. #加大正则项系数,观察模型的系数发生了什么变化
    33. Ridge_ = Ridge(alpha=10**4).fit(Xtrain,Ytrain)
    34. (Ridge_.coef_*100).tolist()
    35. lasso_ = Lasso(alpha=10**4).fit(Xtrain,Ytrain)
    36. (lasso_.coef_*100).tolist()
    37. #看来10**4对于Lasso来说是一个过于大的取值
    38. lasso_ = Lasso(alpha=1).fit(Xtrain,Ytrain)
    39. (lasso_.coef_*100).tolist()
    40. #将系数进行绘图
    41. plt.plot(range(1,9),(reg.coef_*100).tolist(),color="red",label="LR")
    42. plt.plot(range(1,9),(Ridge_.coef_*100).tolist(),color="orange",label="Ridge")
    43. plt.plot(range(1,9),(lasso_.coef_*100).tolist(),color="k",label="Lasso")
    44. plt.plot(range(1,9),[0]*8,color="grey",linestyle="--")
    45. plt.xlabel('w') #横坐标是每一个特征所对应的系数
    46. plt.legend()
    47. plt.show()

     lasso选取最佳的正则化参数取值

    使用交叉验证的Lasso类的参数看起来与岭回归略有不同,这是由于Lasso对于alpha的取值更加敏感的性质决定的。 之前提到过,由于Lasso对正则化系数的变动过于敏感,因此我们往往让 在很小的空间中变动。这个小空间小到超 乎人们的想象(不是0.01到0.02之间这样的空间,这个空间对lasso而言还是太大了)

     

    1. from sklearn.linear_model import LassoCV
    2. #自己建立Lasso进行alpha选择的范围
    3. alpharange = np.logspace(-10, -2, 200,base=10)
    4. #其实是形成10为底的指数函数
    5. #10**(-10)到10**(-2)次方
    6. alpharange.shape
    7. Xtrain.head()
    8. lasso_ = LassoCV(alphas=alpharange #自行输入的alpha的取值范围
    9. ,cv=5 #交叉验证的折数
    10. ).fit(Xtrain, Ytrain)
    11. #查看被选择出来的最佳正则化系数
    12. lasso_.alpha_
    13. #调用所有交叉验证的结果
    14. lasso_.mse_path_
    15. lasso_.mse_path_.shape #返回每个alpha下的五折交叉验证结果
    16. lasso_.mse_path_.mean(axis=1) #有注意到在岭回归中我们的轴向是axis=0吗?
    17. #在岭回归当中,我们是留一验证,因此我们的交叉验证结果返回的是,每一个样本在每个alpha下的交叉验证结果
    18. #因此我们要求每个alpha下的交叉验证均值,就是axis=0,跨行求均值
    19. #而在这里,我们返回的是,每一个alpha取值下,每一折交叉验证的结果
    20. #因此我们要求每个alpha下的交叉验证均值,就是axis=1,跨列求均值
    21. #最佳正则化系数下获得的模型的系数结果
    22. lasso_.coef_
    23. lasso_.score(Xtest,Ytest)
    24. #与线性回归相比如何?
    25. reg = LinearRegression().fit(Xtrain,Ytrain)
    26. reg.score(Xtest,Ytest)
    27. #使用lassoCV自带的正则化路径长度和路径中的alpha个数来自动建立alpha选择的范围
    28. ls_ = LassoCV(eps=0.00001
    29. ,n_alphas=300
    30. ,cv=5
    31. ).fit(Xtrain, Ytrain)
    32. ls_.alpha_
    33. ls_.alphas_ #查看所有自动生成的alpha取值
    34. ls_.alphas_.shape
    35. ls_.score(Xtest,Ytest)
    36. ls_.coef_

     

  • 相关阅读:
    【单元测试与JUnit 4】传统main方法测试代码太麻烦?来试试JUnit4
    PHP 中传值与传引用的区别,什么时候传值什么时候传引用?
    延时队列我在项目里是怎么实现的?
    云原生k8s的金箍棒
    【博学谷学习记录】超强总结,用心分享|Shell字符串
    Shiro框架-史上详解
    ThreadLocal&上传下载文件
    微积分的基本公式共有四大公式:
    Windows内核--RtlCopyUnicodeString和RtlEqualUnicodeString IRQL不一样(3.2)
    (附源码)ssm产品裂变管理系统 毕业设计 100953
  • 原文地址:https://blog.csdn.net/weixin_44267765/article/details/126936246