human
I am working on the file "BikeSharing-Linear.ipynb".
The first task is:
Try to add some custom features
Can you write Python program for it?

Write me a the Python program you requested?
assistant
#Here is the Python program you requested.

class FeatureExtractor(BaseEstimator, TransformerMixin):
    
    ohe = OneHotEncoder(categories='auto', sparse=False)
    scaler = StandardScaler()
    
    categorical_columns = ["week_day", "hour", "season", "weather"]
    numerical_columns = ["temp", "atemp", "humidity", "windspeed"]
    
    def _add_features(self, X):
        X["week_day"] = X.datetime.apply(lambda dttm: parse(dttm).weekday())
        X["hour"] = X.datetime.apply(lambda dttm: parse(dttm).hour)
        
    def _combine(self, *feature_groups):
        return np.hstack(feature_groups)
    
    def collect_stats(self, X):
        self._add_features(X)
        self.ohe.fit(X[self.categorical_columns])
        self.scaler.fit(X[self.numerical_columns])
    
    def fit(self, X, y=None):
        return self    
        
    def transform(self, X, y=None):
        self._add_features(X)
        custom_binary_features = self.ohe.transform(X[self.categorical_columns])
        scaled_features = self.scaler.transform(X[self.numerical_columns])
        return self._combine(
            custom_binary_features, 
            scaled_features,
            X[["holiday", "workingday"]].values
        )  

exctractor = FeatureExtractor()
exctractor.collect_stats(df)
clf = Pipeline([
    ("extractor", exctractor),
    ("regression", linear_model.ElasticNet()),
])

param_grid = {
    "regression__alpha": np.logspace(-3, 2, 10),
    "regression__l1_ratio": np.linspace(0, 1, 10)
}
pd.options.mode.chained_assignment = None
scorerer = make_scorer(rmsle, greater_is_better=False)
researcher = GridSearchCV(clf, param_grid, scoring=scorerer, cv=5, n_jobs=4, verbose=1, refit=False)
researcher.fit(df, df["count"].values)

researcher.best_score_

researcher.best_params_

scorerer = make_scorer(mean_squared_error, greater_is_better=False)
scores = cross_val_score(clf, df, df["count"].values, cv=5, n_jobs=4, scoring=scorerer)
np.mean((-np.array(scores)) ** .5)