{ "info": { "author": "Sumudu Tennakoon", "author_email": "mltoolkitproject@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Environment :: Console", "Intended Audience :: Developers", "Intended Audience :: Education", "Intended Audience :: Science/Research", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python", "Topic :: Scientific/Engineering", "Topic :: Software Development" ], "description": "# MLToolKit \n## Current release: PyMLToolkit [v0.1.8]\n\n\n\nMLToolKit (mltk) is a Python package providing a set of user-friendly functions to help building end-to-end machine learning models in data science research, teaching or production focused projects. \n\n\n\n## Introduction\nMLToolKit supports all stages of the machine learning application development process.\n\n## Installation\n```\npip install pymltoolkit\n```\nIf the installation failed with dependancy issues, execute the above command with --no-dependencies\n\n```\npip install pymltoolkit --no-dependencies\n```\n\n## Functions\n- Data Extraction (SQL, Flatfiles, etc.)\n- Exploratory Data Analysis (statistical summary, univariate analysis, visulize distributions, etc.)\n- Feature Engineering (Supports numeric, text, date/time. Image data support will integrate in later releases of v0.1)\n- Model Building (Currently supported for binary classification and regression only)\n- Hyper Parameter Tuning [in development for v0.2]\n- Cross Validation (will integrate in later releases of v0.1)\n- Model Performance Analysis and Comparison Between Models.\n- JSON input script for executing model building and scoring tasks.\n- Model Building UI [in development for v0.2]\n- ML Model Building Project [in development for v0.2]\n- Auto ML (automated machine learning) [in development for v0.2]\n- Model Deploymet and Serving [included, will be imporved for v0.2]\n\n## Supported Machine Learning Algorithms/Packages\n- RandomForestClassifier: scikit-learn\n- LogisticRegression: statsmodels\n- Deep Feed Forward Neural Network (DFF): tensorflow\n- Convlutional Neural Network (CNN): tensorflow\n- Gradient Boost : catboost\n- Linear Regression: statsmodels\n- RandomForestRegressor: scikit-learn\n- ... More models will be added in the future releases ...\n\n## Usage\n```python\nimport mltk\n```\n\n### Warning: Python Variable, Function or Class names \nThe Python interpreter has a number of built-in functions. It is possible to overwrite thier definitions when coding without any rasing a warning from the Python interpriter. (https://docs.python.org/3/library/functions.html)\nTherfore, AVOID THESE NAMES as your variable, function or class names.\n\n\n\n\n\n\n\n\n\n\n
absallanyasciibinboolbytearraybytes
callablechrclassmethodcompilecomplexdelattrdictdir
divmodenumerateevalexecfilterfloatformatfrozenset
getattrglobalshasattrhashhelphexidinput
intisinstanceissubclassiterlenlistlocalsmap
maxmemoryviewminnextobjectoctopenord
powprintpropertyrangereprreversedroundset
setattrslicesortedstaticmethodstrsumsupertuple
typevarszip__import__
\n\nIf you accedently overwrite any of the built-in function (e.g. list), execute the following to bring built-in defition.\n```python\ndel(list)\n```\n\nSimilarly, avoid using special charcters and spaces in the column names of the DataFrames.\nExecute the following to remove special characters from the column names.\n```python\nData = mltk.clean_column_names(Data, replace='')\n```\n\n## MLToolkit Example\n\n### Data Loading and exploration\n```python\nimport numpy as np\nimport pandas as pd\nimport mltk as mltk\n\nData = mltk.read_data_csv(file=r'C:\\Projects\\Data\\incomedata.csv')\nData = mltk.clean_column_names(Data, replace='')\nData = mltk.add_identity_column(Data, id_label='ID', start=1, increment=1)\nDataStats = mltk.data_description(Data)\n```\n### Data Pre-processing and Feature Engineering\n```python\n# Analyze Response Target\nprint(mltk.variable_frequency(DataFrame=Data, variable='income'))\n\n# Set Target Variables\ntargetVariable = 'HighIncome'\ntargetCondition = \"income=='>50K'\" #For Binary Classification\n\nData=mltk.set_binary_target(Data, target_condition=targetCondition, target_variable=targetVariable)\nprint(mltk.variable_frequency(DataFrame=Data, variable=targetVariable))\n```\n```\n Counts CountsFraction%\nincome \n<=50K 24720 75.91904\n>50K 7841 24.08096\nTOTAL 32561 100.00000\n```\n```python\n# Flag Records to Exclude\nexcludeCondition=\"age < 18\"\naction = 'flag' # 'drop' #\nexcludeLabel = 'EXCLUDE'\nData=mltk.exclude_records(Data, exclude_ondition=excludeCondition, action=action, exclude_label=excludeLabel) # )#\n\n# Get list of uniques values in categorical variables\ncategoryVariables = set({'sex', 'nativecountry', 'race', 'occupation', 'workclass', 'maritalstatus', 'relationship'})\nprint(mltk.category_lists(Data, list(categoryVariables)))\n\n# Merge unique categorical values\ncategory_merges = [{'variable':'maritalstatus', 'category_variable':'maritalstatus', 'group_value':'Married', 'values':[\"Married-civ-spouse\", \"Married-spouse-absent\", \"Married-AF-spouse\"]}]\nData = mltk.merge_categories(Data, category_merges)\n\n# Show Frequency distribution of categorical variable\nsourceVariable='maritalstatus'\ntable = mltk.variable_frequency(Data, variable=sourceVariable, show_plot=False)\ntable.style.background_gradient(cmap='Greens').set_precision(3)\n\n# Response Rate For Categorical Variables\nmltk.variable_responses(Data, variables=categoryVariables, target_variable=targetVariable, show_output=False, show_plot=True)\n```\n# Get numeric units list\n```python\nmltk.get_number_units()\n```\n\n# Variables Manipulations\n```python\n# General form\n{\n\t'type':'category'\n\t'out_type':'cat',\n\t'include':True,\n\t'operation':'bucket',\n\t'variables': {\n\t\t'source':'age',\n\t\t'destination': None # None for mult-variable operations, variable1 (for pair operations), variable1a (for pair sequence operation)\n\t},\n 'parameters': {\n 'labels_str': ['0', '20', '30', '40', '50', '60', 'INF'],\n 'right_inclusive':True,\n \"default\":'OTHER',\n \"null\": 'NA'\n }\n}\n```\n\n```\t\nList of Avaiable Transformation\n |- Date/Numeric Transformations (transform)\n | |- normalize\n | |- datepart\n | |- dateadd\n | |- log\n | |- exponent\n | |- segment (piecewise functions)\n |- String Transformation (str_transform)\n | |- normalize\n | |- strcount\n | |- extract\n |- Multi-variable Operations (operation_mult)\n | |- expression\n |- Sequence Order Check (seq_order)\n | |- seqorder\n |- Numeric/Date Comparison* (comparison)\n | |- numdiff\n | |- ratio\n | |- datediff\n | |- rowmin (pair)\n | |- rowmax (pair)\n |- String Comparison* (str_comparison)\n | |- levenshtein\n | |- jaccard\n | |- ..more to add ..\n |- Pair comparison\n\nList of Avaiable Discrete Feature Transforms\n |- Binary Variable (condition)\n |- Numeric to Catergory (buckets)\n |- Entity Grouping (dictionary)\n |- Pair Equality/Existance (pair_equality)\n |- Category Merge(category_merge)\n```\n\n```python\n# Transform numeric variable\nrule_set = {\n \"operation\":\"normalize\", \n 'variables': {\n 'source':'age', \n 'destination':'normalizedage'\n },\n \"parameters\":{\"method\":\"zscore\"}\n}\nData, transformed_variable = mltk.create_transformed_variable_task(Data, rule_set, return_variable=True)\n\n# Create Categorical Variables from continious variables\nsourceVariable='age'\ntable = mltk.histogram(Data, sourceVariable, n_bins=10, orientation='vertical', density=True, show_plot=True)\nprint(table)\n\n# Divide to categories\nrule_set = { \n 'operation':'bucket',\n 'variables': {\n 'source':'age', \n 'destination':None\n },\n 'parameters': {\n 'labels_str': ['0', '20', '30', '40', '50', '60', 'INF'],\n 'right_inclusive':True,\n \"default\":'OTHER',\n \"null\": 'NA'\n }\n}\nData, categoryVariable = mltk.create_categorical_variable_task(Data, rule_set, return_variable=True)\nmltk.variable_response(DataFrame=Data, variable=categoryVariable, target_variable=targetVariable, show_plot=True)\n```\n```\n Counts HighIncome CountsFraction% ResponseFraction% ResponseRate%\nageGRP \n1_(0,20] 2410 2 7.40149 0.02551 0.08299\n2_(20,30] 8162 680 25.06680 8.67236 8.33129\n3_(30,40] 8546 2406 26.24612 30.68486 28.15352\n4_(40,50] 6983 2655 21.44590 33.86048 38.02091\n5_(50,60] 4128 1547 12.67774 19.72963 37.47578\n6_(60,INF) 2332 551 7.16194 7.02716 23.62779\nTOTAL 32561 7841 100.00000 100.00000 0.24081\n```\n\n```python\n# Create One Hot Encoded Variables\nData, featureVariables, targetVariable = mltk.to_one_hot_encode(Data, category_variables=categoryVariables, binary_variables=binaryVariables, target_variable=targetVariable)\nData[identifierColumns+featureVariables+[targetVariable]].sample(5).transpose()\n```\n### Correlation\n```python\ncorrelation=mltk.correlation_matrix(Data, featureVariables+[targetVariable], target_variable=targetVariable, method='pearson', return_type='list', show_plot=False)\n```\n### Split Train, Validate Test datasets\n```python\nTrainDataset, ValidateDataset, TestDataset = mltk.train_validate_test_split(Data, ratios=(0.6,0.2,0.2))\n```\n### Model Building\n```python\nsample_attributes = {\n\t\t\t\t\t\t'SampleDescription':'Adult Census Income Dataset',\n\t\t\t\t\t\t'NumClasses':2,\n\t\t\t\t\t\t'RecordIdentifiers':identifierColumns\n }\n\nscore_parameters = {\n\t\t\t\t\t'Edges':[0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0],\n\t\t\t\t\t'Percentiles':[0, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 1.0],\n\t\t\t\t\t'Threshold':0.5,\n\t\t\t\t\t'Quantiles':10,\n\t\t\t\t\t'ScoreVariable':'Probability',\n\t\t\t\t\t'ScoreLabel':'Score',\n\t\t\t\t\t'QuantileLabel':'Quantile',\n\t\t\t\t\t'PredictedLabel':'Predicted'\n }\n````\n\n# Classification Models\n\nModel Attributes\n```python\nmodel_attributes = {\n\t\t\t\t\t'ModelID': None,\n\t\t\t\t\t'ModelType':'classification',\n\t\t\t\t\t'ModelName': 'IncomeLevel',\n\t\t\t\t\t'Version':'0.1',\n }\n```\n\nLosgistic Regression\n```python\nmodel_parameters = {\n\t\t\t\t\t'MLAlgorithm':'LGR', # 'RF', # 'NN', # 'CATBST', (# 'CNN', # 'XGBST')\n\t\t\t\t\t'MaxIterations':50\n\t\t\t\t} \n```\n\nRandom Forest\n```python\nmodel_parameters = {\n\t\t\t\t\t'MLAlgorithm':'RF', # 'LGR', # 'NN', # 'CATBST', (# 'CNN', # 'XGBST')\n\t\t\t\t\t'NTrees':500,\n\t\t\t\t\t'MaxDepth':100,\n\t\t\t\t\t'MinSamplesToSplit':10,\n\t\t\t\t\t'Processors':2\n\t\t\t\t} \n```\nNeural Networks\n```python\n# Setup Architecture\n# Binary classification (L1 'units': 2), 32 variables ('input_shape':(48,))\nSimpleDFF_architecture = {\n 'L1':{'type': 'Dense', 'position':'input', 'units': 512, 'activation':'relu', 'input_shape':(48,)},\n 'L2':{'type': 'Dense', 'position':'hidden', 'units': 512, 'activation':'relu'},\n 'L3':{'type': 'Dropout', 'position':'hidden', 'rate':0.5},\n 'L4':{'type': 'Dense', 'position':'output', 'units': 2, 'activation':'softmax', 'output_shape':None},\n }\n\n# Binary classification (L1 'units': 2), 32 variables ('input_shape':(32,))\nLogisticRegressionNN_architecture = {\n 'L1':{'type': 'Dense', 'position':'input', 'units': 2, 'activation':'softmax', 'input_shape':(32,)},\n }\n\n# Binary classification (L8 'units': 2)\nSimpleImageClassifier_architecture = {\n 'L1':{'type': 'Conv2D', 'position':'input', 'filters': 32, 'kernel_size':(3,3), 'strides':(1,1), 'padding':'valid', 'activation':'relu', 'input_shape':(128, 128, 1)},\n 'L2':{'type': 'Conv2D', 'position':'hidden', 'filters': 64, 'kernel_size':(3,3), 'strides':(1,1), 'padding':'valid', 'activation':'relu'},\n 'L3':{'type': 'MaxPooling2D', 'position':'hidden', 'pool_size': (2,2), 'padding':'valid'}, \n 'L4':{'type': 'Dropout', 'position':'hidden', 'rate':0.25},\n 'L5':{'type': 'Flatten', 'position':'hidden'}, \n 'L6':{'type': 'Dense', 'position':'hidden', 'units': 128, 'activation':'relu'},\n 'L7':{'type': 'Dropout', 'position':'hidden', 'rate':0.5},\n 'L8':{'type': 'Dense', 'position':'output', 'units': 2, 'activation':'softmax', 'output_shape':None},\n }\n\nmodel_parameters = {\n\t\t\t\t'MLAlgorithm':'NN',\n\t\t\t\t'BatchSize':512,\n\t\t\t\t'InputShape':InputShape,\n\t\t\t\t'num_classes':2,\n\t\t\t\t'Epochs':10,\n\t\t\t\t'metrics':['accuracy'],\n\t\t\t\t'architecture':SimpleDFF_architecture\n\t\t\t\t} \n```\nCatBoost\n```python\nmodel_parameters = {\n\t\t\t\t\t'MLAlgorithm':'CBST',\n\t\t\t\t\t'NTrees': 500,\n\t\t\t\t\t'MaxDepth':10,\n\t\t\t\t\t'LearningRate':0.7,\n\t\t\t\t\t'LossFunction':'Logloss',#crossEntropy\n\t\t\t\t\t'EvalMatrics':'Accuracy',\n\t\t\t\t\t'Imbalanced':False,\n\t\t\t\t\t'TaskType':'GPU',\n\t\t\t\t\t'Processors':2,\n\t\t\t\t\t'UseBestModel':True\n\t\t\t\t}\n```\n\n### Build Model\n```python\nXModel = mltk.build_ml_model(TrainDataset, ValidateDataset, TestDataset, \n model_variables=modelVariables,\n variable_setup = None,\n target_variable=targetVariable,\n model_attributes=model_attributes, \n sample_attributes=sample_attributes, \n model_parameters=model_parameters, \n score_parameters=score_parameters, \n return_model_object=True, \n show_results=False, \n show_plot=True\n )\n\nprint(XModel.model_attributes['ModelID'])\nprint(XModel.model_interpretation['ModelSummary'])\nprint('ROC AUC: ', XModel.get_auc(curve='roc'))\nprint('PRC AUC: ', XModel.get_auc(curve='prc'))\nprint(XModel.model_evaluation['RobustnessTable'])\n\nXModel.plot_eval_matrics(comparison=False)\n```\n\n```\n minProbability maxProbability meanProbability BucketCount ResponseCount BucketFraction ResponseFraction BucketPrecision CumulativeBucketFraction CumulativeResponseFraction CumulativePrecision\nQuantile \n1 0.00000 0.00008 3.85729e-06 652 3 0.10011 0.00192 0.00460 1.00000 1.00000 0.23967\n2 0.00008 0.00432 1.52655e-03 651 9 0.09995 0.00577 0.01382 0.89989 0.99808 0.26582\n3 0.00435 0.02042 1.10941e-02 652 14 0.10011 0.00897 0.02147 0.79994 0.99231 0.29731\n4 0.02049 0.05702 3.58648e-02 650 20 0.09980 0.01281 0.03077 0.69983 0.98334 0.33677\n5 0.05711 0.12075 8.51409e-02 652 65 0.10011 0.04164 0.09969 0.60003 0.97053 0.38767\n6 0.12086 0.20457 1.63366e-01 651 109 0.09995 0.06983 0.16743 0.49992 0.92889 0.44533\n7 0.20469 0.31870 2.61577e-01 651 190 0.09995 0.12172 0.29186 0.39997 0.85906 0.51478\n8 0.31895 0.46840 4.03550e-01 666 259 0.10226 0.16592 0.38889 0.30002 0.73735 0.58905\n9 0.46854 0.66965 5.68083e-01 641 377 0.09842 0.24151 0.58814 0.19776 0.57143 0.69255\n10 0.66994 0.99967 8.06834e-01 647 515 0.09934 0.32992 0.79598 0.09934 0.32992 0.79598\nDataSet 0.00000 0.99967 2.33167e-01 6513 1561 1.00000 1.00000 0.23967 1.00000 1.00000 0.23967\n```\n\n### Evaluate Model\n\nPlot model performance curves\n```python\nRFModel.plot_eval_matrics(comparison=True)\nLGRModel.plot_eval_matrics(comparison=True)\nNNModel.plot_eval_matrics(comparison=True)\nCBSTModel.plot_eval_matrics(comparison=True)\n```\n\nArea Under Curve (AUC) Comparison\n```python\nModels = [LGRModel, RFModel, CBSTModel, NNModel]\nModelsComp = mltk.model_guages_comparison(Models)\nprint(ModelsComp)\n```\n\n```\n Model PRC_AUC ROC_AUC\n0 INCOMELEVELLGR20190728113633 0.71971 0.88926\n1 INCOMELEVELRF20190728113635 0.69348 0.88113\n2 INCOMELEVELCBST20190728113703 0.71507 0.88975\n3 INCOMELEVELNN20190728113641 0.71396 0.88890\n```\n\nTest Model\n```python\nscore_variable = RFModel.get_score_variable()\nscore_label = RFModel.get_score_label()\n\nTestDataset = mltk.score_processed_dataset(TestDataset, RFModel, edges=None, score_label=None, fill_missing=0)\n\nthreshold = 0.8\nTestDataset = mltk.set_predicted_columns(TestDataset, score_variable, threshold=threshold)\nConfusionMatrix = mltk.confusion_matrix(TestDataset, actual_variable=targetVariable, predcted_variable='Predicted', labels=[0,1], sample_weight=None, totals=True)\nprint(ConfusionMatrix)\n```\n\nComparing Models and Probability Thresholds\n```python\nModels = [LGRModel, RFModel, CBSTModel, NNModel]\nthresholds=[0.7, 0.8, 0.9]\nConfusionMatrixComparison = mltk.confusion_matrix_comparison(TestDataset, Models, thresholds, score_variable=None, show_plot=True)\nConfusionMatrixComparison.style.background_gradient(cmap='RdYlGn').set_precision(3)\n```\n\nComparing Models and Threshold Score (1-10 Scale)\n```python\nModels = [LGRModel, RFModel, CBSTModel, NNModel]\nthresholds=[7, 8, 9]\nConfusionMatrixComparison = mltk.confusion_matrix_comparison(TestDataset, Models, thresholds, score_variable=score_label, show_plot=True)\nConfusionMatrixComparison.style.background_gradient(cmap='RdYlGn').set_precision(3)\n```\n\nSet Custom Score Edges\n``` python\nRobustnessTable, ROCCurve, PrecisionRecallCurve, roc_auc, prc_auc = mltk.model_performance_matrics(ResultsSet=TestDataset, target_variable=targetVariable, score_variable=score_variable, quantile_label='Quantile', quantiles=100, show_plot=True)\nprint('ROC AUC', roc_auc)\nprint('PRC AUC', prc_auc)\n\nprint(RobustnessTable)\n\n# Examine cutoffs\nquantiles=[0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]\nedges, threshold = mltk.get_score_cutoffs(ResultsSet=TestDataset, quantiles=quantiles, target_variable=targetVariable, score_variable=scoreVariable)\nprint('Threshold', threshold)\nprint('Edges', edges)\n\n# Re-bin score buckets\nedges = [0.0, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.75, 0.95, 1.0]\nLGRModel.set_score_edges(edges)\n```\n\n# Regression Models\n\nModel Attributes\n```python\nmodel_attributes = {\n\t\t\t\t\t'ModelID': None, \n\t\t\t\t\t'ModelType':'regression',\n\t\t\t\t\t'ModelName': 'Income',\n\t\t\t\t\t'Version':'0.1',\n }\n```\n\n```python\nmodel_parameters = {\n\t\t\t\t\t'MLAlgorithm':'RFREG', # 'RFREG'\n\t\t\t\t\t'NTrees':200,\n\t\t\t\t\t'MaxDepth':10,\n\t\t\t\t\t'MinSamplesToSplit':6,\n\t\t\t\t\t'Processors':2\n\t\t\t\t } \nmodel_parameters = {'MLAlgorithm':'LREG', 'MaxIterations':100}\n```\n\n```python\nREGModel = mltk.build_ml_model(TrainDataset, ValidateDataset, TestDataset, \n model_variables=modelVariables,\n variable_setup = None,\n target_variable=targetVariable,\n model_attributes=model_attributes, \n sample_attributes=sample_attributes, \n model_parameters=model_parameters, \n score_parameters=score_parameters, \n return_model_object=True, \n show_results=False, \n show_plot=False\n )\n```\n\n```\nprint(REGModel.model_attributes['ModelID'])\nprint(REGModel.model_interpretation['ModelSummary'])\nprint('RMSE =', SelectModel.get_rmse())\nprint('R^2 =', SelectModel.get_r2())\nREGModel.plot_eval_matrics(comparison=True)\nSelectModel.plot_eval_matrics(comparison=True)\n```\n\nSave model\n```python\nsaveFilePath = '{}.pkl'.format(XModel.get_model_id())\nmltk.save_model(XModel, saveFilePath)\n```\n\n### Deployment\nSimplified MLToolkit ETL pipeline for scoring and model re-building (Need to customize based on the project).\n\n\nDefine ETL Function\n```python\ndef ETL(DataFrame, variables_setup_dict=None):\n # Add ID column\n DataFrame = mltk.add_identity_column(DataFrame, id_label='ID', start=1, increment=1)\n\n # Clean column names\n DataFrame = mltk.clean_column_names(DataFrame, replace='')\n input_columns = list(DataFrame.columns)\n\n\tif variables_setup_dict==None:\n\t\tvariables_setup_dict = \"\"\" \n\t\t{\n\t\t\t\"setting\":\"score\",\n\n\t\t\t\"variables\": { \n\t\t\t\t\t\"category_variables\" : [\"sex\", \"race\", \"occupation\", \"workclass\", \"maritalstatus\", \"relationship\"],\n\t\t\t\t\t\"binary_variables\": [],\n\t\t\t\t\t\"target_variable\":\"HighIncome\"\n\t\t\t},\n\n\t\t\t\"preprocess_tasks\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"transform\",\n\t\t\t\t\t\"out_type\":\"cnt\",\n\t\t\t\t\t\"include\": false,\n\t\t\t\t\t\"operation\": \"normalize\",\n\t\t\t\t\t\"variables\": {\n\t\t\t\t\t\t\"source\": \"age\",\n\t\t\t\t\t\t\"destination\": \"normalizedage\"\n\t\t\t\t\t},\n\t\t\t\t\t\"parameters\": {\n\t\t\t\t\t\t\"method\": \"zscore\"\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"category_merge\",\n\t\t\t\t\t\"out_type\":\"cat\",\n\t\t\t\t\t\"include\": true,\n\t\t\t\t\t\"operation\": \"catmerge\",\n\t\t\t\t\t\"variables\": {\n\t\t\t\t\t\t\"source\": \"maritalstatus\",\n\t\t\t\t\t\t\"destination\": \"maritalstatus\"\n\t\t\t\t\t},\n\t\t\t\t\t\"parameters\": {\n\t\t\t\t\t\t\"group_value\": \"Married\",\n\t\t\t\t\t\t\"values\": [ \"Married-civ-spouse\", \"Married-spouse-absent\", \"Married-AF-spouse\" ]\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"entity\",\n\t\t\t\t\t\"out_type\":\"cat\",\n\t\t\t\t\t\"include\": true,\n\t\t\t\t\t\"operation\": \"dictionary\",\n\t\t\t\t\t\"variables\": {\n\t\t\t\t\t\t\"source\": \"nativecountry\",\n\t\t\t\t\t\t\"destination\": \"nativecountryGRP\"\n\t\t\t\t\t},\n\t\t\t\t\t\"parameters\": {\n\t\t\t\t\t\t\"match_type\": null,\n\t\t\t\t\t\t\"dictionary\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"entity\": \"USA\",\n\t\t\t\t\t\t\t\t\"values\": [ \"United-States\" ],\n\t\t\t\t\t\t\t\t\"case\": true\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"entity\": \"Canada\",\n\t\t\t\t\t\t\t\t\"values\": [ \"Canada\" ],\n\t\t\t\t\t\t\t\t\"case\": true\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"entity\": \"OtherAmericas\",\n\t\t\t\t\t\t\t\t\"values\": [ \"South\", \"Mexico\", \"Trinadad&Tobago\", \"Jamaica\", \"Peru\", \"Nicaragua\", \"Dominican-Republic\", \"Haiti\", \"Ecuador\", \"El-Salvador\", \"Columbia\", \"Honduras\", \"Guatemala\", \"Puerto-Rico\", \"Cuba\", \"Outlying-US(Guam-USVI-etc)\"],\n\t\t\t\t\t\t\t\t\"case\": true\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"entity\": \"Europe-Med\",\n\t\t\t\t\t\t\t\t\"values\": [ \"Greece\", \"Holand-Netherlands\", \"Poland\", \"Iran\", \"England\", \"Germany\", \"Italy\", \"Ireland\", \"Hungary\", \"France\", \"Yugoslavia\", \"Scotland\", \"Portugal\" ],\n\t\t\t\t\t\t\t\t\"case\": true\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"entity\": \"Asia\",\n\t\t\t\t\t\t\t\t\"values\": [ \"Vietnam\", \"China\", \"Taiwan\", \"India\", \"Philippines\", \"Japan\", \"Hong\", \"Cambodia\", \"Laos\", \"Thailand\" ],\n\t\t\t\t\t\t\t\t\"case\": true\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"entity\": \"Other\",\n\t\t\t\t\t\t\t\t\"values\": [ \"?\" ],\n\t\t\t\t\t\t\t\t\"case\": true\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"null\": \"NA\",\n\t\t\t\t\t\t\"default\": \"OTHER\"\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"category\",\n\t\t\t\t\t\"out_type\":\"cat\",\n\t\t\t\t\t\"include\": true,\n\t\t\t\t\t\"operation\": \"bucket\",\n\t\t\t\t\t\"variables\": {\n\t\t\t\t\t\t\"source\": \"age\",\n\t\t\t\t\t\t\"destination\": null\n\t\t\t\t\t},\n\t\t\t\t\t\"parameters\": {\n\t\t\t\t\t\t\"labels_str\": [ \"0\", \"20\", \"30\", \"40\", \"50\", \"60\", \"INF\" ],\n\t\t\t\t\t\t\"right_inclusive\": true,\n\t\t\t\t\t\t\"default\": \"OTHER\",\n\t\t\t\t\t\t\"null\": \"NA\"\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"category\",\n\t\t\t\t\t\"out_type\":\"cat\",\n\t\t\t\t\t\"include\": true,\n\t\t\t\t\t\"operation\": \"bucket\",\n\t\t\t\t\t\"variables\": {\n\t\t\t\t\t\t\"source\": \"educationnum\",\n\t\t\t\t\t\t\"destination\": null\n\t\t\t\t\t},\n\t\t\t\t\t\"parameters\": {\n\t\t\t\t\t\t\"labels_str\": [ \"1\", \"5\", \"8\", \"9\", \"12\", \"16\" ],\n\t\t\t\t\t\t\"right_inclusive\": true,\n\t\t\t\t\t\t\"default\": \"OTHER\",\n\t\t\t\t\t\t\"null\": \"NA\"\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"category\",\n\t\t\t\t\t\"out_type\":\"cat\",\n\t\t\t\t\t\"include\": true,\n\t\t\t\t\t\"operation\": \"bucket\",\n\t\t\t\t\t\"variables\": {\n\t\t\t\t\t\t\"source\": \"hoursperweek\",\n\t\t\t\t\t\t\"destination\": null\n\t\t\t\t\t},\n\t\t\t\t\t\"parameters\": {\n\t\t\t\t\t\t\"labels_str\": [ \"0\", \"20\", \"35\", \"40\", \"60\", \"INF\" ],\n\t\t\t\t\t\t\"right_inclusive\": true,\n\t\t\t\t\t\t\"default\": \"OTHER\",\n\t\t\t\t\t\t\"null\": \"NA\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t\t\"\"\"\n\n DataFrame, categoryVariables, binaryVariables, targetVariable = mltk.setup_variables_task(DataFrame, variables_setup_dict)\n\n # Create One Hot Encoded Variables\n DataFrame, featureVariables, targetVariable = mltk.to_one_hot_encode(DataFrame, category_variables=categoryVariables, binary_variables=binaryVariables, target_variable=targetVariable)\n\n return DataFrame, input_columns\n```\n\nScoring/Ranking\n```python\nMLModelObject = mltk.load_model(saveFilePath)\nSampleDataset = pd.read_csv(r'test.csv')\nSampleDataset = ETL(SampleDataset)\n\nSampleDataset = mltk.score_processed_dataset(SampleDataset, MLModelObject, edges=None, score_label=None, fill_missing=0)\nRobustnesstable1 = mltk.robustness_table(ResultsSet=SampleDataset, class_variable=targetVariable, score_variable=score_variable, score_label=score_label, show_plot=True)\n```\n\n```python\nMLModelObject = mltk.load_model(saveFilePath)\n\nTestInput = \"\"\"\n{\n \"ID\": \"A001\",\n \"age\": 32,\n \"workclass\": \"Private\",\n \"education\": \"Doctorate\",\n \"education-num\": 16,\n \"marital-status\": \"Married-civ-spouse\",\n \"occupation\": \"Prof-specialty\",\n \"relationship\": \"Husband\",\n \"race\": \"Asian-Pac-Islander\",\n \"sex\": \"Male\",\n \"capital-gain\": 0,\n \"capital-loss\": 0,\n \"hours-per-week\": 40,\n \"native-country\": \"?\"\n}\n\"\"\"\noutput = mltk.score_records(TestInput, MLModelObject, edges=None, ETL=ETL, return_type='dict') # Other options for return_type, {'json', 'frame'}\n```\nOutput\n```python\n[{'ID': 'A001',\n 'age': 32,\n 'capitalgain': 0,\n 'capitalloss': 0,\n 'education': 'Doctorate',\n 'educationnum': 16,\n 'hoursperweek': 40,\n 'maritalstatus': 'Married',\n 'nativecountry': '?',\n 'occupation': 'Prof-specialty',\n 'race': 'Asian-Pac-Islander',\n 'relationship': 'Husband',\n 'sex': 'Male',\n 'workclass': 'Private',\n 'Probability': 0.6790258814478549,\n 'Score': 7}]\n```\n### JSON Input for scoring\n\nRecords Format for single or fewer number of records\n```json\n[{\n\t\"ID\": \"A001\",\n\t\"age\": 32,\n\t\"workclass\": \"Private\",\n\t\"education\": \"Doctorate\",\n\t\"occupation\": \"Prof-specialty\",\n\t\"sex\": \"Female\",\n\t\"hoursperweek\": 40,\n\t\"nativecountry\": \"USA\"\n}]\n```\n\nSplit Format for mulltiple records\n```json\n{\n\t\"columns\":[\"ID\",\"age\",\"education\",\"hoursperweek\",\"nativecountry\",\"occupation\",\"sex\",\"workclass\"],\n\t\"data\":[[\"A001\",32,\"Doctorate\",40,\"USA\",\"Prof-specialty\",\"Female\",\"Private\"]]\n}\n```\n\nUsing Model Chest to Deploy Models\n```python\nMyModelChest = mltk.ModelChest()\nMyModelChest.add_model(model_key='test', model_file=None, model_object=MLModelObject, replace=False)\nMyModelChest.save_model_chest()\nMyModelChest.get_model_chest_json()\n```\n\nload Models from Model Chest\n```python\nlodedModel = MyModelChest.get_model_object('test')\nlodedModel.get_model_manifest()\n```\n\n## License\n```\nCopyright 2019 Sumudu Tennakoon\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n\n## Cite as\n```\n@misc{mltk2019,\n author = \"Sumudu Tennakoon\",\n title = \"MLToolKit(mltk): A Simplified Toolkit for End-To-End Machine Learing Projects\",\n year = 2019,\n publisher = \"GitHub\",\n howpublished = {\\url{https://mltoolkit.github.io/mltk/}},\n version = \"0.1.7\"\n}\n```\n\n## MLToolKit Project Timeline\n- 2018-07-02 [v0.0.1]: Initial set of functions for data exploration, model building and model evaluation was published to Github. (https://github.com/sptennak/MachineLearning).\n- 2018-01-03 [v0.0.2]: Created more functions for data exploration including web scraping and geo spacial data analysis for for IBM Coursera Data Science Capstone Project was published to Github. (https://github.com/sptennak/Coursera_Capstone).\n- 2019-03-20 [v0.1.0]: Developed and published initial version of model building and serving framework for IBM Coursera Advanced Data Science Professional Certificate Capstone Project. (https://github.com/sptennak/IBM-Coursera-Advanced-Data-Science-Capstone).\n- 2019-07-02 [v0.1.2]: First release of the PyMLToolkit Python package, a collection of clases and functions facilitating end-to-end machine learning model building and serving over RESTful API.\n- 2019-07-04 [v0.1.3]: Minor bug fixes.\n- 2019-07-14 [v0.1.4]: Improved documentation, Integrated TensorFlow Models, Enhancements and Minor bug fixes.\n- 2019-07-28 [v0.1.5]: Integrated CatBoost Models, Improved model building and serving frameework, text analytics functions, support JSON input/output to the ML model bulding and scoring processes, Enhancements and bug fixes.\n- 2019-08-12 [v0.1.6]: Improved Features, Bug Fixes, Enhanced JSON input/output to the ML model bulding and scoring processes (JSON-MLS) and bug fixes.\n- 2019-08-31 [v0.1.7] : Added more data processing functions, Enhanced output formats, Enhanced model deployment, Overall improvements and bug fixes.\n- 2019-09-29 [v0.1.8] : Improved Documentation, Enhancements and bug fixes.\n\n## Future Release Plan\n- TBD [v0.1.9] : Integrate image classification model Deployment, Post additional tutorials and examples, Improved Documentation, Enhancements and bug fixes.\n- TBD [v0.1.10] : Working with Imbalanced Samples, Integrate Cross-validation, Enhancements and bug fixes.\n- TBD [v0.1.11] : Building Ensambled Models, UI Preview, Improved Feature Selection, Cross-validation and Hyper parameter tuning functionality, Enhancements and bug fixes.\n- TBD [v0.1.12]: ML Model Building Projects, Enhancements and bug fixes.\n- 2019-12-31 [v0.1.13]:Comprehensive documentation, Post implementation evaluation functions, Enhanced Data Input and Output functios, Major bug-fix version of the initial release with finalized enhancements.\n- TBD [v0.2.0]: Imporved model building and serving frameework and UI, Support more machine learning algorithms, Support multi-class classification and enhanced text analytics functions.\n- TBD [v0.3.0]: Imporved scalability and performance, Automated Machine Learning.\n- TBD [v0.4.0]: Building continious learning models.\n\n## References\n- https://pandas.pydata.org/\n- https://scikit-learn.org\n- https://www.numpy.org/\n- https://docs.python.org/3.6/library/re.html\n- https://www.statsmodels.org\n- https://matplotlib.org/\n- http://flask.pocoo.org/\n- https://catboost.ai/\n- http://json.org/\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://mltoolkit.github.io/MLToolKit", "keywords": "", "license": "Apache License Version 2.0", "maintainer": "", "maintainer_email": "", "name": "pymltoolkit", "package_url": "https://pypi.org/project/pymltoolkit/", "platform": "", "project_url": "https://pypi.org/project/pymltoolkit/", "project_urls": { "Homepage": "https://mltoolkit.github.io/MLToolKit" }, "release_url": "https://pypi.org/project/pymltoolkit/0.1.8/", "requires_dist": [ "numpy", "scipy", "matplotlib", "pandas", "scikit-learn", "statsmodels" ], "requires_python": "", "summary": "End-to-end Machine Learning Toolkit (MLToolkit/mltk) for Python", "version": "0.1.8" }, "last_serial": 5901233, "releases": { "0.1.2": [ { "comment_text": "", "digests": { "md5": "476496bfdae125c868222c5fc436c5e4", "sha256": "8a07aa1e648366c3506173e64ef86db66c279935b921a400bf0f691a917114f4" }, "downloads": -1, "filename": "pymltoolkit-0.1.2-py3-none-any.whl", "has_sig": false, "md5_digest": "476496bfdae125c868222c5fc436c5e4", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 28802, "upload_time": "2019-07-02T07:22:56", "url": "https://files.pythonhosted.org/packages/70/13/49cd810d3b8dcdcd218aec8c2f2afd96f9323cb71f31d2c249a5b0c91910/pymltoolkit-0.1.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "76d4120b1c20b5fb32c6ad54684c9c17", "sha256": "704b1ef557dc05e1f44ce0fc72e468214ed2120ac3a0dfab31952e3b179b08e1" }, "downloads": -1, "filename": "pymltoolkit-0.1.2.tar.gz", "has_sig": false, "md5_digest": "76d4120b1c20b5fb32c6ad54684c9c17", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18137, "upload_time": "2019-07-02T07:22:58", "url": "https://files.pythonhosted.org/packages/43/2f/25684916f19ea905bff20ad15884eee68c30e7e47b1d5bac28309d34b3ff/pymltoolkit-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "85973def48923f3c9ae268cae79980ff", "sha256": "3f854b35e86ae70e13f2716de371f09a6f36b8b2880f832638cd533fe1b48c50" }, "downloads": -1, "filename": "pymltoolkit-0.1.3-py3-none-any.whl", "has_sig": false, "md5_digest": "85973def48923f3c9ae268cae79980ff", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 32604, "upload_time": "2019-07-04T22:41:32", "url": "https://files.pythonhosted.org/packages/27/3e/d73f8b558400a2054f39493619ac031cd47f57840e47452d84ef03b2c178/pymltoolkit-0.1.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4cec8594ff376d649f35ad692d8703a2", "sha256": "af497986f0a8667cb19eec8fea2da51f462ef90418b3761628d40cb66b9f8696" }, "downloads": -1, "filename": "pymltoolkit-0.1.3.tar.gz", "has_sig": false, "md5_digest": "4cec8594ff376d649f35ad692d8703a2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22330, "upload_time": "2019-07-04T22:41:34", "url": "https://files.pythonhosted.org/packages/bf/01/58810e980feca163e9de95de76fc5ecdd87b6954773aece68b5a461f12e9/pymltoolkit-0.1.3.tar.gz" } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "a4b59c29dddc7c3c4ddcfd16613a0428", "sha256": "bf68d03ad639082b68326cef2b6d8a36cf715c9c089b1694eb95720b483f4141" }, "downloads": -1, "filename": "pymltoolkit-0.1.4-py3-none-any.whl", "has_sig": false, "md5_digest": "a4b59c29dddc7c3c4ddcfd16613a0428", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 40674, "upload_time": "2019-07-14T21:47:22", "url": "https://files.pythonhosted.org/packages/a2/9f/2ed1a612f6940ad75696ab6b0d24f7a93732980e4b4a0d47f82e3f9b743d/pymltoolkit-0.1.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "eb2bd62d1474b9951224035c2007818c", "sha256": "d8ea6c54323391ec6f0a8f63556c4f5005078eff1a58b41f01516999fcbe6872" }, "downloads": -1, "filename": "pymltoolkit-0.1.4.tar.gz", "has_sig": false, "md5_digest": "eb2bd62d1474b9951224035c2007818c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30750, "upload_time": "2019-07-14T21:47:24", "url": "https://files.pythonhosted.org/packages/92/d8/82ff41c11bc7b38891e2aac4c0bfd62f12f17ad59ea6d36ac4d3bfa98d68/pymltoolkit-0.1.4.tar.gz" } ], "0.1.5": [ { "comment_text": "", "digests": { "md5": "11bf296b3e6c5571200ac3623d0537c4", "sha256": "82e2438d13184bd08e79e963e69aeb514d34d8f754cf38ea8bea17fbefd554ec" }, "downloads": -1, "filename": "pymltoolkit-0.1.5-py3-none-any.whl", "has_sig": false, "md5_digest": "11bf296b3e6c5571200ac3623d0537c4", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 52743, "upload_time": "2019-07-28T22:53:35", "url": "https://files.pythonhosted.org/packages/08/5e/967c3e0b39c13ed1c83f12df623b59a0d34294c4cd603a45a992cce8e3bd/pymltoolkit-0.1.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "15d6434a1a8b73910c2f1dd658f9c2ca", "sha256": "0d74928cdc409d6e497461e171727f8919ae218374cdb90f1eca93fb43557f3d" }, "downloads": -1, "filename": "pymltoolkit-0.1.5.tar.gz", "has_sig": false, "md5_digest": "15d6434a1a8b73910c2f1dd658f9c2ca", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 52990, "upload_time": "2019-07-28T22:53:37", "url": "https://files.pythonhosted.org/packages/cb/95/141fb00f91bf7351c520311fb0afcc553b8b8505e47a90e513794f74f684/pymltoolkit-0.1.5.tar.gz" } ], "0.1.6": [ { "comment_text": "", "digests": { "md5": "a89dfeff61ebe0b8b10e191268920045", "sha256": "a815f00d000324bfcf59abef08d6dcb83c8440d7393195426288f44ab03ad96d" }, "downloads": -1, "filename": "pymltoolkit-0.1.6-py3-none-any.whl", "has_sig": false, "md5_digest": "a89dfeff61ebe0b8b10e191268920045", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 58435, "upload_time": "2019-08-12T13:01:38", "url": "https://files.pythonhosted.org/packages/55/dd/bcf103717c708d2a2959aef9e2917d0f263e07c95a5d868ea7e61c8bc99d/pymltoolkit-0.1.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5fa9ce8ed84cb1eefe7ce4203b110c9f", "sha256": "93293c5f2ed3c2e6a250e49bff112468af91b4f68ec9d2669fd29530f3bd0b8c" }, "downloads": -1, "filename": "pymltoolkit-0.1.6.tar.gz", "has_sig": false, "md5_digest": "5fa9ce8ed84cb1eefe7ce4203b110c9f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 63968, "upload_time": "2019-08-12T13:01:41", "url": "https://files.pythonhosted.org/packages/33/35/d041fc5e88041209830e9d19e6fa9261d97248ef7921722a90b258aa1eb1/pymltoolkit-0.1.6.tar.gz" } ], "0.1.7": [ { "comment_text": "", "digests": { "md5": "3dee007cc490e6a9a5b99146d45aa03b", "sha256": "079400ae41f7ba99617bcb0b837a4ddc570e7b7607ec115818e840c1c5490a5c" }, "downloads": -1, "filename": "pymltoolkit-0.1.7-py3-none-any.whl", "has_sig": false, "md5_digest": "3dee007cc490e6a9a5b99146d45aa03b", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 65598, "upload_time": "2019-09-01T20:35:10", "url": "https://files.pythonhosted.org/packages/2b/c3/b15c4920c52039e843c429d3178dea3eb746e4efc8de3556549fb30d5483/pymltoolkit-0.1.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d62626db79ecb4fe61264d9b31cfe345", "sha256": "0ac8509912310dddad9b81e0196e1d15aeeb0fc21d696f4287719e89b3c63b65" }, "downloads": -1, "filename": "pymltoolkit-0.1.7.tar.gz", "has_sig": false, "md5_digest": "d62626db79ecb4fe61264d9b31cfe345", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 71135, "upload_time": "2019-09-01T20:35:20", "url": "https://files.pythonhosted.org/packages/fb/3f/21593295ea183c44242fa72516aacea212ec1f54a2b6cb61698905ce34e9/pymltoolkit-0.1.7.tar.gz" } ], "0.1.8": [ { "comment_text": "", "digests": { "md5": "8040cd9a7d2900cab445125411bce70c", "sha256": "7d535ad5a77c6e3bf213f00d0495c389b299879aaafd47611db687763dc68d0e" }, "downloads": -1, "filename": "pymltoolkit-0.1.8-py3-none-any.whl", "has_sig": false, "md5_digest": "8040cd9a7d2900cab445125411bce70c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 68435, "upload_time": "2019-09-29T01:59:48", "url": "https://files.pythonhosted.org/packages/07/eb/225060a10a1b7e48767e26a1aa06b1ef0f5eee781dd47aa5fa4a4c7ec3a6/pymltoolkit-0.1.8-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f95b753c037660cb4c3e69ad83f84098", "sha256": "f5707e03491a3f760c8cce93038990410414476f3f6e97bf412dc458226850fc" }, "downloads": -1, "filename": "pymltoolkit-0.1.8.tar.gz", "has_sig": false, "md5_digest": "f95b753c037660cb4c3e69ad83f84098", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 74053, "upload_time": "2019-09-29T01:59:51", "url": "https://files.pythonhosted.org/packages/3d/0e/520016525c800b0bddb354682b8675d53085e6b41f3df2e5c585baedc1cd/pymltoolkit-0.1.8.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "8040cd9a7d2900cab445125411bce70c", "sha256": "7d535ad5a77c6e3bf213f00d0495c389b299879aaafd47611db687763dc68d0e" }, "downloads": -1, "filename": "pymltoolkit-0.1.8-py3-none-any.whl", "has_sig": false, "md5_digest": "8040cd9a7d2900cab445125411bce70c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 68435, "upload_time": "2019-09-29T01:59:48", "url": "https://files.pythonhosted.org/packages/07/eb/225060a10a1b7e48767e26a1aa06b1ef0f5eee781dd47aa5fa4a4c7ec3a6/pymltoolkit-0.1.8-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f95b753c037660cb4c3e69ad83f84098", "sha256": "f5707e03491a3f760c8cce93038990410414476f3f6e97bf412dc458226850fc" }, "downloads": -1, "filename": "pymltoolkit-0.1.8.tar.gz", "has_sig": false, "md5_digest": "f95b753c037660cb4c3e69ad83f84098", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 74053, "upload_time": "2019-09-29T01:59:51", "url": "https://files.pythonhosted.org/packages/3d/0e/520016525c800b0bddb354682b8675d53085e6b41f3df2e5c585baedc1cd/pymltoolkit-0.1.8.tar.gz" } ] }