رگرسیون خطی با استفاده از الگوریتم ژنتیک همراه با کدهای پایتون
تخمین قیمت ماشین با استفاده از رگرسیون خطی مبتنی بر الگوریتم ژنتیک
مسائل یادگیری ماشین اگر از نوع بانظارت باشند، به دو دسته ی کلی کلاسیفیکیشن و رگرسیون تقسیم می شوند. در مسائل کلاسیفیکیشن چیزی که باید یاد گرفته شود. از نوع کلاس یا دسته یا به عبارتی یک ویژگی categorical است. اما در مسائل رگرسیون ویژگی که قرار است یاد گرفته شود و پیش بینی شود از نوع عددی یا numerical است.
در مسئله ی پیش رو قرار است قیمت ماشین که یک ویژگی عددی است از روی سایر ویژگی ها یاد گرفته شود. بنابراین ما با یک مسئله رگرسیون روبرو هستیم. برای این کار ابتدا دیتاست مربوطه لود شده و ویژگی های غیر عددی آن جدا شده است. البته این امکان وجود داشت که ویژگی های غیرعددی را نیز به عددی تبدیل کرده و از آن ها نیز استفاده کرد.
رگرسیون خطی خود به تنهایی قادر به حل این مسئله است اما در اینجا از الگوریتم ژنتیک برای حل این مسئله استفاه شده است. به این شکل که مسئله به صورت یافتن خط مناسب y=ax+b تعریف می شود که در آن x یک بردار شامل 14 مولفه (متناظر با تعداد ویژگی ها) خواد بود. همین بردار کروموزم های ما را تشکیل خواهد داد. در ادامه جمعیت اولیه تشکیل شده و در هر مراحله فرآیندهای crossover و mutation نیز انجام خواهند گرفت. در نهایت ضرایب بهینه محاسبه خواهند شد.
from random import random, sample, choice from math import floor from tqdm import tqdm from numpy import array, dot, mean from numpy.linalg import pinv from sys import exit import pandas as pd import math def generate_data(): data = pd.read_csv('C:\\Users\\sobhan\\Desktop\\javadi 1400\\Codes\\Linear Regression\\CarPrice_Assignment.csv') x=data[["symboling", "wheelbase","carlength","carwidth","carheight","curbweight","enginesize","boreratio","stroke","compressionratio","horsepower","peakrpm","citympg","highwaympg"]] y=data["price"] return array(x), array(y) def multiple_linear_regression(inputs, outputs): X, Y = array(inputs), array(outputs) X_t, Y_t = X.transpose(), Y.transpose() coeff = dot((pinv((dot(X_t, X)))), (dot(X_t, Y))) Y_p = dot(X, coeff) Y_mean = mean(Y) SST = array([(i - Y_mean) ** 2 for i in Y]).sum() SSR = array([(i - j) ** 2 for i, j in zip(Y, Y_p)]).sum() COD = (1 - (SSR / SST)) * 100.0 av_error = (SSR / len(Y)) return {'COD': COD, 'coeff': coeff, 'error': av_error} def check_termination_condition(best_individual): if ((best_individual['COD'] >= 99.0) or (generation_count == max_generations)): return True else: return False def create_individual(individual_size): return [random() for i in range(individual_size)] def create_population(individual_size, population_size): return [create_individual(individual_size) for i in range(population_size)] def get_fitness(individual, inputs): predicted_outputs = dot(array(inputs), array(individual)) output_mean = mean(outputs) SST = array( [(i - output_mean) ** 2 for i in outputs]).sum() SSR = array( [(i - j) ** 2 for i, j in zip(outputs, predicted_outputs)]).sum() COD = (1 - (SSR / SST)) * 100.0 av_error = math.sqrt((SSR / len(outputs)))/len(outputs) return {'COD': COD, 'error': av_error, 'coeff': individual} def evaluate_population(population): fitness_list = [get_fitness(individual, inputs) for individual in tqdm(population)] error_list = sorted(fitness_list, key=lambda i: i['error']) best_individuals = error_list[: selection_size] best_individuals_stash.append(best_individuals[0]['coeff']) print('Error: ', best_individuals[0]['error'], 'COD: ', best_individuals[0]['COD']) return best_individuals def crossover(parent_1, parent_2): child = {} loci = [i for i in range(0, individual_size)] loci_1 = sample(loci, floor(0.5*(individual_size))) loci_2 = [i for i in loci if i not in loci_1] chromosome_1 = [[i, parent_1['coeff'][i]] for i in loci_1] chromosome_2 = [[i, parent_2['coeff'][i]] for i in loci_2] child.update({key: value for (key, value) in chromosome_1}) child.update({key: value for (key, value) in chromosome_2}) return [child[i] for i in loci] def mutate(individual): loci = [i for i in range(0, individual_size)] no_of_genes_mutated = floor(probability_of_gene_mutating*individual_size) loci_to_mutate = sample(loci, no_of_genes_mutated) for locus in loci_to_mutate: gene_transform = choice([-1, 1]) change = gene_transform*random() individual[locus] = individual[locus] + change return individual def get_new_generation(selected_individuals): parent_pairs = [sample(selected_individuals, 2) for i in range(population_size)] offspring = [crossover(pair[0], pair[1]) for pair in parent_pairs] offspring_indices = [i for i in range(population_size)] offspring_to_mutate = sample( offspring_indices, floor(probability_of_individual_mutating*population_size) ) mutated_offspring = [[i, mutate(offspring[i])] for i in offspring_to_mutate] for child in mutated_offspring: offspring[child[0]] = child[1] return offspring inputs, outputs = generate_data() individual_size = len(inputs[0]) population_size = 1000 selection_size = floor(0.1*population_size) max_generations = 50 probability_of_individual_mutating = 0.1 probability_of_gene_mutating = 0.25 best_possible = multiple_linear_regression(inputs, outputs) best_individuals_stash = [create_individual(individual_size)] initial_population = create_population(individual_size, 1000) current_population = initial_population termination = False generation_count = 0 while termination is False: current_best_individual = get_fitness(best_individuals_stash[-1], inputs) print('Generation: ', generation_count) best_individuals = evaluate_population(current_population) current_population = get_new_generation(best_individuals) termination = check_termination_condition(current_best_individual) generation_count += 1 else: print(get_fitness(best_individuals_stash[-1], inputs))
دیدگاهتان را بنویسید