机器学习--逐步回归算法,线性回归的特征选择算法

逐步回归算法

监督式学习算法的任务是拟合多个特征与标签的关系,在实际应用中,所收集的数据中,所有的特征可能并不是都与标签有关联。模型中如果包含与标签无关联的特征,不仅会增加数据规模和计算量,还会影响模型对标签的预测效果。因此特征选择是监督式学习算法的一个重要组成部分。
逐步回归是一个贪心算法。它的运行效率较高,但也因为其是贪心算法,有时会做出次优的最优选择。

向前逐步回归算法

向前逐步回归算法是最简单的一种特征选择方法,大概做法为:在向前逐步回归算法的初始阶段,先选定第一个特征,然后重复执行以下几个步骤----首先计算只使用当前选定的特征的线性回归的均方误差,然后逐一引入尚未选取的特征,选择能最大程度降低均方误差的一个特征,判断该特征是否在统计意义上显著地降低均方误差,如果是,就将该特征加入模型。重复循环上述过程,直至没有能够被继续选中的特征为止。

判断选择的特征是否在统计意义上显著降低均方误差

在向前逐步回归算法中,采用F检验来判断均方误差的减小是否具有统计显著性。
给定两个均方误差mse1 和mse2,设mse1>mse2。用F检验计算mse1>mse2的置信度p。
置信度p是在重新采样训练数据并对其重复向前逐步选择算法时再次出现mse1>mse2的概率。
如果置信度p>95%,则认为mse1>mse2这一结论具有统计显著性。

import numpy as np
from scipy.stats import f
# 向前逐步选择
class StepwiseRegression():
    def fit(self,X,y):
        return np.linalg.inv(X.T.dot(X)).dot(X.T).dot(y)

    # 计算均方误差
    def compute_mse(self,X,y):
        w = self.fit(X,y)
        r = y - X.dot(w)
        return r.T.dot(r)

    # 判断引入新特征是否有效降低均方误差
    def f_tesy(self,mse_A,mse_min,m):
        if mse_min > mse_A:
            return False
        F = mse_A/mse_min
        p_value = f.cdf(F,m,m)
        return p_value>0.95


    # 特征选择
    def forward_selection(self,X,y):
        m, n = X.shape
        # 记录特征列数,A为已经选择的特征,C为备选特征
        A, C =[0],[i for i in range(1,n)]
        while len(C)>0:
            # 取训练数据中的A包含的特征
            MSE_A = self.compute_mse(X[:,A],y)
            MSE_min = float("inf")
            j_min = -1
            #遍历未选择的特征,保留均方误差最小值以及代表的特征列
            for j in C:
                MSE_j = self.compute_mse(X[:,A+[j]],y)
                if MSE_j < MSE_min:
                    MSE_min ,j_min = MSE_j,j
            if self.f_tesy(MSE_A,MSE_min,m):
                A.append(j_min)
                C.remove(j_min)
            else:
                break
        self.w = self.fit(X[:,A],y)
        self.A = A


    # 计算标签值
    def predict(self,X):
        return X[:,self.A].dot(self.w)

向前逐步回归算法的应用

# 应用向前逐步回归算法进行特征选择

import numpy as np
from sklearn.preprocessing import PolynomialFeatures
from machine_learning_lib_stepwise_regression import StepwiseRegression
import matplotlib.pyplot as plt
from machine_learning_lib_stepwise_regressiontwo import Stepwiseregression as Step

# 构造数据
def generate_sample(m):
    X = 2 * (np.random.rand(m,1)-0.5)
    y = X + np.random.normal(0,0.3,(m,1))
    return X,y

np.random.seed(100)
# 生成10个点
X,y = generate_sample(10)
plt.scatter(X,y)
poly = PolynomialFeatures(degree=10)
X_poly = poly.fit_transform(X)
model = StepwiseRegression()
model.forward_selection(X_poly,y)
y_pred = X_poly[:,[0,1]].dot(model.w)
plt.plot(X,y_pred)
print(model.A,model.w)
plt.show()

为了直观的观察特征选择的效果,训练数据是通过随机函数产生的,并对其多项式化,产生11个特征,标签以y=x,赋予一定程度的浮动人为产生。

该训练数据如果不进行特征的选择,直接对全部特征进行线性回归,将产生过度拟合的线性回归模型。

未使用特征选择:

机器学习--逐步回归算法,线性回归的特征选择算法_第1张图片

使用特征选择:

机器学习--逐步回归算法,线性回归的特征选择算法_第2张图片

总结:

特征选择能有效的剔除与标签无关联的特征,避免无关特征对模型的影响,导致过度的拟合,但向前逐步回归法是一个贪心算法,在算法的开始,选择了第一个特征为起始,但第一个特征与标签的关系并未进行判断,若第一个特征与标签无关联,则将会产生次优解。

思考:

向后逐步回归算法可以有效解决向前逐步回归算法的影响,向后逐步回归在起始的时候选取全部特征,之后逐一 剔除不能有效降低均方误差的特征。但是向后逐步回归算法也是一个贪心算法,依然可能产生次优解,并且当前选定的特征已经过度拟合,从而具有较小的均方误差,向后逐步回归算法将无法继续从模型中剔除与标签无关的特征。

处理方案:

向前逐步回归算法与向后逐步回归算法的合并使用。
向前逐步回归算法起始选择随机,多次运行,选择最优情况。

你可能感兴趣的:(编程实践,算法,编程思想,机器学习)