【创造者】数据清洗:最小-最大归一化与前向后向消元

引言:

数据清洗是数据预处理的一个重要环节,其目的是通过一系列的技术手段去除数据集中的异常值、噪声、缺失值等不可靠或不适当的数据,以提高数据的质量和可信度。数据清洗通常包括以下几个方面:

  1. 去除重复值:有些数据集中可能出现重复的数据,这种数据对模型训练没有任何帮助,需要去除。

  2. 处理缺失值:数据集中可能因为种种原因存在缺失值,需要进行适当的处理,如填补缺失值、删除含有缺失值的条目等。

  3. 去除异常值:在数据采集过程中,由于各种原因,数据集中可能出现异常值,这种数据会对模型的训练产生负面影响,需要去除。

  4. 数据类型转换:处理计算机无法识别的特殊字符、缺失值标记等,使得数据可以被机器学习算法进行分析。

  5. 特征选择:通过统计学方法和机器学习算法,选择最具预测性能的特征,来提高模型的预测性能。

  6. 数据归一化:将不同量纲的数据转化为相同的量纲,比如将数据标准化为均值为0,标准差为1的形式,来提高模型的训练效率和预测性能。

数据清洗对于机器学习算法的性能和稳定性至关重要。在进行数据清洗时,需要仔细地检查每个数据点,确保尽可能减小数据集中存在的错误和异常值对模型带来的负面影响。同时,也需要结合特定领域知识和经验,采用合适的方式进行清洗处理,以达到最佳的数据清洗效果。

数据归一化处理的作用:

数据归一化的作用是:

  1. 降低数据的复杂度和噪声:不同特征具有不同的量级和数值范围,进行数据归一化后能够将特征值缩放到相似的尺度上,降低了数据中的复杂度和噪声,提高了学习算法的准确性。

  2. 提高模型训练速度:归一化后的数据可以使得模型的收敛速度更快,这是因为归一化后的数据具有相同的尺度,优化过程不会被某些数值较大的特征所主导,从而更加平稳、稳定。

  3. 保护模型不受异常值影响

举一个最简单的例子,比如你要计算一个多元线性回归模型,假设模型中有两个变量,一个房价,一个面积,可能房价的单位是元,那么它的数据有几十万几百万那么大,而对于面积来说,它的单位是平米,甚至是平方千米,那么它的数据的值就会很小。在这种情况下,尽管你的数据没有异常值和噪声,拟合出来的结果依旧不好。所以我们要做一下归一化,把数据都缩放到一个尺度中。

最大-最小归一化:

最小-最大归一化将数据缩放到一个给定的范围(通常是[0,1]),公式为:

实战操作:

我们现在有一组数据如下所示,我们现在要以人口(population)为因变量,面积(Shape_area), 月收入中位数(Income),劳动人口比例(Labour)为自变量计算一个线性回归的模型: 

那么对于一个完整的数据处理,我们需要做的是先看看有没有异常值,数据缺失,需不需要进行数据转换。那么由于我们的例子中的数据比较少,能直观的看出来不需要做这些。

接下来我们需要做的就是数据归一化,通常情况下是将自变量归一化,因变量不需要。

上代码:

import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn import preprocessing

# 加载数据
data = pd.read_csv(r'C:\Users\14295\Desktop\regression\table.csv')

# 指定因变量和自变量
y = data['population']
X = data[['Shape_Area', 'income', 'labour']]


# 对参数进行归一化,最小-最大缩放是将原始数据缩放到 [0, 1] 的区间内
min_max_scaler = preprocessing.MinMaxScaler()
x_scaled = min_max_scaler.fit_transform(X)
# print(type(x_scaled))
X = pd.DataFrame(x_scaled, columns=['Shape_Area', 'income', 'labour']) # 将归一化处理后的数据转化为 DataFrame 格式

代码解释:归一化用的方法是sklearn包中的preprocessing,其中preprocessing.MinMaxScaler()方法就是用来进行数据归一化的。实例化这个方法之后调用这个对象中的fit_transform()方法就可以对所有数据进行归一化处理。注意返回的是一个ndarray类的对象,所以我们还要把它转换成DataFrame类的对象才可以进行进一步的处理。

前向消元:

在进行特征选择时,由于需要评估不同特征集合对模型性能的影响,因此需要逐步加入或删除特征。为了避免出现过拟合的情况,需要设置合适的停止准则,以确保选择的特征集合可以达到良好的泛化能力。

而前向消元(Forward Elimination)是一种逐步加入特征的特征选择方法。该方法通过逐步添加某个特征,来评估特征的重要性和对模型拟合效果的影响。

模型的评估是非常重要的。为了评估回归模型的性能,我们通常需要选择一个合适的评分指标(scoring metric),用该指标来度量模型预测值和目标变量之间的拟合程度。当然,在回归问题中有很多可供选择的评分指标,均方误差(mean squared error, MSE)是其中一种。

均方误差实际上是对所有预测值与实际值之差的平方求和的平均值。公式如下:

前向消元具体步骤: 

1.对于每一个单独的自变量,我们都将其与因变量y进行回归,计算其均方误差,选出均方误差最小的那个是最好的变量。在上面的例子中,自变量是population,那么我们用另外三个变量分别与人口数据进行拟合,这样我们会得出三个一元线性回归模型,比较这三个模型的MSE,最小的那个模型最好,保留那个自变量。

2.假设上一步我们算出来拟合最好的变量是Labour,那么第二步就是在保留这个变量的基础上,在剩下的两个变量中挑出一个与Labour组合继续做拟合,上述例子中,我们有Labour+Income和Labour+Shape_Area两种组合,这两种自变量组合分别于与因变量population做拟合,MSE最小的那个保留。

3.重复上一步,在保留最显著变量的基础上每次加入一个变量,并保留拟合的最好的变量,直到模型达到要求,例如上述例子中,我需要两个最显著的变量,那么我迭代两次就好了。

代码示例:接着上文被归一化处理后的数据

from mlxtend.feature_selection import SequentialFeatureSelector
from sklearn.linear_model import LinearRegression

# 构建线性回归模型
linreg = LinearRegression()

# 使用前向消元进行特征选择
sfs = SequentialFeatureSelector(linreg, forward=True, k_features=1 , scoring='neg_mean_squared_error')
sfs.fit(X, y)

# 输出选择的特征和对应的评分
print('Selected features:', sfs.k_feature_names_)
print('Score:', -sfs.k_score_)

解释代码:

导入sklearn中的LinearRegression函数,这个是用来进行线性回归的

mlxtend库中的SequentialFeatureSelector函数是用来做前向消元的

这段代码使用 mlxtend 库中的 SequentialFeatureSelector 类,实现了前向特征选择功能。

首先,我们传入了一个线性回归对象 linreg,这是因为我们在进行特征选择时要使用到一个评估器(estimator),它用来评估每个特征子集的性能。

接着,我们指定了 forward=True。这表示我们要使用前向选择的方式进行特征选择。也就是说,算法从空特征集开始,每次添加一个特征,直到达到我们指定的特征数 k_features

然后,我们设置了 k_features=3,这是指我们希望最终选择的特征数为 3。如果不知道应该选择多少特征,可以使用其他方法如交叉验证来确定最优特征数。

最后,我们指定了评价指标 scoring='neg_mean_squared_error'。这里我们使用了均方误差(MSE)作为评价指标。由于 sklearn 中默认使用的是最小化指标,而我们通常希望得到最大化指标的结果,因此需要加上负号。

在完成这些设置后,我们使用 fit() 方法对数据进行拟合和特征选择。在拟合过程中,算法会从空特征集出发逐步寻找最优特征组合,直到选择出 k 个最佳特征。

最后,我们可以通过 sfs.k_feature_names_ 查看选择的特征名称,通过 -sfs.k_score_ 查看特征选择的评分(这里需要注意取负操作)。

后向消元:

和前向消元正好相反,后向消元开始是所有变量都加入回归模型,然后每次迭代都去掉一个变量,根据评估标准(如MSE)选择删哪个变量。如果选择用MSE作为评价标准,那么就是删除MSE最大的那个变量。

最后删的符合标准了,迭代结束。后向消元同样也可以用mlxtend 库中的 SequentialFeatureSelector 类来实现,此时只要改forward参数为False就行。

完整代码:

import pandas as pd
from sklearn.linear_model import LinearRegression
from mlxtend.feature_selection import SequentialFeatureSelector
from sklearn import preprocessing
import statsmodels.api as sm

# 加载数据
data = pd.read_csv(r'C:\Users\14295\Desktop\regression\table.csv')

# 指定因变量和自变量
y = data['population']
X = data[['Shape_Area', 'income', 'labour']]


# 对参数进行归一化,最小-最大缩放是将原始数据缩放到 [0, 1] 的区间内
min_max_scaler = preprocessing.MinMaxScaler()
x_scaled = min_max_scaler.fit_transform(X)
# print(type(x_scaled))
X = pd.DataFrame(x_scaled, columns=['Shape_Area', 'income', 'labour']) # 将归一化处理后的数据转化为 DataFrame 格式

# 构建线性回归模型
linreg = LinearRegression()

# 使用前向消元进行特征选择
sfs = SequentialFeatureSelector(linreg, forward=True, k_features=1 , scoring='neg_mean_squared_error')
sfs.fit(X, y)

# 输出选择的特征和对应的评分
print('Selected features:', sfs.k_feature_names_)
print('Score:', -sfs.k_score_)

X_select = X['labour']
X_select = sm.add_constant(X_select)#给选择的自变量添加常数项,即加一列全是1的元素

model = sm.OLS(y, X_select).fit()#拟合模型
print(model.summary())#输出模型

上述代码中我用的是前向消元的特征选择方式,只保留了一个参数,通过print发现最优参数为Labour,于是用此参数基于statsmodel库中的OLS方法进行线性回归建模,并通过fit()方法拟合数据。其中,y 是因变量,X_selected 是自变量矩阵,即选出的特征列与常数列组成的矩阵。

返回:

 其中P>|t|代表参数的P值,coef代表参数的系数,const是常数项。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值