XGBoost를 사용한 기계 학습목적
다음은 복잡한 기계 학습 알고리즘을 처리하기 위해 JMP와 Python 간의 연결을 사용하여 app-builder로 구축한 첫 번째 애플리케이션의 시도입니다.
이 앱의 목적은 jsl로 작성된 그래픽 사용자 인터페이스를 실행하고 해당 인터페이스를 "XGBoost" 기계 학습 API와 연결하는 것입니다.
사용하는 방법
나는 홀드아웃/교차 검증/그리드 검색이라는 3가지 유형의 검증 방식으로 작업할 수 있는 가능성을 구현했습니다. 회귀와 분류는 모두 몇 가지 목표와 고전적인 측정 기준을 기반으로 개발되었습니다.
학습이 끝나면 학습/검증 세트 또는 교차 검증을 위한 평균/표준 개발에 대한 메트릭 값이 보고서에 제공됩니다. 그리드 검색 훈련의 경우 보고서에는 최상의 하이퍼파라미터 결과가 제공되며 조기 중지를 사용하도록 선택할 수 있습니다. 모델을 다시 훈련하지 않고도 새로운 데이터를 예측하기 위해 Python 모델을 내보낼 수도 있습니다(그러나 Python 환경에서 수행해야 함).
그런 다음 앱을 사용하기 전에 JMP가 Python으로 해당 링크를 처리할 수 있는지 확인해야 합니다.




새로운 2024 릴리스의 경우:
파이썬 라이브러리의 업그레이드로 업데이트가 많이 필요했는데, 이를 기회로 실전에서 놓쳤던 기능을 추가하고 버그도 꽤 많이 수정했습니다...
- 이제 python/JMP 사이의 충돌을 피하기 위해 열 이름에 특정 패턴을 갖도록 강제하고(모든 특수 문자, 구두점, 공백을 지웁니다) JMP 16에서 도입된 새로운 가능성을 활용하여 점이 있는 10진수 형식을 방지합니다. 이전에 겪었던 특정 충돌.
- 또한 이제 분류 문제에 대한 응답이 올바른 형식인지 확인하고 있습니다(숫자여야 하며 xgboost에 대한 변경 사항이 0에서 시작해야 하며 아마도 numpy 변경 사항과 연결되어 있을 것임). 이진 응답에 대한 클래스 문제를 수정하고 있습니다. 이는 추가 기능의 첫 번째 버전에서 어떤 경우에 발생할 수 있습니다.
- 생성된 학습 및 테스트 데이터 세트를 csv로 내보내고 이 추가 기능을 클래식 Python(따라서 다른 ML 알고리즘과 혼합하여 더욱 재미있게) 동일한 기반으로 작업할 수 있도록 확인란을 추가했습니다 ^^ ).

- 'Gamma' 하이퍼파라미터 추가(일명 'min_split_loss', 즉 노드의 추가 분할을 정당화하는 데 필요한 손실 함수의 최소 감소를 지정하여 트리 정규화 정도 확인).

- 이제 피팅 후 모델의 하이퍼파라미터를 추가 기능과 동일한 순서로 체계적으로 표시하여 이러한 하이퍼파라미터를 모델 성능과 더 쉽게 연관시키고 추가 기능에 다시 쉽게 복사할 수 있도록 합니다(그리드 검색에서 이동할 때). 예를 들어 교차 검증을 위해).

- 이제 훈련된 모델에서 사용하고 F-Score로 정규화한 특성 목록을 검색하고 정규화가 0.20보다 큰 특성을 표시한 다음 JMP에 직접 복사하여 붙여넣을 수 있는 형식으로 로그에 표시합니다. 따라서 다른 분석에 더 쉽게 추가할 수 있습니다.) 이 목록은 F-Score 값을 감소시켜 정렬됩니다.


시스템 설정
다음 시스템 구성을 사용하여 추가 기능을 개발하고 테스트했습니다.
JMP 17
numpy, pandas, pathlib, 다중 프로세스, scikit-learn, xgboost가 포함된 Python 3.11 또는 3.12
클래식 데이터 세트(타이타닉, 보스턴 하우스 등)를 사용하여 테스트되었습니다.

예측 모델링 및 데이터 마이닝Re: JMP Addin에서 XGBoost를 사용한 기계 학습(JMP 앱 + Python)오케이 프랑크
답장을 보내 주셔서 감사합니다.
이미 바다처럼 나는 단지 알고 싶었습니다. 이제 분명합니다.
수신펠리체
Re: JMP Addin에서 XGBoost를 사용한 기계 학습(JMP 앱 + Python)Felice 안녕하세요. 피드백을 보내주셔서 감사합니다!
문제가 정확히 무엇인지는 기억나지 않지만 파이썬 전송 중에 숫자가 아닌 데이터를 처리하는 데 문제가 있었습니다.
그리고 JMP가 파이썬 코드를 실행하자마자 오류 보고가 없기 때문에 근본 원인을 파악하고 해결하지 못했습니다. categorial에 대한 Python 스크립트 코드는 괜찮았고 JMP 코드도 있었지만 JMP 코드와 Python 코드가 스크립트를 충돌시켰습니다...
언젠가는 다시 돌아봐야 겠어요!
예를 들어 yes = 1 및 no = 2 또는 setosa = 1, versicolor = 2, virginica =3 등과 같이 값을 다시 코딩하면 됩니다. 조금 번거롭지만 이 버그를 우회하기 위해서였습니다.
Re: JMP Addin에서 XGBoost를 사용한 기계 학습(JMP 앱 + Python)차오 프랑크. 당신의 애드인은 정말 잘되었습니다.
그냥 호기심. 분류 작업을 선택할 때 응답 변수 유형이 숫자여야 하는 이유는 무엇입니까? 범주형 변수(나쁨 vs 좋음, 기준선 vs 실험, 고양이 vs 개 등)를 기대하고 있었습니다.
수신펠리체
Re: JMP Addin에서 XGBoost를 사용한 기계 학습(JMP 앱 + Python)프랭크는 문제 없습니다. 공유해 주셔서 감사합니다.
Re: JMP Addin에서 XGBoost를 사용한 기계 학습(JMP 앱 + Python)감사합니다!
예, Python 지원이 시간이 지남에 따라 개선되기를 바랍니다.
인터페이스의 경우 죄송합니다. 거의 여가 시간에 이 추가 기능을 만들었지만 회사에서 JMP 라이선스를 지불했기 때문에 이 소스 코드가 비공개로 유지되기를 원하는 고용주가 소스 코드 게시를 확인해야 한다고 생각합니다.
Re: JMP Addin에서 XGBoost를 사용한 기계 학습(JMP 앱 + Python)이것은 훌륭합니다! 공유해 주셔서 감사합니다*
Windows의 Python과 관련하여 Python 3.6이 포함된 Anaconda는 JMP 15에서 기본적으로 작동하지만 2년 된 패키지이므로 모든 패키지를 업데이트해야 합니다. JMP가 다음 버전에서 Python 지원을 개선하기를 바랍니다.
(*참고) 구축한 인터페이스는 다른 Python API에서 사용할 수 있습니다. 소스코드도 공개하셨나요?
문안 인사.
Re: JMP Addin에서 XGBoost를 사용한 기계 학습(JMP 앱 + Python)안녕 루스
나는 무슨 일이 일어나고 있는지에 대한 단서가 없어서 매우 유감입니다. Mac OS가 Windows와 다르게 디렉토리를 처리하는 방식에 문제가 있다고 생각했지만 충돌은 파이썬 부분에 있으며 그 이전에는 없습니다. 또한 파일 내보내기 옵션을 사용하지 않은 동안 충돌이 발생합니다.
아마도 당신이 언급한 패키지 문제와 관련이 있을 것입니다. Windows 10의 동일한 패키지가 여전히 괜찮은지 확인하기 위해 가능한 한 빨리 패키지를 업그레이드하려고 합니다.
내 애드인을 사용해 주셔서 감사합니다! 
프랑크
Re: JMP Addin에서 XGBoost를 사용한 기계 학습(JMP 앱 + Python)제 문제를 봐주셔서 감사합니다. @Franck_R .내 Python 설치는 다른 코드(제안한 테스트 코드 포함)에 대해 JMP와 함께 작동하지만 아직 발견하지 못한 패키지 또는 추가 기능에 필요한 기타 누락된 구성 요소에 문제가 있을 수 있습니다. 지금은 완전히 당황했습니다. 기회가 되면 Windows 컴퓨터에서 설정하여 다시 시도해 보겠습니다.
이것을 커뮤니티에 올려주셔서 다시 한 번 감사드립니다. 매우 유용한 애플리케이션입니다!
Re: JMP Addin에서 XGBoost를 사용한 기계 학습(JMP 앱 + Python)내 컴퓨터에 문제가 없는 동일한 데이터 세트:

Re: JMP Addin에서 XGBoost를 사용한 기계 학습(JMP 앱 + Python)안녕,
예 문제는 실제로 Python 부분에 있습니다. 죄송합니다.
파이썬 코드가 전혀 실행되지 않았기 때문에 이상합니다: "try" 명령 전에 코드가 충돌했습니다! 그런 충돌은 절대 넣지 않습니다....
하지만 JMP는 Python의 오류 메시지를 작성하지 않기 때문에 로그를 디버그하기가 까다롭습니다... 설명 없이 Python 코드만 던집니다... Python을 JMP와 함께 사용하고 Python에 문제가 발생하면 명시적인 오류 코드가 없습니다. JMP 외부에서 모든 Python 코드를 개발한 다음 해당 코드를 JMP에 통합해야 했습니다.
이 데이터 세트는 내 컴퓨터에서 잘 처리되지만 Windows 10 및 Python 3.7에서 작업합니다.
가장 먼저 확인해야 할 것은 JMP 15.1이 Python 3.8을 처리할 수 있다는 것입니다. 사실인지 확실하지 않습니다(예를 들어 Python 3.7에는 몇 가지 어려움이 있었습니다. 참조). https://community.jmp.com/t5/Discussions/JMP-14-Python-abilities-working-Im-confused/td-p/184515
스크립팅 색인에서 예제 코드를 실행해 보십시오.
여기에 기본 이름( 1 );
파이썬 초기화();
파이썬 제출(
"\[
str = '날쌘 갈색 여우가 게으른 개를 뛰어넘다';
a = 200;
]\"
);
getStr = Python Get( str );
getNum = Python Get(a);
표시( getStr, getNum );
파이썬 용어();
그렇다면 데이터 세트에 누락된 값이 있습니까? (데이터 세트에서 누락된 값을 확인하지 않으며 일부 누락된 값이 있는 재작업된 보스턴 데이터 세트인 경우 충돌할 수 있습니다.)
나는 그것을 확인할 방법이 없기 때문에 내 코드가 Mac OS를 처리할 수 있는지도 확신할 수 없으며 Python 통합은 아마도 Windows와 약간 다를 수 있습니다...
Re: JMP Addin에서 XGBoost를 사용한 기계 학습(JMP 앱 + Python)사용할 수 있게 해주셔서 감사합니다! 적절한 유효성 검사 열과 숫자 ID 열을 포함하고 숫자 표시기로 "chas" 변수를 포함하도록 약간 조정한 Boston Housing 데이터에서 실행하려고 합니다. (아래 스크린샷 참조) MacOS 10.15.3에서 Python 3.8.2 및 numpy 1.18.2, pandas 1.0.3, scikit-learn 0.23.1 및 XGBoost 1.1.0에서 JMP Pro 15.1을 실행하고 있습니다. 아래 로그를 복사하고 있습니다. 분명히 무언가가 약간 작동하지만 Python이 충돌합니다. 결국 "Send Expects Scriptable Object in access or evaluation of 'Send'"라는 경고가 표시됩니다. 이 오류는 Python이 충돌하고 보낼 개체를 만들지 않았기 때문에 발생한다고 생각합니다.
무엇이 잘못되고 있는지에 대한 아이디어가 있습니까? 나는 스크립팅 전문가는 아니지만 이 약점 외에도 로그의 일부 프랑스어 출력을 이해하지 못합니다 
감사해요!
룻
"*** DEBUG Report: Start"
"******* Fonction update OK"
"**** Valeurs initialisées"
2
"**** OK avant lancement algo"
"***** La table de travail est:"
DataTable("Boston Housing.jmp")
/Library/Frameworks/Python.framework/Versions/3.8/lib/python38.zip
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/lib-dynload
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/aeosa
/**********/
# Partie import des biblios Python
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_squared_error
from xgboost import XGBRegressor
from joblib import dump, load
from pathlib import Path
# Optionnel
#from xgboost import plot_tree
# On affiche pas les warnings python
import warnings
warnings.simplefilter("ignore")
try:
# On créé des DataFrame avec les Data Table JMP
data_frame_train = pd.DataFrame(dt_train)
data_frame_valid = pd.DataFrame(dt_valid)
data_frame_test = pd.DataFrame(dt_test)
# On récupère l'index du DF avec Id pour le réutiliser dans la génération du dataframe de la réponse
Id_train = data_frame_train[colId]
Id_valid = data_frame_valid[colId]
Id_test = data_frame_test[colId]
# On fixe l'index du DF avec Id
data_frame_train.set_index(colId)
data_frame_valid.set_index(colId)
data_frame_test.set_index(colId)
# On conserve la table train non modifiée
data_frame_train_initial = pd.DataFrame(dt_train)
# On fixe l'index du DF avec Id
data_frame_train_initial.set_index(colId)
# On fixe le y
y_train = data_frame_train[colY]
y_valid = data_frame_valid[colY]
y_test = data_frame_test[colY]
# On fixe les facteurs: ce sont ici les colonnes récupérées de la liste des colonnes de JMP donc les features contenus dans liste_colonne
X_train = data_frame_train[liste_colonne]
X_valid = data_frame_valid[liste_colonne]
X_test = data_frame_test[liste_colonne]
# MODELISATION
# On définit le modèle comme étant un régresseur XGBoost
# my_model = XGBRegressor(n_estimators=100, learning_rate=0.05, random_state=0)
#param_dist = {'n_estimators':2,'learning_rate'=0.05,'random_state'=0 }
# ATTENTION: le transfert de variable est piégeux car un integer est converti en decimal
# Or dans cette list de paramètre XGBoost ne tolère pas tout le temps des décimals, il faut donc convertir en Integer avec int()
# Conversion des paramètres:
Int_Nb_Iterations = int(Nb_Iterations)
Int_Max_Depth = int (Max_Depth)
Int_Min_Child = int (Min_Child)
# Assignation des paramètres
max_depth = Int_Max_Depth
min_child_weight = Int_Min_Child
subsample = Sub_Sample
colsample_bytree = Col_Sample
objective = Objective
num_estimators = Int_Nb_Iterations
learning_rate = Learning_Rate
my_model = XGBRegressor(max_depth=max_depth,min_child_weight=min_child_weight,subsample=subsample,colsample_bytree=colsample_bytree,objective=objective,n_estimators=num_estimators,learning_rate=learning_rate)
# On fitte le modèle
my_model.fit(X_train, y_train)
# On récupère les prédictions sur le set de la table train partie validation
predictions_sur_train_XGBoost = my_model.predict(X_train)
predictions_sur_validation_XGBoost = my_model.predict(X_valid)
# Calculate Score
#score_train = mean_absolute_error(predictions_sur_train_XGBoost, y_train)
#score_valid = mean_absolute_error(predictions_sur_validation_XGBoost, y_valid)
if Type_Score == 'MAE': score_train = mean_absolute_error(predictions_sur_train_XGBoost, y_train); score_valid = mean_absolute_error(predictions_sur_validation_XGBoost, y_valid)
elif Type_Score == 'RMSE': score_train = mean_squared_error(predictions_sur_train_XGBoost, y_train) ; score_valid = mean_squared_error(predictions_sur_validation_XGBoost, y_valid)
else: print("toto")
# Export prévisions sur table train et validate
output_train_XGBoost = pd.DataFrame({colY: predictions_sur_train_XGBoost,colId : Id_train})
output_validation_XGBoost = pd.DataFrame({colY: predictions_sur_validation_XGBoost, colId : Id_valid })
# On concatene les dataframe train et valid afin de réentrainer le modèle sur l'ensemble des données pour prédire le y_test
X_full = pd.concat([X_train, X_valid])
y_full = pd.concat([y_train, y_valid])
# On réentraine le modèle sur train + validate et on l'exporte sur test
my_model.fit(X_full, y_full)
predictions_sur_test_XGBoost = my_model.predict(X_test)
output_test_XGBoost = pd.DataFrame({colY: predictions_sur_test_XGBoost,colId : Id_test})
# ------------------------- Essais de sortie graphique: plantage car JMP 15.1 n'est pas fonctionnel
# fit = alg.fit(dtrain[ft_cols].values, dtrain['y'].values)
# ft_weights = pd.DataFrame(fit.feature_importances_, columns=['weights'], index=ft_cols)
# model = xgb.train(params, d_train, 1000, watchlist)
# fig, ax = plt.subplots(figsize=(12,18))
# xgb.plot_importance(model, max_num_features=50, height=0.8, ax=ax)
# plt.show()
# ft_weights = my_model.feature_importances_
#import matplotlib.pylab as plt
#from matplotlib import pyplot
#from xgboost import plot_importance
#plot_importance(model, max_num_features=10) # top 10 most important features
#plt.show()
# -------------------------
if int(File_Save_Check) == 1:
data_folder = Path(File_Save_Directory)
file_to_save = data_folder / File_Save_Name
dump(my_model, file_to_save)
except:
print("python has crashed check your parameters")
/**********/
Send Expects Scriptable Object in access or evaluation of 'Send'


답변: XGBoost를 사용한 기계 학습안녕
새로운 Python 버전 + 새로운 기능 + 버그 수정과의 호환성으로 추가 기능을 업데이트했습니다.
답변: XGBoost를 사용한 기계 학습matplotlib과 충돌이 발생한 이유에 대해 설명할 수 있습니다. JMP의 기본 창 이벤트 루프와 matplotlib의 기본 창 이벤트 루프가 충돌합니다. Python 공유 라이브러리가 JMP의 프로세스 공간에 로드되므로 JMP에는 이미 기본 창이 있습니다. 일반적인 방법으로 호출된 Matplotlib는 기본 창 루프가 있다고 믿습니다. 선택한 matplolib 백엔드에 전적으로 달려 있습니다. 14 이후에는 maptplotlib 백엔드를 비대화형 'AGG' 백엔드로 강제 설정했으며, matplotlib에 그림을 표시하는 대신 저장하라고 지시하면 완전히 사용할 수 있습니다. 여러분이 볼 수 있는 또 다른 문제는 JMP가 모든 경우에 충돌을 일으키지 않고 종료된다는 것입니다. 닫힌 마지막 matplotib 창은 JMP 제어 외부에서 C 수준의 종료()를 호출했습니다. JMP 18.0은 AGG 백엔드에 강제하지 않고 Windows에서 matplotlib를 허용하는 경우 좀 더 관대하지만 Mac에서는 기본 Cocoa 백엔드가 여전히 충돌합니다. matplotlib 개발자가 공개한 버그 보고서가 있습니다. Mac에서는 PySide 또는 PyQt 백엔드를 사용하여 어느 정도 성공했지만 여전히 실패했습니다. matplotlib를 호출하는 가장 좋은 방법은 Figure를 이미지로 저장하는 것입니다.
답변: XGBoost를 사용한 기계 학습안녕 폴,
후속 조치와 설명에 감사드립니다! JMP 18에서 Python과의 통합이 계속되는 것을 보니 반갑습니다...