Уменьшение влияния одной переменной на выход в регрессионной модели - PullRequest
6 голосов
/ 02 марта 2020

В настоящее время я реализую модель процесса гауссовой регрессии, и у меня возникли некоторые проблемы при попытке применить ее к объему моей проблемы. Моя проблема заключается в том, что в качестве входных данных для моей модели используются три переменные, одно из этих значений (theta) имеет гораздо более значительное влияние, чем два других, alpha1 и alpha2. Входы и выходы имеют следующие значения (только несколько значений для лучшего понимания):

# X (theta, alpha1, alpha2)
array([[ 9.07660169,  0.61485493,  1.70396493],
       [ 9.51498486, -5.49212002, -0.68659511],
       [10.45737558, -2.2739529 , -2.03918961],
       [10.46857663, -0.4587848 ,  0.54434441],
       [ 9.10133699,  8.38066374,  0.66538822],
       [ 9.17279647,  0.36327109, -0.30558115],
       [10.36532505,  0.87099676, -7.73775872],
       [10.13681026, -1.64084098, -0.09169159],
       [10.38549264,  1.80633583,  1.3453195 ],
       [ 9.72533357,  0.55861224,  0.74180309])

# y
array([4.93483686, 5.66226844, 7.51133372, 7.54435854, 4.92758927,
       5.0955348 , 7.26606153, 6.86027353, 7.36488184, 6.06864003])

Как видно, theta значительно меняет значение y, тогда как изменения alpha1 и alpha2 гораздо более тонкие по сравнению с y.

Ситуация, с которой я сталкиваюсь, заключается в том, что я применяю модель к своим данным, и из этой модели я применяю минимизацию с помощью Scipy к настройке модели. одна из входных переменных зафиксирована, как при этой минимизации. Приведенный ниже код может лучше проиллюстрировать:

# model fitting
kernel = C(1.0, (1e-3, 1e3))*RBF(10,(1e-2,1e2))
model = GaussianProcessRegressor(kernel = kernel, n_restarts_optimizer = 9,optimizer='fmin_l_bfgs_b')
model.fit(X,y)

# minimization
bnds = np.array([(theta,theta),
                 (alpha1.min(),
                  alpha1.max()),
                 (alpha2.min(),
                  alpha2.max())])

x0 = [theta,alpha1.min(),alpha2.min()]

residual_plant = minimize(lambda x: -model.predict(np.array([x])),
                          x0, method='SLSQP',bounds=bnds, 
                          options = {'eps': np.radians(5)})

Моя цель в том, чтобы я хотел установить первую переменную value как фиксированное значение и изучить влияние двух других переменных * 1016. * и alpha2 имеют выход y для указанного значения c theta. Причина c, лежащая в основе минимизации, заключается в том, что я хочу найти комбинации alpha t1 и alpha2, которые возвращают мне оптимальный y для этого фиксированного theta. Поэтому мне было интересно, как мне это сделать, так как я считаю, что theta должно сильно влиять на влияние, которое оказывают две другие мои переменные на мой вывод, и тогда это может отрицательно влиять на мою модель на задачу, которую я имею в рука, поскольку она имеет больший вес и будет скрывать влияние alpha1 и alpha2 на мою модель, однако я не могу игнорировать это или не вводить его в свою модель, так как хочу найти оптимальное значение y для этого фиксированного theta и, следовательно, мне все равно нужно было бы использовать theta в качестве входных данных.

Мой вопрос: как бороться с такой проблемой? Есть ли какой-нибудь статистический прием, чтобы устранить или хотя бы уменьшить это влияние, не исключая theta из моей модели? Есть ли лучший способ справиться с моей проблемой?

Ответы [ 3 ]

2 голосов
/ 11 марта 2020

Мое общее понимание вашего вопроса состоит в том, что вы хотите достичь двух вещей:

  1. Изучить влияние альфа1 и альфа2 после превращения тэты в постоянную (т.е. устранение влияние тета на модель).

  2. Найти наилучшую комбинацию альфа1 и альфа2, которая возвращает оптимальное значение y для этого фиксированного тета.

Это можно обобщить при изучении корреляции между входными переменными и целевой переменной.

Поскольку корреляция изучает изменения отношения между одной переменной к другой независимо, тогда вы сможете получить хорошее представление о влиянии альфа1, альфа2 и тета на y.

Существуют две интересные корреляции, которые помогут вам:

  1. Соотношение Пирсона: численно отражает силу линейная корреляция.
  2. Корреляция Спирмена: Численно отражает силу монотонной c корреляции (т.е. ank, в случае, если корреляция не линейная).

Давайте попробуем:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

df = pd.DataFrame(columns=['theta', 'alpha1', 'alpha2', 'y'],
                  data=[[ 9.07660169,  0.61485493,  1.70396493, 4.93483686],
                       [ 9.51498486, -5.49212002, -0.68659511, 5.66226844],
                       [10.45737558, -2.2739529 , -2.03918961,  7.51133372],
                       [10.46857663, -0.4587848 ,  0.54434441, 7.54435854],
                       [ 9.10133699,  8.38066374,  0.66538822, 4.92758927],
                       [ 9.17279647,  0.36327109, -0.30558115, 5.0955348],
                       [10.36532505,  0.87099676, -7.73775872, 7.26606153],
                       [10.13681026, -1.64084098, -0.09169159, 6.86027353],
                       [10.38549264,  1.80633583,  1.3453195, 7.36488184],
                       [ 9.72533357,  0.55861224,  0.74180309, 6.06864003]])


plt.figure(figsize=(10, 8))
ax = sns.heatmap(df.corr(method="pearson"), annot=True)
plt.xticks(rotation = 90)
plt.title('Pearson Correlation Heatmap')
plt.show()

plt.figure(figsize=(10, 8))
ax = sns.heatmap(df.corr(method="spearman"), annot=True)
plt.xticks(rotation = 90)
plt.title('Spearman Correlation Heatmap')
plt.show()

Pearson's Correlation

Spearman's Correlation

Как видите, мы получили очень хорошее представление о связи между тета, альфа1 и альфа2 друг с другом и с у.

Согласно стандарту Коэна, мы можем заключить, что:

  • Alpha1 и Alpha2 имеют среднюю корреляцию с y.
  • Theta имеет очень сильную корреляцию с y.
  • Alpha1 имеет слабая линейная корреляция с альфа2, но средняя монотонность c корреляция.
  • Альфа1 и Альфа2 имеют среднюю корреляцию с тета.

Но подождите минуту, так как альфа1 и альфа2 имеют среднюю корреляцию с Если слабая корреляция (к средней) между собой, мы можем затем использовать дисперсию для получения функции оптимизации L, которая представляет собой линейную комбинацию между alpha1 и alpha2, следующим образом:

Let m, n быть двумя весами, которые максимизируют корреляция между функциями alpha1 и alpha2 с y согласно функции оптимизации L:

m * alpha1 + n * alpha2

Оптимальные коэффициенты m и n, достигающие максимальной корреляции между L и y, зависят на дисперсиях alpha1, alpha2 и y.

Из этого можно сделать следующее оптимизационное решение:

m = [ ???(?,?) * ???(?,?) − ???(?,?) * ???(?) / ???(?,?) * ???(?,?) − ???(?,?) * ???(?) ] * n

, где a, b и c соответствуют alpha1, alpha2 и y соответственно.

Выбрав m или n как 1 или -1, мы можем найти оптимальное решение для разработки новой функции.

cov = df[['alpha1', 'alpha2', 'y']].cov()

# applying the optimization function: a = alpha1 , b = alpha2 and c = y
# note that cov of a feature with itself = variance
coef = (cov['alpha2']['y'] * cov['alpha1']['alpha2'] - cov['alpha1']['y'] * cov['alpha2']['alpha2']) / \
       (cov['alpha1']['y'] * cov['alpha1']['alpha2'] - cov['alpha2']['y'] * cov['alpha1']['alpha1'])
# let n = 1 --> m = coef --> L = coef * alpha1 + alpha2 :  which is the new feature to add
df['alpha12'] = coef * df['alpha1'] + df['alpha2']

covariance correlation after alpha12

Как вы можете заметить, заметно улучшилось соотношение введенного альфа12.

Более того в связи с вопросом 1, чтобы уменьшить корреляцию тета; и так как корреляция определяется как:

Corr(theta, y) = Cov(theta, y) / [sqrt(Var(that)) * sqrt(Var(y))]

Вы можете увеличить дисперсию тета. Для этого просто выберите n точек из некоторого распределения и добавьте их в соответствующие индексы как шум. Сохраните этот список шумов для будущего использования на тот случай, если вам нужно вернуться к исходной тэте, что-то вроде этого:

cov = df[['y', 'theta']].cov()
print("Theta Variance :: Before = {}".format(cov['theta']['theta']))

np.random.seed(2020)  # add seed to make it reproducible for future undo
# create noise drawn from uniform distribution
noise = np.random.uniform(low=1.0, high=10., size=df.shape[0])
df['theta'] += noise  # add noise to increase variance
cov = df[['y', 'theta']].cov()
print("Theta Variance :: After = {}".format(cov['theta']['theta']))

# df['theta'] -= noise to back to original variance

plt.figure(figsize=(15, 15))
ax = sns.heatmap(df.corr(method="spearman"), annot=True)
plt.xticks(rotation = 90)
plt.title('Spearman Correlation Heatmap After Reducing Variance of Theta\n')
plt.show()

plt.figure(figsize=(15, 15))
ax = sns.heatmap(df.corr(method="pearson"), annot=True)
plt.xticks(rotation = 90)
plt.title('Pearson Correlation Heatmap After Reducing Variance of Theta\n')
plt.show()

Theta Variance :: Before = 0.3478030891329485

Theta Variance :: После = 7.552229545792681

pearson corr after theta var

spearman corr after theta var

Теперь Alpha12 берет на себя инициативу и имеет наибольшее влияние на целевую переменную y.

2 голосов
/ 02 марта 2020

Во-первых, нормализовали ли вы данные перед тренировкой?

Во-вторых, похоже, что вы хотите видеть связь между x и y с постоянной тета.

Если вы берете свой набор данных и отсортировав его по тета, вы можете попытаться найти группу записей, в которых тэта одинакова или очень похожа, где ее дисперсия мала и не сильно меняется. Вы можете взять эту группу данных, сформировать новый фрейм данных и удалить столбец тета (потому что мы выбрали часть набора данных, где тета имеет низкую дисперсию, и поэтому она не очень полезна). Затем вы можете обучить вашу модель или визуализировать данные только для данных alpha1 и alpha2.

0 голосов
/ 05 марта 2020

Я бы сказал, что влияние тэты на ваш предиктор не может скрыть влияние других переменных. Влияние других переменных может быть небольшим, но, скорее всего, так оно и есть. Я бы взял полученную оценку и оптимизировал бы y для постоянной тета, как

...