Градиент приличный с использованием SGDRegressor алгоритма scikit-learn - PullRequest
0 голосов
/ 04 февраля 2019

Я внедряю Gradient Decent с использованием алгоритма scikit-learn SGDRegressor в моем наборе данных аренды, чтобы прогнозировать арендную плату на основе площади, но получаю странные коэффициенты и перехват, и, следовательно, странные прогнозы для аренды.


Набор данных для аренды: rentals.csv (столбец с полировкой
area,bedrooms,furnished,cost
650,2,1,33000
750,3,0,55000
247,1,0,10500
1256,4,0,65000
900,3,0,37000
900,3,0,50000
550,2,0,30000
1700,4,0,72000
1300,4,0,45000
1600,4,2,57000
475,2,1,30000
800,3,0,45000
350,2,0,15000
247,1,0,11500
247,1,0,16500
247,1,0,15000
330,2,0,16000
450,2,2,25000
325,1,0,13500
1650,4,0,90000
650,2,0,31000
1650,4,0,65000
900,3,0,40000
635,2,0,30000
475,2,2,28000
1120,3,0,45000
1000,3,0,38000
900,3,2,50000
610,3,0,28000
400,2,0,17000

Код Python с альфа-значением = .000001 и max_iter = 1000

import pandas
full_data = pandas.read_csv ("./rentals.csv")
rentals = pandas.DataFrame ({'area':full_data.area,'cost':full_data.cost})

from sklearn.model_selection import train_test_split
train, test = train_test_split (rentals, test_size=0.2, random_state=11)

trainX = pandas.DataFrame ({'area': train['area']})
trainY = pandas.DataFrame ({'cost': train['cost']})
testX = pandas.DataFrame ({'area': test['area']})
testY = pandas.DataFrame ({'cost': test['cost']})

from sklearn.linear_model import SGDRegressor
reg = SGDRegressor(max_iter=1000, alpha=.000001, tol=.0001)

reg.fit (trainX, trainY)

from sklearn.metrics import mean_squared_error, r2_score

print ('Coefficients: \n', reg.coef_)
print ('Intercept: \n', reg.intercept_)

yhat = reg.predict (testX)

print ('Mean squared error: \n', mean_squared_error (testY, yhat))
print ('Variance score: \n', r2_score (testY, yhat))

print('yhat :: ',yhat)

ВЫХОД

Coefficients:
 [-1.77569698e+12]
Intercept:
 [2.20231032e+10]
Mean squared error:
 2.7699546187784015e+30
Variance score:
 -1.1843036374824519e+22
yhat ::  [-4.38575131e+14 -2.30838405e+15 -9.76611316e+14 -1.77567496e+15
 -2.23025338e+15 -1.42053556e+15]

Когда альфа = .00000001

reg = SGDRegressor(max_iter=1000, alpha=.00000001, tol=.0001)

ВЫХОД

Coefficients:
 [-1.35590231e+12]
Intercept:
 [-9.70811558e+10]
Mean squared error:
 1.6153367348228915e+30
Variance score:
 -6.906427844848468e+21
yhat ::  [-3.35004951e+14 -1.76277008e+15 -7.45843351e+14 -1.35599939e+15
 -1.70311038e+15 -1.08481893e+15]

Я пробовал все значения до альфа = .00000000001

reg = SGDRegressor(max_iter=1000, alpha=.00000000001, tol=.0001)

ВЫХОД

Coefficients:
 [1.81827102e+12]
Intercept:
 [8.5060188e+09]
Mean squared error:
 2.9044685546452095e+30
Variance score:
 -1.2418155340525837e+22
yhat ::  [4.49121448e+14 2.36376083e+15 1.00005757e+15 1.81827952e+15
 2.28375691e+15 1.45462532e+15]

Подскажите, пожалуйста, что не так в моем коде? Почему я получаю неправильные значения?

Заранее спасибо.

1 Ответ

0 голосов
/ 05 февраля 2019

Нет ничего плохого в коде.Интересно, что если мы заменим SGDRegressor на простой LinearRegression, результаты получатся хорошими (coef = ~ 40, r2score = ~ 0.7).Должно быть что-то в данных, которые стохастическому градиенту не нравятся.

То, что я считаю, что происходит, так это то, что из-за большого масштаба данных градиент становится слишком большим, и алгоритм расходится.

Мы можем убедиться в этом, установив низкую скорость обучения, заставляя алгоритм делать небольшие шаги, даже если градиент высокий:

reg = SGDRegressor(max_iter=1000, alpha=.000001, tol=.0001, learning_rate='constant', eta0=1e-7)

# Coefficients: [46.75739932]
# Intercept: [0.11470854]
# Mean squared error: 75520077.45401965
# Variance score: 0.6771113077975406

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

mu_x = trainX.mean().values
mu_y = trainY.mean().values
scale_x = trainX.std().values
scale_y = trainY.std().values

trainX = (trainX - mu_x) / scale_x
trainY = (trainY - mu_y) / scale_y

reg = SGDRegressor(max_iter=1000, alpha=.000001, tol=.0001)

reg.fit(trainX, trainY)

yhat = reg.predict((testX - mu_x) / scale_x) * scale_y + mu_y

# Coefficients: [0.89319654]
# Intercept: [0.00064678]
# Mean squared error: 59575772.471740596
# Variance score: 0.7452817328999215

Центрирование и масштабирование данных очень помогают.Есть также scikit-learn StandardScaler, но мне нравится показывать ручной подход, чтобы проиллюстрировать, что происходит.

...