Здравствуйте и спасибо за чтение этого вопроса.
Я заинтересован в решении линейных задач наименьших квадратов. Для этого я написал следующий код:
import numpy
def create_orthogonal_matrix(dimension):
"""
:param dimension: The desired dimensions of the matrix.
:return: Random dimension x dimension sized orthogonal matrix.
"""
H = numpy.random.randn(dimension, dimension)
return numpy.linalg.qr(H)[0]
def generate_benign_eigenvalues(beta=4):
"""
:return: Sorted (descending) list of length number_of_parameters of eigenvalues which agrees with the required properties.
"""
eigenvalues = [0] * number_of_parameters
for k in range(1, number_of_parameters + 1):
eigenvalues[k - 1] = (k ** (-1)) * (numpy.log(k + 1) ** (-beta))
eigenvalues.sort(reverse=True)
return eigenvalues
def generate_population_covariance(eigenvalues=[]):
"""
:param eigenvalues: Sorted list (descending order) of number_of_parameters desired positive eigenvalues for covariance.
:return: Square root of a Random symmetric positive definite matrix dimensions number_of_parameters x number_of_parameters with the desired eigenvalues.
"""
eigenvectors = create_orthogonal_matrix(len(eigenvalues))
sqrt_of_cov = eigenvectors @ numpy.diag(numpy.sqrt(eigenvalues))
return sqrt_of_cov
def generate_benign_data(sigma=0.1):
"""
:param sigma: Standard deviation of noise
:return: Data x shaped population_size x number_of_parameters of distributed N(0, cov) with required eigenvalues. y distributed N(0, 1) real.
"""
eigenvalues = generate_benign_eigenvalues()
sqrt_cov = generate_population_covariance(eigenvalues)
x = numpy.zeros((population_size, number_of_parameters))
for i in range(population_size):
x[i] = sqrt_cov @ numpy.random.standard_normal(number_of_parameters)
noise = numpy.random.normal(loc=0, scale=sigma, size=x.shape[0])
noise = numpy.reshape(noise, (len(noise), 1))
y = x @ actual_solution + noise
y = numpy.reshape(y, (len(y), 1))
return x, y
def train_test_split(x, y):
"""
:param x: Entire population data
:param y: Entire population targets
:return: Split to train and test sets in the order x_train, y_train, x_test, y_test
"""
x_train, y_train = x[:training_sample_size], y[:training_sample_size]
x_test, y_test = x[training_sample_size:], y[training_sample_size:]
return x_train, y_train, x_test, y_test
# Problem setup
population_size = 2000
training_sample_size = int(0.2 * population_size)
testing_sample_size = population_size - training_sample_size
number_of_parameters = training_sample_size * int(numpy.sqrt(training_sample_size))
actual_solution = numpy.random.uniform(-50, 50, number_of_parameters)
actual_solution = numpy.reshape(actual_solution, (number_of_parameters, 1)) # We want to find this.
x, y = generate_benign_data()
x_train, y_train, x_test, y_test = train_test_split(x, y)
# Find best fit and compare errors with random guess.
solution_for_training_set = numpy.linalg.lstsq(x_train, y_train, rcond=None)[0]
random_solution = numpy.random.uniform(-50, 50, number_of_parameters)
random_solution = numpy.reshape(random_solution, (number_of_parameters, 1))
train_mse_best_fit = (numpy.linalg.norm(x_train @ solution_for_training_set - y_train) ** 2) / training_sample_size
test_mse_best_fit = (numpy.linalg.norm(x_test @ solution_for_training_set - y_test) ** 2) / testing_sample_size
test_mse_random = (numpy.linalg.norm(x_test @ random_solution - y_test) ** 2) / testing_sample_size
print("Results on benign covariance:")
print("Training set error with best training solution = ", train_mse_best_fit)
print("Testing set error with best training solution = ", test_mse_best_fit)
print("Testing set error with random solution = ", test_mse_random)
Проще говоря, я рисую матрицу x
из многомерного нормального распределения со средним нулем и некоторой специальной ковариационной матрицей (случайной, но с фиксированными собственными значениями) , создайте скрытый вектор решения actual_solution
и вектор шума noise
, и наш целевой вектор y = x @ actual_solution + noise
Меня интересует решение задачи линейной регрессии w_best = argmin |xw - y|^2
Код Я написал отлично работает и дает желаемый результат.
Проблема в том, что, когда параметр pop_size становится относительно большим (ничего лишнего), я получаю исключения из памяти. Например, если pop_size равен 10000, то матрица H
в create_orthogonal_matrix
равна 88000 x 88000.
Я знаю, что некоторые люди работают с гигантскими матрицами, поэтому это должно быть выполнимо. Я просто не знаю, как они это делают. Кто-нибудь может помочь, пожалуйста?
Для пояснения : Я понимаю, что тренировка только на 20% данных и с таким большим количеством параметров - верный способ переобучиться, но это нормально. Я заинтересован в переоснащении. Однако теория говорит, что если собственные значения ковариационной матрицы нормального распределения, из которого мы производим выборку, обладают определенным специальным свойством, то у нас будет хорошая тестовая ошибка, несмотря на нашу исходную позицию переоснащения, поэтому игнорируйте это.