본문 바로가기
데이터 분석

PAPS로 학생 군집화하여 체육시간 모둠 나누는 프로그램 만들기(ChatGPT)

by 너구리선생님 2023. 4. 3.
반응형

#실행 프로그램 다운로드 및 사용 방법은 글 제일 아래를 참고

 

얼마전 학생들과 함께 민첩성을 기르기 위한 운동인 지그재그 달리기를 했다.

지그재그 달리기란 깔때기를 Z 모양으로 둠으로써 학생들도 Z모양으로 방향을 재빠르게 바꾸면서 달리는 것이다.

 

여기에 재미를 위해

(유튜브 "열정기백쌤"의 아이디어인)

다른 모둠을 터치하면 승리한다는, 게임적인 요소를 추가했다.

*자세한 활동은 유튜브의 "열정기백쌤_지그재그 달리기"를 참고

 

그랬는데... 분명 학생들을 랜덤으로 모둠을 잘 나눴음에도 불구하고 특정 모둠만 계속해서 승리하는 일이 벌어졌다.

패배하는 학생들의 의욕을 고취시키기 위해 패배하는 학생들에게 추가적인 미션(게임이 끝날 때까지 잡히지 않으면 콩주머니를 주겠다)을 주었고, 승리하는 학생들에게는 잡으면 보상을 2배를 주겠다고 했다.

*콩주머니는 우리 반 학급 보상 체계. 일종의 칭찬 스티커라고 생각하면 된다.

 

수업이 끝나고 어떻게 하면 체육시간 학생 모둠을 균형잡히게 나눌 수 있을까 고민했다.

고민하던 중 매년 4월에 실시하는 PAPS 측정이 다가오고 있다는 것을 깨달았다.

*PAPS란 학생 건강 체력평가 시스템으로 체격, 심폐지구력, 유연성, 글력 및 근지구력, 순발력을 평가한다.

 

우리 학교의 PAPS 측정 종목으로는 다음의 항목이 있었다.

-신장 및 체중 측정

-왕복 오래달리기(단위 : 횟수)

-앉아 윗몸 앞으로 굽히기(단위 : cm)

-윗몸 말아올리기(단위 : 횟수)

-50m 달리기(단위 : 초)

 

위 항목들을 측정하고 난 후 Excel을 활용해 표로 정리했다.

*교사는 NICE에 학생 PAPS 결과를 입력하게 되어있다. NICE 입력을 위해 Excel로 미리 정리를 하거나, 입력을 마친 후 NICE에서 Excel로 다운 받을 수도 있다.

Excel 입력 양식

 위 양식에 모든 학생들의 정보를 입력하고 난 후 군집화를 시작했다.


 

[군집화 프로그래밍]

1. 필요한 라이브러리 불러오기

import pandas as pd #데이터 분석 라이브러리
from sklearn.cluster import KMeans #군집화 알고리즘 라이브러리
from sklearn.preprocessing import MinMaxScaler #데이터 스케일링 라이브러리

 

2. 학생 PAPS 측정 결과 Excel 파일 불러오기

df = pd.read_excel("Paps 측정.xlsx") #Excel 속 정보 표로 가져오기
df_copy = df.copy() #표 복사

 

(3. 가명 처리하기)

#실제 군집화할 때는 필요하지 않은 단계

#우리 반 학생의 PAPS 측정 데이터를 실제로 활용하였기 때문에, 누구의 측정 결과인지 알 수 없도록 이름과 측정 순서를 조정하였음

from string import ascii_uppercase #알파벳 A-Z까지 가져오기 위한 라이브러리
df_copy.sample(frac=1).reset_index(drop=True) #학생 순서(행) 무작위로 섞기
alphabet_list = list(ascii_uppercase) #알파벳 A-Z까지의 값이 담긴 List
df_copy["이름"] = alphabet_list[:23] #실제 학생 이름을 "A-Z" 중 하나로 바꾸기

 

4. 데이터 스케일링 하기

#스케일링이란 데이터 값의 크기를 조정하는 것

#왕복 오래달리기는 특정 구간을 달린 횟수를 기입하였는데 우리반 최대값이 131이었다. 앉아 윗몸 앞으로 굽히기는 cm를 측정하였는데 최대값이 26.5였다.

#위와 같이 각 종목별로 데이터의 범위가 다른데, 이를 동일한 구간으로 조정해주는 작업을 데이터 스케일링이라고 한다

#나는 이번에 MinMaxScaler를 활용하여 모든 데이터 값을 0~1사이의 중 하나로 조정하였다.

#최소값은 0이되고, 최대값은 1이 된다(왕복 오래달리기의 최대값 131은 1이 되는 것이다)

scaler = MinMaxScaler()
df_MinMax = pd.DataFrame(scaler.fit_transform(df_copy.iloc[:, 2:])) #성별, 이름 값은 측정에서 제외
df_preprocess = pd.concat([df_copy.iloc[:, :2], df_MinMax], axis=1)
df_preprocess.columns = df.columns

 

5. 데이터 조정하기

#다른 종목과 달리 50M 달리기는 값이 크면 좋지 않다

#따라서 (1-측정값)을 했다

df_preprocess["50M 달리기"] = 1-df_preprocess["50M 달리기"]

 

6. 군집화하기

#우리반은 6모둠으로 구성되어있다. 따라서, 6개의 모둠으로 군집화를 진행했다

#군집화 결과는 때마다 조금씩 다를 수 있다

kmeans = KMeans(n_clusters=6)
cluster = kmeans.fit(df_preprocess.iloc[:, 2:])
result = pd.concat([df_preprocess, pd.DataFrame(cluster.labels_)], axis=1)
result = result.rename(columns={0:"그룹"})

 

7. 결과값 출력하기

#각 그룹에 속한 학생 이름을 데이터와 함께 표로 살펴보았다.

pd.pivot_table(result, index=["그룹", "이름"])

[결과값 확인]

출력 결과

#그룹 0~5는 단순 숫자일 뿐, 서열을 나타내지 않음

#그룹 0이 그룹 5보다 더 신체능력이 좋다는 의미가 아니라는 것

#학생 이름이 알파벳인 이유는 가명처리를 했기 때문

#실제 프로그램에서는 가명처리를 하지 않았으므로, 학생 이름이 그대로 나옴

 

 결과는 몹시 흥미로웠다.

 우리 반에서 학생 L의 신체 능력은 독보적이다.

  PAPS 측정을 하며 내가 느낀바도 학생 L이 독보적이라고 생각했다.

 이 친구와 어깨를 나란히 하는 친구가 없다고 생각했는데, 분석 결과도 마찬가지다.

 

 그 외의 학생들은 정말 비슷비슷하게 묶였다.

 내가 직접 위 23명의 학생들을 군집화한다면, 정말 골치아플 것이다.

 군집화 하는 것도 어려울 뿐더러, 군집화를 하고 난 후에 그 근거가 객관적이지 않기 때문이다.

 

 이를 바탕으로 우리 반 체육 모둠을 구성하고 수업을 진행해보려 한다.

 물론 PAPS가 학생의 신체능력을 모두 반영한다고 볼 수 없으나, 이전의 임의로 분류하는 방식보다는 더 신체능력을 골고루 반영한다.


[프로그램 만들기]

 이제 이 프로그램을 다른 선생님들에게도 나누고 싶다는 마음이 들었다.

 이를 위해 복잡한 프로그래밍을 직접 할 필요 없이 클릭만으로 결과를 살펴볼 수 있는 GUI 프로그램을 만들기로 했다.

 

 내가 직접 이 프로그램을 프로그래밍할 수도 있지만,

 이번에는 챗GPT를 활용하기로 했다.

 

아래는 챗GPT와 주고받은 문답.

내가 한 질문1

엑셀에 들어있는 속성은 ['성별', '이름', '오래달리기', '50M 달리기', '윗몸말아올리기', '앉아윗몸앞으로굽히기'] 이야. 위 속성을 바탕으로 군집화를 진행하려 해. 아래는 군집화를 진행한 코드야. 우선 살펴봐.

import pandas as pd
from sklearn.cluster import KMeans
from sklearn.preprocessing import MinMaxScaler

df = pd.read_excel("Paps 측정.xlsx")
df_copy = df.copy()

from string import ascii_uppercase
df_copy.sample(frac=1).reset_index(drop=True)
alphabet_list = list(ascii_uppercase)
df_copy["이름"] = alphabet_list[:23]

scaler = MinMaxScaler()
df_MinMax = pd.DataFrame(scaler.fit_transform(df_copy.iloc[:, 2:]))
df_preprocess = pd.concat([df_copy.iloc[:, :2], df_MinMax], axis=1)
df_preprocess.columns = df.columns
df_preprocess["50M 달리기"] = 1-df_preprocess["50M 달리기"]

kmeans = KMeans(n_clusters=6)
cluster = kmeans.fit(df_preprocess.iloc[:, 2:])
result = pd.concat([df_preprocess, pd.DataFrame(cluster.labels_)], axis=1)
result = result.rename(columns={0:"그룹"})

pd.pivot_table(result, index=["그룹", "이름"])

 챗GPT 대답1

해당 코드를 살펴보면, 엑셀 파일을 읽어와 데이터를 전처리하고, MinMaxScaler를 이용하여 스케일링을 수행하고, KMeans 군집화를 수행한 후 결과를 출력하는 것으로 보입니다.

군집의 수는 6개로 지정되어 있으며, 그룹화된 결과는 pivot_table로 출력됩니다. 하지만 이 코드에서 누락된 부분이 많아서 실행시 오류가 발생할 가능성이 있습니다.

따라서, 해당 코드를 실행하기 위해서는 "Paps 측정.xlsx" 파일이 먼저 준비되어 있어야 하며, 필요한 라이브러리도 모두 설치되어 있어야 합니다. 또한 코드 상에서 누락된 부분이 있을 수 있으므로, 해당 코드를 실행하기 전에 추가적인 수정이 필요할 수도 있습니다.

내가 한 질문2

xlsx 파일은 이미 준비되어있고, 라이브러리도 모두 설치되어있어.

아래의 GUI를 추가해줘. "군집화" 버튼을 누르면 위 코드의 군집화를 실행하고, GUI 팝업창에 그 결과를 보여주는 GUI 프로그램.

 챗GPT 대답2 + 소스코드

아래는 군집화 버튼을 클릭하면 군집화가 실행되고, 결과를 GUI 팝업창에 보여주는 예시 코드입니다.
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.preprocessing import MinMaxScaler
from tkinter import *
from tkinter import messagebox

def run_clustering():
    # 엑셀 파일 읽어오기
    df = pd.read_excel("Paps 측정.xlsx")
    
    # 이름 칼럼 추가
    from string import ascii_uppercase
    alphabet_list = list(ascii_uppercase)
    df["이름"] = alphabet_list[:23]
    
    # 데이터 스케일링
    scaler = MinMaxScaler()
    df_MinMax = pd.DataFrame(scaler.fit_transform(df.iloc[:, 2:]))
    df_preprocess = pd.concat([df.iloc[:, :2], df_MinMax], axis=1)
    df_preprocess.columns = df.columns
    df_preprocess["50M 달리기"] = 1-df_preprocess["50M 달리기"]
    
    # 군집화 실행
    kmeans = KMeans(n_clusters=6)
    cluster = kmeans.fit(df_preprocess.iloc[:, 2:])
    
    # 군집 결과 저장
    result = pd.concat([df_preprocess, pd.DataFrame(cluster.labels_)], axis=1)
    result = result.rename(columns={0:"그룹"})
    pivot_table = pd.pivot_table(result, index=["그룹", "이름"])
    
    # 결과 출력
    root = Tk()
    root.geometry("500x500")
    root.title("군집화 결과")
    output_text = Text(root)
    output_text.insert(END, pivot_table)
    output_text.pack()
    messagebox.showinfo("알림", "군집화 완료!")
    root.mainloop()

# GUI 프로그램 생성
window = Tk()
window.geometry("200x100")
window.title("군집화")

# 군집화 버튼 생성
button = Button(window, text="군집화", command=run_clustering)
button.pack()

window.mainloop()
이 코드를 실행하면, 군집화 버튼이 있는 GUI 창이 생성됩니다. 군집화 버튼을 클릭하면 군집화가 실행되며, 결과는 팝업창과 함께 GUI 창에 출력됩니다.

[최종 프로그램 실행 결과]

군집화 버튼을 눌러보자
결과창

 

너무너무 잘된다... 챗GPT 최고...

원래 내가 스스로 코드를 짜면 1시간 정도 넘게 걸릴텐데 챗GPT는 10초 컷이다.


[실행 프로그램 공유]

 

챗GPT와 협업한 위 프로그램은 복잡한 프로그래밍 화면을 볼 필요 없이, 간단히 다른 사람의 컴퓨터에서도 실행 가능하도록 exe 파일로 제작하였다.

아래에 다운받을 수 있도록 공유한다.

 

아래 사이트로 이동한 후 다운로드 한 후 압축을 풀고,

dist의 "Paps 측정.xlsx"에 측정 값을 넣는다.

그 후 "PapsClusteringGUI.exe"을 실행하고 "군집화" 버튼을 클릭하면 된다.

군집화된 것을 바탕으로 학생의 모둠을 직접 나누면 끝!!

 

https://drive.google.com/file/d/1tvPORkdllgYQDgZ_iRZ4W0L3SZ1_X6W6/view?usp=sharing 

 

Download.zip

 

drive.google.com

반응형

댓글