import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error, r2_score
from genetic_selection import GeneticSelectionCV # 使用遗传算法进行特征选择
def main():
# 加载特征数据
feature_data = pd.read_excel(r'F:\value.xlsx', usecols=range(7, 82))
# 加载目标数据
target_data = pd.read_excel(r'F:\value.xlsx', usecols=[4])
X = feature_data
y = np.ravel(target_data)
print('特征变量', X)
print('目标变量', y)
# 数据集划分(训练集和验证集)
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.3, random_state=19)
# 定义随机森林模型
rf = RandomForestRegressor(random_state=22)
# 使用遗传算法进行特征选择
ga_selector = GeneticSelectionCV(
estimator=rf, # 使用随机森林作为评估模型
cv=5, # 交叉验证折数
verbose=1, # 输出选择过程信息
scoring="neg_mean_squared_error", # 使用负均方误差作为评价指标
max_features=30, # 最大选择特征数量
n_population=50, # 种群大小
n_generations=40, # 遗传算法迭代次数
crossover_proba=0.5, # 交叉概率
mutation_proba=0.2, # 变异概率
n_jobs=1, # 使用所有可用 CPU 核心
)
# 用 GA 选择特征
print("开始特征选择...")
ga_selector.fit(X_train, y_train)
selected_features = ga_selector.support_ # 返回选择的特征
print("选择的特征索引:", np.where(selected_features)[0])
# 筛选特征
X_train_selected = X_train.iloc[:, selected_features]
X_val_selected = X_val.iloc[:, selected_features]
# 在选择的特征子集上重新训练随机森林模型
print("使用选择后的特征子集训练模型...")
model_rf = rf.fit(X_train_selected, y_train)
# 训练集预测
y_pred_train = model_rf.predict(X_train_selected)
RMSE_train = mean_squared_error(y_train, y_pred_train, squared=False)
BIAS_train = (y_train - y_pred_train).mean()
R2_train = r2_score(y_train, y_pred_train)
print('Train-----RMSE:', RMSE_train, 'Bias:', BIAS_train, 'R2:', R2_train)
# 验证集预测
y_pred_val = model_rf.predict(X_val_selected)
RMSE_val = mean_squared_error(y_val, y_pred_val, squared=False)
BIAS_val = (y_val - y_pred_val).mean()
R2_val = r2_score(y_val, y_pred_val)
print('Val-----RMSE:', RMSE_val, 'Bias:', BIAS_val, 'R2:', R2_val)
# 使用主函数保护
if __name__ == '__main__':
main()
控制台输出如下内容:
开始特征选择...
Selecting features with genetic algorithm.
gen nevals avg std min max
0 50 [-1689233.340288 15.5 1288417.408882] [ 132640.484096 8.324062 118855.937815] [-1993414.764388 1. 794613.031974] [-1361847.132161 30. 1604670.159824]
1 31 [-1596205.675204 17.4 1242454.89035 ] [ 112154.635926 8.082079 159195.260478] [-1850846.51772 1. 794613.031974] [-1361847.132161 29. 1536775.426679]
2 34 [-1541257.900282 17.9 1222741.333435] [ 94544.523254 8.065358 107835.771368] [-1826911.502755 1. 794613.031974] [-1361847.132161 28. 1420109.541843]
3 36 [-1505689.011012 17.28 1214273.567862] [ 88663.766513 9.35316 140756.747476] [-1701451.302327 1. 794613.031974] [-1360326.345861 30. 1474747.421698]
4 33 [-1470950.375228 16.7 1198462.191744] [ 96625.86281 10.3 177327.953406] [-1796661.07115 1. 794613.031974] [-1290751.468545 30. 1539519.141468]
avg 列[-1689233.340288 15.5 1288417.408882]
这个列表中:
第1个值: 平均适应度值(目标函数值),通常越高越好。
例如:-1689233.340288
代表第0代个体的目标函数值的平均值。
注意这里是负值,通常是因为使用了最小化问题的目标函数,例如误差(MSE、负对数似然等)。
第2个值: 平均特征数量,代表每个个体选择了多少个特征。
例如:15.5
代表第0代平均每个个体选择了约15.5个特征。
第3个值: 平均模型性能,例如模型的AUC、F1得分或准确率等。
例如:1288417.408882
表示每个个体(特征组合)在模型中的平均性能。
std 列[132640.484096 8.324062 118855.937815]
这个列表中:
第1个值: 适应度值的标准差,表示目标函数值的离散程度。
例如:132640.484096
表示目标函数值的波动范围。
第2个值: 特征数量的标准差,表示个体选择特征数量的离散程度。
例如:8.324062
表示特征数量的波动范围较大。
第3个值: 模型性能的标准差,表示个体在性能上的波动范围。
例如:118855.937815
表示不同特征组合的模型性能波动幅度。
min 列[-1993414.764388 1. 794613.031974]
这个列表中:
第1个值: 当前世代中目标函数值的最小值(最差适应度值)。
例如:-1993414.764388
代表第0代中最差个体的适应度值。
第2个值: 当前世代中最小的特征数量。
例如:1.0
表示第0代中有个体只选择了1个特征。
第3个值: 当前世代中模型性能的最小值。
例如:794613.031974
表示最差个体的模型性能。
max 列[-1361847.132161 30. 1604670.159824]
这个列表中:第1个值: 当前世代中目标函数值的最大值(最优适应度值)。
例如:-1361847.132161
表示第0代中最优个体的适应度值。
第2个值: 当前世代中特征数量的最大值。
例如:30.0
表示第0代中有个体选择了最多30个特征。
第3个值: 当前世代中模型性能的最大值。
例如:1604670.159824
表示最优个体的模型性能。 根据运行结果,调整种群规模,迭代世代数,交叉率,变异率,修改适应度函数等来得出最优特征变量下的最优模型。调整思路如下:
作用:控制每次迭代中候选解的数量,较大的种群可以更全面地搜索特征空间。
增大种群大小:如果特征空间较大(如上百个特征),可以尝试增大种群大小(如从 50 调整为 100 或 200)。这能增加多样性,避免过早陷入局部最优解。种群越大,计算开销越高,需根据硬件性能和时间限制进行调整。
作用:控制算法运行的迭代轮数,更多的迭代可以帮助遗传算法更充分地优化。
增加迭代次数:如果观察到精度在较早的代数就停止提升,可以将迭代次数从 30 提升到 50 或 100;监控每一代的性能提升,若多次迭代精度没有显著变化,可提前停止。
作用:控制种群中两个候选解之间交换基因(特征组合)的概率。
适当增大:如果解的多样性不足(即种群在初期很快趋于一致),可以提高交叉概率(如从 0.8 提高到 0.9);适当减小:如果种群中解的质量较低,可以稍微降低交叉概率(如降到 0.6),避免过多的随机扰动。
作用:控制种群中候选解随机改变基因(特征选择)的概率,防止陷入局部最优解。
增大变异概率:若观察到算法在较早的代数陷入局部最优(即性能指标不再提升),可以增大变异概率(如从 0.4 调整到 0.6 或 0.7);减少变异概率:若解的质量波动过大,可以适当减小(如降低到 0.2 或以下)。
作用:控制评估模型性能时划分数据的方式。
增大折数:如果数据量足够,可以增大交叉验证折数(如从 5 调整到 10),从而得到更稳定的模型评估结果;减小折数:在数据量较少时,减少折数(如调整到 3),避免过拟合或数据不足。
作用:限制最终选择的特征数量。
减少特征数量:如果模型过拟合,尝试减少最大选择特征数量(如从 20 调整到 10);增大特征数量:如果模型欠拟合,尝试增加最大选择特征数量(如从 20 调整到 30)。