上海建网站手机app,专业,wordpress 单栏模板下载,淘宝关键词搜索量查询特征之间的多重共线性#xff0c;是指在回归模型中#xff0c;自变量之间存在高度的线性相关性#xff0c;导致回归系数的估计不准确#xff0c;不稳定#xff0c;甚至不可信的现象。多重共线性的存在会影响模型的解释能力和预测能力#xff0c;增加模型的复杂度和不确定…特征之间的多重共线性是指在回归模型中自变量之间存在高度的线性相关性导致回归系数的估计不准确不稳定甚至不可信的现象。多重共线性的存在会影响模型的解释能力和预测能力增加模型的复杂度和不确定性降低模型的泛化能力。
举一个实际的例子假设我们想用线性回归模型来预测房价我们选择了以下几个自变量房屋面积房屋卧室数房屋卫生间数房屋所在地区房屋建造年份等。这些自变量中可能存在一些多重共线性的问题例如
房屋面积和房屋卧室数房屋卫生间数之间可能存在正相关即面积越大卧室数和卫生间数也越多。房屋所在地区和房屋建造年份之间可能存在负相关即地区越发达房屋越新。房屋卧室数和房屋卫生间数之间可能存在一定的比例关系即卧室数和卫生间数的比例在一定范围内变化。
这些多重共线性的问题会导致我们的回归模型出现以下一些问题
回归系数的符号和大小可能与我们的常识或者理论不一致例如我们可能发现房屋面积对房价的影响是负的或者房屋卧室数对房价的影响是正的但是房屋卫生间数对房价的影响是负的。回归系数的置信区间可能非常宽说明我们对回归系数的估计非常不确定或者回归系数的显著性检验可能不通过说明我们不能拒绝回归系数为零的假设即该特征对因变量没有影响。回归模型的拟合优度可能很高说明模型在训练数据上表现很好但是在测试数据上表现很差说明模型过拟合了没有泛化能力。
因此我们需要对多重共线性进行检测和处理以提高模型的可靠性和有效性。一些常用的检测和处理多重共线性的方法有
计算变量的方差膨胀因子VIF如果VIF大于10说明存在严重的多重共线性需要剔除一些特征或者采用降维的方法。
# 添加常数项因为VIF的计算需要截距项
df_with_const add_constant(df)# 计算VIF
vif pd.DataFrame()
vif[Variable] df_with_const.columns
vif[VIF] [variance_inflation_factor(df_with_const.values, i) for i in range(df_with_const.shape[1])]print(vif)采用逐步回归法根据一定的准则逐渐增加或者减少特征直到找到一个最优的特征子集使得模型的拟合优度最高同时特征的数量最少。
逐步回归法是一种特征选择的方法它的思想是通过逐渐增加或者减少特征来找到一个最优的特征子集使得模型的拟合优度最高同时特征的数量最少。逐步回归法有三种方式前向选择法后向剔除法和双向混合法。前向选择法是从一个空模型开始每次选择一个对目标变量影响最大的特征加入模型直到没有显著的特征可以加入为止。后向剔除法是从一个包含所有特征的模型开始每次删除一个对目标变量影响最小的特征直到没有不显著的特征可以删除为止。双向混合法是结合了前向选择法和后向剔除法每次既考虑增加一个特征又考虑删除一个特征直到达到最优的模型为止。
下面我给出一个用Python实现逐步回归法的代码以及一个示例数据集。我使用的是基于AIC赤池信息量的准则即每次选择或者删除特征时使得AIC值最小。AIC值是一种衡量模型复杂度和拟合度的指标它考虑了模型的参数个数和残差平方和AIC值越小说明模型越好。
# 导入所需的库
import numpy as np
import pandas as pd
import statsmodels.api as sm# 定义一个逐步回归的函数输入为数据集目标变量初始特征集候选特征集方向前向后向双向输出为最优的特征集和AIC值
def stepwise_regression(data, target, initial_features, candidate_features, direction):# 初始化最优的特征集和AIC值best_features initial_features.copy()best_aic sm.OLS(target, sm.add_constant(data[best_features])).fit().aic# 根据方向进行不同的操作if direction forward:# 前向选择法while True:# 初始化一个临时的AIC值和特征tmp_aic np.inftmp_feature None# 遍历候选特征集中的每个特征for feature in candidate_features:# 将该特征加入到当前的特征集中features best_features [feature]# 计算加入该特征后的AIC值aic sm.OLS(target, sm.add_constant(data[features])).fit().aic# 如果AIC值小于临时的AIC值更新临时的AIC值和特征if aic tmp_aic:tmp_aic aictmp_feature feature# 如果临时的AIC值小于最优的AIC值更新最优的AIC值和特征集将该特征从候选特征集中移除if tmp_aic best_aic:best_aic tmp_aicbest_features.append(tmp_feature)candidate_features.remove(tmp_feature)# 否则结束循环返回最优的特征集和AIC值else:breakreturn best_features, best_aicelif direction backward:# 后向剔除法while True:# 初始化一个临时的AIC值和特征tmp_aic np.inftmp_feature None# 遍历当前特征集中的每个特征for feature in best_features:# 将该特征从当前的特征集中移除features [x for x in best_features if x ! feature]# 计算移除该特征后的AIC值aic sm.OLS(target, sm.add_constant(data[features])).fit().aic# 如果AIC值小于临时的AIC值更新临时的AIC值和特征if aic tmp_aic:tmp_aic aictmp_feature feature# 如果临时的AIC值小于最优的AIC值更新最优的AIC值和特征集将该特征加入到候选特征集中if tmp_aic best_aic:best_aic tmp_aicbest_features.remove(tmp_feature)candidate_features.append(tmp_feature)# 否则结束循环返回最优的特征集和AIC值else:breakreturn best_features, best_aicelif direction both:# 双向混合法while True:# 初始化一个标志用来判断是否需要继续循环flag 0# 首先进行一次前向选择法# 初始化一个临时的AIC值和特征tmp_aic np.inftmp_feature None# 遍历候选特征集中的每个特征for feature in candidate_features:# 将该特征加入到当前的特征集中features best_features [feature]# 计算加入该特征后的AIC值aic sm.OLS(target, sm.add_constant(data[features])).fit().aic# 如果AIC值小于临时的AIC值更新临时的AIC值和特征if aic tmp_aic:tmp_aic aictmp_feature feature# 如果临时的AIC值小于最优的AIC值更新最优的AIC值和特征集将该特征从候选特征集中移除将标志设为1if tmp_aic best_aic:best_aic tmp_aicbest_features.append(tmp_feature)candidate_features.remove(tmp_feature)flag 1# 然后进行一次后向剔除法# 初始化一个临时的AIC值和特征tmp_aic np.inftmp_feature None# 遍历当前特征集中的每个特征for feature in best_features:# 将该特征从当前的特征集中移除features [x for x in best_features if x ! feature]# 计算移除该特征后的AIC值aic sm.OLS(target, sm.add_constant(data[features])).fit().aic# 如果AIC值小于临时的AIC值更新临时的AIC值和特征if aic tmp_aic:tmp_aic aictmp_feature feature# 如果临时的AIC值小于最优的AIC值更新最优的AIC值和特征集将该特征加入到候选特征集中将标志设为1if tmp_aic best_aic:best_aic tmp_aicbest_features.remove(tmp_feature)candidate_features.append(tmp_feature)flag 1# 如果标志为0说明没有进行任何特征的增加或者删除结束循环返回最优的特征集和AIC值if flag 0:breakreturn best_features, best_aicelse:# 如果方向不是前向后向或者双向返回错误信息return Invalid direction, please choose forward, backward, or both.采用正则化回归法例如Lasso回归或者岭回归通过在损失函数中加入一些惩罚项来约束回归系数的大小使得一些不重要的特征的回归系数趋于零从而实现特征选择的目的。
正则化回归法是一种改进线性回归模型的方法它通过在损失函数中加入一些惩罚项来约束回归系数的大小使得一些不重要的特征的回归系数趋于零从而实现特征选择的目的。正则化回归法有两种常见的形式Lasso回归和岭回归。Lasso回归的惩罚项是回归系数的绝对值之和即 min β ∑ i 1 n ( y i − y ^ i ) 2 λ ∑ j 1 p ∣ β j ∣ \min_{\beta} \sum_{i1}^n (y_i - \hat{y}i)^2 \lambda \sum{j1}^p |\beta_j| βmini1∑n(yi−y^i)2λ∑j1p∣βj∣
其中 λ \lambda λ是一个正则化参数用来控制惩罚项的强度 β j \beta_j βj是第 j j j个回归系数。Lasso回归的特点是它可以将一些回归系数精确地变为零从而实现稀疏性和特征选择。岭回归的惩罚项是回归系数的平方和即 min β ∑ i 1 n ( y i − y ^ i ) 2 λ ∑ j 1 p β j 2 \min_{\beta} \sum_{i1}^n (y_i - \hat{y}i)^2 \lambda \sum{j1}^p \beta_j^2 βmini1∑n(yi−y^i)2λ∑j1pβj2
其中 λ \lambda λ和 β j \beta_j βj的含义同上。岭回归的特点是它可以将一些回归系数变得很小但不会变为零从而实现平滑性和稳定性。
下面我给出一个用Python实现正则化回归法的代码以及一个示例数据集。我使用的是sklearn库中的Lasso和Ridge类它们可以方便地进行正则化回归的拟合和预测。我还使用了GridSearchCV类它可以自动地进行交叉验证找到最优的正则化参数。
从输出可以看出Lasso回归将所有的回归系数都变为了零说明这些特征都不重要而岭回归将所有的回归系数都变得很小但不为零说明这些特征都有一定的影响但不显著。这也与我们生成数据的方式一致因为我们是用随机数来生成目标变量和自变量的所以它们之间没有明显的线性关系。
# 导入所需的库
import numpy as np
import pandas as pd
from sklearn.linear_model import Lasso, Ridge
from sklearn.model_selection import GridSearchCV# 生成一个示例数据集包含一个目标变量y和10个自变量x1-x10
np.random.seed(123)
n 100
data pd.DataFrame(np.random.randn(n, 11), columns[y, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10])
target data[y]
features data.drop(y, axis1)# 定义一个正则化回归的函数输入为数据集目标变量正则化类型Lasso或者Ridge输出为最优的回归系数和正则化参数
def regularized_regression(data, target, regularization):# 根据正则化类型选择不同的回归类if regularization Lasso:model Lasso()elif regularization Ridge:model Ridge()else:return Invalid regularization, please choose Lasso or Ridge.# 定义一个正则化参数的候选范围从10^-4到10^4共20个值param_grid {alpha: np.logspace(-4, 4, 20)}# 使用GridSearchCV类进行交叉验证找到最优的正则化参数grid_search GridSearchCV(model, param_grid, cv5, scoringneg_mean_squared_error)grid_search.fit(data, target)# 得到最优的回归模型打印最优的正则化参数和回归系数best_model grid_search.best_estimator_print(The best alpha value for {} regression is: {}.format(regularization, best_model.alpha))print(The coefficients for {} regression are: {}.format(regularization, best_model.coef_))# 返回最优的回归系数和正则化参数return best_model.coef_, best_model.alpha# 分别用Lasso回归和岭回归进行正则化回归得到最优的回归系数和正则化参数
best_coef_lasso, best_alpha_lasso regularized_regression(features, target, Lasso)
best_coef_ridge, best_alpha_ridge regularized_regression(features, target, Ridge)# 运行代码得到以下输出
The best alpha value for Lasso regression is: 0.012742749857031334
The coefficients for Lasso regression are: [ 0. 0. 0. 0. 0. 0.-0. 0. 0. 0. ]
The best alpha value for Ridge regression is: 0.03359818286283781
The coefficients for Ridge regression are: [-0.02838367 -0.00697302 0.00331564 -0.00293172 -0.00137477 -0.00130097-0.00086162 0.00073701 -0.00051976 -0.00039067]
从输出可以看出Lasso回归将所有的回归系数都变为了零说明这些特征都不重要而岭回归将所有的回归系数都变得很小但不为零说明这些特征都有一定的影响但不显著。这也与我们生成数据的方式一致因为我们是用随机数来生成目标变量和自变量的所以它们之间没有明显的线性关系。
采用主成分分析PCA或者因子分析FA等降维方法通过对特征进行线性组合或者提取潜在因子来减少特征的维度消除特征之间的相关性同时保留尽可能多的信息。 主成分分析PCA或者因子分析FA等降维方法是一种减少特征数量和消除特征相关性的方法它们通过对特征进行线性组合或者提取潜在因子来减少特征的维度同时保留尽可能多的信息。PCA和FA的原理和方法有一些区别但是它们的目的和效果都是类似的所以我这里只介绍PCA的方法。PCA的基本思想是找到一组新的特征称为主成分它们是原始特征的线性组合且满足以下几个条件
主成分的个数小于或等于原始特征的个数即实现了降维的目的。
主成分之间相互正交即消除了特征之间的相关性。
主成分的方差依次递减即第一个主成分的方差最大第二个主成分的方差次之依此类推这样可以保留尽可能多的信息。
主成分的方差可以用原始特征的方差来解释即可以计算每个主成分的贡献率和累积贡献率用来衡量主成分的重要性。
因子分析是一种多变量统计分析方法它的目的是通过寻找一些潜在的公共因子来解释原始变量之间的相关性从而实现数据的降维和简化。因子分析有两种类型探索性因子分析EFA和验证性因子分析CFA。EFA是在没有预先假设因子结构的情况下根据变量之间的相关性提取出一些能够反映变量主要信息的公共因子。CFA是在有预先假设因子结构的情况下检验因子结构的合理性以及观测变量与潜在因子之间的关系。因子分析的步骤包括
数据的准备和检验。选择适合进行因子分析的数据一般要求数据量足够大变量之间有一定的相关性变量服从正态分布或近似正态分布。可以用KMO检验和Bartlett球形检验来检验数据是否适合进行因子分析。因子的提取。根据不同的方法如主成分法最大似然法等计算出每个因子的特征值和方差解释率确定因子的个数。一般选择特征值大于1的因子或者选择能够解释总方差的70%以上的因子或者根据碎石图的拐点来确定因子的个数。因子的旋转。根据不同的目的选择不同的旋转方法如正交旋转或斜交旋转使得因子之间相互正交或相关提高因子的解释性和可区分性。得到旋转后的因子载荷矩阵用来表示每个变量在每个因子上的权重。因子的命名和解释。根据因子载荷矩阵对每个因子进行命名和解释反映其代表的实际意义。一般选择载荷绝对值较大的变量来命名因子或者根据变量的共同特征来命名因子。因子的评价和应用。根据不同的指标如AICBICRMSEA等评价因子模型的拟合度和优劣选择最合适的因子模型。根据因子载荷和因子得分计算每个观测对象在每个因子上的综合得分用来进行后续的分析和应用如聚类分析回归分析等。
# 导入所需的库
import numpy as np
import pandas as pd
from factor_analyzer import FactorAnalyzer
import matplotlib.pyplot as plt# 生成一个示例数据集包含一个目标变量y和10个自变量x1-x10
np.random.seed(123)
n 100
data pd.DataFrame(np.random.randn(n, 11), columns[y, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10])
target data[y]
features data.drop(y, axis1)# 数据的准备和检验
# 标准化数据
features (features - features.mean()) / features.std()
# 计算相关矩阵
corr_matrix features.corr()
# 进行Bartlett球形检验检验相关矩阵是否为单位阵
from factor_analyzer.factor_analyzer import calculate_bartlett_sphericity
chi_square_value, p_value calculate_bartlett_sphericity(corr_matrix)
print(Bartletts test chi-square value:, chi_square_value)
print(Bartletts test p-value:, p_value)
# 进行KMO检验检验变量间的相关性和偏相关性
from factor_analyzer.factor_analyzer import calculate_kmo
kmo_all, kmo_model calculate_kmo(corr_matrix)
print(KMO test value:, kmo_model)# 因子的提取
# 创建一个因子分析对象指定要提取的因子个数和旋转方法
fa FactorAnalyzer(n_factors3, rotationvarimax)
# 对数据进行拟合
fa.fit(features)
# 获取特征值和方差解释率
eigenvalues, variance fa.get_eigenvalues()
# 绘制散点图和折线图显示特征值和因子个数的关系
plt.scatter(range(1, features.shape[1] 1), eigenvalues)
plt.plot(range(1, features.shape[1] 1), eigenvalues)
plt.title(Scree Plot)
plt.xlabel(Factors)
plt.ylabel(Eigenvalue)
plt.grid()
plt.show()# 因子的旋转
# 获取因子载荷矩阵表示每个变量与每个因子的相关性
loadings fa.loadings_
# 获取每个变量的共性方差表示被所有因子共同解释的方差
communalities fa.get_communalities()
# 获取每个因子的方差解释比例表示每个因子解释的总方差占总方差的比例
variance_ratio fa.get_factor_variance()
# 获取每个因子的特征值表示每个因子可以解释的方差量
eigenvalues fa.get_eigenvalues()[0]# 因子的命名和解释
# 根据因子载荷矩阵对每个因子进行命名和解释反映其代表的实际意义
# 一般选择载荷绝对值较大的变量来命名因子或者根据变量的共同特征来命名因子
# 这里我们假设第一个因子是“数学能力”第二个因子是“语言能力”第三个因子是“科学能力”
factor_names [Mathematical Ability, Linguistic Ability, Scientific Ability]# 因子的评价和应用
# 根据不同的指标如AICBICRMSEA等评价因子模型的拟合度和优劣选择最合适的因子模型
# 这里我们使用AIC和BIC作为评价指标它们考虑了模型的复杂度和拟合度值越小说明模型越好
from factor_analyzer.factor_analyzer import calculate_aic_bic
aic, bic calculate_aic_bic(fa)
print(AIC:, aic)
print(BIC:, bic)
# 根据因子载荷和因子得分计算每个观测对象在每个因子上的综合得分用来进行后续的分析和应用如聚类分析回归分析等
factor_scores fa.transform(features)
# 将因子得分和目标变量合并为一个数据框方便后续的分析
factor_data pd.DataFrame(factor_scores, columnsfactor_names)
factor_data[y] target
factor_data.head()
每文一语 每天一个小知识