{
  "id": "G8jRDBvwsMkkMiLN",
  "name": "[3/3] Anomaly detection tool (crops dataset)",
  "tags": [
    {
      "id": "spMntyrlE9ydvWFA",
      "name": "anomaly-detection",
      "createdAt": "2024-12-08T22:05:15.945Z",
      "updatedAt": "2024-12-09T12:50:19.287Z"
    }
  ],
  "nodes": [
    {
      "id": "e01bafec-eb24-44c7-b3c4-a60f91666350",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1200,
        180
      ],
      "parameters": {
        "color": 6,
        "width": 400,
        "height": 740,
        "content": "\uc6b0\ub9ac\ub294 \uc5ec\uae30\uc11c \uc791\ubb3c \ub370\uc774\ud130\uc14b\uacfc \ud568\uaed8 \uc791\uc5c5\ud558\uace0 \uc788\uc2b5\ub2c8\ub2e4:  \n\ub370\uc774\ud130\uc14b\uc5d0 \uc788\ub294 \uae30\uc874 (\uc774\uc0c1 \uc0ac\ud56d\uc774 \uc544\ub2cc) \uc791\ubb3c \uc774\ubbf8\uc9c0\ub4e4\uc740:  \n- '\uc9c4\uc8fc \uae30\uc7a5(\ubc14\uc988\ub77c)',  \n- '\ub2f4\ubc30 \uc2dd\ubb3c',  \n- '\uccb4\ub9ac',  \n- '\ubaa9\ud654',  \n- '\ubc14\ub098\ub098',  \n- '\uc624\uc774',  \n- '\uc625\uc218\uc218',  \n- '\ubc00',  \n- '\uc815\ud5a5',  \n- '\uc218\uc218',  \n- '\uc62c\ub9ac\ube0c \ub098\ubb34',  \n- '\ub300\ub450',  \n- '\ucee4\ud53c \ub098\ubb34',  \n- '\ubcbc',  \n- '\ub808\ubaac',  \n- '\uaca8\uc790\uc720',  \n- '\ub179\ub450',  \n- '\ucf54\ucf54\ub11b',  \n- '\ubcd1\uc544\ub9ac\ucf69',  \n- '\ud30c\uc778\uc560\ud50c',  \n- '\uc0ac\ud0d5\uc218\uc218',  \n- '\ud574\ubc14\ub77c\uae30',  \n- '\uace0\ucd94',  \n- '\uc5ec\uc6b0 \uacac\uacfc(\ub9c8\uce74\ub098)',  \n- '\ud669\ub9c8',  \n- '\ud30c\ud30c\uc57c',  \n- '\ucc28',  \n- '\uce74\ub2e4\uba48',  \n- '\uc544\ubaac\ub4dc'"
      },
      "typeVersion": 1
    },
    {
      "id": "b9943781-de1f-4129-9b81-ed836e9ebb11",
      "name": "Embed image",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        680,
        60
      ],
      "parameters": {
        "url": "https://api.voyageai.com/v1/multimodalembeddings",
        "method": "POST",
        "options": {},
        "jsonBody": "={{\n{\n  \"inputs\": [\n    {\n      \"content\": [\n        {\n          \"type\": \"image_url\",\n          \"image_url\": $('Image URL hardcode').first().json.imageURL\n        }\n      ]\n    }\n  ],\n  \"model\": \"voyage-multimodal-3\",\n  \"input_type\": \"document\"\n}\n}}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "47b72bc2-4817-48c6-b517-c1328e402468",
      "name": "Get similarity of medoids",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        940,
        60
      ],
      "parameters": {
        "url": "={{ $('Variables for medoids').first().json.qdrantCloudURL }}/collections/{{ $('Variables for medoids').first().json.collectionName }}/points/query",
        "method": "POST",
        "options": {},
        "jsonBody": "={{\n{\n  \"query\": $json.data[0].embedding,\n  \"using\": \"voyage\",\n  \"limit\": $('Info About Crop Labeled Clusters').first().json.cropsNumber,\n  \"with_payload\": true,\n  \"filter\": {\n      \"must\": [\n          {      \n          \"key\": $('Variables for medoids').first().json.clusterCenterType,\n          \"match\": {\n              \"value\": true\n              }\n          }\n      ]\n  }\n}\n}}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "qdrantApi"
      },
      "credentials": {
        "qdrantApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "42d7eb27-ec38-4406-b5c4-27eb45358e93",
      "name": "Compare scores",
      "type": "n8n-nodes-base.code",
      "position": [
        1140,
        60
      ],
      "parameters": {
        "language": "python",
        "pythonCode": "points = _input.first()['json']['result']['points']\nthreshold_type = _('Variables for medoids').first()['json']['clusterThresholdCenterType']\n\nmax_score = -1\ncrop_with_max_score = None\nundefined = True\n\nfor center in points:\n    if center['score'] >= center['payload'][threshold_type]:\n        undefined = False\n        if center['score'] > max_score:\n            max_score = center['score']\n            crop_with_max_score = center['payload']['crop_name']\n\nif undefined:\n    result_message = \"ALERT, we might have a new undefined crop!\"\nelse:\n    result_message = f\"Looks similar to {crop_with_max_score}\"\n\nreturn [{\n    \"json\": {\n        \"result\": result_message\n    }\n}]\n"
      },
      "typeVersion": 2
    },
    {
      "id": "23aa604a-ff0b-4948-bcd5-af39300198c0",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1200,
        -220
      ],
      "parameters": {
        "width": 400,
        "height": 380,
        "content": "## \uc791\ubb3c \uc774\uc0c1 \ud0d0\uc9c0 \ub3c4\uad6c\n### \uc774\ub294 \uc791\ubb3c\uc758 \uc774\uc0c1\uc744 \uc9c1\uc811 \ud0d0\uc9c0\ud558\ub294 \ub370 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \ub3c4\uad6c\uc785\ub2c8\ub2e4. \n\uc785\ub825\uc73c\ub85c (\uc5b4\ub5a4) **\uc774\ubbf8\uc9c0 URL**\uc744 \ubc1b\uace0, **\ud14d\uc2a4\ud2b8 \uba54\uc2dc\uc9c0**\ub97c \ubc18\ud658\ud558\uc5ec \uc774 \uc774\ubbf8\uc9c0\uac00 Qdrant\uc5d0 \uc800\uc7a5\ub41c \uc791\ubb3c \ub370\uc774\ud130\uc14b\uc5d0 \ube44\ud574 \uc774\uc0c1\uc801\uc778\uc9c0 \uc5ec\ubd80\ub97c \uc54c\ub824\uc90d\ub2c8\ub2e4. \n\n* \uc774\ubbf8\uc9c0 URL\uc740 Execute Workflow Trigger\ub97c \ud1b5\ud574 \ubc1b\uc544\uc640\uc11c Voyage.ai Embeddings API\ub97c \uc774\uc6a9\ud574 \uc784\ubca0\ub529 \ubca1\ud130\ub97c \uc0dd\uc131\ud569\ub2c8\ub2e4.\n* \ubc18\ud658\ub41c \ubca1\ud130\ub294 Qdrant \uceec\ub809\uc158\uc744 \uc870\ud68c\ud558\uc5ec \uc8fc\uc5b4\uc9c4 \uc791\ubb3c\uc774 \uac01 \uc774\ubbf8\uc9c0 \ud074\ub798\uc2a4(\uc791\ubb3c \uc720\ud615)\uc758 **\uc784\uacc4\uac12 \uc810\uc218**\uc640 \ube44\uad50\ud574 \uc54c\ub824\uc9c4 \uc791\ubb3c\uc778\uc9c0 \ud655\uc778\ud569\ub2c8\ub2e4.\n* \ub9cc\uc57d \uc774\ubbf8\uc9c0\uc758 \uc810\uc218\uac00 \ubaa8\ub4e0 \uc784\uacc4\uac12\ubcf4\ub2e4 \ub0ae\uc73c\uba74, \ud574\ub2f9 \uc774\ubbf8\uc9c0\ub294 \ub370\uc774\ud130\uc14b\uc758 \uc774\uc0c1\uc73c\ub85c \uac04\uc8fc\ub429\ub2c8\ub2e4. \n\n### \ucd9c\ub825"
      },
      "typeVersion": 1
    },
    {
      "id": "3a79eca2-44f9-4aee-8a0d-9c7ca2f9149d",
      "name": "Variables for medoids",
      "type": "n8n-nodes-base.set",
      "position": [
        -200,
        60
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "dbbc1e7b-c63e-4ff1-9524-8ef3e9f6cd48",
              "name": "clusterCenterType",
              "type": "string",
              "value": "is_medoid"
            },
            {
              "id": "a994ce37-2530-4030-acfb-ec777a7ddb05",
              "name": "qdrantCloudURL",
              "type": "string",
              "value": "https://152bc6e2-832a-415c-a1aa-fb529f8baf8d.eu-central-1-0.aws.cloud.qdrant.io"
            },
            {
              "id": "12f0a9e6-686d-416e-a61b-72d034ec21ba",
              "name": "collectionName",
              "type": "string",
              "value": "=agricultural-crops"
            },
            {
              "id": "4c88a617-d44f-4776-b457-8a1dffb1d03c",
              "name": "clusterThresholdCenterType",
              "type": "string",
              "value": "is_medoid_cluster_threshold"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "13b25434-bd66-4293-93f1-26c67b9ec7dd",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -340,
        260
      ],
      "parameters": {
        "color": 6,
        "width": 360,
        "height": 200,
        "content": "**clusterCenterType** - \ub458 \uc911 \ud558\ub098  \n* \"is_text_anchor_medoid\" \ub610\ub294  \n* \"is_medoid\"  \n\n**clusterThresholdCenterType** - \ub458 \uc911 \ud558\ub098  \n* \"is_text_anchor_medoid_cluster_threshold\" \ub610\ub294  \n* \"is_medoid_cluster_threshold\""
      },
      "typeVersion": 1
    },
    {
      "id": "869b0962-6cae-487d-8230-539a0cc4c14c",
      "name": "Info About Crop Labeled Clusters",
      "type": "n8n-nodes-base.set",
      "position": [
        440,
        60
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "5327b254-b703-4a34-a398-f82edb1d6d6b",
              "name": "=cropsNumber",
              "type": "number",
              "value": "={{ $json.result.hits.length }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "5d3956f8-f43b-439e-b176-a594a21d8011",
      "name": "Total Points in Collection",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        40,
        60
      ],
      "parameters": {
        "url": "={{ $json.qdrantCloudURL }}/collections/{{ $json.collectionName }}/points/count",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"exact\": true\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "qdrantApi"
      },
      "credentials": {
        "qdrantApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "14ba3db9-3965-4b20-b333-145616d45c3a",
      "name": "Each Crop Counts",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        240,
        60
      ],
      "parameters": {
        "url": "={{ $('Variables for medoids').first().json.qdrantCloudURL }}/collections/{{ $('Variables for medoids').first().json.collectionName }}/facet",
        "method": "POST",
        "options": {},
        "jsonBody": "={{\n{\n  \"key\": \"crop_name\",\n  \"limit\": $json.result.count,\n  \"exact\": true\n}\n}}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "qdrantApi"
      },
      "credentials": {
        "qdrantApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "e37c6758-0556-4a56-ab14-d4df663cb53a",
      "name": "Image URL hardcode",
      "type": "n8n-nodes-base.set",
      "position": [
        -480,
        60
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "46ceba40-fb25-450c-8550-d43d8b8aa94c",
              "name": "imageURL",
              "type": "string",
              "value": "={{ $json.query.imageURL }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "b24ad1a7-0cf8-4acc-9c18-6fe9d58b10f2",
      "name": "Execute Workflow Trigger",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "position": [
        -720,
        60
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "50424f2b-6831-41bf-8de4-81f69d901ce1",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -240,
        -80
      ],
      "parameters": {
        "width": 180,
        "height": 120,
        "content": "\uc774\uc804 2\uac1c\uc758 \ud30c\uc774\ud504\ub77c\uc778\uc5d0\uc11c \uc5c5\ub85c\ub4dc \ubc0f \uc900\ube44\ud55c Qdrant\uc758 \uceec\ub809\uc158\uc5d0 \uc811\uadfc\ud558\uae30 \uc704\ud55c \ubcc0\uc218\ub4e4"
      },
      "typeVersion": 1
    },
    {
      "id": "2e8ed3ca-1bba-4214-b34b-376a237842ff",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        40,
        -120
      ],
      "parameters": {
        "width": 560,
        "height": 140,
        "content": "\uc774 \uc138 \ub178\ub4dc\ub294 \uc6b0\ub9ac Qdrant \uceec\ub809\uc158\uc5d0 \uc5bc\ub9c8\ub098 \ub9ce\uc740 \ub2e4\ub978 \ud074\ub798\uc2a4(\uc791\ubb3c)\uac00 \uc788\ub294\uc9c0 \uc54c\uc544\ub0b4\uae30 \uc704\ud574 \ud544\uc694\ud569\ub2c8\ub2e4: cropsNumber (\"Get similarity of medoids\" \ub178\ub4dc\uc5d0\uc11c \ud544\uc694\ud569\ub2c8\ub2e4. \n[\ub178\ud2b8] \"Total Points in Collection\" -> \"Each Crop Counts\"\ub294 \"[2/4] Set up medoids (2 types) for anomaly detection (crops dataset)\" \ud30c\uc774\ud504\ub77c\uc778\uc5d0\uc11c \uc774\ubbf8 \uc0ac\uc6a9\ub418\uace0 \uc124\uba85\ub418\uc5c8\uc2b5\ub2c8\ub2e4."
      },
      "typeVersion": 1
    },
    {
      "id": "e2fa5763-6e97-4ff5-8919-1cb85a3c6968",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        620,
        240
      ],
      "parameters": {
        "height": 120,
        "content": "\uc5ec\uae30\uc11c, \uc6b0\ub9ac\ub294 \uc774 \uc6cc\ud06c\ud50c\ub85c\uc6b0 \ub3c4\uad6c\uc5d0 \uc804\ub2ec\ub41c \uc774\ubbf8\uc9c0\ub97c Voyage \uc784\ubca0\ub529 \ubaa8\ub378\ub85c \uc784\ubca0\ub529\ud558\uc5ec \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc758 \ubaa8\ub4e0 \uc791\ubb3c \uc774\ubbf8\uc9c0\uc640 \ube44\uad50\ud569\ub2c8\ub2e4."
      },
      "typeVersion": 1
    },
    {
      "id": "cdb6b8d3-f7f4-4d66-850f-ce16c8ed98b9",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        920,
        220
      ],
      "parameters": {
        "width": 400,
        "height": 180,
        "content": "\uc774\ubbf8\uc9c0\uac00 \ubaa8\ub4e0 \ud074\ub7ec\uc2a4\ud130 \uc911\uc2ec(\uc791\ubb3c)\uacfc \uc5bc\ub9c8\ub098 \uc720\uc0ac\ud55c\uc9c0 \ud655\uc778\ud558\ub294 \uc911.  \n\ub9cc\uc57d \uc774\uc804 \uc6cc\ud06c\ud50c\ub85c\uc6b0\uc5d0\uc11c \uc124\uc815\ud558\uace0 \uc911\uc2ec\uc5d0 \uc800\uc7a5\ud55c \uac83\uacfc \ub354 \uc720\uc0ac\ud558\ub2e4\uba74, \uc774 \uc774\ubbf8\uc9c0\ub294 \uc774 \uc791\ubb3c \ud074\ub798\uc2a4\uc5d0 \uc18d\ud560 \uac00\ub2a5\uc131\uc774 \ub192\uc2b5\ub2c8\ub2e4; \uadf8\ub807\uc9c0 \uc54a\uc73c\uba74, \ud074\ub798\uc2a4\uc5d0 \ube44\uc815\uc0c1\uc801\uc785\ub2c8\ub2e4.  \n\uc774\ubbf8\uc9c0\uac00 \ubaa8\ub4e0 \ud074\ub798\uc2a4\uc5d0 \ub300\ud574 \ube44\uc815\uc0c1\uc801\uc774\ub77c\uba74, \uadf8\uac83\uc740 \uc774\uc0c1\uc785\ub2c8\ub2e4."
      },
      "typeVersion": 1
    },
    {
      "id": "03b4699f-ba43-4f5f-ad69-6f81deea2641",
      "name": "Sticky Note22",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -620,
        580
      ],
      "parameters": {
        "color": 4,
        "width": 540,
        "height": 300,
        "content": "### \uc774\uc0c1 \ud0d0\uc9c0\n\n1. \uccab \ubc88\uc9f8 \ud30c\uc774\ud504\ub77c\uc778\uc740 (crops) \ub370\uc774\ud130\uc14b\uc744 Qdrant\uc758 \uceec\ub809\uc158\uc5d0 \uc5c5\ub85c\ub4dc\ud569\ub2c8\ub2e4.\n2. \ub450 \ubc88\uc9f8 \ud30c\uc774\ud504\ub77c\uc778\uc740 \uc774 Qdrant \uceec\ub809\uc158\uc5d0 \ud074\ub7ec\uc2a4\ud130 (\ud074\ub798\uc2a4) \uc13c\ud130\ub97c \uc124\uc815\ud558\uace0 \ud074\ub7ec\uc2a4\ud130 (\ud074\ub798\uc2a4) \uc784\uacc4\uac12 \uc810\uc218\ub97c \uc124\uc815\ud569\ub2c8\ub2e4.\n3. **\uc774\uac83\uc740 \uc785\ub825\uc73c\ub85c \uc5b4\ub5a4 \uc774\ubbf8\uc9c0\ub4e0 \ubc1b\uc544\ub4e4\uc774\uace0 Qdrant (crops) \uceec\ub809\uc158\uc73c\ub85c \uc218\ud589\ub41c \ubaa8\ub4e0 \uc900\ube44 \uc791\uc5c5\uc744 \uc0ac\uc6a9\ud558\ub294 \uc774\uc0c1 \ud0d0\uc9c0 \ub3c4\uad6c\uc785\ub2c8\ub2e4.**\n\n### \uc7ac\uc0dd\uc131 \ubc29\ubc95\n\nKaggle\uc5d0\uc11c [crops](https://www.kaggle.com/datasets/mdwaquarazam/agricultural-crops-image-classification) \ub370\uc774\ud130\uc14b\uc744 \uc790\uc2e0\uc758 Google Storage \ubc84\ud0b7\uc5d0 \uc5c5\ub85c\ub4dc\ud574\uc57c \ud558\uba70, [Qdrant Cloud](https://qdrant.tech/documentation/quickstart-cloud/)\uc5d0 \ub300\ud55c APIs/\uc5f0\uacb0\uc744 \uc7ac\uc0dd\uc131\ud574\uc57c \ud569\ub2c8\ub2e4 (**Free Tier** \ud074\ub7ec\uc2a4\ud130\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\uc74c), Voyage AI API \ubc0f Google Cloud Storage.\n\n**\uc77c\ubc18\uc801\uc73c\ub85c, \ud30c\uc774\ud504\ub77c\uc778\uc740 \uc5b4\ub5a4 \uc774\ubbf8\uc9c0 \ub370\uc774\ud130\uc14b\uc5d0\ub3c4 \uc801\uc6a9\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.**"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "f67b764b-9e1a-4db0-b9f2-490077a62f74",
  "connections": {
    "Embed image": {
      "main": [
        [
          {
            "node": "Get similarity of medoids",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Each Crop Counts": {
      "main": [
        [
          {
            "node": "Info About Crop Labeled Clusters",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Image URL hardcode": {
      "main": [
        [
          {
            "node": "Variables for medoids",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Variables for medoids": {
      "main": [
        [
          {
            "node": "Total Points in Collection",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute Workflow Trigger": {
      "main": [
        [
          {
            "node": "Image URL hardcode",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get similarity of medoids": {
      "main": [
        [
          {
            "node": "Compare scores",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Total Points in Collection": {
      "main": [
        [
          {
            "node": "Each Crop Counts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Info About Crop Labeled Clusters": {
      "main": [
        [
          {
            "node": "Embed image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}