새로워지기/마흔의 생활코딩

Pandas AI | 판다스AI with LLM Agent, OpenAI, MySQL

청춘만화 2024. 6. 19. 13:48

파이썬의 데이터 분석 라이브러리로 "관계형" 또는 "레이블이 지정된" 데이터 작업을 쉽게 할 수 있도록 설계된 빠르고 유연하며 표현력이 풍부한 데이터 구조를 제공하는 Python 패키지다. 데이터 분석을 위한 도구로 넘파이와 함께.. 완전 전문가가 아니라면 어쩌면 넘파이보다 더 자주 만나게 되는 패키지이다. 

그 패키지를 기반으로 LLM을 적용한, 데이터 분석을 위한 오픈 소스 AI 에이전트가 pandas-ai이다.

1. Pandas AI | 판다스AI와 로컬 LLM와의 만남(feat.ollama)
👉  2. Pandas AI | 판다스AI with Agent, OpenAI, MySQL 

지난번엔 로컬 LLM을 통해 데이터프레임을 스마트데이터프레임으로 구성하여 이것 저것 해봤다면 이번엔 순수? LLM Agent에 직접 파일을 업로드하는 방법, 로컬 LLM이 아닌 오픈API를 사용하는 방법 그리고 MySQL 데이터 베이스에 직접 연결해서 사용하는 실습을 정리해보기로 한다 

 

 

 


0. 레퍼런스

데이터 분석을 위한 오픈 소스 AI 에이전트

 

PandasAI - Conversational Data Analysis

PandasAI is a Python library that integrates generative artificial intelligence capabilities into pandas, making dataframes conversational

pandas-ai.com

깃허브

 

GitHub - Sinaptik-AI/pandas-ai: Chat with your database (SQL, CSV, pandas, polars, mongodb, noSQL, etc). PandasAI makes data ana

Chat with your database (SQL, CSV, pandas, polars, mongodb, noSQL, etc). PandasAI makes data analysis conversational using LLMs (GPT 3.5 / 4, Anthropic, VertexAI) and RAG. - Sinaptik-AI/pandas-ai

github.com

 

 

 


LLM Agent 

1. 먼저 지난번과 같이 로컬 llm으로 초기화, streamlit으로 화면을 구성한다.이번엔 지난번과 다르게 사이바 형태의 UI를 구성해보기로 한다 

from pandasai.llm.local_llm import LocalLLM
import streamlit as st 

model = LocalLLM(
    api_base="<http://localhost:11434/v1>",
    model="llama3"
)

#st.UI-타이틀 
st.title("Data analysis with PandasAl Agent")

#st.UI-데이터 세트로드 
uploaded_file = st.sidebar.file_uploader(
    "upload a CSV file", 
    type=['csv']
)

2. 그리고 지난번과 같이 파일이 정상적으로 업로드되면 해당 파일을 읽어서 3행을 테이블 형태로 구성하는 코드를 작성한다. 달라진 점은 LLM Agent의 인스턴스를 생성하여 모델에 연동하고, 답변도 데이터프레임이 아닌 에이전트로부터 받도록 구성되어 있다. 

...

#st.UI-read & write 
if uploaded_file is not None:
    data = pd.read_csv(uploaded_file)
    st.write(data.head(3))

    agent = Agent(data, config={"llm":model})
    prompt = st.text_area("Enter your prompt:")
    
    if st.button("Generate"):
        if prompt:
            with st.spinner("Generating response..."):
                st.write(agent.chat(prompt))

 

파일 업로드 후 '데이터세트의 마지막 3개열을 반환'을 요청한 결과이다. 

그리고 이번엔 조금더 많은 파일을 업로드 후, 결측치를 물어보고 위치와 해당 행을 출력해가는 과정이다. 

그리고 이번엔 나이에 대한 박스플롯을 멤버십 유형별로 그려달라고 요청한 결과이다. 

 

 

 


OpenAI API 

가장 다른 점이 있다면, from pandasai.llm.local_llm import LocalLLM 대신 from pandasai.llm.openai import OpenAI를 사용하고 있다는 점이다. 그리고 API 키를 입력하는 부분이 추가되었다.

from pandasai.llm.openai import OpenAI
import streamlit as st 
from pandasai import SmartDataframe
import pandas as pd
from pandasai import Agent

OPENAI_API_KEY = "sk-********************************"
llm = OpenAI(api_token=OPENAI_API_KEY)

#st.UI-타이틀 
st.title("Data analysis with PandasAl Agent")

#st.UI-sidebar 데이터 세트로드  
uploaded_file = st.sidebar.file_uploader(
    "upload a CSV file", 
    type=['csv']
)

#st.UI-read & write 
if uploaded_file is not None:
    data = pd.read_csv(uploaded_file)
    st.write(data.head(3))

    agent = Agent(data, config={"llm":llm})
    prompt = st.text_area("Enter your prompt:")
    
    if st.button("Generate"):
        if prompt:
            with st.spinner("Generating response..."):
                st.write(agent.chat(prompt))

이를 통해 Age와 Total Spend(0.96)와 Items Purchased(0.74)는 강한 양의 상관 관계를 갖고 있음을 알 수 있었다. 

 

 

 


MySQL

일단 아래 링크를 참고해서 MySQL을 설치하고

 

(Mac) MySQL 완전 삭제, 설치 그리고 설정 가이드

Local LLM Agent로 서비스를 구성하려다보니.. 간만에 MySQL을 다시 설치하게 되었다. 8.x이후부터 바뀐 정책도 그렇고 컴퓨터에 남아 있는 버전은 너무 오래되었고 기억도 가물가물해서.. 이전에 작성

normalstory.tistory.com

캐글에서 적절한 샘플 데이터(csv)를 다운로드 받은 후 데이터베이스 테이블에 import 한다. 

 

E-commerce Customer Behavior Dataset

Exploring Customer Engagement and Purchasing Patterns in an E-commerce

www.kaggle.com

 

from pandasai.llm.local_llm import LocalLLM
import streamlit as st 
from pandasai.connectors import MySQLConnector
from pandasai import SmartDataframe

model = LocalLLM(
    api_base="<http://localhost:11434/v1>",
    model="llama3"
)

my_connector = MySQLConnector(
    config={
        "host": "localhost",
        "port":3306,
        "database":"EComUsr",
        "username":"root",
        "password":"****!",
        "table": "customer"
    }
)

df_connector = SmartDataframe(my_connector, config={"llm":model})

#st.UI-타이틀 
st.title("MySQL with Llama3")

prompt = st.text_input("Enter your prompt:")

if st.button("Generate"):
    if prompt :
        with st.spinner("Generate response.."):
            st.write(df_connector.chat(prompt))