[분류] 학생 데이터 분석 & 성적 등급 예측 모델

2023. 11. 19. 22:05ML&DL/Data Analysis

[ 학생의 정보 데이터로 성적 등급을 예측해보기]

 

데이터셋 출처

 https://www.kaggle.com/aljarah/xAPI-Edu-Data

 

Students' Academic Performance Dataset

xAPI-Educational Mining Dataset

www.kaggle.com

 

데이터 컬럼 

gender: 학생의 성별 (M: 남성, F: 여성)
NationaliTy: 학생의 국적
PlaceofBirth: 학생이 태어난 국가
StageID: 학생이 다니는 학교 (초,중,고)
GradeID: 학생이 속한 성적 등급
SectionID: 학생이 속한 반 이름
Topic: 수강한 과목
Semester: 수강한 학기 (1학기/2학기)
Relation: 주 보호자와 학생의 관계
raisedhands: 학생이 수업 중 손을 든 횟수
VisITedResources: 학생이 과목 공지를 확인한 횟수
Discussion: 학생이 토론 그룹에 참여한 횟수
ParentAnsweringSurvey: 부모가 학교 설문에 참여했는지 여부
ParentschoolSatisfaction: 부모가 학교에 만족했는지 여부
StudentAbscenceDays: 학생의 결석 횟수 (7회 이상/미만)
Class: 학생의 성적 등급 (L: 낮음, M: 보통, H: 높음)

 

💻 실습

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns



* 데이터 불러오기 / 확인

df = pd.read_csv('xAPI-Edu-Data.csv')
df

 

 

 

* EDA 및 데이터 기초 통계 분석

df.head()
df.info()

 

 

df.describe()

 

 

df['gender'].value_counts()

M    305

F    175

Name: gender, dtype: int64

df['NationalITy'].value_counts()

KW             179

Jordan         172

Palestine       28

Iraq            22

lebanon         17

Tunis           12

SaudiArabia     11

Egypt            9

Syria            7

USA              6

Iran             6

Lybia            6

Morocco          4

venzuela         1

Name: NationalITy, dtype: int64

 

 

* 데이터 분석 - 시각화

- 수업 중 손을 든 횟수와 성적 등급

sns.histplot(x='raisedhands', data=df, hue='Class', hue_order=['L', 'M', 'H'], kde=True)

 

=> 손을 많이 든 학생일수록 높은 등급의 성적

 

- 과목 공지를 확인한 횟수와 성적 등급

sns.histplot(x='VisITedResources', data=df, hue='Class', hue_order=['L', 'M', 'H'], kde=True)

sns.jointplot(x='VisITedResources', y='raisedhands', data=df, hue='Class', hue_order=['L', 'M', 'H'])

 

 

=> 공지를 많이 확인한 학생일수록 높은 등급의 성적

 

* 범주별  통계 확인

sns.countplot(x='Class', data=df, order=['L', 'M', 'H'])

 

sns.countplot(x='gender', data=df, hue='Class', hue_order=['L', 'M', 'H'])

 

sns.countplot(x='NationalITy', data=df, hue='Class', hue_order=['L', 'M', 'H'])
plt.xticks(rotation=90)
plt.show()

 

 

 

* 데이터 전처리

- 범주형 데이터 수치화

- L : 0 ,M : 1 , H : 2

df['Class_value'] = df['Class'].map(dict(L=0, M=1, H=2))
df.head()

 

 

- 수치형은 drop으로 제외

- y 타겟

X = pd.get_dummies(df.drop(['ParentschoolSatisfaction', 'Class', 'Class_value'], axis=1),
                   columns=['gender', 'NationalITy', 'PlaceofBirth',
                            'StageID', 'GradeID','SectionID', 'Topic',
                            'Semester', 'Relation', 'ParentAnsweringSurvey',
                            'StudentAbsenceDays'],
                   drop_first=True)
y = df['Class_value']

 

- train/test 데이터 분리 7:3

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=1)

 

* 모델 학습

 

from sklearn.linear_model import LogisticRegression

model_lr = LogisticRegression(max_iter=10000)
model_lr.fit(X_train, y_train)

 

* 모델 학습 결과 평가

from sklearn.metrics import classification_report
pred = model_lr.predict(X_test)
print(classification_report(y_test, pred))

 

 

from xgboost import XGBClassifier

model_xgb = XGBClassifier()
model_xgb.fit(X_train, y_train)
pred = model_xgb.predict(X_test)
print(classification_report(y_test, pred))

 

 

* 딥러닝 모델 학습

import tensorflow as tf
from tensorflow.keras import layers, models
from tensorflow.keras.callbacks import EarlyStopping

# 딥러닝 모델 생성
model_deep = models.Sequential()
input_dim = X_train.shape[1]
model_deep.add(layers.InputLayer(input_shape=(input_dim,)))
model_deep.add(layers.Dense(128, activation='relu'))
model_deep.add(layers.Dense(64, activation='relu'))
model_deep.add(layers.Dense(3, activation='softmax'))

# 모델 컴파일
model_deep.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# EarlyStopping 콜백 정의
early_stopping = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)

# 원-핫 인코딩
y_train_one_hot = tf.keras.utils.to_categorical(y_train, num_classes=3)

# 딥러닝 모델 학습
model_deep.fit(X_train, y_train_one_hot, epochs=1000, batch_size=32, validation_split=0.2, callbacks=[early_stopping])
# 테스트 데이터의 원-핫 인코딩
y_test_one_hot = tf.keras.utils.to_categorical(y_test, num_classes=3)

# 딥러닝 모델 평가
test_evaluation_result = model_deep.evaluate(X_test, y_test_one_hot)

# 테스트 평가 결과 출력
print(f'Test Loss: {test_evaluation_result[0]}')
print(f'Test Accuracy: {test_evaluation_result[1]}')