nnadeau/pybotics

View on GitHub
examples/machine_learning.ipynb

Summary

Maintainability
Test Coverage
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Robot Machine Learning\n",
    "\n",
    "- Many robot predictive maintenance applications require being able to decide whether a new observation belongs to the same distribution as existing observations or should be considered as an outlier.\n",
    "- More information may be found here: https://scikit-learn.org/stable/modules/outlier_detection.html"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create Robot Models\n",
    "\n",
    "- We will create one \"nominal\" robot and one \"defective\" robot.\n",
    "- The defective robot will include a small offset at the TCP (e.g., imagine the tool is wearing out)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pybotics.predefined_models import ur10\n",
    "from pybotics.robot import Robot\n",
    "\n",
    "nominal_robot = Robot.from_parameters(ur10())\n",
    "\n",
    "defective_robot = Robot.from_parameters(ur10())\n",
    "defective_robot.tool.position = [0.1, 0, 0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create Database\n",
    "\n",
    "- We need to \"collect\" a large amount of data for machine learning applications"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from pybotics.geometry import matrix_2_vector\n",
    "\n",
    "joints = np.random.uniform(low=-np.pi, high=np.pi, size=(1000, 6))\n",
    "nominal_poses = np.array(\n",
    "    [matrix_2_vector(nominal_robot.fk(j)) for j in joints])\n",
    "defective_poses = np.array(\n",
    "    [matrix_2_vector(defective_robot.fk(j)) for j in joints])\n",
    "\n",
    "inliers = np.hstack((joints, nominal_poses))\n",
    "outliers = np.hstack((joints, defective_poses))\n",
    "outliers = outliers[:20]\n",
    "\n",
    "data = np.vstack((inliers, outliers))\n",
    "\n",
    "truth = np.ones(len(data))\n",
    "truth[-len(outliers):] = -1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Outlier Detection\n",
    "\n",
    "- The data contains outliers which are defined as observations that are far from the others (i.e., defective TCP). \n",
    "- Outlier detection estimators try to fit the regions where the training data is the most concentrated, ignoring the deviant observations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 98.04%\n"
     ]
    }
   ],
   "source": [
    "from sklearn.neighbors import LocalOutlierFactor\n",
    "\n",
    "# create classifier\n",
    "clf = LocalOutlierFactor(contamination='auto')\n",
    "\n",
    "# predict\n",
    "y_pred = clf.fit_predict(data)\n",
    "\n",
    "# compute accuracy\n",
    "n_errors = (y_pred != truth).sum()\n",
    "accuracy = (1 - n_errors / len(y_pred)) * 100\n",
    "print(f\"Accuracy: {accuracy:.2f}%\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}