Sklearn

Bike Sharing Demand

Задача на kaggle: https://www.kaggle.com/c/bike-sharing-demand

По историческим данным о прокате велосипедов и погодным условиям необходимо оценить спрос на прокат велосипедов.

В исходной постановке задачи доступно 11 признаков: https://www.kaggle.com/c/prudential-life-insurance-assessment/data

В наборе признаков присутсвуют вещественные, категориальные, и бинарные данные.

Для демонстрации используется обучающая выборка из исходных данных train.csv, файлы для работы прилагаются.

Библиотеки


In [ ]:
from sklearn import cross_validation, grid_search, linear_model, metrics

import numpy as np
import pandas as pd

In [ ]:
%pylab inline

Загрузка данных


In [ ]:
raw_data = pd.read_csv('bike_sharing_demand.csv', header = 0, sep = ',')

In [ ]:
raw_data.head()

datetime - hourly date + timestamp

season - 1 = spring, 2 = summer, 3 = fall, 4 = winter

holiday - whether the day is considered a holiday

workingday - whether the day is neither a weekend nor holiday

weather - 1: Clear, Few clouds, Partly cloudy, Partly cloudy 2: Mist + Cloudy, Mist + Broken clouds, Mist + Few clouds, Mist 3: Light Snow, Light Rain + Thunderstorm + Scattered clouds, Light Rain + Scattered clouds 4: Heavy Rain + Ice Pallets + Thunderstorm + Mist, Snow + Fog

temp - temperature in Celsius

atemp - "feels like" temperature in Celsius

humidity - relative humidity

windspeed - wind speed

casual - number of non-registered user rentals initiated

registered - number of registered user rentals initiated

count - number of total rentals


In [ ]:
print raw_data.shape

In [ ]:
raw_data.isnull().values.any()

Предобработка данных

Типы признаков


In [ ]:
raw_data.info()

In [ ]:
raw_data.datetime = raw_data.datetime.apply(pd.to_datetime)

In [ ]:
raw_data['month'] = raw_data.datetime.apply(lambda x : x.month)
raw_data['hour'] = raw_data.datetime.apply(lambda x : x.hour)

In [ ]:
raw_data.head()

Обучение и отложенный тест


In [ ]:
train_data = raw_data.iloc[:-1000, :]
hold_out_test_data = raw_data.iloc[-1000:, :]

In [ ]:
print raw_data.shape, train_data.shape, hold_out_test_data.shape

In [ ]:
print 'train period from {} to {}'.format(train_data.datetime.min(), train_data.datetime.max())
print 'evaluation period from {} to {}'.format(hold_out_test_data.datetime.min(), hold_out_test_data.datetime.max())

Данные и целевая функция


In [ ]:
#обучение
train_labels = train_data['count'].values
train_data = train_data.drop(['datetime', 'count'], axis = 1)

In [ ]:
#тест
test_labels = hold_out_test_data['count'].values
test_data = hold_out_test_data.drop(['datetime', 'count'], axis = 1)

Целевая функция на обучающей выборке и на отложенном тесте


In [ ]:
pylab.figure(figsize = (16, 6))

pylab.subplot(1,2,1)
pylab.hist(train_labels)
pylab.title('train data')

pylab.subplot(1,2,2)
pylab.hist(test_labels)
pylab.title('test data')

Числовые признаки


In [ ]:
numeric_columns = ['temp', 'atemp', 'humidity', 'windspeed', 'casual', 'registered', 'month', 'hour']

In [ ]:
train_data = train_data[numeric_columns]
test_data = test_data[numeric_columns]

In [ ]:
train_data.head()

In [ ]:
test_data.head()

Модель


In [ ]:
regressor = linear_model.SGDRegressor(random_state = 0)

In [ ]:
regressor.fit(train_data, train_labels)
metrics.mean_absolute_error(test_labels, regressor.predict(test_data))

In [ ]:
print test_labels[:10]

In [ ]:
print regressor.predict(test_data)[:10]

In [ ]:
regressor.coef_

Scaling


In [ ]:
from sklearn.preprocessing import StandardScaler

In [ ]:
#создаем стандартный scaler
scaler = StandardScaler()
scaler.fit(train_data, train_labels)
scaled_train_data = scaler.transform(train_data)
scaled_test_data = scaler.transform(test_data)

In [ ]:
regressor.fit(scaled_train_data, train_labels)
metrics.mean_absolute_error(test_labels, regressor.predict(scaled_test_data))

In [ ]:
print test_labels[:10]

In [ ]:
print regressor.predict(scaled_test_data)[:10]

Подозрительно хорошо?


In [ ]:
print regressor.coef_

In [ ]:
print map(lambda x : round(x, 2), regressor.coef_)

In [ ]:
train_data.head()

In [ ]:
train_labels[:10]

In [ ]:
np.all(train_data.registered + train_data.casual == train_labels)

In [ ]:
train_data.drop(['casual', 'registered'], axis = 1, inplace = True)
test_data.drop(['casual', 'registered'], axis = 1, inplace = True)

In [ ]:
scaler.fit(train_data, train_labels)
scaled_train_data = scaler.transform(train_data)
scaled_test_data = scaler.transform(test_data)

In [ ]:
regressor.fit(scaled_train_data, train_labels)
metrics.mean_absolute_error(test_labels, regressor.predict(scaled_test_data))

In [ ]:
print map(lambda x : round(x, 2), regressor.coef_)

Pipeline


In [ ]:
from sklearn.pipeline import Pipeline

In [ ]:
#создаем pipeline из двух шагов: scaling и классификация
pipeline = Pipeline(steps = [('scaling', scaler), ('regression', regressor)])

In [ ]:
pipeline.fit(train_data, train_labels)
metrics.mean_absolute_error(test_labels, pipeline.predict(test_data))

Подбор параметров


In [ ]:
pipeline.get_params().keys()

In [ ]:
parameters_grid = {
    'regression__loss' : ['huber', 'epsilon_insensitive', 'squared_loss', ],
    'regression__n_iter' : [3, 5, 10, 50], 
    'regression__penalty' : ['l1', 'l2', 'none'],
    'regression__alpha' : [0.0001, 0.01],
    'scaling__with_mean' : [0., 0.5],
}

In [ ]:
grid_cv = grid_search.GridSearchCV(pipeline, parameters_grid, scoring = 'mean_absolute_error', cv = 4)

In [ ]:
%%time
grid_cv.fit(train_data, train_labels)

In [ ]:
print grid_cv.best_score_
print grid_cv.best_params_

Оценка по отложенному тесту


In [ ]:
metrics.mean_absolute_error(test_labels, grid_cv.best_estimator_.predict(test_data))

In [ ]:
np.mean(test_labels)

In [ ]:
test_predictions = grid_cv.best_estimator_.predict(test_data)

In [ ]:
print test_labels[:10]

In [ ]:
print test_predictions[:10]

In [ ]:
pylab.figure(figsize=(16, 6))

pylab.subplot(1,2,1)
pylab.grid(True)
pylab.scatter(train_labels, pipeline.predict(train_data), alpha=0.5, color = 'red')
pylab.scatter(test_labels, pipeline.predict(test_data), alpha=0.5, color = 'blue')
pylab.title('no parameters setting')
pylab.xlim(-100,1100)
pylab.ylim(-100,1100)

pylab.subplot(1,2,2)
pylab.grid(True)
pylab.scatter(train_labels, grid_cv.best_estimator_.predict(train_data), alpha=0.5, color = 'red')
pylab.scatter(test_labels, grid_cv.best_estimator_.predict(test_data), alpha=0.5, color = 'blue')
pylab.title('grid search')
pylab.xlim(-100,1100)
pylab.ylim(-100,1100)