Baseline model and assessment - Uses 100 days rather than cumsum versus unadjusted popularity

In [20]:
import pandas as pd
import numpy as np
%matplotlib inline

import matplotlib.pyplot as plt
In [13]:
df = pd.read_feather('../data/basemodel.feather')
df.head()
Out[13]:
track_id popularity all_streams log_all_streams
0 00kzys67XYXiB31cSP5jfo 40 2483 7.817223
1 00mc2RHScEYMEFlc7FRGaK 28 660 6.492240
2 04HzRAn3BJaIvmhpvc1GVT 51 5666 8.642239
3 04qrVtScdD4IBGSL5q6yEv 49 14832 9.604542
4 09aaq7feVx9Jykdw0f00QU 52 8853 9.088512
In [48]:
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
from sklearn.grid_search import GridSearchCV
from sklearn.metrics import r2_score
from sklearn.metrics import mean_squared_error
model = LinearRegression(fit_intercept = True)
x = df[['popularity']]
y = df[['log_all_streams']]

def PolynomialRegression(degree=2, **kwargs):
    return make_pipeline(PolynomialFeatures(degree), LinearRegression(**kwargs))

param_grid = {'polynomialfeatures__degree': np.arange(3), 'linearregression__normalize': [True, False]}

grid = GridSearchCV(PolynomialRegression(), param_grid, cv = 5, error_score=mean_squared_error)
grid.fit(x,y)
Out[48]:
GridSearchCV(cv=5,
       error_score=<function mean_squared_error at 0x7f2d9181fb70>,
       estimator=Pipeline(memory=None,
     steps=[('polynomialfeatures', PolynomialFeatures(degree=2, include_bias=True, interaction_only=False)), ('linearregression', LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False))]),
       fit_params={}, iid=True, n_jobs=1,
       param_grid={'polynomialfeatures__degree': array([0, 1, 2]), 'linearregression__normalize': [True, False]},
       pre_dispatch='2*n_jobs', refit=True, scoring=None, verbose=0)
In [49]:
model = grid.best_estimator_
y_pred = model.predict(x)

plt.scatter(y_pred, y_pred - y)
plt.hlines(y = 0, xmin = 6, xmax = 10)

rmse = np.sqrt(np.sum((y_pred - y)**2))
print(f'RMSE: {rmse}')
print(f'Rsq: {r2_score(y,y_pred)}')
RMSE: log_all_streams    8.756124
dtype: float64
Rsq: 0.3292778744281144
In [50]:
plt.scatter(x,y)
lim = plt.axis()
plt.scatter(x,y_pred, c = 'red')
Out[50]:
<matplotlib.collections.PathCollection at 0x7f2d88c74ba8>

Next iteration

  • Evaluate outlier at 0 popularity. It seems to skew the results. It looks like linear would be a good fit here actually
In [52]:
df.sort_values('popularity')
Out[52]:
track_id popularity all_streams log_all_streams
6 0A488iaPeDAUP5q7Jm3paF 0 3175 8.063063
41 1ekNZULmcBHp3WRNKft7ou 8 101 4.615121
11 0DPXH5sPDVwjsqfgvmi1yt 26 358 5.880533
37 1cinSNWNJeGVxMgUSNCHRT 27 1543 7.341484
1 00mc2RHScEYMEFlc7FRGaK 28 660 6.492240
26 0uc7dcChlOHGqfcgmQtD1k 29 1052 6.958448
25 0U1pfb8oRmhHazPuIOndaM 30 794 6.677083
36 1ceX0RJWaTob6mJuENTUVG 32 157 5.056246
34 17oEEVCQy3VGZuYIv4fk7g 34 115 4.744932
53 5FqevirebpKNGF5FQk60ey 35 22155 10.005818
31 0YjlkuZpp05Z9aZsoeTL3S 36 1718 7.448916
51 1TDS5WmnoAMCksGScA62rp 38 799 6.683361
15 0iHqFwZn8z4HvbjHJctOua 39 2213 7.702104
9 0D19xrl4GXZWih4NX5Yue8 40 591 6.381816
0 00kzys67XYXiB31cSP5jfo 40 2483 7.817223
49 1qLi7TR7RUGedFwV9b8sot 41 2490 7.820038
38 1dlip6LqrFE3cBdyMqQExf 41 611 6.415097
12 0e3y2auTf9hpAMlK9l9BWm 41 175 5.164786
21 0Qq6DG8zjPu8nl8AXi49lw 42 3868 8.260493
50 1QwgOsR7M0vVYO1mBZs9uP 44 1437 7.270313
42 1fNSjDh98pwR0HAkvIcDj3 44 15342 9.638349
14 0iHA83002w19QxhOIixKDy 44 22155 10.005818
27 0UvtpHJIvFGuCgJ9rV95Qe 44 5956 8.692154
28 0VUJYazoMnaZIu5HTQIuB6 44 2829 7.947679
17 0lvN2fIgifvC63C70WQZDz 45 454 6.118097
32 0ySovENVdl0e50eJDdQMML 45 580 6.363028
23 0rIZGjN9oQTyAwByKpeGBf 46 3806 8.244334
10 0D6I50oBN4opIAaPp0MRrb 47 8446 9.041448
8 0bPSRn4crnh5f1JhELPlyL 47 8609 9.060563
39 1Ea4QAgJoNCFHqNj7oCOon 47 580 6.363028
33 122lxLiuCUAdpaGOk2KSbe 48 2169 7.682022
5 0A1xaq9kcUeVZwXHDJAtH8 48 2263 7.724447
29 0WYZBUsTyhUkaH2eQ6HUlU 48 523 6.259581
16 0iUC7NOX8g5dXVRX61LmJW 49 2001 7.601402
47 1ONgRO7Mp49j33EAAMoK3i 49 1955 7.578145
3 04qrVtScdD4IBGSL5q6yEv 49 14832 9.604542
45 1KVQsZPeztZ7GnpVfqAnFX 50 27939 10.237779
20 0OmgaIr7HdNJpanSQbyKov 50 2165 7.680176
7 0A500BtVTgViTjhWS07yEr 50 11059 9.311000
2 04HzRAn3BJaIvmhpvc1GVT 51 5666 8.642239
4 09aaq7feVx9Jykdw0f00QU 52 8853 9.088512
30 0xhY4rD6Gj3djZRyT7T08b 53 1434 7.268223
44 1imBH4y5b85vL1mFDxBp9N 54 34178 10.439337
48 1OZWyPMwub90x2V6TzRIsz 54 9363 9.144521
18 0NsZlandaYpsQZ98GjymqZ 54 4063 8.309677
22 0rEwD7QVscNnz05ooEb0qB 55 3105 8.040769
43 1ie1M25b3I0Kvl1DQY6lbI 55 1824 7.508787
46 1lLuhJSggOEPVfSgfa9r2n 55 1453 7.281386
24 0Tt81ZbYRH0Aj04CJBRYWK 58 8902 9.094031
35 184HI8TB2GGFMkgOQvVwYW 58 9823 9.192482
19 0Nw0Z2VXKuiFSikzWvgqR6 59 11839 9.379154
40 1EDkPryAg1Sv2H2WNoKRLJ 60 3116 8.044305
52 4n8df1lKaP8on42bdQJHcz 60 12822 9.458918
13 0gOloXVox0hwdtty5VsCfS 62 39833 10.592451