<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Готовим данные к линейной модели. Уберем n-ные столбцы после one-hot encoding, чтоб не образовывалась линейная зависимость
Step1:  Вариант с квадратами
Step2:  Вариант поскейленных данных
Step3:  В прошлом ноутбуке изучается рпспределение цен. Оно так себе - очень большая плотность в начале вариационного ряда и она быстро падает до очень маленьких значений. При таких данных имеет смысл прологарифмировать колонку и работать уже с логарифмом. Не забудем перед посчетом ошибки модели возвести экспоненту в получившуюся степень.
Step4:  Комбинации вышеизложенных вариантов.
Step5:  Для каждого варианта составляем модель, обучаем ее и сопоставляем ошибки.
Step6:  При нескольких прогонках мною было подмечено, что ошибки моделей хоть и меняются, но относительно друг друга модели в среднем особо не передвигатся
Step7:  В среднем RMSE была чуть меньше. Лучше остальных те же модели (вот это уже стабильно просматривалось)
Step8:  Если усреднять запуски, то результаты лучше у модели с регуляризацией, причем у Ridge. По итогам всех эспериментов наилучшей выглядит модель для sq_log данных.
Теперь запустим эти 8 вариантов для RandomForest
Подгрузим заново датасет, чтоб можно было использовать удаленные для линейных моделей колонки. Деревьям они как раз не помешают.
<ASSISTANT_TASK:>
Python Code:
data.drop(['Bal_na', 'Distr_N', 'Brick_na'], axis = 1, inplace = True)
Explanation: Готовим данные к линейной модели. Уберем n-ные столбцы после one-hot encoding, чтоб не образовывалась линейная зависимость
End of explanation
data_sq = data.copy()
squared_columns = ['Distance', 'Kitsp', 'Livsp', 'Totsp', 'Metrokm']
squared_columns_new = ['Distance_sq', 'Kitsp_sq', 'Livsp_sq', 'Totsp_sq', 'Metrokm_sq']
for i in range(len(squared_columns)):
    data_sq[squared_columns_new[i]] = [x**2 for x in data_sq[squared_columns[i]]]
data_sq.head(3)
Explanation: Вариант с квадратами: зависимость цены от каких-то признаков может быть квадратичной. Не будем исследовать очень подробно, от каких именно, просто по всем не категориальным добавим колонку "признак в квадрате". По идее тем, которые зависят скорее линейно, модель сама поставит в коэфициент при квадрате что-то маленькое.
End of explanation
from sklearn.preprocessing import scale
to_scale = ['Distance', 'Floor', 'Kitsp', 'Livsp', 'Nfloors', 'Totsp', 'Metrokm']
data_sc = data.copy()
data_sc[to_scale] = scale(data_sc[to_scale], axis = 1)
data_sc.head(3)
Explanation: Вариант поскейленных данных
End of explanation
data_log = data.copy()
data_log['Price'] = np.log(data_log['Price'])
data_log['Price'].head()
Explanation: В прошлом ноутбуке изучается рпспределение цен. Оно так себе - очень большая плотность в начале вариационного ряда и она быстро падает до очень маленьких значений. При таких данных имеет смысл прологарифмировать колонку и работать уже с логарифмом. Не забудем перед посчетом ошибки модели возвести экспоненту в получившуюся степень.
End of explanation
data_sc_log = data.drop('Price', axis = 1)
data_sc_log[to_scale] = scale(data_sc_log[to_scale], axis = 1)
data_sc_log['Price'] = np.log(data['Price'])
data_sc_log.head(3)
data_sq_log = data.drop('Price', axis = 1)
for i in range(len(squared_columns)):
    data_sq_log[squared_columns_new[i]] = [x**2 for x in data_sq_log[squared_columns[i]]]
    
data_sq_log['Price'] = np.log(data['Price'])
data_sq_log.head(3)
data_sc_sq_log = data.drop('Price', axis = 1)
data_sc_sq_log[to_scale] = scale(data_sc_sq_log[to_scale], axis = 1)
for i in range(len(squared_columns)):
    data_sc_sq_log[squared_columns_new[i]] = [x**2 for x in data_sc_sq_log[squared_columns[i]]]
    
data_sc_sq_log['Price'] = np.log(data['Price'])
data_sc_sq_log.head(3)
data_sq_sc_log = data.drop('Price', axis = 1)
for i in range(len(squared_columns)):
    data_sq_sc_log[squared_columns_new[i]] = [x**2 for x in data_sq_sc_log[squared_columns[i]]]
data_sq_sc_log[to_scale] = scale(data_sq_sc_log[to_scale], axis = 1)
data_sq_sc_log['Price'] = np.log(data['Price'])
data.head(3)
datasets = [data, data_sq, data_sc, data_log, data_sc_log, data_sq_log, data_sc_sq_log, data_sq_sc_log]
Explanation: Комбинации вышеизложенных вариантов.
End of explanation
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
from math import sqrt
simple = LinearRegression()
squared = LinearRegression()
scaled = LinearRegression()
log = LinearRegression()
sc_log = LinearRegression()
sq_log = LinearRegression()
sc_sq_log = LinearRegression()
sq_sc_log = LinearRegression()
models = [
    
    ('simple', simple),
    ('squared', squared),
    ('scaled', scaled),
    ('log', log), 
    ('sc_log', sc_log),
    ('sq_log', sq_log),
    ('sc_sq_log', sc_sq_log),
    ('sq_sc_log', sq_sc_log)
    
]
for i in range(len(models)):
    
        tmp = datasets[i]
        train = tmp.drop('Price', axis = 1)
        target = tmp['Price']
        target = pd.DataFrame(target)
    
        Xtr, Xval, Ytr, Yval = train_test_split(train, target, test_size=0.2)
        
        modelname, model = models[i]
        model.fit(Xtr, Ytr);
        
        predictions = model.predict(Xval)
        
        
        if (modelname.find('log', 0, len(modelname)) < 0):
            rmse = sqrt(mean_squared_error(Yval, predictions))
            mae = mean_absolute_error(Yval, predictions)
            print('Model:', modelname, '     RMSE: ', rmse, '   MAE: ', mae)
        else:
            rmse = sqrt(mean_squared_error(np.exp(Yval), np.exp(predictions)))
            mae = mean_absolute_error(np.exp(Yval), np.exp(predictions))
            print('Model:', modelname, '     RMSE: ', rmse, '   MAE: ', mae)
Explanation: Для каждого варианта составляем модель, обучаем ее и сопоставляем ошибки.
End of explanation
from sklearn.linear_model import Lasso
simple = Lasso(alpha = 0.01, max_iter = 100000, tol = 0.01)
squared = Lasso(alpha = 0.01, max_iter = 100000, tol = 0.01)
scaled = Lasso(alpha = 0.01, max_iter = 100000, tol = 0.01)
log = Lasso(alpha = 0.01, max_iter = 100000, tol = 0.01)
sc_log = Lasso(alpha = 0.01, max_iter = 100000, tol = 0.01)
sq_log = Lasso(alpha = 0.01, max_iter = 100000, tol = 0.01)
sc_sq_log = Lasso(alpha = 0.01, max_iter = 100000, tol = 0.01)
sq_sc_log = Lasso(alpha = 0.01, max_iter = 100000, tol = 0.01)
models = [
    ('simple', simple),
    ('squared', squared),
    ('scaled', scaled),
    ('log', log), 
    ('sc_log', sc_log),
    ('sq_log', sq_log),
    ('sc_sq_log', sc_sq_log),
    ('sq_sc_log', sq_sc_log)
]
for i in range(len(models)):
    
        tmp = datasets[i]
        train = tmp.drop('Price', axis = 1)
        target = tmp['Price']
        target = pd.DataFrame(target)
    
        Xtr, Xval, Ytr, Yval = train_test_split(train, target, test_size=0.2)
        
        modelname, model = models[i]
        model.fit(Xtr, Ytr);
        
        predictions = model.predict(Xval)
        coef = model.coef_
        zeros = []
        for j in range(len(Xtr.columns)):
            if coef[j] == 0:
                zeros.append(Xtr.columns[j])
                
        if (modelname.find('log', 0, len(modelname)) < 0):
            rmse = sqrt(mean_squared_error(Yval, predictions))
            mae = mean_absolute_error(Yval, predictions)
            print('Model:', modelname, '     RMSE: ', rmse, '   MAE: ', mae, '   Coef: ', zeros)
        else:
            rmse = sqrt(mean_squared_error(np.exp(Yval), np.exp(predictions)))
            mae = mean_absolute_error(np.exp(Yval), np.exp(predictions))
            print('Model:', modelname, '     RMSE: ', rmse, '   MAE: ', mae, '  Coef: ', zeros)
Explanation: При нескольких прогонках мною было подмечено, что ошибки моделей хоть и меняются, но относительно друг друга модели в среднем особо не передвигатся: лидируют simple, squared и sq_log.
Теперь попробуем регуляризовать.
End of explanation
from sklearn.linear_model import Ridge
simple = Ridge(alpha = .01, max_iter = 10000)
squared = Ridge(alpha = .01, max_iter = 10000)
scaled = Ridge(alpha = .01, max_iter = 10000)
log = Ridge(alpha = .01, max_iter = 10000)
sc_log = Ridge(alpha = .01, max_iter = 10000)
sq_log = Ridge(alpha = .01, max_iter = 10000)
sc_sq_log = Ridge(alpha = .01, max_iter = 10000)
sq_sc_log = Ridge(alpha = .01, max_iter = 10000)
models = [
    ('simple', simple),
    ('squared', squared),
    ('scaled', scaled),
    ('log', log), 
    ('sc_log', sc_log),
    ('sq_log', sq_log),
    ('sc_sq_log', sc_sq_log),
    ('sq_sc_log', sq_sc_log)
]
for i in range(len(models)):
    
        tmp = datasets[i]
        train = tmp.drop('Price', axis = 1)
        target = tmp['Price']
        target = pd.DataFrame(target)
    
        Xtr, Xval, Ytr, Yval = train_test_split(train, target, test_size=0.2)
        
        modelname, model = models[i]
        model.fit(Xtr, Ytr);
        
        predictions = model.predict(Xval)
       
        if (modelname.find('log', 0, len(modelname)) < 0):
            rmse = sqrt(mean_squared_error(Yval, predictions))
            mae = mean_absolute_error(Yval, predictions)
            print('Model:', modelname, '     RMSE: ', rmse, '   MAE: ', mae)
        else:
            rmse = sqrt(mean_squared_error(np.exp(Yval), np.exp(predictions)))
            mae = mean_absolute_error(np.exp(Yval), np.exp(predictions))
            print('Model:', modelname, '     RMSE: ', rmse, '   MAE: ', mae)
Explanation: В среднем RMSE была чуть меньше. Лучше остальных те же модели (вот это уже стабильно просматривалось): sq_log, simple, squared.
End of explanation
data_rf = pd.read_csv('/Users/tatanakuzenko/cian_data_clear_for_modeling.csv')
data_sq_rf = data_rf
for i in range(len(squared_columns_new)):
        data_sq_rf[squared_columns_new[i]] = 0
for i in range(len(squared_columns)):
    data_sq_rf[squared_columns_new[i]] = [x**2 for x in data_sq_rf[squared_columns[i]]]
data_sc_rf = data.copy()
data_sc_rf[to_scale] = scale(data_sc_rf[to_scale], axis = 1)
data_log_rf = data.copy()
data_log_rf['Price'] = np.log(data_log_rf['Price'])
data_sq_log_rf = data.drop('Price', axis = 1)
for i in range(len(squared_columns)):
    data_sq_log_rf[squared_columns_new[i]] = [x**2 for x in data_sq_log_rf[squared_columns[i]]]
    
data_sq_log_rf['Price'] = np.log(data['Price'])
data_sc_log_rf = data.drop('Price', axis = 1)
data_sc_log_rf[to_scale] = scale(data_sc_log_rf[to_scale], axis = 1)
data_sc_log_rf['Price'] = np.log(data['Price'])
data_sc_sq_log_rf = data.drop('Price', axis = 1)
data_sc_sq_log_rf[to_scale] = scale(data_sc_sq_log_rf[to_scale], axis = 1)
for i in range(len(squared_columns)):
    data_sc_sq_log_rf[squared_columns_new[i]] = [x**2 for x in data_sc_sq_log_rf[squared_columns[i]]]
    
data_sc_sq_log_rf['Price'] = np.log(data['Price'])
data_sq_sc_log_rf = data.drop('Price', axis = 1)
for i in range(len(squared_columns)):
    data_sq_sc_log_rf[squared_columns_new[i]] = [x**2 for x in data_sq_sc_log_rf[squared_columns[i]]]
data_sq_sc_log_rf[to_scale] = scale(data_sq_sc_log_rf[to_scale], axis = 1)
data_sq_sc_log_rf['Price'] = np.log(data['Price'])
datasets_rf = [data_rf, data_sq_rf, data_sc_rf, data_log_rf, data_sc_log_rf, data_sq_log_rf, data_sc_sq_log_rf, data_sq_sc_log_rf]
from sklearn.ensemble import RandomForestRegressor
simple = RandomForestRegressor(n_estimators=60, criterion='mse', max_depth=15)
squared = RandomForestRegressor(n_estimators=60, criterion='mse', max_depth=15)
scaled = RandomForestRegressor(n_estimators=60, criterion='mse', max_depth=15)
log = RandomForestRegressor(n_estimators=60, criterion='mse', max_depth=15)
sc_log = RandomForestRegressor(n_estimators=60, criterion='mse', max_depth=15)
sq_log = RandomForestRegressor(n_estimators=60, criterion='mse', max_depth=15)
sc_sq_log = RandomForestRegressor(n_estimators=60, criterion='mse', max_depth=15)
sq_sc_log = RandomForestRegressor(n_estimators=60, criterion='mse', max_depth=15)
models = [
    ('simple', simple),
    ('squared', squared),
    ('scaled', scaled),
    ('log', log), 
    ('sc_log', sc_log),
    ('sq_log', sq_log),
    ('sc_sq_log', sc_sq_log),
    ('sq_sc_log', sq_sc_log)
]
for i in range(len(models)):
    
        tmp = datasets[i]
        train = tmp.drop('Price', axis = 1)
        target = tmp['Price']
    
        Xtr, Xval, Ytr, Yval = train_test_split(train, target, test_size=0.2)
        
        modelname, model = models[i]
        model.fit(Xtr, Ytr);
        
        predictions = model.predict(Xval)
       
        if (modelname.find('log', 0, len(modelname)) < 0):
            rmse = sqrt(mean_squared_error(Yval, predictions))
            mae = mean_absolute_error(Yval, predictions)
            print('Model:', modelname, '     RMSE: ', rmse, '   MAE: ', mae)
        else:
            rmse = sqrt(mean_squared_error(np.exp(Yval), np.exp(predictions)))
            mae = mean_absolute_error(np.exp(Yval), np.exp(predictions))
            print('Model:', modelname, '     RMSE: ', rmse, '   MAE: ', mae)
Explanation: Если усреднять запуски, то результаты лучше у модели с регуляризацией, причем у Ridge. По итогам всех эспериментов наилучшей выглядит модель для sq_log данных.
Теперь запустим эти 8 вариантов для RandomForest
Подгрузим заново датасет, чтоб можно было использовать удаленные для линейных моделей колонки. Деревьям они как раз не помешают.
End of explanation
<END_TASK>