<jupyter_start><jupyter_text>Rating vs Reviews<jupyter_code>x=train_data.Reviews.to_numpy()
y=train_data.Rating.to_numpy()
plt.scatter(x,y)
x=x/30.0
y=y/5.0
plt.scatter(x,y)
m,c=np.random.random(),np.random.random()
def learn(x,y,m,c,epoch):
    for i in range(epoch):
        error=y-(m*x+c)
        x_error=(y-(m*x+c))*x
        error=np.sum(error)/len(x)
        x_error=np.sum(x_error)/len(x)
        learning_rate = 0.01
        delta_m= learning_rate *x_error
        delta_c =learning_rate*error
        m+=delta_m
        c+=delta_c
    return(m,c)   
m,c=learn(x,y,m,c,20000)
x1=[0,1]
y1=[0*m+c,1*m+c]
plt.scatter(x,y)
plt.plot(x1,y1, color='red')<jupyter_output><empty_output><jupyter_text>Rating vs Installs<jupyter_code>x=train_data.Installs.to_numpy()
y=train_data.Rating.to_numpy()
plt.scatter(x,y)
x=x/15.0
y=y/5.0
plt.scatter(x,y)
m,c=np.random.random(),np.random.random()
def learn(x,y,m,c,epoch):
    for i in range(epoch):
        error=y-(m*x+c)
        x_error=(y-(m*x+c))*x
        error=np.sum(error)/len(x)
        x_error=np.sum(x_error)/len(x)
        learning_rate = 0.01
        delta_m= learning_rate *x_error
        delta_c =learning_rate*error
        m+=delta_m
        c+=delta_c
    return(m,c)   
m,c=learn(x,y,m,c,20000)
x1=[0,1]
y1=[0*m+c,1*m+c]
plt.scatter(x,y)
plt.plot(x1,y1, color='red')<jupyter_output><empty_output><jupyter_text>Rating vs App size<jupyter_code>x=train_data.Size.to_numpy()
y=train_data.Rating.to_numpy()
plt.scatter(x,y)
x=x/15.0
y=y/6.0
plt.scatter(x,y)
m,c=np.random.random(),np.random.random()
def learn(x,y,m,c,epoch):
    for i in range(epoch):
        error=y-(m*x+c)
        x_error=(y-(m*x+c))*x
        error=np.sum(error)/len(x)
        x_error=np.sum(x_error)/len(x)
        learning_rate = 0.01
        delta_m= learning_rate *x_error
        delta_c =learning_rate*error
        m+=delta_m
        c+=delta_c
    return(m,c)   
m,c=learn(x,y,m,c,20000)
x1=[0,1]
y1=[0*m+c,1*m+c]
plt.scatter(x,y)
plt.plot(x1,y1,color='red')<jupyter_output><empty_output><jupyter_text>Rating vs Category<jupyter_code>x=train_data.Category.to_numpy()
y=train_data.Rating.to_numpy()
plt.scatter(x,y)
x=x/40.0
y=y/6.0
plt.scatter(x,y)
m,c=np.random.random(),np.random.random()
def learn(x,y,m,c,epoch):
    for i in range(epoch):
        error=y-(m*x+c)
        x_error=(y-(m*x+c))*x
        error=np.sum(error)/len(x)
        x_error=np.sum(x_error)/len(x)
        learning_rate = 0.01
        delta_m= learning_rate *x_error
        delta_c =learning_rate*error
        m+=delta_m
        c+=delta_c
    return(m,c)   
m,c=learn(x,y,m,c,20000)
x1=[0,1]
y1=[0*m+c,1*m+c]
plt.scatter(x,y)
plt.plot(x1,y1,color='red')<jupyter_output><empty_output><jupyter_text>Multiple Linear Regression<jupyter_code>from sklearn import linear_model
df1=pd.DataFrame(train_data,columns=['Rating','Size','Category','Reviews'])
x=df1.drop(['Rating'],axis=1).values
y=df1['Rating'].values
print(x)
print(y)
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3,random_state=0)
from sklearn.linear_model import LinearRegression
ml=LinearRegression()
ml.fit(x_train,y_train)
y_pred=ml.predict(x_test)
plt.scatter(y_test,y_pred)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.title('Actual vs Predicted')
pred_y_df=pd.DataFrame({'Actual Value':y_test,'Predicted value':y_pred,'Difference': y_test-y_pred})
pred_y_df[0:20]<jupyter_output><empty_output><jupyter_text>Linear Regression<jupyter_code># Train Test Split
# Split data to 70% of the training and 30% for the validation
y = train_data['Rating']
X = train_data.drop(columns=['Rating'])
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
print("Training Set Dimensions:", X_train.shape)
print("Validation Set Dimensions:", X_test.shape)
model = LinearRegression()
model.fit(X_train, y_train)
y_pred=model.predict(X_test)
y_pred[1:11]
# Measure mean squared error for validation sets
print('Mean squared Error for Test Set:', mean_squared_error(y_test, y_pred))
from sklearn.metrics import mean_absolute_error
# Measure mean absolute error for validation sets
print('Mean absolute Error for Test Set:', mean_absolute_error(y_test, y_pred))
from sklearn.metrics import r2_score
# Measure R-squared for validation sets
print('R-squared Error for Test Set:', r2_score(y_test, y_pred))
import math
# Measure root mean squared error for validation sets
print('Root mean squared Error for Test Set:', math.sqrt(mean_squared_error(y_test, y_pred)))<jupyter_output>Root mean squared Error for Test Set: 0.47490865828789797<jupyter_text>KNN Model: K-Nearest Neighbors Model<jupyter_code>from sklearn.neighbors import KNeighborsRegressor
# Fit model
knr = KNeighborsRegressor(n_neighbors = 5)
knr.fit(X_train, y_train)

# Measure mean squared error for training and validation sets
print('Mean squared Error for Training Set:', mean_squared_error(y_train, knr.predict(X_train)))
print('Mean squared Error for Test Set:', mean_squared_error(y_test, knr.predict(X_test)))<jupyter_output>Mean squared Error for Training Set: 0.1618615339949217
Mean squared Error for Test Set: 0.24331168271222978<jupyter_text>Random Forest Regressor<jupyter_code>from sklearn.ensemble import RandomForestRegressor
# Train Random Forest Regressor
randomf = RandomForestRegressor(n_estimators=300)
randomf.fit(X_train, y_train)

# Measure mean squared error for training and validation sets
print('Mean squared Error for Training Set:', mean_squared_error(y_train, randomf.predict(X_train)))
print('Mean squared Error for Test Set:', mean_squared_error(y_test, randomf.predict(X_test)))
# Important features for random forest regressor
for name, importance in zip(X.columns, randomf.feature_importances_):
    print('feature:', name, "=", importance)
    
importances = randomf.feature_importances_
indices = np.argsort(importances)
features = X.columns
plt.figure(figsize=(6, 4))
plt.title('Feature Importances')
plt.barh(range(len(indices)), importances[indices], color='g', align='center')
plt.yticks(range(len(indices)), [features[i] for i in indices])
plt.xlabel('Relative Importance')
plt.show()<jupyter_output>feature: Category = 0.09787285756361797
feature: Reviews = 0.3393285584647029
feature: Size = 0.29473025819616694
feature: Installs = 0.10101916829515543
feature: Type = 0.005276351932548129
feature: Price = 0.02655492907226782
feature: Content Rating = 0.025566720490326933
feature: Genres = 0.10965115598521398<jupyter_text>Bagging Regressor<jupyter_code>from sklearn.ensemble import BaggingRegressor 
# Fit model
br = BaggingRegressor(random_state=300)
                            
br.fit(X_train, y_train)

# Measure mean squared error for training and validation sets
print('Mean squared Error for Training Set:', mean_squared_error(y_train, br.predict(X_train)))
print('Mean squared Error for Test Set:', mean_squared_error(y_test, br.predict(X_test)))<jupyter_output>Mean squared Error for Training Set: 0.03989299884581395
Mean squared Error for Test Set: 0.21711816904674575<jupyter_text>Conclusion Above all techniques, Random Forest Regressor performed best with testing mean squared error of 0.19 which is also confirmed with the help of Lazy-Library which tells us which model is best among all types.![image.png](attachment:image.png)  P1 (Reviews)<jupyter_code>X = train_data.iloc[:, 2:3].values
Y = train_data.iloc[:, 1].values
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, random_state=0)
from sklearn.linear_model import LinearRegression
regressor = LinearRegression()
regressor.fit(x_train, y_train)
regressor.predict(x_test)
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from math import sqrt
print("Coeff: %0.3f" % regressor.coef_)
print("Intercept: %0.3f" % regressor.intercept_)
print("R2 score : %.3f" % r2_score(y_test, regressor.predict(x_test)))
print("MSE: %.3f" % mean_squared_error(y_test, regressor.predict(x_test)))
print("RMSE: %.3f" % sqrt(mean_squared_error(y_test, regressor.predict(x_test))))
print("MAE: %.3f" % sqrt(mean_absolute_error(y_test, regressor.predict(x_test))))
#AIC,BIC,RSS
y = train_data['Rating']

#define predictor variables
x = train_data[['Reviews']]

#add constant to predictor variables
x = sm.add_constant(x)

#fit regression model
model = sm.OLS(y, x).fit()

#view AIC of model
print(model.aic)
print(model.bic)
print(model.ssr)
model = LinearRegression()
X, y = train_data[["Reviews"]], train_data.Rating
model.fit(X, y)

#display adjusted R-squared
1 - (1-model.score(X, y))*(len(y)-1)/(len(y)-X.shape[1]-1)
#cp

m=len(Y)
p=1
hat_sigma_squared=(1/(m-p-1))*2477.032016599371
Cp=(1/m)*(2477.032016599371+2* hat_sigma_squared)
Cp<jupyter_output><empty_output><jupyter_text>P2 (Installs)<jupyter_code>X = train_data.iloc[:, 4:5].values
Y = train_data.iloc[:, 1].values
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, random_state=0)
from sklearn.linear_model import LinearRegression
regressor = LinearRegression()
regressor.fit(x_train, y_train)
regressor.predict(x_test)
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from math import sqrt
print("Coeff: %0.3f" % regressor.coef_)
print("Intercept: %0.3f" % regressor.intercept_)
print("R2 score : %.3f" % r2_score(y_test, regressor.predict(x_test)))
print("MSE: %.3f" % mean_squared_error(y_test, regressor.predict(x_test)))
print("RMSE: %.3f" % sqrt(mean_squared_error(y_test, regressor.predict(x_test))))
print("MAE: %.3f" % sqrt(mean_absolute_error(y_test, regressor.predict(x_test))))
#AIC,BIC,RSS
y = train_data['Rating']

#define predictor variables
x = train_data[['Installs']]

#add constant to predictor variables
x = sm.add_constant(x)

#fit regression model
model = sm.OLS(y, x).fit()

#view AIC of model
print(model.aic)
print(model.bic)
print(model.ssr)
model = LinearRegression()
X, y = train_data[["Reviews"]], train_data.Rating
model.fit(X, y)

#display adjusted R-squared
1 - (1-model.score(X, y))*(len(y)-1)/(len(y)-X.shape[1]-1)
#cp

m=len(Y)
p=1
hat_sigma_squared=(1/(m-p-1))*2482.0304240419223
Cp=(1/m)*(2482.0304240419223+2* hat_sigma_squared)
Cp<jupyter_output><empty_output><jupyter_text>P1+P2 (Reviews and Installs)<jupyter_code>X = train_data.iloc[:, 2:5:2].values
Y = train_data.iloc[:, 1].values
X.shape
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, random_state=0)
from sklearn.linear_model import LinearRegression
regressor = LinearRegression()
regressor.fit(x_train, y_train)
regressor.predict(x_test)
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from math import sqrt
print( regressor.coef_)
print("Intercept: %0.3f" % regressor.intercept_)
print("R2 score : %.3f" % r2_score(y_test, regressor.predict(x_test)))
print("MSE: %.3f" % mean_squared_error(y_test, regressor.predict(x_test)))
print("RMSE: %.3f" % sqrt(mean_squared_error(y_test, regressor.predict(x_test))))
print("MAE: %.3f" % sqrt(mean_absolute_error(y_test, regressor.predict(x_test))))
#AIC,BIC,RSS
y = train_data['Rating']

#define predictor variables
x = train_data[['Installs','Reviews']]

#add constant to predictor variables
x = sm.add_constant(x)

#fit regression model
model = sm.OLS(y, x).fit()

#view AIC of model
print(model.aic)
print(model.bic)
print(model.ssr)
model = LinearRegression()
X, y = train_data[["Reviews"]], train_data.Rating
model.fit(X, y)

#display adjusted R-squared
1 - (1-model.score(X, y))*(len(y)-1)/(len(y)-X.shape[1]-1)
#cp

m=len(Y)
p=2
hat_sigma_squared=(1/(m-p-1))*2476.7734899504253
Cp=(1/m)*(2476.7734899504253+2* 2*hat_sigma_squared)
Cp<jupyter_output><empty_output><jupyter_text>All Predictors<jupyter_code>X = train_data.iloc[:, 2:].values
Y = train_data.iloc[:, 1].values
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, random_state=0)
from sklearn.linear_model import LinearRegression
regressor = LinearRegression()
regressor.fit(x_train, y_train)
regressor.predict(x_test)
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from math import sqrt
print( regressor.coef_)
print("Intercept: %0.3f" % regressor.intercept_)
print("R2 score : %.3f" % r2_score(y_test, regressor.predict(x_test)))
print("MSE: %.3f" % mean_squared_error(y_test, regressor.predict(x_test)))
print("RMSE: %.3f" % sqrt(mean_squared_error(y_test, regressor.predict(x_test))))
print("MAE: %.3f" % sqrt(mean_absolute_error(y_test, regressor.predict(x_test))))
#AIC,BIC,RSS
y = train_data['Rating']

#define predictor variables
x = train_data[['Installs','Reviews','Size','Type','Price','Content Rating','Genres']]

#add constant to predictor variables
x = sm.add_constant(x)

#fit regression model
model = sm.OLS(y, x).fit()

#view AIC of model
print(model.aic)
print(model.bic)
print(model.ssr)
model = LinearRegression()
X, y = train_data[["Reviews"]], train_data.Rating
model.fit(X, y)

#display adjusted R-squared
1 - (1-model.score(X, y))*(len(y)-1)/(len(y)-X.shape[1]-1)
#cp

m=len(Y)
p=7
hat_sigma_squared=(1/(m-p-1))*2476.7734899504253
Cp=(1/m)*(2476.7734899504253+2* 7*hat_sigma_squared)
Cp<jupyter_output><empty_output><jupyter_text>Pzero<jupyter_code>y = train_data['Rating']
y_zero = np.full((len(train_data.Rating),1),train_data.Rating.mean())
from sklearn.linear_model import LinearRegression
regressor = LinearRegression()
regressor.fit(y_zero, y)
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from math import sqrt
print( regressor.coef_)
print("Intercept: %0.3f" % regressor.intercept_)
print("R2 score : %.3f" % r2_score(y, y_zero))
print("MSE: %.3f" % mean_squared_error(y, y_zero))
print("RMSE: %.3f" % sqrt(mean_squared_error(y, y_zero)))
print("MAE: %.3f" % sqrt(mean_absolute_error(y, y_zero)))
#AIC,BIC,RSS
y = train_data['Rating']

#define predictor variables
x = y_zero

#add constant to predictor variables
x = sm.add_constant(x)

#fit regression model
model = sm.OLS(y, x).fit()

#view AIC of model
print(model.aic)
print(model.bic)
print(model.ssr)
model = LinearRegression()
X, y = y_zero, train_data.Rating
model.fit(X, y)

#display adjusted R-squared
1 - (1-model.score(X, y))*(len(y)-1)/(len(y)-X.shape[1]-1)
#cp

m=len(y)
p=0
hat_sigma_squared=(1/(m-p-1))*2488.73631830937
Cp=(1/m)*(2488.73631830937+2*0* hat_sigma_squared)
Cp<jupyter_output><empty_output><jupyter_text>Ridge Regression  For  P1 (Reviews)<jupyter_code>X = train_data[['Reviews']]
Y = train_data['Rating']
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(X,Y,test_size=0.30,random_state=1)
print(X_train.shape, X_test.shape, y_train.shape,y_test.shape)
from sklearn.linear_model import Ridge
ridgeReg=Ridge(alpha=0.05, normalize=True)
ridgeReg.fit(X_train,y_train)
pred=ridgeReg.predict(X_test)
mse=np.mean((pred-y_test)**2)
mse
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from math import sqrt
print(ridgeReg.coef_)
print("Intercept: %0.3f" % ridgeReg.intercept_)
print("R2 score : %.3f" % r2_score(y_test,ridgeReg.predict(X_test)))
print("MSE: %.3f" % mean_squared_error(y_test, ridgeReg.predict(X_test)))
print("RMSE: %.3f" % sqrt(mean_squared_error(y_test, ridgeReg.predict(X_test))))
print("MAE: %.3f" % sqrt(mean_absolute_error(y_test, ridgeReg.predict(X_test))))
import statsmodels.api as sm
X_train_sm=sm.add_constant(X_train)
lr=sm.OLS(y_train,X_train_sm).fit()
lr.params
print(lr.ssr)
#cp

m=len(Y)
p=1
hat_sigma_squared=(1/(m-p-1))*1742.9957318861946
Cp=(1/m)*(1742.9957318861946+2*1* hat_sigma_squared)
Cp
lr.summary()<jupyter_output><empty_output><jupyter_text>For  P2 (Installs)<jupyter_code>X = train_data[['Installs']]
Y = train_data['Rating']
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(X,Y,test_size=0.30,random_state=1)
print(X_train.shape, X_test.shape, y_train.shape,y_test.shape)
from sklearn.linear_model import Ridge
ridgeReg=Ridge(alpha=0.05, normalize=True)
ridgeReg.fit(X_train,y_train)
pred=ridgeReg.predict(X_test)
mse=np.mean((pred-y_test)**2)
mse
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from math import sqrt
print(ridgeReg.coef_)
print("Intercept: %0.3f" % ridgeReg.intercept_)
print("R2 score : %.3f" % r2_score(y_test,ridgeReg.predict(X_test)))
print("MSE: %.3f" % mean_squared_error(y_test, ridgeReg.predict(X_test)))
print("RMSE: %.3f" % sqrt(mean_squared_error(y_test, ridgeReg.predict(X_test))))
print("MAE: %.3f" % sqrt(mean_absolute_error(y_test, ridgeReg.predict(X_test))))
import statsmodels.api as sm
X_train_sm=sm.add_constant(X_train)
lr=sm.OLS(y_train,X_train_sm).fit()
lr.params
print(lr.ssr)
#cp

m=len(Y)
p=1
hat_sigma_squared=(1/(m-p-1))*1746.6225916651158
Cp=(1/m)*(1746.6225916651158+2*1* hat_sigma_squared)
Cp
lr.summary()<jupyter_output><empty_output><jupyter_text>For P3 (Size)<jupyter_code>X = train_data[['Size']]
Y = train_data['Rating']
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(X,Y,test_size=0.30,random_state=1)
print(X_train.shape, X_test.shape, y_train.shape,y_test.shape)
from sklearn.linear_model import Ridge
ridgeReg=Ridge(alpha=0.05, normalize=True)
ridgeReg.fit(X_train,y_train)
pred=ridgeReg.predict(X_test)
mse=np.mean((pred-y_test)**2)
mse
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from math import sqrt
print(ridgeReg.coef_)
print("Intercept: %0.3f" % ridgeReg.intercept_)
print("R2 score : %.3f" % r2_score(y_test,ridgeReg.predict(X_test)))
print("MSE: %.3f" % mean_squared_error(y_test, ridgeReg.predict(X_test)))
print("RMSE: %.3f" % sqrt(mean_squared_error(y_test, ridgeReg.predict(X_test))))
print("MAE: %.3f" % sqrt(mean_absolute_error(y_test, ridgeReg.predict(X_test))))
import statsmodels.api as sm
X_train_sm=sm.add_constant(X_train)
lr=sm.OLS(y_train,X_train_sm).fit()
lr.params
print(lr.ssr)
#cp

m=len(Y)
p=1
hat_sigma_squared=(1/(m-p-1))*1739.5159280750015
Cp=(1/m)*(1739.5159280750015+2*1* hat_sigma_squared)
Cp
lr.summary()<jupyter_output><empty_output><jupyter_text>Lasso Regression  For P1 (Reviews)<jupyter_code>X = train_data[['Reviews']]
Y = train_data['Rating']
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(X,Y,test_size=0.30,random_state=1)
print(X_train.shape, X_test.shape, y_train.shape,y_test.shape)
from sklearn.linear_model import Lasso
lassoReg=Lasso(alpha=0.05, normalize=True)
lassoReg.fit(X_train,y_train)
laspred=lassoReg.predict(X_test)
las_mse=np.mean((laspred-y_test)**2)
las_mse
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from math import sqrt
print("Coeffiecient: %0.3f" % lassoReg.coef_)
print("Intercept: %0.3f" % lassoReg.intercept_)
print("R2 score : %.3f" % r2_score(y_test,lassoReg.predict(X_test)))
print("MSE: %.3f" % mean_squared_error(y_test, lassoReg.predict(X_test)))
print("RMSE: %.3f" % sqrt(mean_squared_error(y_test, lassoReg.predict(X_test))))
print("MAE: %.3f" % sqrt(mean_absolute_error(y_test, lassoReg.predict(X_test))))
import statsmodels.api as sm
X_train_sm=sm.add_constant(X_train)
lr=sm.OLS(y_train,X_train_sm).fit()
lr.params
print(lr.ssr)
#cp

m=len(Y)
p=1
hat_sigma_squared=(1/(m-p-1))*1742.9957318861946
Cp=(1/m)*(1742.9957318861946+2*1* hat_sigma_squared)
Cp
lr.summary()<jupyter_output><empty_output><jupyter_text>For P2 (Installs)<jupyter_code>X = train_data[['Installs']]
Y = train_data['Rating']
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(X,Y,test_size=0.30,random_state=1)
print(X_train.shape, X_test.shape, y_train.shape,y_test.shape)
from sklearn.linear_model import Lasso
lassoReg=Lasso(alpha=0.05, normalize=True)
lassoReg.fit(X_train,y_train)
laspred=lassoReg.predict(X_test)
las_mse=np.mean((laspred-y_test)**2)
las_mse
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from math import sqrt
print("Coeffiecient: %0.3f" % lassoReg.coef_)
print("Intercept: %0.3f" % lassoReg.intercept_)
print("R2 score : %.3f" % r2_score(y_test,lassoReg.predict(X_test)))
print("MSE: %.3f" % mean_squared_error(y_test, lassoReg.predict(X_test)))
print("RMSE: %.3f" % sqrt(mean_squared_error(y_test, lassoReg.predict(X_test))))
print("MAE: %.3f" % sqrt(mean_absolute_error(y_test, lassoReg.predict(X_test))))
import statsmodels.api as sm
X_train_sm=sm.add_constant(X_train)
lr=sm.OLS(y_train,X_train_sm).fit()
lr.params
print(lr.ssr)
#cp

m=len(Y)
p=1
hat_sigma_squared=(1/(m-p-1))*1746.6225916651158
Cp=(1/m)*(1746.6225916651158+2*1* hat_sigma_squared)
Cp
lr.summary()<jupyter_output><empty_output><jupyter_text>For P3 (Size)<jupyter_code>X = train_data[['Size']]
Y = train_data['Rating']
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(X,Y,test_size=0.30,random_state=1)
print(X_train.shape, X_test.shape, y_train.shape,y_test.shape)
from sklearn.linear_model import Lasso
lassoReg=Lasso(alpha=0.05, normalize=True)
lassoReg.fit(X_train,y_train)
laspred=lassoReg.predict(X_test)
las_mse=np.mean((laspred-y_test)**2)
las_mse
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from math import sqrt
print("Coeffiecient: %0.3f" % lassoReg.coef_)
print("Intercept: %0.3f" % lassoReg.intercept_)
print("R2 score : %.3f" % r2_score(y_test,lassoReg.predict(X_test)))
print("MSE: %.3f" % mean_squared_error(y_test, lassoReg.predict(X_test)))
print("RMSE: %.3f" % sqrt(mean_squared_error(y_test, lassoReg.predict(X_test))))
print("MAE: %.3f" % sqrt(mean_absolute_error(y_test, lassoReg.predict(X_test))))
import statsmodels.api as sm
X_train_sm=sm.add_constant(X_train)
lr=sm.OLS(y_train,X_train_sm).fit()
lr.params
print(lr.ssr)
#cp

m=len(Y)
p=1
hat_sigma_squared=(1/(m-p-1))*1739.5159280750015
Cp=(1/m)*(1739.5159280750015+2*1* hat_sigma_squared)
Cp
lr.summary()<jupyter_output><empty_output><jupyter_text>Polynomial Regression  For P1 (Reviews)<jupyter_code>X = train_data[['Reviews']]
Y = train_data['Rating']
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(X,Y,test_size=0.3,random_state=0)
from sklearn.preprocessing import PolynomialFeatures
polynom=PolynomialFeatures(degree=5)
X_polynom=polynom.fit_transform(X_train)
X_polynom
PolyRegr=LinearRegression()
PolyRegr.fit(X_polynom,y_train)
y_predict_polyr=PolyRegr.predict(polynom.fit_transform(X_test))
from sklearn import metrics
r_square=metrics.r2_score(y_test,y_predict_polyr)
r_square
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from math import sqrt
print(PolyRegr.coef_)
print("Intercept: %0.3f" % PolyRegr.intercept_)
print("R2 score : %.3f" % r2_score(y_test, PolyRegr.predict(polynom.fit_transform(X_test))))
print("MSE: %.3f" % mean_squared_error(y_test, PolyRegr.predict(polynom.fit_transform(X_test))))
print("RMSE: %.3f" % sqrt(mean_squared_error(y_test, PolyRegr.predict(polynom.fit_transform(X_test)))))
print("MAE: %.3f" % sqrt(mean_absolute_error(y_test, PolyRegr.predict(polynom.fit_transform(X_test)))))
plt.scatter(X_train, y_train,color='red')
plt.plot(X_train, PolyRegr.predict(polynom.fit_transform(X_train)),color='blue')
import statsmodels.api as sm
X_train_sm=sm.add_constant(X_polynom)
lr=sm.OLS(y_train,X_train_sm).fit()
lr.params
print(lr.ssr)
#cp

m=len(Y)
p=1
hat_sigma_squared=(1/(m-p-1))*1697.2194190803843
Cp=(1/m)*(1697.2194190803843+2*1* hat_sigma_squared)
Cp

lr.summary()<jupyter_output><empty_output><jupyter_text>For P2 (Installs)<jupyter_code>X = train_data[['Installs']]
Y = train_data['Rating']
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(X,Y,test_size=0.3,random_state=0)
from sklearn.preprocessing import PolynomialFeatures
polynom=PolynomialFeatures(degree=5)
X_polynom=polynom.fit_transform(X_train)
X_polynom
PolyRegr=LinearRegression()
PolyRegr.fit(X_polynom,y_train)
y_predict_polyr=PolyRegr.predict(polynom.fit_transform(X_test))
from sklearn import metrics
r_square=metrics.r2_score(y_test,y_predict_polyr)
r_square
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from math import sqrt
print(PolyRegr.coef_)
print("Intercept: %0.3f" % PolyRegr.intercept_)
print("R2 score : %.3f" % r2_score(y_test, PolyRegr.predict(polynom.fit_transform(X_test))))
print("MSE: %.3f" % mean_squared_error(y_test, PolyRegr.predict(polynom.fit_transform(X_test))))
print("RMSE: %.3f" % sqrt(mean_squared_error(y_test, PolyRegr.predict(polynom.fit_transform(X_test)))))
print("MAE: %.3f" % sqrt(mean_absolute_error(y_test, PolyRegr.predict(polynom.fit_transform(X_test)))))
plt.scatter(X_train, y_train,color='red')
plt.plot(X_train, PolyRegr.predict(polynom.fit_transform(X_train)),color='blue')
import statsmodels.api as sm
X_train_sm=sm.add_constant(X_polynom)
lr=sm.OLS(y_train,X_train_sm).fit()
lr.params
print(lr.ssr)
#cp

m=len(Y)
p=1
hat_sigma_squared=(1/(m-p-1))*1689.8477131108657
Cp=(1/m)*(1689.8477131108657+2*1* hat_sigma_squared)
Cp
lr.summary()<jupyter_output><empty_output><jupyter_text>For P3 (Size)<jupyter_code>X = train_data[['Size']]
Y = train_data['Rating']
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(X,Y,test_size=0.3,random_state=0)
from sklearn.preprocessing import PolynomialFeatures
polynom=PolynomialFeatures(degree=3)
X_polynom=polynom.fit_transform(X_train)
X_polynom
PolyRegr=LinearRegression()
PolyRegr.fit(X_polynom,y_train)
y_predict_polyr=PolyRegr.predict(polynom.fit_transform(X_test))
from sklearn import metrics
r_square=metrics.r2_score(y_test,y_predict_polyr)
r_square
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from math import sqrt
print(PolyRegr.coef_)
print("Intercept: %0.3f" % PolyRegr.intercept_)
print("R2 score : %.3f" % r2_score(y_test, PolyRegr.predict(polynom.fit_transform(X_test))))
print("MSE: %.3f" % mean_squared_error(y_test, PolyRegr.predict(polynom.fit_transform(X_test))))
print("RMSE: %.3f" % sqrt(mean_squared_error(y_test, PolyRegr.predict(polynom.fit_transform(X_test)))))
print("MAE: %.3f" % sqrt(mean_absolute_error(y_test, PolyRegr.predict(polynom.fit_transform(X_test)))))
plt.scatter(X_train, y_train,color='red')
plt.plot(X_train, PolyRegr.predict(polynom.fit_transform(X_train)),color='blue')
import statsmodels.api as sm
X_train_sm=sm.add_constant(X_polynom)
lr=sm.OLS(y_train,X_train_sm).fit()
lr.params
print(lr.ssr)
#cp

m=len(Y)
p=1
hat_sigma_squared=(1/(m-p-1))*1726.128598259959
Cp=(1/m)*(1726.128598259959+2*1* hat_sigma_squared)
Cp
lr.summary()<jupyter_output><empty_output><jupyter_text>For All Predictors<jupyter_code>X = train_data[['Installs','Reviews','Size','Type','Price','Content Rating','Genres']]
Y = train_data['Rating']
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(X,Y,test_size=0.3,random_state=0)
from sklearn.preprocessing import PolynomialFeatures
polynom=PolynomialFeatures(degree=1)
X_polynom=polynom.fit_transform(X_train)
X_polynom
PolyRegr=LinearRegression()
PolyRegr.fit(X_polynom,y_train)
y_predict_polyr=PolyRegr.predict(polynom.fit_transform(X_test))
from sklearn import metrics
r_square=metrics.r2_score(y_test,y_predict_polyr)
r_square
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from math import sqrt
print(PolyRegr.coef_)
print("Intercept: %0.3f" % PolyRegr.intercept_)
print("R2 score : %.3f" % r2_score(y_test, PolyRegr.predict(polynom.fit_transform(X_test))))
print("MSE: %.3f" % mean_squared_error(y_test, PolyRegr.predict(polynom.fit_transform(X_test))))
print("RMSE: %.3f" % sqrt(mean_squared_error(y_test, PolyRegr.predict(polynom.fit_transform(X_test)))))
print("MAE: %.3f" % sqrt(mean_absolute_error(y_test, PolyRegr.predict(polynom.fit_transform(X_test)))))
import statsmodels.api as sm
X_train_sm=sm.add_constant(X_polynom)
lr=sm.OLS(y_train,X_train_sm).fit()
lr.params
print(lr.ssr)
#cp

m=len(Y)
p=7
hat_sigma_squared=(1/(m-p-1))*1716.3094780776185
Cp=(1/m)*(1716.3094780776185+2*7* hat_sigma_squared)
Cp
lr.summary()<jupyter_output><empty_output><jupyter_text>Gradient Descent  For P1 (Reviews)<jupyter_code>def predicted_y(weight,x,intercept):
    y_lst=[]
    for i in range(len(x)):
        y_lst.append(weight@x[i]+intercept)
    return np.array(y_lst)
    

# linear loss
def loss(y,y_predicted):
    n=len(y)
    s=0
    for i in range(n):
        s+=(y[i]-y_predicted[i])**2
    return (1/n)*s

#derivative of loss w.r.t weight
def dldw(x,y,y_predicted):
    s=0
    n=len(y)
    for i in range(n):
        s+=-x[i]*(y[i]-y_predicted[i])
    return (2/n)*s
    

# derivative of loss w.r.t bias
def dldb(y,y_predicted):
    n=len(y)
    s=0
    for i in range(len(y)):
        s+=-(y[i]-y_predicted[i])
    return (2/n) * s

# gradient function
def gradient_descent(x,y):
    weight_vector=np.random.randn(x.shape[1])
    intercept=0
    epoch = 1000
    n = len(x)
    linear_loss=[]
    learning_rate = 0.01
    for i in range(epoch):
        
        
        y_predicted = predicted_y(weight_vector,x,intercept)
        
        weight_vector = weight_vector - learning_rate *dldw(x,y,y_predicted) 
        
        
        intercept = intercept - learning_rate * dldb(y,y_predicted)
        linear_loss.append(loss(y,y_predicted))
        
    plt.plot(np.arange(1,epoch),linear_loss[1:])
    plt.xlabel("number of epoch")
    plt.ylabel("loss")
    
    return weight_vector,intercept
x_sr = train_data.iloc[:, 2:3].values
y = train_data.iloc[:, 1].values

from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x_sr, y, test_size=0.3, random_state=0)

from sklearn.preprocessing import StandardScaler
sc=StandardScaler()
X_transform=sc.fit_transform(x_train)
w,b=gradient_descent(X_transform,y_train)
print("weight:",w)
print("bias:",b)
def predict(inp):
    y_lst=[]
    for i in range(len(inp)):
        y_lst.append(w@inp[i]+b)
    return np.array(y_lst)
X_test=sc.fit_transform(x_test)
y_pred=predict(X_test)
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from math import sqrt
print("R2 score : %.3f" % r2_score(y_test, y_pred))
print("MSE: %.3f" % mean_squared_error(y_test, y_pred))
print("RMSE: %.3f" % sqrt(mean_squared_error(y_test, y_pred)))
print("MAE: %.3f" % sqrt(mean_absolute_error(y_test, y_pred)))<jupyter_output>R2 score : 0.003
MSE: 0.229
RMSE: 0.479
MAE: 0.560<jupyter_text>For P2 (Installs)<jupyter_code>def predicted_y(weight,x,intercept):
    y_lst=[]
    for i in range(len(x)):
        y_lst.append(weight@x[i]+intercept)
    return np.array(y_lst)
    

# linear loss
def loss(y,y_predicted):
    n=len(y)
    s=0
    for i in range(n):
        s+=(y[i]-y_predicted[i])**2
    return (1/n)*s

#derivative of loss w.r.t weight
def dldw(x,y,y_predicted):
    s=0
    n=len(y)
    for i in range(n):
        s+=-x[i]*(y[i]-y_predicted[i])
    return (2/n)*s
    

# derivative of loss w.r.t bias
def dldb(y,y_predicted):
    n=len(y)
    s=0
    for i in range(len(y)):
        s+=-(y[i]-y_predicted[i])
    return (2/n) * s

# gradient function
def gradient_descent(x,y):
    weight_vector=np.random.randn(x.shape[1])
    intercept=0
    epoch = 100
    n = len(x)
    linear_loss=[]
    learning_rate =0.5

    for i in range(epoch):
        
        
        y_predicted = predicted_y(weight_vector,x,intercept)
        
        weight_vector = weight_vector - learning_rate *dldw(x,y,y_predicted) 
        
        
        intercept = intercept - learning_rate * dldb(y,y_predicted)
        linear_loss.append(loss(y,y_predicted))
        
    plt.plot(np.arange(1,epoch),linear_loss[1:])
    plt.xlabel("number of epoch")
    plt.ylabel("loss")
    
    return weight_vector,intercept
x_sr = train_data.iloc[:, 4:5].values
y = train_data.iloc[:, 1].values

from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x_sr, y, test_size=0.3, random_state=0)

from sklearn.preprocessing import StandardScaler
sc=StandardScaler()
X_transform=sc.fit_transform(x_train)
w,b=gradient_descent(X_transform,y_train)
print("weight:",w)
print("bias:",b)
def predict(inp):
    y_lst=[]
    for i in range(len(inp)):
        y_lst.append(w@inp[i]+b)
    return np.array(y_lst)
X_test=sc.fit_transform(x_test)
y_pred=predict(X_test)
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from math import sqrt
print("R2 score : %.3f" % r2_score(y_test, y_pred))
print("MSE: %.3f" % mean_squared_error(y_test, y_pred))
print("RMSE: %.3f" % sqrt(mean_squared_error(y_test, y_pred)))
print("MAE: %.3f" % sqrt(mean_absolute_error(y_test, y_pred)))<jupyter_output>R2 score : 0.002
MSE: 0.229
RMSE: 0.479
MAE: 0.561<jupyter_text>For P3 (Size)<jupyter_code>def predicted_y(weight,x,intercept):
    y_lst=[]
    for i in range(len(x)):
        y_lst.append(weight@x[i]+intercept)
    return np.array(y_lst)
    

# linear loss
def loss(y,y_predicted):
    n=len(y)
    s=0
    for i in range(n):
        s+=(y[i]-y_predicted[i])**2
    return (1/n)*s

#derivative of loss w.r.t weight
def dldw(x,y,y_predicted):
    s=0
    n=len(y)
    for i in range(n):
        s+=-x[i]*(y[i]-y_predicted[i])
    return (2/n)*s
    

# derivative of loss w.r.t bias
def dldb(y,y_predicted):
    n=len(y)
    s=0
    for i in range(len(y)):
        s+=-(y[i]-y_predicted[i])
    return (2/n) * s

# gradient function
def gradient_descent(x,y):
    weight_vector=np.random.randn(x.shape[1])
    intercept=0
    epoch = 100
    n = len(x)
    linear_loss=[]
    learning_rate =0.1
    for i in range(epoch):
        
        
        y_predicted = predicted_y(weight_vector,x,intercept)
        
        weight_vector = weight_vector - learning_rate *dldw(x,y,y_predicted) 
        
        
        intercept = intercept - learning_rate * dldb(y,y_predicted)
        linear_loss.append(loss(y,y_predicted))
        
    plt.plot(np.arange(1,epoch),linear_loss[1:])
    plt.xlabel("number of epoch")
    plt.ylabel("loss")
    
    return weight_vector,intercept
x_sr = train_data.iloc[:, 3:4].values
y = train_data.iloc[:, 1].values

from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x_sr, y, test_size=0.3, random_state=0)

from sklearn.preprocessing import StandardScaler
sc=StandardScaler()
X_transform=sc.fit_transform(x_train)
w,b=gradient_descent(X_transform,y_train)
print("weight:",w)
print("bias:",b)
def predict(inp):
    y_lst=[]
    for i in range(len(inp)):
        y_lst.append(w@inp[i]+b)
    return np.array(y_lst)
X_test=sc.fit_transform(x_test)
y_pred=predict(X_test)
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from math import sqrt
print("R2 score : %.3f" % r2_score(y_test, y_pred))
print("MSE: %.3f" % mean_squared_error(y_test, y_pred))
print("RMSE: %.3f" % sqrt(mean_squared_error(y_test, y_pred)))
print("MAE: %.3f" % sqrt(mean_absolute_error(y_test, y_pred)))<jupyter_output>R2 score : 0.006
MSE: 0.228
RMSE: 0.478
MAE: 0.559<jupyter_text>For P1+P2 (Reviews and Installs)<jupyter_code>def predicted_y(weight,x,intercept):
    y_lst=[]
    for i in range(len(x)):
        y_lst.append(weight@x[i]+intercept)
    return np.array(y_lst)
    

# linear loss
def loss(y,y_predicted):
    n=len(y)
    s=0
    for i in range(n):
        s+=(y[i]-y_predicted[i])**2
    return (1/n)*s

#derivative of loss w.r.t weight
def dldw(x,y,y_predicted):
    s=0
    n=len(y)
    for i in range(n):
        s+=-x[i]*(y[i]-y_predicted[i])
    return (2/n)*s
    

# derivative of loss w.r.t bias
def dldb(y,y_predicted):
    n=len(y)
    s=0
    for i in range(len(y)):
        s+=-(y[i]-y_predicted[i])
    return (2/n) * s

# gradient function
def gradient_descent(x,y):
    weight_vector=np.random.randn(x.shape[1])
    intercept=0
    epoch = 500
    n = len(x)
    linear_loss=[]
    learning_rate = 0.05

    for i in range(epoch):
        
        
        y_predicted = predicted_y(weight_vector,x,intercept)
        
        weight_vector = weight_vector - learning_rate *dldw(x,y,y_predicted) 
        
        
        intercept = intercept - learning_rate * dldb(y,y_predicted)
        linear_loss.append(loss(y,y_predicted))
        
    plt.plot(np.arange(1,epoch),linear_loss[1:])
    plt.xlabel("number of epoch")
    plt.ylabel("loss")
    
    return weight_vector,intercept
x_sr = train_data.iloc[:, 2:5:2].values
y = train_data.iloc[:, 1].values

from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x_sr, y, test_size=0.3, random_state=0)

from sklearn.preprocessing import StandardScaler
sc=StandardScaler()
X_transform=sc.fit_transform(x_train)
w,b=gradient_descent(X_transform,y_train)
print("weight:",w)
print("bias:",b)
def predict(inp):
    y_lst=[]
    for i in range(len(inp)):
        y_lst.append(w@inp[i]+b)
    return np.array(y_lst)
X_test=sc.fit_transform(x_test)
y_pred=predict(X_test)
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from math import sqrt
print("R2 score : %.3f" % r2_score(y_test, y_pred))
print("MSE: %.3f" % mean_squared_error(y_test, y_pred))
print("RMSE: %.3f" % sqrt(mean_squared_error(y_test, y_pred)))
print("MAE: %.3f" % sqrt(mean_absolute_error(y_test, y_pred)))<jupyter_output>R2 score : 0.003
MSE: 0.229
RMSE: 0.479
MAE: 0.560<jupyter_text>For All Predictors<jupyter_code>def predicted_y(weight,x,intercept):
    y_lst=[]
    for i in range(len(x)):
        y_lst.append(weight@x[i]+intercept)
    return np.array(y_lst)
    

# linear loss
def loss(y,y_predicted):
    n=len(y)
    s=0
    for i in range(n):
        s+=(y[i]-y_predicted[i])**2
    return (1/n)*s

#derivative of loss w.r.t weight
def dldw(x,y,y_predicted):
    s=0
    n=len(y)
    for i in range(n):
        s+=-x[i]*(y[i]-y_predicted[i])
    return (2/n)*s
    

# derivative of loss w.r.t bias
def dldb(y,y_predicted):
    n=len(y)
    s=0
    for i in range(len(y)):
        s+=-(y[i]-y_predicted[i])
    return (2/n) * s

# gradient function
def gradient_descent(x,y):
    weight_vector=np.random.randn(x.shape[1])
    intercept=0
    epoch = 100
    n = len(x)
    linear_loss=[]
    learning_rate = 0.01

    for i in range(epoch):
        
        
        y_predicted = predicted_y(weight_vector,x,intercept)
        
        weight_vector = weight_vector - learning_rate *dldw(x,y,y_predicted) 
        
        
        intercept = intercept - learning_rate * dldb(y,y_predicted)
        linear_loss.append(loss(y,y_predicted))
        
    plt.plot(np.arange(1,epoch),linear_loss[1:])
    plt.xlabel("number of epoch")
    plt.ylabel("loss")
    
    return weight_vector,intercept
x_sr = train_data.iloc[:, 2:].values
y = train_data.iloc[:, 1].values

from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x_sr, y, test_size=0.3, random_state=0)

from sklearn.preprocessing import StandardScaler
sc=StandardScaler()
X_transform=sc.fit_transform(x_train)
w,b=gradient_descent(X_transform,y_train)
print("weight:",w)
print("bias:",b)
def predict(inp):
    y_lst=[]
    for i in range(len(inp)):
        y_lst.append(w@inp[i]+b)
    return np.array(y_lst)
X_test=sc.fit_transform(x_test)
y_pred=predict(X_test)
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from math import sqrt
print("R2 score : %.3f" % r2_score(y_test, y_pred))
print("MSE: %.3f" % mean_squared_error(y_test, y_pred))
print("RMSE: %.3f" % sqrt(mean_squared_error(y_test, y_pred)))
print("MAE: %.3f" % sqrt(mean_absolute_error(y_test, y_pred)))<jupyter_output>R2 score : -1.860
MSE: 0.658
RMSE: 0.811
MAE: 0.825<jupyter_text>Feature Selection and AIC,BIC Calculation<jupyter_code>X=train_data.drop(columns='Rating',axis=1)
Y=train_data.Rating
MLR_reg = linear_model.LinearRegression(fit_intercept=True)
def fit_linear_reg(X,Y):
    MLR_reg.fit(X,Y)
    RSS=mean_squared_error(Y,MLR_reg.predict(X))*len(Y)
    R_squared=MLR_reg.score(X,Y)
    return RSS , R_squared
from tqdm import tnrange, tqdm_notebook
k=5
RSS_list, R_squared_list, feature_list=[],[],[]
numb_features=[]

for k in tnrange(1,len(X.columns)+1,desc='Loop...'):
    for combo in itertools.combinations(X.columns,k):
        tmp_result=fit_linear_reg(X[list(combo)],Y)
        RSS_list.append(tmp_result[0])
        R_squared_list.append(tmp_result[1])
        feature_list.append(combo)
        numb_features.append(len(combo))
        
df=pd.DataFrame({'numb_features':numb_features,'RSS':RSS_list,'R_squared':R_squared_list,'features':feature_list})        
df
##Finding Best subsets for each number of features

df_min=df[df.groupby('numb_features')['RSS'].transform(min)==df['RSS']]
df_max=df[df.groupby('numb_features')['R_squared'].transform(max)==df['R_squared']]
display(df_min.head(3))
display(df_max.head(3))
#Addingg columns to the dataframe with RSS and R squared values of the best subset
df['min_RSS']=df.groupby('numb_features')['RSS'].transform(min)
df['max_R_squared']=df.groupby('numb_features')['R_squared'].transform(max)
df.head()
#Plotting the best subset selection process
fig=plt.figure(figsize=(14,5))
ax=fig.add_subplot(1,2,1)
ax.scatter(df.numb_features,df.RSS,alpha=0.2,color='darkblue')
ax.set_xlabel('Features')
ax.set_ylabel('RSS')
ax.set_title('RSS-Best Subset selection')

ax=fig.add_subplot(1,2,2)
ax.scatter(df.numb_features,df.R_squared,alpha=0.2,color='darkblue')
ax.set_xlabel('Features')
ax.set_ylabel('R_squared')
ax.set_title('R_squared-Best Subset selection')
remaining_features=list(X.columns.values)
features=[]
RSS_list,R_squared_list=[np.inf],[np.inf]
features_list=dict()

for i in range(1,k+1):
    best_RSS=np.inf
    for combo in itertools.combinations(remaining_features,1):
        RSS=fit_linear_reg(X[list(combo)+features], Y)
        if RSS[0]<best_RSS:
            best_RSS=RSS[0]
            best_R_squared=RSS[1]
            best_feature=combo[0]
    features.append(best_feature)
    remaining_features.remove(best_feature)
    
    RSS_list.append(best_RSS)
    R_squared_list.append(best_R_squared)
    features_list[i]=features.copy()
print('Forward stepwise subset selection')
print('Number of features |', 'Features |', "RSS")
display([(i,features_list[i],round(RSS_list[i])) for i in range(1,8)])
df1=pd.concat([pd.DataFrame({'features':features_list}),pd.DataFrame({'RSS':RSS_list, 'R_squared':R_squared_list})],axis=1,join='inner')
df1['numb_features']=df1.index
df1
##Computing the c_p, AIC, BIC and adjusted R_square
m=len(Y)
p=8
hat_sigma_squared=(1/(m-p-1))*min(df1['RSS'])

df1['C_p']=(1/m)*(df1['RSS']+2*df1['numb_features']* hat_sigma_squared)
df1['AIC']=(1/(m*hat_sigma_squared))* (df1['RSS']+2*df1['numb_features']*hat_sigma_squared)
df1['BIC']=(1/(m*hat_sigma_squared))* (df1['RSS']+np.log(m) *df1['numb_features']*hat_sigma_squared)
df1['R_squared_adj']=1-((1-df1['R_squared'])*(m-1)/(m-df1['numb_features']-1))
df1
#Plotting the computed values as a function of number of features
variables=['C_p', 'AIC','BIC', 'R_squared_adj']
fig=plt.figure(figsize=(18,6))

for i,v in enumerate(variables):
    ax=fig.add_subplot(1,4,i+1)
    ax.plot(df1['numb_features'],df1[v],color='lightblue')
    ax.scatter(df1['numb_features'],df1[v],color='darkblue')
    if v=='R_squared_adj':
        ax.plot(df1[v].idxmax(),df1[v].max(), marker='x',markersize=20)
    else:
        ax.plot(df1[v].idxmin(),df1[v].min(), marker='x',markersize=20)
        
    ax.set_xlabel('Number of predictors')
    ax.set_ylabel(v)
fig.suptitle('Subset selection using C_p, AIC,BIC, Adjusted R2',fontsize=16)
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14881345886429434, 'fraction_numerical': 0.0350605238562017, 'mean_word_length': 6.1098865478119935, 'pattern_counts': {'":': 0, '<': 113, '<?xml version=': 0, '>': 112, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '30', 'dir': 'jupyter-structured-clean-dedup', 'id': '267162', 'license': 'MIT', 'n_tokens_mistral': 18924, 'n_tokens_neox': 17686, 'n_words': 2811, 'path': 'Regression Analysis (Jupyter).ipynb', 'repo_name': 'Vikalp981/Data-Analysis-of-Play-Store-Apps', 'size': '43867'}