tableau / TabPy

Execute Python code on the fly and display results in Tableau visualizations:
https://tableau.github.io/TabPy/
MIT License
1.56k stars 598 forks source link

TypeError: Object of type float32 is not JSON serializable #422

Closed sahil0094 closed 4 years ago

sahil0094 commented 4 years ago

Environment information:

Describe the issue File "d:\anaconda\lib\site-packages\tabpy\tabpy_tools\query_object.py", line 96, in _make_serializable json.dumps(result) File "d:\anaconda\lib\json__init__.py", line 231, in dumps return _default_encoder.encode(obj) File "d:\anaconda\lib\json\encoder.py", line 199, in encode chunks = self.iterencode(o, _one_shot=True) File "d:\anaconda\lib\json\encoder.py", line 257, in iterencode return _iterencode(o, 0) File "d:\anaconda\lib\json\encoder.py", line 179, in default raise TypeError(f'Object of type {o.class.name} ' TypeError: Object of type float32 is not JSON serializable

0golovatyi commented 4 years ago

@sahil0094 What command/steps lead to the error message?

sahil0094 commented 4 years ago

This is the tabpy log that i have added above. On querying rest service in my notebook i got this. Below is the command: client.query('Loan_Prediction', _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8) Here Loan _Prediction is my endpoint

0golovatyi commented 4 years ago

@sahil0094 I am not sure I understand what are you trying to do what that command is - script in a calculated field?

Looking at the fragment you provided it is possible you are passing a single value where there should be a collection. Here are some details for how TabPy is called by Tableau - https://github.com/tableau/TabPy/blob/master/docs/TableauConfiguration.md#anatomy-of-a-python-calculation.

sahil0094 commented 4 years ago

SCRIPT_REAL(" return tabpy.query('Loan_Prediction',_arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8)['response']", ([Credit_History]),([Number of Dependents]),([Education_param]),([Marital Status]),([Semi_Urban_Prop]),([Urban_Prop]),([Total_Income_Param]),([EMI_Param]))

This is the script in calculated field

sahil0094 commented 4 years ago

And this is the function that is being called. Just a XGBoost model used for classification

def loan_defaulter(_arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8): from pandas import DataFrame import numpy as np

Load data from tableau (brought in as lists) into a dictionary

d1=dict()
d1={'Credit_History': _arg1,'Dependents': _arg2,'Education': _arg3,'Married': _arg4,

'Prop__Semiurban': _arg5,'Prop__Urban': _arg6,'Total_Income': _arg7,'EMI': _arg8}

Convert the dictionary to a Pandas Dataframe

df = DataFrame(data=d1)

Applying boxcox
df[['Total_Income','EMI']]=pt.transform(df[['Total_Income','EMI']])
Use the loaded model to develop predictions for the new data from Tableau
predictions = load_xgb.predict_proba(df[['Credit_History','Dependents','Education','Married',
                                         'Prop__Semiurban','Prop__Urban','Total_Income','EMI']])[:,1]
print(predictions)
return [i for i in predictions]
0golovatyi commented 4 years ago

@sahil0094 From the first look I don't see issues in your script. You can add something like print(_argX) for each parameter to check what is being sent from Tableau side.

sahil0094 commented 4 years ago

I modified the code to print the arguments and couldn't find anything that could help ([1], [2], [1], [1], [1], [0], [13999], [213]) These are the arguments that i got

nmannheimer commented 4 years ago

Hi @sahil0094 can you add the line: predictions = predictions.tolist() to your code? I think the datatype of the XGBoost model output is a numpy float32 which is causing problems. Converting it to a list should make it a default Python type which should work. Let me know if that works.

Otherwise you can try: return [float(i) for i in predictions]

sahil0094 commented 4 years ago

i tried the second approach and it's working fine. Thanks @nmannheimer