JMP에서 파이썬의 광범위한 기능을 활용하기 위해 노력하는 과정에서 파이썬의 유연성과 JMP의 직관적이고 상호작용적인 사용자 경험을 통합하는 과제에 직면했습니다. JMP 18 이전에는 JMP의 번거로운 파이썬 통합 기능을 우회하기 위해 서버에서 파이썬을 실행하는 임시방편을 사용했습니다. 하지만 JMP 18 출시와 함께 파이썬 통합 기능이 다시 도입되어 이 과정이 간소화되었습니다.
프로그래밍 전문 지식 없이도 JMP 사용자가 Python을 활용할 수 있도록 지원한다는 초기 개념을 바탕으로 JMPyFacade(JMPy)를 개발했습니다. 이 도구는 JMP와 유사한 친숙한 인터페이스를 제공하여, 동적으로 생성된 사용자 인터페이스를 통해 미리 정의된 Python 서비스를 실행할 수 있도록 하며, 동시에 기본 Python 및 JSL 코드를 추상화합니다.
본 발표에서는 JMPyFacade의 기술 아키텍처를 살펴보고 JMP와 Python 간의 격차를 효과적으로 해소하는 방법을 시연합니다. 참석자들은 Python을 JMP 내에서 활용하여 효율적이고 매력적인 데이터 분석을 수행하는 방법을 배우게 됩니다.
안녕하세요, JMP와 Python을 연동하여 원활하고 효과적인 분석을 구현하는 방법에 대한 포스터 발표에 오신 것을 환영합니다. 저는 핀란드 무라타에 근무하는 야르모 히르보넨입니다. 이 포스터에서는 JMP에서 Python을 활용해야 하는 이유, 즉 JMP에 Python을 통합해야 하는 이유를 설명하겠습니다. 통합과 관련하여 몇 가지 유의할 사항과, 저와 동료 에로가 무라타에서 개발한 통합 활용 애플리케이션을 소개하겠습니다. 그럼 먼저 JMP에서 이 기능을 활용해야 하는 이유부터 살펴보겠습니다.
JMP는 뛰어난 분석 기능을 갖춘 시각적이고 상호작용적인 도구입니다. 반면 파이썬은 데이터 관련 작업에서 사실상 표준 프로그래밍 언어로 자리 잡았습니다. 파이썬은 잘 구축된 라이브러리가 많으며, 귀사에서도 자체적인 파이썬 개발 역량을 보유하고 있을 가능성이 있습니다.
저는 이 문제를 두 가지 관점에서 봅니다. 우선, JMP에서 기본적으로 제공되지 않는 기능, 예를 들어 Torch와 같은 머신러닝 모델에 접근할 수 있는 초기 사용자들이 있을 것이고, 기존 JMP에서는 사용할 수 없었던 파일 형식에도 접근할 수 있게 될 것입니다.
한 가지 예로 Parquet 파일을 들 수 있는데, Python에서 Parquet 파일을 열고 통합 기능을 통해 JMP로 가져올 수 있습니다. Python을 먼저 사용하는 사용자라면 JMP의 시각화 및 대화형 도구를 활용할 수 있으며, 이러한 도구는 JMP에서 직접 사용하거나 Python에서 통합된 방식으로 사용할 수 있습니다. 물론 JMP에서만 사용할 수 있는 분석 기능도 있습니다. JMP와 Python의 통합과 관련하여 한 가지 유의할 점은 Python이 JMP 18과 함께 설치된다는 것입니다.
JMP 인스턴스당 초기 로드 시 속도가 다소 느립니다. 즉, JMP 인스턴스에 처음 로드될 때 시간이 좀 걸리지만, JMP를 완전히 종료하지 않고 다음 로드 시에는 더 빨라집니다. 아주 간단한 작업을 수행하는 경우에는 이 점을 고려해야 할 수도 있습니다. JSL만 사용하여 구현하는 것이 더 빠를 수 있으므로 시도해 볼 가치가 있습니다.
패키지 관리 및 설치 과정에서 문제가 발생할 수 있지만, 관련 문서가 제공되기는 합니다. 하지만 문제를 해결하는 데 다소 어려움이 있을 수 있습니다. 사용 가능한 환경이 하나뿐이므로 가상 환경 작업에 익숙한 경우 현재 작업 통합 환경에서는 가상 환경을 사용할 수 없습니다. JSL과 Python의 데이터 타입 변환에 대한 기본적인 이해가 필요하지만, 관련 문서가 웹페이지에 제공되어 있습니다. 스코프(스코핑)는 다소 혼란스러울 수 있습니다. Python은 기본적으로 전역 스코프를 사용하며, 변수 이름을 어떻게 지정하느냐에 따라 여러 스크립트 간에 변수가 얽힐 수 있습니다.
마지막으로, 제 생각에는 파이썬 디버깅과 개발이 다소 번거롭고 몰입하기 어려운 경험일 수 있다는 점이 가장 큰 문제 중 하나일 것입니다. 이는 주로 JMP에서 파이썬을 초기화하거나 커널을 재시작할 수 없기 때문이며, 결국 일종의 "개발 주기"에 갇히게 됩니다. 파이썬으로 개발을 하고 테스트를 하려고 하는데, 예를 들어 특정 변수에서 정리해야 할 부분이 있을 것 같다는 생각이 들게 되는 것이죠.
현재로서는 JMP 인스턴스를 닫고, JMP를 다시 실행한 다음, 모든 것을 다시 로드하여 코드를 테스트하는 방법밖에 없습니다. 이는 순환 과정이 아니라, 기본적으로 여기서 오류가 발생하여 처음부터 전체를 다시 시작해야 하는 상황입니다. 즉, 작업 흐름이 끊어지는 것입니다. 이는 사용자에게 불편함을 초래하며, 파이썬 코드를 작성하는 방식에 따라 어느 정도 완화할 수는 있습니다.
그럼 이제 저희 애플리케이션인 JMPyFacade에 대해 알아보겠습니다. 먼저, 이름에서 알 수 있듯이 복잡한 JMP 및 Python 코드를 JMP와 유사한 사용자 인터페이스로 감싸는 방식에서 유래했습니다. 버전 관리 기능이 추가되어 JMP 사용자가 미리 정의된 Python 기능에 접근할 수 있게 됩니다. 이러한 기능을 서비스라고 부릅니다. 서비스는 간단한 데이터셋 생성부터 훨씬 복잡한 학습 모델 구축까지 다양합니다.
저희가 이 기능을 통해 하려는 것은 JMP 사용자들이 파이썬을 사용하고 있다는 사실조차 인지하지 못한 채 파이썬의 기능을 활용할 수 있도록 하는 것입니다. 이전에도 비슷한 기능을 구현한 적이 있지만, 당시에는 JMP의 파이썬 통합 기능이 다소 불편했기 때문에 서버를 통해 우회하는 방식을 사용했습니다. 하지만 JMP 18부터는 네이티브 통합 기능을 사용할 수 있게 되었고, 상당히 잘 작동합니다.
사용자가 애플리케이션을 실행하면 다음과 같은 흐름이 나타납니다. 먼저 애드인을 실행하고, 업데이트 여부를 확인합니다. 업데이트가 없으면 업데이트를 받고 애드인을 다시 실행합니다. 업데이트가 없는 경우 JMP에서 LS Python을 초기화합니다. 이 단계의 목적은 기본적으로 주문 업데이트를 생성하는 것입니다. 사용자가 애드인을 실행하지 않은 상태에서 실행하면, 이와 같은 애플리케이션에서 주문 정보가 존재하지 않는 경우 문제가 발생할 수 있습니다.
이러한 초기화가 완료되면, 패키지 관리 시스템에서 업데이트해야 할 패키지가 있는지 확인하고, 필요한 경우 업데이트합니다. 업데이트할 패키지가 없으면 다음 단계로 진행합니다. 사용자가 테이블을 열어 놓았는지 확인하고, 테이블이 없으면 추가 기능을 종료하고 사용자에게 테이블을 열어 놓고 실행하라고 알립니다. 현재로서는 하나의 정적 테이블만 지원하기 때문에 이러한 절차를 따릅니다.
사용자가 테이블을 열고 분석을 원할 때 패키지를 가져옵니다. 문제가 발생하면 다시 한번 중지되고 오류 로그가 표시됩니다. 성공적으로 완료되면 사용자 인터페이스를 초기화하고 생성하여 사용자가 해당 도구를 사용할 수 있도록 합니다. JMP 인스턴스에 사용자 인터페이스가 이미 존재하는 경우, 해당 인터페이스를 프런트엔드로 가져오고 별도의 초기화 작업은 수행하지 않습니다.
백그라운드에서 어떻게 작동하는지 간략하게 설명드리자면, 데이터 유형, JMP 클래스를 활용하고 파이썬 측에서는 Pydantic 패키지를 사용하여 모델을 생성하고 유형 유효성 검사 및 데이터 유효성 검사를 수행합니다.
여기 HDBSCAN의 예시가 있습니다. 예를 들어, 이 features 인수를 보면 문자열 목록이고, 최소 길이가 1인 필드이며 JSON 스키마를 사용하는 숫자 열입니다. JMP는 이 값을 받으면 해당 유형의 클래스를 생성해야 한다는 것을 알게 됩니다. 그러면 버튼, 열 목록 상자가 생성되고, 사용자는 최소한 하나의 숫자 열을 입력해야 제대로 작동합니다. 또한 다양한 데이터 유형에 따라 정수형, 숫자형(8개 항목), 체크박스(불리언 값) 등과 같은 다양한 유형의 요소가 존재합니다.
사용자가 서비스를 실행할 준비가 되면 열을 채우고 '서비스 실행' 버튼을 클릭합니다. 그러면 JMP 코드 측에서 해당 열들을 포함하고 제외되지 않은 열들을 추출하여 데이터의 부분집합을 생성합니다. 이렇게 추출된 데이터는 파이썬 함수를 호출할 때 사용됩니다. 파이썬 코드 관리 측면에서 좀 더 편리하기 때문에 이러한 방식을 사용하는 것입니다.
Python은 알고리즘을 실행하여 부분집합의 값을 업데이트합니다. 부분집합과 Python이 값을 반환하면 JMP는 "이제 원래 테이블을 업데이트할 수 있겠군"이라고 판단합니다. JMP는 테이블을 업데이트하고 부분집합을 닫은 다음, 원래 테이블에 필요한 테이블 스크립트와 열 속성을 생성합니다. 사용자가 서비스를 실행할 때마다, 생성해야 할 열이 있는 경우 테이블에 새 열이 생성됩니다.
이제 몇 가지 사용 예시를 살펴보겠습니다. 기본적인 예시로, 사용자가 애드인을 실행하면 버전 관리 시스템에서 업데이트를 확인합니다. 이 경우 사용자는 애드인에서 tSNE를 실행하려고 하므로 왼쪽 메뉴에서 tSNE를 선택하고 필요한 열을 입력합니다. 또한, tSNE의 공식 문서를 참조하여 작동 방식, 기능, 매개변수 등을 확인할 수 있습니다. 서비스 실행 준비가 완료되면 "서비스 실행" 버튼을 클릭하고 JMP 테이블에 새 열이 추가됩니다. 이제 사용자는 일반적인 JMP 버튼처럼 새 열을 사용하여 작업을 수행할 수 있습니다.
다음으로 보고서 스크립트를 살펴보겠습니다. 이 경우에는 입력 매개변수만 표시됩니다. 여기서는 좀 더 복잡하거나, 과도하거나, 광범위한 예제를 보여드리겠습니다. 이 데모는 대화형 모드입니다. 제 생각에 이것이 저희가 제공하는 최고의 기능 중 하나입니다. 이 기능은 항상 새로운 열을 생성하는 것이 아니라 정적 열을 업데이트하고, 사용자가 사용자 인터페이스에서 값을 변경하면 파이썬 알고리즘을 즉시 다시 실행합니다. 예를 들어, 이 기능을 사용하여 데이터 분석이나 알고리즘 미세 조정을 수행할 수 있습니다.
여기서 사용자는 키보드의 위쪽 화살표를 클릭하면 파이썬 알고리즘이 계속 다시 실행되고, 사용자가 값을 업데이트할 때마다 클러스터링 결과가 변경됩니다. 뷰가 많아질수록 구성 요소도 달라지므로, 사용자가 입력한 값에 따라 완전히 다른 클러스터를 얻을 수 있습니다. 여기서 값을 대화형으로 수정하여 최적의 결과를 찾은 다음, 파이썬으로 돌아가서 해당 결과를 활용할 수 있습니다.
다음으로, 여러 알고리즘을 활용하는 특징 중요도 서비스가 있습니다. 이 서비스는 샤플리 값을 사용하여 모델링이나 예측에 가장 중요한 특징을 결정합니다. 모델을 실행하면 샤플리 값과 선택된 알고리즘의 순위가 반환됩니다. 이 경우 RGBM, XGBoost, AdaBoost가 선택되었습니다. 사용자는 여기에서 값을 복사하여 JMP에서 해당 열을 사용하여 모델링을 시작할 수 있습니다.
마지막으로, 이 도구의 향후 개선 사항에 대해 말씀드리자면, 현재 하나의 정적 테이블만 지원하는 것에 더해 동적 테이블 지원, 더 많은 서비스, 이미지 분석 및 자체 맞춤형 머신러닝 모델 추가 등이 있습니다. 또한, 상호작용성을 개선하여 Python을 통해 그래픽 스크립트를 직접 생성하거나 업데이트할 수 있도록 하고, Python 모델을 내보내고 가져오는 기능도 추가할 예정입니다. JMP의 뛰어난 실험 설계(DOE) 기능을 활용하여 매개변수를 미세 조정하고, 파이프라인을 구축하여 여러 서비스를 순차적으로 실행할 수 있도록 할 것입니다. 현재의 동적 기능을 더욱 개선하고, JMP19의 개선 사항에 따라 리팩토링을 통해 도구를 더욱 향상시킬 수 있도록 할 계획입니다. 마지막으로, 이 도구를 오픈소스로 공개하여 저희뿐만 아니라 더 많은 사람들이 개발에 참여할 수 있도록 하는 방안도 논의해 보겠습니다. 감사합니다.