{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"building_metadata = pd.read_csv(\"../input/ashrae-energy-prediction/building_metadata.csv\")\ntrain = pd.read_csv(\"../input/ashrae-energy-prediction/train.csv\")\nweather_train = pd.read_csv(\"../input/ashrae-energy-prediction/weather_train.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Original code from https://www.kaggle.com/gemartin/load-data-reduce-memory-usage by @gemartin\n\nfrom pandas.api.types import is_datetime64_any_dtype as is_datetime\nfrom pandas.api.types import is_categorical_dtype\n\ndef reduce_mem_usage(df, use_float16=False):\n    \"\"\"\n    Iterate through all the columns of a dataframe and modify the data type to reduce memory usage.        \n    \"\"\"\n    \n    start_mem = df.memory_usage().sum() / 1024**2\n    print(\"Memory usage of dataframe is {:.2f} MB\".format(start_mem))\n    \n    for col in df.columns:\n        if is_datetime(df[col]) or is_categorical_dtype(df[col]):\n            continue\n        col_type = df[col].dtype\n        \n        if col_type != object:\n            c_min = df[col].min()\n            c_max = df[col].max()\n            if str(col_type)[:3] == \"int\":\n                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:\n                    df[col] = df[col].astype(np.int8)\n                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:\n                    df[col] = df[col].astype(np.int16)\n                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:\n                    df[col] = df[col].astype(np.int32)\n                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:\n                    df[col] = df[col].astype(np.int64)  \n            else:\n                if use_float16 and c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:\n                    df[col] = df[col].astype(np.float16)\n                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:\n                    df[col] = df[col].astype(np.float32)\n                else:\n                    df[col] = df[col].astype(np.float64)\n        else:\n            df[col] = df[col].astype(\"category\")\n\n    end_mem = df.memory_usage().sum() / 1024**2\n    print(\"Memory usage after optimization is: {:.2f} MB\".format(end_mem))\n    print(\"Decreased by {:.1f}%\".format(100 * (start_mem - end_mem) / start_mem))\n    \n    return df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def intpo(df):\n    feat = [\"air_temperature\", \"dew_temperature\", \"precip_depth_1_hr\", \"sea_level_pressure\", \"wind_speed\"]\n    site_ids = df.site_id.unique()\n    df_new = pd.DataFrame()\n    for i in site_ids:\n        new = df[feat][df.site_id == i].interpolate(limit_direction='both', method='linear')\n        #new = new[feat].fillna((new[feat].median()), inplace=True)\n        df_new = pd.concat([df_new, new]).reset_index(drop = True)\n    \n    df_new[feat] = df_new[feat].fillna(df_new[feat].median())\n    df[feat] = df_new\n    return df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def med_fill(df):\n    feat = [\"cloud_coverage\", \"wind_direction\"]\n    site_ids = df.site_id.unique()\n    df_new = pd.DataFrame()\n    for i in site_ids:\n        new = df[feat][df.site_id == i].fillna((df[feat][df.site_id == i].median()))\n        df_new = pd.concat([df_new, new]).reset_index(drop = True)\n    \n    df_new = df_new.fillna(df_new.median())\n    df[feat] = df_new\n    return df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def time_edit(df):\n    df[\"timestamp\"] = pd.to_datetime(df[\"timestamp\"])\n    df[\"hour\"] = df[\"timestamp\"].dt.hour.astype(np.uint8)\n    df[\"weekday\"] = df[\"timestamp\"].dt.dayofweek.astype(np.uint8)\n    df[\"month\"] = df[\"timestamp\"].dt.month\n    \n    holidays = {\"2016-01-01\", \"2016-01-18\", \"2016-02-15\", \"2016-05-30\", \"2016-07-04\", \"2016-09-05\", \"2016-10-10\", \"2016-11-11\",\n               \"2016-11-24\", \"2016-11-25\", \"2016-12-25\", \"2017-01-02\", \"2017-01-16\", \"2017-02-20\", \"2017-05-29\", \"2017-07-04\",\n                \"2017-09-04\", \"2017-10-09\", \"2017-11-10\", \"2017-11-23\", \"2017-11-24\", \"2017-12-25\", \"2018-01-01\", \"2018-01-15\",\n                \"2018-02-19\", \"2018-05-28\", \"2018-07-04\", \"2018-09-03\", \"2018-10-08\", \"2018-11-12\", \"2018-11-22\", \"2018-11-23\",\n                \"2018-12-25\"}\n    df[\"is_holiday\"] = 0\n    df[\"is_holiday\"][df[\"timestamp\"].isin(holidays)] = 1\n    df['group'] = df['timestamp'].dt.month\n    df['group'].replace((1, 7), 1, inplace = True)\n    df['group'].replace((2, 8), 2, inplace = True)\n    df['group'].replace((3, 9), 3, inplace = True)\n    df['group'].replace((4, 10), 4, inplace = True)\n    df['group'].replace((5, 11), 5, inplace = True)\n    df['group'].replace((6, 12), 6, inplace = True)\n    \n    return df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"weather_train = intpo(weather_train)\nweather_train = med_fill(weather_train)\nweather_train['precip_depth_1_hr'][weather_train['precip_depth_1_hr'] == -1] = 0","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#https://www.kaggle.com/isaienkov/lightgbm-fe-1-19\ndef degToCompass(num):\n    val=int((num/22.5)+.5)\n    arr=[i for i in range(0,16)]\n    return arr[(val % 16)]\n\nweather_train['wind_direction'] = weather_train['wind_direction'].apply(degToCompass)\nweather_train[\"wind_direction\"] = weather_train['wind_direction'].astype(np.uint8)\n\nfrom sklearn import preprocessing\nle = preprocessing.LabelEncoder()\nbuilding_metadata[\"primary_use\"] = le.fit_transform(building_metadata[\"primary_use\"])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"building_metadata[\"square_feet\"] = np.log(building_metadata[\"square_feet\"])\ntrain[\"meter_reading_log\"] = np.log1p(train[\"meter_reading\"])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train = train.merge(building_metadata, on = 'building_id', how = 'left')\ntrain = train.merge(weather_train, on = ['site_id', 'timestamp'], how = 'left')\ntrain = time_edit(train)\n\ndel weather_train","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#https://www.kaggle.com/ragnar123/another-1-08-lb-no-leak\ndef make_is_bad_zero(Xy_subset, min_interval=48, summer_start=3000, summer_end=7500):\n    \"\"\"Helper routine for 'find_bad_zeros'.\n    \n    This operates upon a single dataframe produced by 'groupby'. We expect an \n    additional column 'meter_id' which is a duplicate of 'meter' because groupby \n    eliminates the original one.\"\"\"\n    meter = Xy_subset.meter_id.iloc[0]\n    is_zero = Xy_subset.meter_reading == 0\n    if meter == 0:\n        # Electrical meters should never be zero. Keep all zero-readings in this table so that\n        # they will all be dropped in the train set.\n        return is_zero\n\n    transitions = (is_zero != is_zero.shift(1))\n    all_sequence_ids = transitions.cumsum()\n    ids = all_sequence_ids[is_zero].rename(\"ids\")\n    if meter in [2, 3]:\n        # It's normal for steam and hotwater to be turned off during the summer\n        keep = set(ids[(Xy_subset.timestamp < summer_start) |\n                       (Xy_subset.timestamp > summer_end)].unique())\n        is_bad = ids.isin(keep) & (ids.map(ids.value_counts()) >= min_interval)\n    elif meter == 1:\n        time_ids = ids.to_frame().join(Xy_subset.timestamp).set_index(\"timestamp\").ids\n        is_bad = ids.map(ids.value_counts()) >= min_interval\n\n        # Cold water may be turned off during the winter\n        jan_id = time_ids.get(0, False)\n        dec_id = time_ids.get(8283, False)\n        if (jan_id and dec_id and jan_id == time_ids.get(500, False) and\n                dec_id == time_ids.get(8783, False)):\n            is_bad = is_bad & (~(ids.isin(set([jan_id, dec_id]))))\n    else:\n        raise Exception(f\"Unexpected meter type: {meter}\")\n\n    result = is_zero.copy()\n    result.update(is_bad)\n    return result\n\ndef find_bad_zeros(X, y):\n    \"\"\"Returns an Index object containing only the rows which should be deleted.\"\"\"\n    Xy = X.assign(meter_reading=y, meter_id=X.meter)\n    is_bad_zero = Xy.groupby([\"building_id\", \"meter\"]).apply(make_is_bad_zero)\n    return is_bad_zero[is_bad_zero].index.droplevel([0, 1])\n\ndef find_bad_sitezero(X):\n    \"\"\"Returns indices of bad rows from the early days of Site 0 (UCF).\"\"\"\n    return X[(X.timestamp < 3378) & (X.site_id == 0) & (X.meter == 0)].index\n\ndef find_bad_building1099(X, y):\n    \"\"\"Returns indices of bad rows (with absurdly high readings) from building 1099.\"\"\"\n    return X[(X.building_id == 1099) & (X.meter == 2) & (y > 3e4)].index\n\n# binds all together\ndef find_bad_rows(X, y):\n    return find_bad_zeros(X, y).union(find_bad_sitezero(X)).union(find_bad_building1099(X, y))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train[\"timestamp\"] = (train[\"timestamp\"] - pd.to_datetime(\"2016-01-01\")).dt.total_seconds() // 3600\nbad_rows = find_bad_rows(train.drop([\"meter_reading\"], axis = 1), train[\"meter_reading\"])\ntrain = train.drop(index = bad_rows)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train = reduce_mem_usage(train,use_float16=True)\nbuilding_metadata = reduce_mem_usage(building_metadata,use_float16=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"feat = list(train.columns.values)\nfeatures = [x for x in feat if x not in ['timestamp', 'meter_reading', 'year','group', \"meter_reading_log\"]]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn import metrics\nimport lightgbm as lgb\nfrom sklearn.model_selection import GroupKFold\nfrom tqdm import tqdm\nimport gc","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#https://www.kaggle.com/ragnar123/another-1-08-lb-no-leak\ndef run_lgbm(train, num_rounds = 1000, folds = 6):\n    kf = GroupKFold(n_splits = folds)\n    param =  {'num_leaves': 500,\n             'objective': 'regression',\n             'learning_rate': .03,\n             'boosting': 'gbdt',\n             'feature_fraction': .7,\n             'bagging_fraction': .1,\n             'bagging_freq': 5,\n             'n_jobs': 10,\n             'seed': 654321,\n             'metric': 'rmse'\n              }\n    \n    target = 'meter_reading_log'\n    categorical = ['building_id', 'meter', 'site_id', 'primary_use' , 'is_holiday', 'weekday', 'month']\n\n    models = []\n    oof = np.zeros(len(train))\n    for tr_idx, val_idx in tqdm(kf.split(train, groups = train['group']), total = folds):\n        tr_x, tr_y = train[features].iloc[tr_idx], train[target].iloc[tr_idx]\n        vl_x, vl_y = train[features].iloc[val_idx], train[target].iloc[val_idx]\n        tr_data = lgb.Dataset(tr_x, label = tr_y,  categorical_feature = categorical)\n        vl_data = lgb.Dataset(vl_x, label = vl_y,  categorical_feature = categorical)\n        clf = lgb.train(param, tr_data, num_rounds, valid_sets = [tr_data, vl_data], verbose_eval = 25, \n                        early_stopping_rounds = 50)\n        models.append(clf)\n        oof[val_idx] = clf.predict(vl_x)\n        gc.collect()\n    score = np.sqrt(metrics.mean_squared_error(train[target], np.clip(oof, a_min=0, a_max=None)))\n    \n    return models\n    \nmodels = run_lgbm(train)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test = pd.read_csv(\"../input/ashrae-energy-prediction/test.csv\")\nweather_test = pd.read_csv(\"../input/ashrae-energy-prediction/weather_test.csv\")\n\nweather_test = intpo(weather_test)\nweather_test = med_fill(weather_test)\nweather_test['precip_depth_1_hr'][weather_test['precip_depth_1_hr'] == -1] = 0\n\nweather_test['wind_direction'] = weather_test['wind_direction'].apply(degToCompass)\nweather_test[\"wind_direction\"] = weather_test['wind_direction'].astype(np.uint8)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test = reduce_mem_usage(test,use_float16=True)\nweather_test = reduce_mem_usage(weather_test,use_float16=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test = test.merge(building_metadata, on = 'building_id', how = 'left')\ntest = test.merge(weather_test, on = ['site_id', 'timestamp'], how = 'left')\ntest = time_edit(test)\ndel weather_test, building_metadata","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#https://www.kaggle.com/ragnar123/another-1-08-lb-no-leak\nresult = []\nstep_size = 50000\ni = 0\nfor j in tqdm(range(int(np.ceil(test.shape[0]/50000)))):\n    result.append(np.expm1(np.mean([model.predict(test[features].iloc[i : i + step_size]) for model in models], axis=0)))\n    i += step_size\n\nresult = np.concatenate(result)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission = pd.read_csv(\"../input/ashrae-energy-prediction/sample_submission.csv\")\nsubmission[\"meter_reading\"] = result\nsubmission.to_csv(\"submission.csv\", index = False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del models, result","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.models import Sequential\nfrom keras.layers import Dense, LSTM, Dropout, BatchNormalization\nfrom keras.callbacks import EarlyStopping, ModelCheckpoint\nfrom keras.optimizers import Adam, RMSprop\nfrom keras import backend as K\nfrom keras.losses import MSE","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def root_mean_squared_error(y_true, y_pred):\n        return K.sqrt(K.mean(K.square(y_pred - y_true)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def lstm_model(df):\n    \n    model = Sequential()\n    model.add(LSTM(units = 64, return_sequences=True, input_shape=(None, df.shape[1])))\n    model.add(Dropout(0.25))\n    model.add(Dense(64, activation='relu'))\n    model.add(LSTM(units = 64, return_sequences = True))\n    model.add(Dropout(0.2))\n    model.add(Dense(64, activation='relu'))\n    model.add(LSTM(units = 32))\n    model.add(Dropout(0.25))\n    model.add(Dense(1))\n    model.compile(optimizer = Adam(lr=0.01), loss = MSE, metrics = [root_mean_squared_error])\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test = test[features]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def run_model(train, test):\n    \n    kf = GroupKFold(n_splits = 6)\n    i = 0\n    results = np.zeros((test.shape[0], 5))\n    target = 'meter_reading_log'\n    model = lstm_model(train[features])\n    \n    for tr_idx, val_idx in tqdm(kf.split(train, groups = train['group']), total = 6):\n        K.clear_session()\n        tr_x, tr_y = train[features].iloc[tr_idx], train[target].iloc[tr_idx]\n        vl_x, vl_y = train[features].iloc[val_idx], train[target].iloc[val_idx]\n\n        tr_x, tr_y = tr_x.values[:], tr_y.values[:]\n        vl_x, vl_y = vl_x.values[:], vl_y.values[:]\n        tr_x = tr_x.reshape((tr_x.shape[0], 1, tr_x.shape[1]))\n        tr_y = tr_y.reshape((tr_y.shape[0], 1))\n        vl_x = vl_x.reshape((vl_x.shape[0], 1, vl_x.shape[1]))\n        vl_y = vl_y.reshape((vl_y.shape[0], 1))\n\n        rlst = EarlyStopping(monitor = 'val_root_mean_squared_error', min_delta = .0001, patience = 5, verbose = True, mode = 'min')\n        model.fit(tr_x, tr_y, batch_size = 512, epochs = 50, validation_data = [vl_x, vl_y], callbacks = [rlst], verbose=1)\n\n        results[i] = model.predict(test, batch_size=512)\n        i += 1\n    return results","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#results = run_model(train, test)\n#result_f = np.expm1(np.mean(results)).reshape(test.shape[0], 1)\n#result_f = np.concatenate(result_f)\n#submission = pd.read_csv(\"../input/ashrae-energy-prediction/sample_submission.csv\")\n#submission[\"meter_reading\"] = result_f\n#submission.to_csv(\"submission.csv\", index = False)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":1}