brunch

You can make anything
by writing

C.S.Lewis

by 브라보 Aug 06. 2023

지피티로 그래프 그려 직관적으로 데이터 이해하기

이 보다 더 쉬울 순 없다! 

처음 챗 GPT로 데이터 분석을 하시는 분들이시면 data upload plug-in 사용을 추천하지 않는다. 필자는 데이터를 업로드해 주는 플러그인을 사용해 일주일 간 시간을 허비하다 지운 후 데이터 업로드가 제대로 되었다. 


인간은 진화적으로 비주얼 정보를 심벌로 된 정보보다 더 빨리 알아차리고 프로세싱을 한다. 이러한 인간 이해를 바탕으로 본고는 직관적으로 데이터를 이해할 수 있도록 챗GPT를 사용해 그래프를 그려 시각화하기로 한다.


이미 작자가 생각해 둔 분석이나 그래프가 있어 아래와 같이 명령을 할 경우 시간을 단축하고 작자가 원하는 것을 바로 얻을 수 있다는 장점이 있다. 즉, 알면 알 수록 데이터 분석을 더욱 정확하게 빨리 그리고 제대로 할 수 있다. 본고가 사용한 데이터는 각각 개인이 20번씩 리포트한 것으로 이 방법으로 그래프를 그리려면 적어도 각 개인이 5번 이상 리포트 한 것이어야 이 방법이 의미가 있다고 볼 수 있다. 


아래는 나의 명령어고 영어로 명령을 해서 한국어로 번역을 했고 개인 정보 이유로 챗GPT가 보여주는 어떠한 코드는 복사해서 붙여 넣기를 하였다. 


 각 개인 "ID"에 대해 다항식 방정식을 사용하여 산점도를 그리십시오. 각 그래프에서 X축에는 "expect" 변수를 사용하고 Y축에는 "expect_cha"를 사용하십시오. 각 그래프에 방정식을 포함하고 수렴점 또는 점들을 검은색으로 표시하여 그 값들을 나타내십시오. X축을 "Expect"로, Y축을 "시간 경과에 따른 Expect의 변화"로 라벨링 하십시오. 시작하십시오.


Graph a scatter plot for each individual "ID" using a polynomial equation. In each graph, use the variable "expect" on the X-axis and "expect_cha" on the Y-axis. Make sure to include the equation for each graph and mark the convergence point or points in black, indicating their values. Label the X-axis as "Expect" and the Y-axis as "Change in Expect over Time

아래 박스는 챗GPT가 진행 과정을 정리하여 그것의 프로세스가 실행되었는지의 여부를 사용자에게 알려준다. [DONE]이라고 표시된 부분은 이미 데이터 읽기를 마쳤다는 의미이다.


import pandas as pd


# Read the provided CSV data

data = pd.read_csv("/mnt/data/귀하의파일이름_2020.03.03.csv")


# Display the first few rows of the data to understand its structure

data.head()


윗 리스트에서 1번을 끝내고 제2번을 실행하고 있다. 즉, 각각 아이디 별로 그래프를 그릴 준비 과정 중 한 부분이다. 아래, Hotkeys List에서 나에게 어떤 방향으로 나아가고 싶냐고 물어봐서 나는 W를 선택했다. 계획대로 각각 개인 몇 명의 그래프를 먼저 보기로 했다. 


# Extract unique IDs from the data

unique_ids = data['id'].unique()


unique_ids

아래 지피티 할 일 요약리스트 중 [Pending]은 진행을 기다리는 과제를 말하고 [in progress]는 진행 중인 과제를 말한다. 

아래 모습은 지피티가 명령대로 그림 scatter plot인데, convergence point가 첫 번째 그래프는 옳으나 두 번째 그래프는 옳지 않다. 즉, 알아야 지피티가 틀린 점을 이해할 수 있고 고칠 수 있다. "Knowledge will set you free!"

그리하여, 본고는 아래와 같이 다시 명령을 했다. 즉, 잘 못 된 부분을 고쳐서 다시 그래프를 그려달라고 부탁했다. 


이것을 올바르게 수행해야 합니다. 수렴점은 X축에서 Y 값이 0에 도달하는 지점입니다. 다항식 방정식을 사용하여 각 개인 "ID"에 대한 산점도를 그리십시오. 각 그래프에서 X축에 "expect" 변수를 사용하고 Y축에 "expect_cha"를 사용하십시오. 각 그래프에 방정식을 포함하십시오. 그리고 수렴점 또는 점들을 검은색으로 표시하여 그 값들을 나타내십시오. X축을 "Expect"로 표시하고 Y축을 "시간 경과에 따른 Expect의 변화"로 라벨링 하십시오. 시작하십시오.


You need to do this correctly. A convergence point is where the Y value reaches 0 on the X-axis. Graph a scatter plot for each individual "ID" using a polynomial equation. In each graph, use the variable "expect" on the X-axis and "expect_cha" on the Y-axis. Make sure to include the equation for each graph and mark the convergence point or points in black, indicating their values. Label the X-axis as "Expect" and the Y-axis as "Change in Expect over Time". Go.


아래 그래프를 보면 수렴점을 제대로 표기하였다. 

그러나, 검은색 화살표가 미학적으로 거슬린다. 그래서 아래와 같이 명령했다. 


"그래프에서 검은색 화살표를 삭제하고 각 ID에 대해 그래프를 그리세요. 출발하세요."

"Delete the black arrow in the graphs and graph for each ID. Go."


아래와 같이 흉물스러운 검정 화살표가 사라졌다. 

하지만, Equation이 상당히 거슬린다. 그리하여 아래와 같이 다시 명령했다. 


"각 그래프에 대한 방정식을 다시 작성하여 다항식 항이 올바르게 표시되도록 하십시오."

"Rewrite the equation for each graph so that the polynomial term shows correctly."


그리하여, 아래와 같이 올바른 항이 표기되었다. 하지만, X-축과 Y-축 범위가 들쑥날쑥이다. 

고로, 아래와 같이 명령했다. "'expect'와 'expect_cha'의 범위를 제공해 주세요." "Provide me with the ranges for 'expect' and 'expect_cha'."


"X축에는 0에서 6까지의 스케일을 사용하여 각 그래프를 수정합시다. Y축에는 -3에서 5까지입니다. 나머지는 그대로 유지됩니다."

결국 생성된 아래 그래프는 각각 개인 그래프의 X와 Y의 범위가 일정하다. 

def save_revised_graph_to_image(data, id, directory):

    subset = data[data['id'] == id].dropna(subset=['expect', 'expect_cha'])

    x = subset['expect'].values.astype(float)

    y = subset['expect_cha'].values.astype(float)    

    # Fit polynomial equation

    coefficients = np.polyfit(x, y, 2)

    poly = np.poly1d(coefficients)

    x_new = np.linspace(0, 6, 300)

    y_new = poly(x_new)


    # Find convergence point (where y=0)

    roots = np.roots(coefficients)    

    plt.figure(figsize=(8, 5))

    plt.scatter(x, y, label=f'ID: {id}')

    plt.plot(x_new, y_new, 'r-', label=f'Equation: {coefficients[0]:.2f}x^2 + {coefficients[1]:.2f}x + {coefficients[2]:.2f}')    

    for root in roots:

        if 0 <= root <= 6:  # Only plot roots that are within the revised range of x values

            plt.plot(root, 0, 'ko')

            plt.annotate(f'{root:.2f}', xy=(root, 0))    

    plt.xlim(0, 6)

    plt.ylim(-3, 5)

    plt.xlabel('Expect')

    plt.ylabel('Change in Expect over Time')

    plt.legend()

    plt.title(f'Scatter plot for ID: {id}')

    plt.grid(True)    

    # Save the plot as an image

    plt.savefig(f"{directory}/revised_graph_for_id_{id}.png")

    plt.close()


# Remove previous images and save each revised graph as a new image

shutil.rmtree(image_directory)

os.makedirs(image_directory)


for id in unique_ids[~np.isnan(unique_ids)]:

    save_revised_graph_to_image(data, id, image_directory)



매거진의 이전글 GPT와 대화하기 4
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari