自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

遺傳進(jìn)化算法進(jìn)行高效特征選擇

人工智能 算法
在目標(biāo)函數(shù)方面,遺傳算法(GA)能夠取得比序列前向選擇(SFS)更好的結(jié)果,因?yàn)樗軌蚶帽M可能多的CPU內(nèi)核來并行運(yùn)行目標(biāo)函數(shù),但代價(jià)是它的運(yùn)行速度是所有算法中最慢的。

在構(gòu)建機(jī)器學(xué)習(xí)模型時(shí),特征選擇是一個(gè)關(guān)鍵的預(yù)處理步驟。使用全部特征往往會導(dǎo)致過擬合、增加計(jì)算復(fù)雜度等問題。因此,我們需要從原始特征集中選擇一個(gè)最優(yōu)子集,以提高模型的泛化性能和效率。

特征選擇的目標(biāo)是找到一個(gè)二元掩碼向量,對應(yīng)每個(gè)特征的保留(1)或剔除(0)。例如,對于10個(gè)特征,這個(gè)掩碼向量可能是[1,0,1,1,0,0,1,0,1,0]。我們需要通過某種優(yōu)化方法,尋找一個(gè)使目標(biāo)函數(shù)(如模型的貝葉斯信息準(zhǔn)則BIC)最小化的最優(yōu)掩碼。

當(dāng)特征數(shù)量較小時(shí),我們可以使用暴力搜索等枚舉方法。但隨著特征數(shù)量的增加,搜索空間將呈指數(shù)級增長,枚舉搜索將變得無法承受。這時(shí)我們需要借助啟發(fā)式優(yōu)化算法,例如遺傳算法、模擬退火等,在有限時(shí)間內(nèi)找到一個(gè)近似最優(yōu)解。

本文以Kaggle房價(jià)數(shù)據(jù)集(213個(gè)特征)為例,比較了經(jīng)典的序貫特征選擇算法(SFS)和一種稱為進(jìn)化策略(CMA-ES)的啟發(fā)式優(yōu)化算法在特征選擇任務(wù)上的表現(xiàn)。實(shí)驗(yàn)結(jié)果表明,CMA-ES相比SFS能更快地converge到更優(yōu)的特征子集,從而獲得更小的BIC值和更佳的模型泛化性能

GA - 遺傳算法

遺傳算法是一種啟發(fā)式優(yōu)化算法,其靈感源自達(dá)爾文的進(jìn)化論和自然選擇理論。在自然界中,生物個(gè)體通過基因遺傳,攜帶有利于生存和繁衍的特征,經(jīng)過漫長的自然選擇過程,適者生存,不斷進(jìn)化。類似地,遺傳算法也是通過模擬這一自然進(jìn)化過程,對問題的潛在解決方案(個(gè)體)進(jìn)行遺傳、變異和選擇,最終得到滿足目標(biāo)條件的最優(yōu)或近似最優(yōu)解。

以特征選擇為例,假設(shè)我們有N個(gè)特征,需要確定一個(gè)長度為N的二進(jìn)制向量[1, 0, 0, 1, 1, 1, ...]來表示選擇(1)或剔除(0)每個(gè)特征,目標(biāo)是找到一個(gè)使成本函數(shù)或目標(biāo)函數(shù)最小化的最優(yōu)特征組合。我們可以將每個(gè)這樣的二進(jìn)制向量看作一個(gè)"個(gè)體",每個(gè)位置上的0或1就是該個(gè)體的一個(gè)"基因"。

遺傳算法基本步驟:

  1. 評估:計(jì)算每個(gè)個(gè)體的適應(yīng)度(目標(biāo)函數(shù)值)。
  2. 選擇:根據(jù)適應(yīng)度挑選出若干個(gè)體作為父代。
  3. 交叉:隨機(jī)選擇兩個(gè)父代個(gè)體,按一定交叉方式組合它們的基因,產(chǎn)生新的個(gè)體(子代)。
  4. 變異:以一定的小概率改變子代個(gè)體中的某些基因值。
  5. 替換:用新產(chǎn)生的子代個(gè)體替換種群中適應(yīng)度較低的個(gè)體。

通過不斷迭代上述過程,種群中個(gè)體的平均適應(yīng)度就會不斷提高,最終可以得到滿足要求的最優(yōu)或近似最優(yōu)解。

一些關(guān)鍵概念和組件:

  1. 個(gè)體(Individual):表示種群中的一個(gè)候選解,通常用染色體(一串?dāng)?shù)字或字符)來表示。
  2. 種群(Population):包含多個(gè)個(gè)體的集合。
  3. 適應(yīng)度函數(shù)(Fitness Function):用于評估每個(gè)個(gè)體的優(yōu)劣程度。
  4. 選擇(Selection):根據(jù)適應(yīng)度函數(shù)的結(jié)果,從當(dāng)前種群中選擇部分個(gè)體作為父代,用于產(chǎn)生下一代種群。
  5. 交叉(Crossover):將兩個(gè)父代個(gè)體的染色體進(jìn)行組合,產(chǎn)生一個(gè)或多個(gè)新的子代個(gè)體。
  6. 變異(Mutation):通過改變個(gè)體染色體上的某些位,增加種群的多樣性。
  7. 最佳個(gè)體(Hall of Fame):用于保存迄今為止找到的最佳個(gè)體,防止在進(jìn)化過程中被淘汰或丟失。
  8. 優(yōu)秀個(gè)體(Elitism):在每一代中,直接將當(dāng)前種群中的優(yōu)秀個(gè)體傳遞到下一代,而不需要經(jīng)過選擇、交叉和變異等操作。

遺傳算法首先隨機(jī)生成一組這樣的個(gè)體,構(gòu)成初始種群。比如,如果N=12,種群數(shù)量為8,那么初始種群可能包含8個(gè)長度為12的隨機(jī)二進(jìn)制向量。

遺傳算法-種群遺傳算法-種群

群體創(chuàng)建后,通過目標(biāo)函數(shù)對每個(gè)個(gè)體進(jìn)行評估。

接下來是選擇階段,旨在保留具有良好特征的個(gè)體,淘汰表現(xiàn)不佳的個(gè)體。這一過程有多種策略可供選擇,從簡單的排序法到更加復(fù)雜的隨機(jī)錦標(biāo)賽選擇等。選擇策略需要權(quán)衡探索(嘗試新的解決方案)和利用(保留已知的良好解決方案)之間的平衡。遺傳算法的核心在于通過有效探索來尋找最優(yōu)解。常見的選擇技術(shù)包括:錦標(biāo)賽選擇、輪盤賭選擇、等級選擇等。

經(jīng)過選擇后,遺傳算法會在保留的優(yōu)秀個(gè)體基因庫中引入變異,以產(chǎn)生新的候選解。主要有兩種變異技術(shù):交叉和突變。

交叉是模仿生物交配過程,將兩個(gè)親代個(gè)體的部分基因隨機(jī)組合,產(chǎn)生新的子代個(gè)體。這一過程能夠?qū)⒂H代的良好特征組合在一起,有望產(chǎn)生更優(yōu)秀的后代。

突變則是對個(gè)體的基因做出少量隨機(jī)改變,以引入新的多樣性,避免群體過早收斂于局部最優(yōu)解。

遺傳算法-交叉遺傳算法-交叉

變異,同樣是指自然界中遺傳物質(zhì)發(fā)生隨機(jī)突變,基因庫中引入新的價(jià)值,從而增加其多樣性。

遺傳算法-變異遺傳算法-變異

之后,算法循環(huán)往復(fù):再次通過目標(biāo)函數(shù)評估個(gè)體,進(jìn)行選擇,然后是交叉、變異等。

可以使用各種停止標(biāo)準(zhǔn):如果目標(biāo)函數(shù)在一定代數(shù)內(nèi)停止改進(jìn),循環(huán)就會中斷?;蛘吣阋部梢栽O(shè)定一個(gè)硬性的停止條件,即已評估的總代數(shù)?;蛘咭詴r(shí)間為基礎(chǔ),或者觀察外部信號等。無論如何,具有最佳目標(biāo)值的個(gè)體都應(yīng)被視為問題的解決方案。

在遺傳算法(GA)中,隨機(jī)選擇技術(shù)有時(shí)可能會由于偶然因素而放棄當(dāng)代種群中最優(yōu)秀的個(gè)體。盡管發(fā)生概率不高,但這種情況確實(shí)存在。這就是引入"精英主義"策略的目的,它確保無論如何,種群中的優(yōu)秀個(gè)體都會被保留下來。然而,過度使用精英主義也可能導(dǎo)致算法陷入局部最優(yōu)解,從而錯(cuò)失全局最優(yōu)解。GA本質(zhì)上是一種探索性算法,根據(jù)我有限的經(jīng)驗(yàn),為其引入過多偏見并不利于尋找最優(yōu)解。GA本身就提供了大量的算法變體可供嘗試和探索。

在GA中,我們可以調(diào)整以下幾個(gè)超參數(shù):

  • 種群規(guī)模(個(gè)體數(shù)量)
  • 基因突變概率
  • 個(gè)體交叉概率
  • 個(gè)體選擇策略等

手動嘗試不同超參數(shù)組合是尋找最優(yōu)參數(shù)的一種方式。另一種高級方法是將GA封裝到優(yōu)化框架(如Optuna)中,利用框架自動搜索最佳超參數(shù),但這種方式計(jì)算代價(jià)較高。

無論采用何種方式,GA都為我們提供了一種靈活有趣的優(yōu)化探索方式,讓我們可以充分發(fā)揮創(chuàng)意。

特征選擇的GA代碼

下面是一個(gè)可用于特征選擇的簡單 GA 代碼。它使用了功能強(qiáng)大的 deap 庫,但學(xué)習(xí)曲線可能比較陡峭。不過,這個(gè)簡單的版本應(yīng)該足夠清晰。

上下滑動查看更多源碼
# to maximize the objective
# fitness_weights = 1.0
# to minimize the objective
fitness_weights = -1.0

# copy the original dataframes into local copies, once
X_ga = X.copy()
y_ga = y.copy()

# 'const' (the first column) is not an actual feature, do not include it
X_features = X_ga.columns.to_list()[1:]

try:
    del creator.FitnessMax
    del creator.Individual
except Exception as e:
    pass

creator.create("FitnessMax", base.Fitness, weights=(fitness_weights,))
creator.create(
    "Individual", array.array, typecode='b', fitness=creator.FitnessMax
)

try:
    del toolbox
except Exception as e:
    pass

toolbox = base.Toolbox()
# Attribute generator
toolbox.register("attr_bool", random.randint, 0, 1)
# Structure initializers
toolbox.register(
    "individual",
    tools.initRepeat,
    creator.Individual,
    toolbox.attr_bool,
    len(X_features),
)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)


def evalOneMax(individual):
    # objective function
    # create True/False selector list for features
    # and add True at the start for 'const'
    cols_select = [True] + [i == 1 for i in list(individual)]
    # fit model using the features selected from the individual
    lin_mod = sm.OLS(y_ga, X_ga.loc[:, cols_select], hascnotallow=True).fit()
    return (lin_mod.bic,)


toolbox.register("evaluate", evalOneMax)
toolbox.register("mate", tools.cxTwoPoint)
toolbox.register("mutate", tools.mutFlipBit, indpb=0.05)
toolbox.register("select", tools.selTournament, tournsize=3)

random.seed(0)
pop = toolbox.population(n=300)
hof = tools.HallOfFame(1)
pop, log = algorithms.eaSimple(
    pop, toolbox, cxpb=0.5, mutpb=0.2, ngen=10, halloffame=hof, verbose=True
)

best_individual_ga_small = list(hof[0])
best_features_ga_small = [
    X_features[i] for i, val in enumerate(best_individual_ga_small) if val == 1
]
best_objective_ga_small = (
    sm.OLS(y_ga, X_ga[['const'] + best_features_ga_small], hascnotallow=True)
    .fit()
    .bic
)
print(f'best objective: {best_objective_ga_small}')
print(f'best features:  {best_features_ga_small}')

代碼使用對象來定義個(gè)體和整個(gè)種群,并采取評估(目標(biāo)函數(shù))、交叉/交配、突變和選擇的策略。起初,代碼從包含 300 個(gè)個(gè)體的種群開始,然后調(diào)用 eaSimple() 函數(shù)(該函數(shù)包含了交叉、變異和選擇的預(yù)設(shè)序列),并且僅運(yùn)行 10 代以簡化過程。名人堂的規(guī)模為 1,它會保留絕對最優(yōu)秀的個(gè)體,以防它們在選擇等過程中被意外變異或跳過。

名人堂并非精英主義,而是從群體中復(fù)制最優(yōu)秀的個(gè)體,并僅在錫罐中保留一個(gè)非活動副本。精英主義則是將活躍種群中最優(yōu)秀的個(gè)體一代一代地保留下來。

這個(gè)簡單的代碼很容易理解,但效率很低。下面有更復(fù)雜版本的 GA 代碼,更復(fù)雜、更優(yōu)化的代碼 1000 代后。

# to maximize the objective
# fitness_weights = 1.0
# to minimize the objective
fitness_weights = -1.0

# copy the original dataframes into local copies, once
X_ga = X.astype(float).copy()
y_ga = y.astype(float).copy()

# 'const' (the first column) is not an actual feature, do not include it
X_features = X_ga.columns.to_list()[1:]

try:
    del creator.FitnessMax
    del creator.Individual
except Exception as e:
    pass

creator.create("FitnessMax", base.Fitness, weights=(fitness_weights,))
creator.create(
    "Individual", array.array, typecode='b', fitness=creator.FitnessMax
)

try:
    del toolbox
except Exception as e:
    pass

toolbox = base.Toolbox()
# Attribute generator
toolbox.register("attr_bool", random.randint, 0, 1)
# Structure initializers
toolbox.register(
    "individual",
    tools.initRepeat,
    creator.Individual,
    toolbox.attr_bool,
    len(X_features),
)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)


def evalMany(individuals):
    # individuals is an array of shape (n_individuals, n_features)
    # transform it into a list of lists:
    # - a list of individuals
    # - each individual is a list of feature selectors
    ind_list = [list(i) for i in list(individuals)]
    ret = []
    for ind in ind_list:
        # create a list of True/False feature selectors from each individual
        # pre-pend True to always select the 'const' feature
        cols_select = [True] + [i == 1 for i in list(ind)]
        # fit model using the features selected from the individual
        lin_mod = sm.OLS(y_ga, X_ga.loc[:, cols_select], hascnotallow=True).fit()
        ret.append((lin_mod.bic,))
    return ret


# multiprocess pool to evaluate individuals
def joblib_map(f, njobs, *iters):
    return Parallel(n_jobs=njobs)(delayed(f)(*args) for args in zip(*iters))


def selElitistAndTournament(
    individuals, k_tournament, k_elitist=0, tournsize=3
):
    # elitist tournament
    # in addition to the regular tournament, ensure the top #k_elistist individuals are preserved
    return tools.selBest(individuals, k_elitist) + tools.selTournament(
        individuals, k_tournament, tournsize
    )


# Hyperparameters
population_size = 1000
crossover_probability = 0.5
individual_mutation_probability = 0.2
gene_mutation_probability = 0.1
tournament_size = 3
elite_size = 0

n_jobs = os.cpu_count()

# register the pool as the mapper
# and the custom function as the evaluator
toolbox.register("map_multi", joblib_map)
toolbox.register("evaluate", evalMany)

toolbox.register("mate", tools.cxTwoPoint)
toolbox.register("mutate", tools.mutFlipBit, indpb=gene_mutation_probability)
# toolbox.register("select", tools.selTournament, tournsize=tournament_size)
# selection with tournament and optional elitism
toolbox.register(
    "select",
    selElitistAndTournament,
    k_tournament=population_size - elite_size,
    k_elitist=elite_size,
    tournsize=tournament_size,
)

random.seed(0)
population = toolbox.population(n=population_size)
hall_of_fame = tools.HallOfFame(1)
objective_runs_ga = 0

# Evaluate the individuals with an invalid fitness
invalid_ind = [ind for ind in population if not ind.fitness.valid]
# split the population in a list with n_jobs elements
# each element is an array containing multiple individuals
# send individuals to the evaluator
fitnesses_nested = toolbox.map_multi(
    toolbox.evaluate, n_jobs, np.array_split(invalid_ind, n_jobs)
)
objective_runs_ga += len(invalid_ind)
fitnesses = []
for l in fitnesses_nested:
    fitnesses += l
for ind, fit in zip(invalid_ind, fitnesses):
    ind.fitness.values = fit

hall_of_fame.update(population)

n_gen = 1000
best_objective_per_gen_ga = np.full(n_gen, np.nan)
best_objective_ga = np.nan
best_generation_ga = 0
gene_values_mean = np.zeros((n_gen, len(X_features)))
gene_maes = np.full(n_gen, np.nan)
time_to_best_ga = np.inf
# Begin the generational process
iterator = tqdm(range(1, n_gen + 1), desc='generation')
t_start = time.time()
for gen in iterator:
    t_start_loop = time.time()

    # Select the next generation of individuals
    offspring = toolbox.select(population)
    # Vary the pool of individuals via cross-over and mutation
    offspring = algorithms.varAnd(
        offspring,
        toolbox,
        crossover_probability,
        individual_mutation_probability,
    )
    # Evaluate the individuals with an invalid fitness
    invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
    # split the population in a list with n_jobs elements
    # each element is an array containing multiple individuals
    # send list to the evaluator pool
    fitnesses_nested = toolbox.map_multi(
        toolbox.evaluate, n_jobs, np.array_split(invalid_ind, n_jobs)
    )
    objective_runs_ga += len(invalid_ind)
    fitnesses = []
    for l in fitnesses_nested:
        fitnesses += l
    for ind, fit in zip(invalid_ind, fitnesses):
        ind.fitness.values = fit
    # Update the hall of fame with the generated individuals
    hall_of_fame.update(offspring)
    # Replace the current population by the offspring
    population[:] = offspring

    t_end_loop = time.time()

    # record the mean gene values across the population
    gene_values_mean[gen - 1, :] = np.array(population).mean(axis=0)
    if gen >= 2:
        gene_maes[gen - 1] = mean_absolute_error(
            gene_values_mean[gen - 2, :], gene_values_mean[gen - 1, :]
        )
    # pick best individual for stats recording
    best_individual_ga = tools.selBest(population, 1)[0]
    best_objective_per_gen_ga[gen - 1] = best_individual_ga.fitness.values[0]
    if (
        best_objective_ga is np.nan
        or fitness_weights * best_individual_ga.fitness.values[0]
        > fitness_weights * best_objective_ga
    ):
        best_objective_ga = best_individual_ga.fitness.values[0]
        best_generation_ga = gen
        time_to_best_ga = t_end_loop - t_start
        print(
            f'gen: {gen:4n}, curr/prev gene MAE: {gene_maes[gen - 1]:.4f}, new best objective: {best_objective_ga:.4f}, time to best: {time_to_best_ga:.4f}'
        )

    if os.path.isfile('break'):
        # to gracefully break the loop, manually create a file called 'break'
        print(f'Found break file, stopping now.')
        iterator.close()
        break
g_completed_ga = gen

best_individual_ga = list(hall_of_fame[0])
best_features_ga = [
    X_features[i] for i, val in enumerate(best_individual_ga) if val == 1
]
best_objective_ga = (
    sm.OLS(y_ga, X_ga[['const'] + best_features_ga], hascnotallow=True).fit().bic
)  

## 強(qiáng)烈建議關(guān)注#公眾號:數(shù)據(jù)STUDIO 更多優(yōu)質(zhì)內(nèi)容每日更新!
best objective:  33705.569572544795
best generation: 787
objective runs:  600525
time to best:    158.027 sec

同樣,在選擇任何特征之前的基準(zhǔn) BIC 計(jì)算:

上下滑動查看更多源碼
print(f'best objective:  {best_objective_ga}')
print(f'best generation: {best_generation_ga}')
print(f'objective runs:  {objective_runs_ga}')
print(f'time to best:    {time_to_best_ga:.3f} sec')
print(f'best features:   {best_features_ga}')

gvm_df = (
    pd.DataFrame(
        gene_values_mean,
        columns=X_features,
        index=range(1, gene_values_mean.shape[0] + 1),
    )
    .sort_index(axis=1)
    .iloc[:g_completed_ga]
)
if g_completed_ga > 20:
    x_ticks = list(range(1, g_completed_ga + 1, round(g_completed_ga / 20)))
else:
    x_ticks = list(range(1, g_completed_ga + 1))
if x_ticks[-1] != g_completed_ga:
    x_ticks.append(g_completed_ga)

fig, ax = plt.subplots(
    3,
    1,
    sharex=True,
    height_ratios=[24, 1, 1],
    figsize=(12, 48),
    layout='constrained',
)

sns.heatmap(
    gvm_df.sort_index(axis=1).T,
    vmin=0.0,
    vmax=1.0,
    cmap='viridis',
    cbar=True,
    cbar_kws={'fraction': 0.01, 'anchor': (0.0, 1.0)},
    ax=ax[0],
)
ax[0].set_title('Population average of gene values after each generation')
ax[0].axvline(x=best_generation_ga, color='C7')
ax[0].set_xlabel('generation')
ax[0].tick_params(axis='both', reset=True)
ax[0].set_xticks(x_ticks)
ax[0].set_xticklabels(x_ticks)

ax[1].set_xlabel('generation')
ax[1].plot(list(range(2, g_completed_ga + 1)), gene_maes[1:g_completed_ga])
ax[1].vlines(
    x=best_generation_ga,
    ymin=gene_maes[1:g_completed_ga].min(),
    ymax=gene_maes[1:g_completed_ga].max(),
    colors='C7',
)
ax[1].set_xlabel('generation')
ax[1].set_ylabel('MAE')
ax[1].set_title(
    'Mean absolute error of average gene values between current generation and previous generation'
)
ax[1].tick_params(axis='both', reset=True)

ax[2].set_xlabel('generation')
ax[2].plot(
    list(range(1, g_completed_ga + 1)),
    best_objective_per_gen_ga[:g_completed_ga],
)
ax[2].vlines(
    x=best_generation_ga,
    ymin=min(best_objective_per_gen_ga[:g_completed_ga]),
    ymax=max(best_objective_per_gen_ga[:g_completed_ga]),
    colors='C7',
)
ax[2].set_xlabel('generation')
ax[2].set_ylabel('best objective')
ax[2].set_title('Best objective')

fig.suptitle('Genetic algorithm')
fig.savefig('ga-performance.png')
fig.show()

best objective:  33705.569572544795

best generation: 787
objective runs:  600525
time to best:    158.027 sec
best features:   ['BedroomAbvGr', 'BldgType_1Fam', 'BsmtFinSF1', 'BsmtFinSF2', 'BsmtUnfSF', 'Condition1_Norm', 'Condition2_PosN', 'ExterQual_Ex', 'Exterior1st_BrkFace', 'Functional_Sev', 'Functional_Typ', 'GarageArea', 'GrLivArea', 'HeatingQC_Ex', 'KitchenQual_Ex', 'LandContour_HLS', 'LotArea', 'LotConfig_CulDSac', 'LowQualFinSF', 'Neighborhood_BrkSide', 'Neighborhood_Crawfor', 'Neighborhood_NWAmes', 'Neighborhood_NoRidge', 'Neighborhood_NridgHt', 'Neighborhood_Somerst', 'Neighborhood_StoneBr', 'OverallCond', 'OverallQual', 'PoolArea', 'RoofMatl_WdShngl', 'SaleCondition_Normal', 'SaleType_New', 'TotalBsmtSF', 'WoodDeckSF', 'YearBuilt']
上下滑動查看更多

遺傳算法-優(yōu)化歷史上面是一段優(yōu)化算法的描述,該算法用于在1000代進(jìn)化過程中尋找最佳特征組合。進(jìn)化過程將特征的受歡迎程度用熱圖可視化表示,橫向代表不同特征,縱向代表進(jìn)化代數(shù)。熱圖上顏色越深,代表該特征在該代群體中越受歡迎。從熱圖可以看出,一些特征在整個(gè)進(jìn)化過程中保持較高受歡迎度;另一些特征則很快被淘汰;還有些特征的受歡迎程度隨著進(jìn)化代數(shù)的增加而有所波動。該可視化展示了進(jìn)化算法在特征選擇過程中的動態(tài)變化,有助于了解算法的工作原理和特征的重要性。

各種方法之間的比較

我們嘗試了三種不同的技術(shù):SFS、CMA-ES 和 GA。就找到的最佳目標(biāo)和找到目標(biāo)所花費(fèi)的時(shí)間而言,它們之間的比較如何?

這些測試是在一臺安裝了Ubuntu 22.04和Python 3.11.7的AMD Ryzen 7 5800X3D(8/16核)機(jī)器上進(jìn)行的。SFS和GA分別通過一個(gè)包含16個(gè)Worker的多進(jìn)程池來運(yùn)行目標(biāo)函數(shù)。CMA-ES是單進(jìn)程的,多進(jìn)程運(yùn)行似乎沒有明顯的改進(jìn),但我相信如果有更多的工作來使算法并行化,情況會有所改善。

這些是執(zhí)行時(shí)間。對SFS來說,是總執(zhí)行時(shí)間。對于CMA-ES和GA,這是達(dá)到最佳解決方案所需的時(shí)間。時(shí)間越短越好。

SFS:    42.448 sec
GA:     158.027 sec
CMA-ES: 48.326 sec

目標(biāo)函數(shù)被調(diào)用的次數(shù)--越少越好:

SFS:    22791
GA:     600525
CMA-ES: 20000

為目標(biāo)函數(shù)找到的最佳值,與基準(zhǔn)值相比——越少越好:

baseline BIC: 34570.1662
SFS:          33708.9860
GA:           33705.5696
CMA-ES:       33703.0705

在目標(biāo)函數(shù)方面,遺傳算法(GA)能夠取得比序列前向選擇(SFS)更好的結(jié)果,因?yàn)樗軌蚶帽M可能多的CPU內(nèi)核來并行運(yùn)行目標(biāo)函數(shù),但代價(jià)是它的運(yùn)行速度是所有算法中最慢的。GA調(diào)用目標(biāo)函數(shù)的次數(shù)遠(yuǎn)遠(yuǎn)超過其他方法。對超參數(shù)進(jìn)行進(jìn)一步優(yōu)化可能會提高GA的性能。

相比之下,SFS的運(yùn)行速度很快(能夠在所有CPU內(nèi)核上并行運(yùn)行),但其性能一般。SFS是所有算法中最簡單的。

如果你只是想快速估算出近似最優(yōu)的特征集,而不太在意精度,SFS是一個(gè)不錯(cuò)的選擇。

然而,如果你追求最優(yōu)目標(biāo)值,無約束進(jìn)化策略(CMA-ES)似乎是最好的選擇。

責(zé)任編輯:武曉燕 來源: 數(shù)據(jù)STUDIO
相關(guān)推薦

2024-07-16 12:54:40

2018-05-14 12:30:37

數(shù)據(jù)驅(qū)動算法優(yōu)化

2024-05-30 16:37:29

2017-09-22 15:03:08

Python遺傳算法GAFT框架

2021-04-16 20:46:21

PythonXGBoost 特征

2025-01-16 07:10:00

2024-09-12 10:06:21

2023-09-26 22:22:30

選擇排序Python

2021-04-09 10:02:29

機(jī)器學(xué)習(xí)人工智能計(jì)算機(jī)

2024-03-25 11:37:40

機(jī)器學(xué)習(xí)人工智能進(jìn)化算法

2021-03-10 15:49:20

人工智能遺傳算法

2017-07-12 14:23:25

遺傳算法java自然選擇

2023-12-12 07:34:54

炎凰數(shù)據(jù)大數(shù)據(jù)分析數(shù)據(jù)庫開發(fā)

2017-11-16 15:25:54

Go語言算法代碼

2009-08-14 09:41:03

C#遺傳算法

2014-06-05 09:23:47

程序員高效

2023-09-06 18:37:21

可視化數(shù)倉平臺

2022-06-30 09:00:00

算法庫開發(fā)pymoode

2013-05-07 09:11:26

程序員程序員特征

2009-10-14 08:32:14

Windows 7PHP高校IT
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號