import pandas as pd

import seaborn as sns

import matplotlib.pyplot as plt

import statsmodels.formula.api as smf

from scipy import stats

data = pd.read_csv("Performance Index.csv")

data.columns = data.columns.str.strip()

model_columns = ["jpi", "aptitude", "technical", "general", "tol"]

data[model_columns] = data[model_columns].apply(pd.to_numeric, errors="coerce")

data = data.dropna(subset=model_columns).copy()

data.describe()

sns.pairplot(data[model_columns])

plt.suptitle("Scatterplot Matrix of Variables", y = 1.02)

plt.show()

sns.heatmap(data[model_columns].corr(), annot = True, cmap = 'coolwarm')

plt.title("Correlation Heatmap")

plt.show()

model = smf.ols('jpi ~ aptitude + technical + general + tol', data = data).fit()

print(model.summary())

from patsy import dmatrices

from statsmodels.stats.outliers_influence import variance_inflation_factor

y,X = dmatrices('jpi ~ aptitude + technical + general + tol', data = data, return_type = 'dataframe')

vif_data = pd.DataFrame()

vif_data['Variable'] = X.columns

vif_data['VIF'] = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]

vif_data

model2 = smf.ols('jpi ~ aptitude + technical + general', data = data).fit()

print(model2.summary())

data['fitted'] = model2.fittedvalues

data['residuals'] = model2.resid

data['Actual - Predicted'] = data['jpi'] - data['fitted']

data.head()

plt.scatter(data['fitted'], data['residuals'])

plt.axhline(0, color = 'red', linestyle = '--')

plt.xlabel("Fitted values")

plt.ylabel("Residuals")

plt.title("Fitted vs Residual")

plt.show()

stats.probplot(data['residuals'], dist = "norm", plot = plt)

plt.title('QQ Plot for residuals')

plt.show()

from scipy.stats import shapiro

stat, p = shapiro(data['residuals'])

print(f'Shapiro-Wilk Test Statistic = {stat: .4f}, p-value = {p:.4f}')

if p > 0.05:
    print("Residuals appear normally distributed (fail to reject H0)")
else:
    print("Residuals deviate from normality(reject H0)")

influence = model2.get_influence()

influence.summary_frame()

from statsmodels.graphics.regressionplots import influence_plot

influence_plot(model2, criterion = "Cooks")

newdata = pd.read_csv("Performance Index new.csv")

newdata.columns = newdata.columns.str.strip()

newdata[["aptitude", "technical", "general"]] = newdata[["aptitude", "technical", "general"]].apply(pd.to_numeric, errors="coerce")

newdata['pred'] = model2.predict(newdata)

newdata
