안녕하세요 여러분,
Datatable을 만드는 JSL 스크립트가 있고, JSL 스크립트 내에 Python 코드 블록이 있는데, 이를 DataTable에 전달하여 훈련된 머신 러닝 모델을 사용하여 DataTable에 대한 예측을 하고 싶습니다. Python 코드 블록 전에는 DataTable에 액세스할 수 있고 JMP에서도 열립니다. 하지만 Python 코드 블록 이후에 "Show(preds_df)"를 사용하여 DataTable을 기반으로 하는 신경망 모델에서 만든 예측에 액세스하려고 하면 "이름이 확인되지 않음: preds_df가 'preds_df'에 액세스하거나 평가 중"이라는 오류가 발생합니다. 저는 JMP Pro 17을 사용하고 있습니다. 검토할 코드 블록은 아래와 같습니다.
<
Clear Log();
Clear Symbols();
Names Default To Here( 1 );
// Define the list of options for the dropdown
SITE = {"SITE_1", "SITE_2"};
MODELS = {"NN_MODEL", "RNN_MODEL"};
PythonConnection = Python Connect();
conn = PythonConnection << Is Connected;
PythonConnection << Send( dt);
close(dt);
PythonConnection << Send(MODELS);
PythonConnection << Execute("
import pandas as pd
from sklearn.preprocessing import StandardScaler
import torch
import pickle
import numpy as np
// Model Selection
if 'NN_MODEL' in MODELS:
model = 'NN_MODEL'
else:
model = 'RNN_MODEL'
# Extract categorical and numerical features from data
categorical_features = ['NAME', 'COUNTRY', 'SCHOOL']
numerical_features = ['AGE', 'SIZE', 'HEIGHT', 'WEIGHT']
# One-Hot encoding for categorical features in place
process_df = pd.get_dummies(dt, columns=categorical_features, drop_first=True)
# Normalize numerical features
scaler = StandardScaler()
new_df[numerical_features] = scaler.fit_transform(process_df[numerical_features])
# Exclude bin columns from the model input
B_cols = ['B1', 'B8', 'B9', 'B10']
B_columns = [col for col in B_cols if col in process_df.columns]
input_df = process_df.drop(B_columns, axis=1)
labels = process_df[B_cols]
ids = process_df[B_cols].index
# Load the trained model based on user selection
if model == 'NN_MODEL':
model_path = '.\\nn_model.pth'
model = torch.load(model_path)
model.eval()
# Convert DataFrame to tensor
in_tensor = torch.tensor(input_df.values, dtype=torch.float32)
# Predict using the model
with torch.no_grad():
nn_preds = model(in_tensor)
nn_preds = torch.round(nn_preds).to(torch.int).numpy()
nn_preds = np.clip(nn_preds, a_min=0, a_max=None)
preds_df = pd.DataFrame(nn_preds.numpy(), index=ids, columns=labels)
else:
model_path = '.\\rnn_model.pkl'
with open(model_path, 'rb') as file:
model = pickle.load(file)
rnn_preds = model.predict(input_df)
rnn_preds = np.clip(rnn_preds, a_min=0, a_max=None)
preds_df = pd.DataFrame(rnn_preds, index=ids, columns=labels)
"
);
Show(preds_df)
>
매우 빠르게 살펴보면, preds_df는 JMP 테이블이 아니라 단지 pandas 데이터프레임이기 때문에 JMP에서 접근할 수 없습니다.
JSL 스크립트 끝에서 다음을 시도해 보세요.
dt = Python Get( preds_df );
dt << New Data View;
또한 JMP 18은 Python 스크립트를 기본적으로 실행할 수 있으므로 JSL 스크립트에 내장할 필요가 없습니다.
파이썬 블록 밖에서 시각화하기 위해 데이터프레임을 JMP 데이터 테이블로 변환하는 방법이 있나요?
"Send는 Send의 액세스 또는 평가에서 스크립트 가능 개체를 예상합니다. "dt" << /*###*/새 데이터 보기/*###*/"
할 수 있습니다. JMP17에서 직접 할 수 있는지는 기억이 나지 않지만 예를 들어 .csv 파일을 통해 할 수 있습니다. pandas 데이터 프레임에서 .csv를 만든 다음 해당 경로를 JMP에 전달하여 엽니다.
첫째, << Execute()의 구문이 잘못되었습니다. 스크립팅 인덱스에서 예를 참조하세요. Execute의 첫 번째 매개변수는 입력의 JSL 목록이고, 그 뒤에 출력 변수의 JSL 목록이 오고, 그 뒤에 스크립트가 오고, 그 뒤에 선택적 echo(1 또는 0) 매개변수가 옵니다.
스크립트는 JSL의 '원시' 문자열 마커 "[여기 스크립트]"로 구분되어야 공백과 줄 끝이 보존됩니다. 구문 오류가 발생하지 않는 것이 놀랍지만 19에서도 동일한 오류가 없는 것을 확인했습니다. 조사하고 있습니다. 저에게는 show preds_df가 단순히 인쇄되었습니다.
dt = .;
누락된 것입니다. 그러면 물론 다음을 의미합니다.
dt << 새 데이터 보기
dt(누락)를 스크립팅할 수 없기 때문에 오류가 발생합니다.
아래 코드는 귀하의 문제를 재현합니다.
conn = Python Connect();
conn << Get Version();
conn << Execute( "
import pandas as pd
import numpy as np
pandas_df = pd.DataFrame(
{
"A": 1.0,
"B": pd.Timestamp("20130102"),
"C": pd.Series(1, index=list(range(4)), dtype="float32"),
"D": np.array([3] * 4, dtype="int32"),
"E": pd.Categorical(["test", "train", "test", "train"]),
"F": "foo",
}
)
print(pandas_df)
]\", echo(1) );
dt = Python Get(pandas_df);
show(dt);
dt << New Data View;
이 코드는 예상대로 실행됩니다
conn = Python Connect();
conn << Get Version();
conn << Execute( {},{},"\[
import pandas as pd
import numpy as np
pandas_df = pd.DataFrame(
{
"A": 1.0,
"B": pd.Timestamp("20130102"),
"C": pd.Series(1, index=list(range(4)), dtype="float32"),
"D": np.array([3] * 4, dtype="int32"),
"E": pd.Categorical(["test", "train", "test", "train"]),
"F": "foo",
}
)
print(pandas_df)
]\", echo(1) );
dt = Python Get(pandas_df);
show(dt);
dt << New Data View;
주의할 점 몇 가지 JMP 17은 JMP 18 이상과 함께 설치된 임베디드 Python이 아닌 사용자 환경에서 Python을 활용한 마지막 버전입니다.JMP 14-17에서 Python Send(dt); 는 데이터 테이블을 임시 CSV 파일에 저장한 다음 pandas가 해당 CSV 파일을 데이터 프레임으로 읽어오도록 하여 Python 환경에서 pandas 데이터 프레임을 생성했습니다.Python Get(df);는 pandas가 데이터 프레임을 CSV 파일에 쓰고 JMP가 CSV 파일을 가져오도록 하는 것과 유사하게 동작했습니다.즉, JMP 데이터 테이블과 pandas 데이터 프레임의 데이터 사본이 2개 있었습니다.
이것은 내장된 Python 3.11.x와 내장 jmp가 도입되면서 JMP 18에서 변경되었습니다. jmp.DataTable 클래스를 제공하는 import 패키지입니다. 이는 Python에서 액세스할 수 있는 JMP 데이터 테이블에 대한 메모리 내 라이브 참조를 도입합니다. JMP 18+의 Python Send(dt);는 이제 pandas 데이터그램 대신 jmp.DataTable 객체를 생성합니다. dt2 = Python Get(dt)는 변수에 할당하는 데이터 테이블 참조만 가져옵니다. dfdt = Python Get(data_frame);는 여전히 CSV 파일을 통해 데이터 프레임을 데이터 테이블로 변환하고 로드하는 이전 메커니즘을 사용합니다. JMP 18에는 스크립트 디렉토리에 원래 dt->csv->df 및 df->csv->dt 변환을 수행하는 방법을 보여주는 Python 샘플 스크립트가 있습니다. JMP 19는 Portable Dataframe Protocol을 지원하므로 메모리에서 dt->df 또는 df->dt로 이동하는 한 줄짜리 코드입니다. dt2pandas.jsl, dt2pands.py, dt2pandas2dt.py라는 샘플
JMP 17의 경우:
Names Default to here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
// I have multiple Python's on system so I choose 3.10 where I have
// matplotlib, pandas, numpy, ... installed
Python Init(Use Python Version("3.10"));
Python Send(dt);
close(dt);
dtdf = Python Get("dt");
Show(dtdf);
dtdf << New Data View;
이것은 제 머신에서 잘 작동합니다. 이것을 실행할 수 없다면 오류가 표시되는지 확인하기 위해 로그를 검사하세요. 필요한 경우 Python Init()를 환경에 맞게 수정하세요.
제이엠피 19
conn = Python Connect();
conn << Get Version();
conn << Execute( {},{},"\[
import jmp
import pandas as pd
import numpy as np
pandas_df = pd.DataFrame(
{
"A": 1.0,
"B": pd.Timestamp("20130102"),
"C": pd.Series(1, index=list(range(4)), dtype="float32"),
"D": np.array([3] * 4, dtype="int32"),
"E": pd.Categorical(["test", "train", "test", "train"]),
"F": "foo",
}
)
print( pandas_df )
# JMP 19 create a data table direcly from a dataframe
dt = jmp.from_dataframe(pandas_df)
print( dt )
]\", echo(1) );
show(dt);
// dt << New Data View; // already on screen
JMP 18+에서는 JSL 래퍼가 필요 없이 편집기에서 Python 스크립트를 실행하면 훨씬 더 많은 작업을 수행할 수 있습니다.