"""
# Student Result Prediction
"""
"""
<img src="https://www.rvcj.com/wp-content/uploads/2014/12/Exam.png"> 

"""
"""
Story :
Prediction of next semester cgpa is very difficult. Prediction of next semester cgpa can be done by analyzing the past performance of a student.

Data collection :
This data has been collected manually from a website of a Technical University. Roll number has been converted to a random number for the privacy of the students. College code and subject is real and the semester cgpa is also a real world dataset.

Solution :
Prediction of the next semester marks can be determined by using machine learning algorithms. In my point of view advance regression technique can be a good performer for this case.


"""
"""
<img src = "https://cache.careers360.mobi/media/presets/860X430/article_images/2020/7/15/CBSE-Class-10-result-2020-statistics.jpg" >
"""
"""
# Importing Libraries for work
"""
import numpy as np 
import matplotlib.pyplot as plt
import plotly as p 
import seaborn as sns
import pandas as pd 

import warnings
warnings.filterwarnings("ignore")

import plotly.express as px 
"""
# Reading Data From the Datasetm
"""
df = pd.read_csv("/kaggle/input/student-semester-result/data.csv") 
"""
# View the Data
"""
df.head()
df.tail()
df.shape    # View the Dimensions of the data. 
df.describe()   # View the Statistical Summary of the Data.  
df.describe().T   # Transpose of the Statistical summary view. 
pd.set_option('precision',2)  # Just for viewing the Data More clearly. 
df.describe()
df.info()   # Data type of the Data. 
"""
- We can see there is a column name Gender which doesn't have int or float values. So, I want to see that data. 
"""
df['Gender'] 
"""
- There are some values that are Female and Some are Male and others are F and M. 
So in it we have to make similar values like F for female and M for Male. 
"""
df['Gender'].replace({'Female':'F','Male':'M'},inplace=True)
df['Gender']  
"""
- Now Our values of the Gender Column is set. 
"""
df
"""
- We can see that there are NaN values in the Roll Number Column. 
"""
"""
# Handling Missing values
"""
df.isnull().sum()
df['Subject Code'].value_counts() 
df['College Code'].value_counts()
df['Gender'].value_counts()
"""
- make Roll No values in the Int type
"""
df['Roll'].fillna(0,inplace=True)        # Replacing Null values from 0 
df['Roll no.'].fillna(0,inplace=True)                 # Replacing Null values from 0 

df['Roll_no']=df['Roll']+df['Roll no.']            # combining two columns into one. 
df.drop(columns=['Roll','Roll no.'],inplace=True)
df['Roll_no'].astype(int)
df.isnull().sum()
"""
- There are some Null values in the Data also. 
"""
df.describe()
df['1st'].mean()
df['Gender'].fillna(0,inplace=True)                 # Replacing Null values from 0 


df['1st'].fillna(df['1st'].mean(),inplace = True)        # Replacing Null values from 0  
df['2nd'].fillna(df['2nd'].mean(),inplace=True)        # Replacing Null values from 0  
df['3rd'].fillna(df['3rd'].mean(),inplace=True)        # Replacing Null values from 0  
df['4th'].fillna(df['4th'].mean(),inplace=True)        # Replacing Null values from 0  
df['5th'].fillna(df['5th'].mean(),inplace=True)        # Replacing Null values from 0   
df.isnull().sum()
"""
# We can combine College Code, Subject Code and Roll_no Column together 
"""
df['College Code']=df['College Code'].astype(str)
df['Subject Code']=df['Subject Code'].astype(str)
df['Roll_no']=df['Roll_no'].astype(str)
df['studentid']=df['College Code']+df['Subject Code']+df['Roll_no']
df['studentid']
df.drop(columns=['Subject Code','Roll_no'],inplace=True)
df.info()
"""
- Now there are no Null values in the whole data. 
"""
# Pair plot of correlation

import seaborn as sns
sns.pairplot(df)
df
"""
# Select only relevent columns only. 
"""
df1 = df[['1st','2nd', '3rd', '4th','5th']] 
df1
from sklearn.model_selection import train_test_split

X = df1[['1st','2nd','3rd','4th']] 
y = df1['5th']  

X_train, X_test, y_train, y_test = train_test_split(X , y, test_size=1/3, random_state=21)

X
y
import sklearn.linear_model as skl_lm
regr = skl_lm.LinearRegression()
regr.fit(X_train,y_train)

round( (regr.score(X_test,y_test)*100) , 2   )
round( (regr.score(X_train,y_train)*100) , 2   ) 
regr.predict([[20, 334.34, 34.3443, 34.34]])  
regr.intercept_
y_pred = regr.predict(X_test)
difference = y_test - y_pred
dif = round(difference, 2)   
df3 = pd.DataFrame({'Actual': y_test, 'Predicted': y_pred, 'Difference': dif})
df3.head()
"""
# Residual Sum of Squares
"""
min_rss = np.sum((regr.intercept_+regr.coef_*X - y.values.reshape(-1,1))**2)
min_rss
"""
# MSE
"""
mse = min_rss/len(y)                                   #  min_rss / degree of freedom   
mse                                   #value should be 0 to infinite but not negative. 
"""
# Stats Model
"""
#  OLS = ordinary least square method. 

import statsmodels.api as sm
X2 = sm.add_constant(X)
est = sm.OLS(y,X2) 
est2=est.fit()
est2.summary()
import pandas_profiling as pp
profile = pp.ProfileReport(df)
profile.to_file("output.html")
Thanks 