{"id":32954982,"url":"https://github.com/joshuaeckroth/clj-ml","last_synced_at":"2025-11-13T03:00:56.733Z","repository":{"id":7579474,"uuid":"8934589","full_name":"joshuaeckroth/clj-ml","owner":"joshuaeckroth","description":"A machine learning library for Clojure built on top of Weka and friends","archived":false,"fork":true,"pushed_at":"2021-12-05T08:10:47.000Z","size":608,"stargazers_count":135,"open_issues_count":3,"forks_count":20,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-10-23T22:45:34.193Z","etag":null,"topics":["clojure","data-science","machine-learning","weka"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"bmabey/clj-ml","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/joshuaeckroth.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-03-21T17:40:26.000Z","updated_at":"2025-09-22T12:44:11.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/joshuaeckroth/clj-ml","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/joshuaeckroth/clj-ml","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshuaeckroth%2Fclj-ml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshuaeckroth%2Fclj-ml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshuaeckroth%2Fclj-ml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshuaeckroth%2Fclj-ml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/joshuaeckroth","download_url":"https://codeload.github.com/joshuaeckroth/clj-ml/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshuaeckroth%2Fclj-ml/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":284145006,"owners_count":26954846,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-13T02:00:06.582Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","data-science","machine-learning","weka"],"created_at":"2025-11-12T22:00:41.096Z","updated_at":"2025-11-13T03:00:56.726Z","avatar_url":"https://github.com/joshuaeckroth.png","language":"Clojure","funding_links":[],"categories":["Clojure"],"sub_categories":["[Tools](#tools-1)"],"readme":"# clj-ml\n\nA machine learning library for Clojure built on top of Weka and friends.\n\nThis library (specifically, some dependencies) requires Java 1.7+.\n\n## Installation\n\n### Installing from Clojars\n\n    [cc.artifice/clj-ml \"0.8.5\"]\n\n### Installing from Maven\n\n(add Clojars repository)\n\n    \u003cdependency\u003e\n      \u003cgroupId\u003ecc.artifice\u003c/groupId\u003e\n      \u003cartifactId\u003eclj-ml\u003c/artifactId\u003e\n      \u003cversion\u003e0.8.5\u003c/version\u003e\n    \u003c/dependency\u003e\n\n## Supported algorithms\n\n * Filters\n   * Discretization (supervised, unsupervised, PKI)\n   * Nominal to binary (supervised, unsupervised)\n   * Numeric to nominal\n   * String to word vector\n   * Attribute manipulation (reorder, add, remove range, remove percentage, etc.)\n   * Resample (supervised, unsupervised)\n   * Replace missing values with mean (numeric attributes) or mode (nominal attributes)\n\n * Classifiers\n   * k-Nearest neighbor\n   * Decision trees: C4.5/J4.8, Boosted stump, Random forest, Rotation forest, M5P\n   * Naive Bayes\n   * Multilayer perceptrons\n   * Support vector machines (grid-based training), SMO, Spegasos\n   * Raced Incremental Logit Boost\n\n * Regression\n   * Linear\n   * Logistic\n   * Pace\n   * Additive gradient boosting\n\n * Clusterers\n   * k-Means\n   * Cobweb\n   * Expectation-maximization\n\n## Usage\n\nAPI documenation can be found [here](http://clj-ml.artifice.cc/doc/index.html).\n\n### I/O of data\n\n```clojure\nuser\u003e (use 'clj-ml.io)\nnil\n\nuser\u003e (def ds (load-instances :arff \"file:///home/josh/git/clj-ml/iris.arff\"))\n#'user/ds\nuser\u003e ds\n#\u003cInstances @relation iris\n\n@attribute sepallength numeric\n@attribute sepalwidth numeric\n@attribute petallength numeric\n@attribute petalwidth numeric\n@attribute class {Iris-setosa,Iris-versicolor,Iris-virginica}\n\n@data\n5.1,3.5,1.4,0.2,Iris-setosa\n4.9,3,1.4,0.2,Iris-setosa\n4.7,3.2,1.3,0.2,Iris-setosa\n4.6,3.1,1.5,0.2,Iris-setosa\n5,3.6,1.4,0.2,Iris-setosa\n5.4,3.9,1.7,0.4,Iris-setosa\n4.6,3.4,1.4,0.3,Iris-setosa\n...\n\nuser\u003e (def ds (load-instances :arff \"http://repository.seasr.org/Datasets/UCI/arff/iris.arff\"))\n#'user/ds\n\nuser\u003e (save-instances :csv \"iris.csv\" ds)\nnil\nuser\u003e (println (slurp \"iris.csv\"))\nsepallength,sepalwidth,petallength,petalwidth,class\n5.1,3.5,1.4,0.2,Iris-setosa\n4.9,3,1.4,0.2,Iris-setosa\n4.7,3.2,1.3,0.2,Iris-setosa\n4.6,3.1,1.5,0.2,Iris-setosa\n5,3.6,1.4,0.2,Iris-setosa\n5.4,3.9,1.7,0.4,Iris-setosa\n4.6,3.4,1.4,0.3,Iris-setosa\n5,3.4,1.5,0.2,Iris-setosa\n4.4,2.9,1.4,0.2,Iris-setosa\n4.9,3.1,1.5,0.1,Iris-setosa\n5.4,3.7,1.5,0.2,Iris-setosa\n...\n\nuser\u003e (def ds (load-instances :csv \"file:///home/josh/git/clj-ml/iris.csv\"))\n#'user/ds\nuser\u003e ds\n#\u003cInstances @relation stream\n\n@attribute sepallength numeric\n@attribute sepalwidth numeric\n@attribute petallength numeric\n@attribute petalwidth numeric\n@attribute class {Iris-setosa,Iris-versicolor,Iris-virginica}\n\n@data\n5.1,3.5,1.4,0.2,Iris-setosa\n4.9,3,1.4,0.2,Iris-setosa\n4.7,3.2,1.3,0.2,Iris-setosa\n4.6,3.1,1.5,0.2,Iris-setosa\n5,3.6,1.4,0.2,Iris-setosa\n5.4,3.9,1.7,0.4,Iris-setosa\n4.6,3.4,1.4,0.3,Iris-setosa\n5,3.4,1.5,0.2,Iris-setosa\n```\n\n### Working with datasets\n\n```clojure\nuser\u003e (use 'clj-ml.data)\nnil\n\nuser\u003e (def ds (make-dataset \"my-name\" [:length :width {:style nil} {:kind [:good :bad]}]\n                            [[12 24 \"longish\" :good]\n                             [8 5 \"shortish\" :bad]]))\n#'user/ds\nuser\u003e ds\n#\u003cClojureInstances @relation my-name\n\n@attribute length numeric\n@attribute width numeric\n@attribute style string\n@attribute kind {good,bad}\n\n@data\n12,24,longish,good\n8,5,shortish,bad\u003e\n\nuser\u003e (dataset-seq ds)\n(#\u003cInstance 12,24,longish,good\u003e #\u003cInstance 8,5,shortish,bad\u003e)\n\nuser\u003e (map instance-to-map (dataset-seq ds))\n({:kind :good, :style \"longish\", :width 24.0, :length 12.0}\n{:kind :bad, :style \"shortish\", :width 5.0, :length 8.0})\n\nuser\u003e (map instance-to-vector (dataset-seq ds))\n([12.0 24.0 \"longish\" :good] [8.0 5.0 \"shortish\" :bad])\n```\n\n### Filtering datasets\n\n```clojure\nuser\u003e (use 'clj-ml.filters 'clj-ml.io)\nnil\n\nuser\u003e (def ds (load-instances :csv \"file:///home/josh/git/clj-ml/iris.csv\"))\n#'user/ds\n\nuser\u003e (def discretize (make-filter :unsupervised-discretize\n                                   {:dataset-format ds\n                                    :attributes [:sepallength :petallength]}))\n#'user/discretize\n\nuser\u003e (def filtered-ds (filter-apply discretize ds))\n#'user/filtered-ds\n\nuser\u003e (map instance-to-map (dataset-seq filtered-ds))\n({:class :Iris-setosa, :petalwidth 0.2, :petallength :'(-inf-1.59]',\n :sepalwidth 3.5, :sepallength :'(5.02-5.38]'}\n{:class :Iris-setosa, :petalwidth 0.2, :petallength :'(-inf-1.59]',\n :sepalwidth 3.0, :sepallength :'(4.66-5.02]'}\n{:class :Iris-setosa, :petalwidth 0.2, :petallength :'(-inf-1.59]',\n :sepalwidth 3.2, :sepallength :'(4.66-5.02]'}\n{:class :Iris-setosa, :petalwidth 0.2, :petallength :'(-inf-1.59]',\n :sepalwidth 3.1, :sepallength :'(-inf-4.66]'}\n{:class :Iris-setosa, :petalwidth 0.2, :petallength :'(-inf-1.59]',\n :sepalwidth 3.6, :sepallength :'(4.66-5.02]'}\n...) ;; the petallength and sepallength attributes are now nominal\n```\n\nEquivalently,\n\n```clojure\nuser\u003e (def filtered-ds (-\u003e\u003e \"file:///home/josh/git/clj-ml/iris.csv\"\n                            (load-instances :csv)\n                            (make-apply-filter :unsupervised-discretize\n                                               {:attributes [:sepallength :petallength]})))\n```\n\n### Using classifiers\n\n```clojure\nuser\u003e (use 'clj-ml.classifiers 'clj-ml.data 'clj-ml.utils)\nnil\n\nuser\u003e (def ds (-\u003e (load-instances :arff \"file:///home/josh/git/clj-ml/iris.arff\")\n                  (dataset-set-class :class)))\n#'user/ds\n\nuser\u003e (def classifier (-\u003e (make-classifier :decision-tree :c45)\n                          (classifier-train ds)))\n#'user/classifier\n\nuser\u003e (def instance (-\u003e (first (dataset-seq ds))\n                        (instance-set-class-missing)))\n\nuser\u003e (classifier-classify classifier instance)\n:Iris-setosa\n```\n\nEvaluation:\n\n```clojure\nuser\u003e (def evaluation (classifier-evaluate classifier :cross-validation ds 10))\n#'user/evaluation\n\nuser\u003e (clojure.pprint/pprint (dissoc evaluation :summary :confusion-matrix))\n{:incorrect 7.0,\n :root-relative-squared-error 36.693518966642074,\n :sf-entropy-gain -4076.3670930399717,\n :recall\n {:Iris-setosa 0.9795918367346939,\n  :Iris-versicolor 0.94,\n  :Iris-virginica 0.94},\n :kb-information 217.7935138195151,\n :kb-relative-information 13741.240800360849,\n :false-positive-rate\n {:Iris-setosa 0.0,\n  :Iris-versicolor 0.04040404040404041,\n  :Iris-virginica 0.030303030303030304},\n :percentage-correct 95.30201342281879,\n :roc-area\n {:Iris-setosa 0.984845423317842,\n  :Iris-versicolor 0.9456,\n  :Iris-virginica 0.9496},\n :kb-mean-information 1.4617014350303028,\n :percentage-unclassified 0.0,\n :percentage-incorrect 4.697986577181208,\n :root-mean-squared-error 0.17297908222448935,\n :unclassified 0.0,\n :correlation-coefficient\n {:nan \"Can't compute correlation coefficient: class is nominal!\"},\n :correct 142.0,\n :sf-mean-entropy-gain -27.358168409664238,\n :mean-absolute-error 0.04083212821368881,\n :relative-absolute-error 9.187228848079984,\n :error-rate 0.04697986577181208,\n :kappa 0.9295222650179066,\n :f-measure\n {:Iris-setosa 0.9896907216494846,\n  :Iris-versicolor 0.9306930693069307,\n  :Iris-virginica 0.94},\n :false-negative-rate\n {:Iris-setosa 0.02040816326530612,\n  :Iris-versicolor 0.06,\n  :Iris-virginica 0.06},\n :evaluation-object #\u003cEvaluation weka.classifiers.Evaluation@6a7272ca\u003e,\n :average-cost 0.0,\n :precision\n {:Iris-setosa 1.0,\n  :Iris-versicolor 0.9215686274509803,\n  :Iris-virginica 0.94}}\n\nuser\u003e (println (:summary evaluation))\n\nCorrectly Classified Instances         142               95.302  %\nIncorrectly Classified Instances         7                4.698  %\nKappa statistic                          0.9295\nMean absolute error                      0.0408\nRoot mean squared error                  0.173 \nRelative absolute error                  9.1872 %\nRoot relative squared error             36.6935 %\nTotal Number of Instances              149     \nIgnored Class Unknown Instances                  1     \n\nnil\nuser\u003e (println (:confusion-matrix evaluation))\n=== Confusion Matrix ===\n\n  a  b  c   \u003c-- classified as\n 48  1  0 |  a = Iris-setosa\n  0 47  3 |  b = Iris-versicolor\n  0  3 47 |  c = Iris-virginica\n\nnil\n```\nSaving and restoring (trained) classifiers:\n\n```clojure\n\nuser\u003e (serialize-to-file classifier \"my-classifier.bin\")\n\"my-classifier.bin\"\n\nuser\u003e (def classifier2 (deserialize-from-file \"my-classifier.bin\"))\n#'user/classifier2\n\nuser\u003e (classifier-classify classifier2 instance)\n:Iris-setosa\n```\n\nText document handling:\n\n```clojure\nuser\u003e (def docs [{:id 10\n                  :title \"Document title 1\"\n                  :fulltext \"This is the fulltext...\"\n                  :has-class? false}\n                 {:id 11\n                  :title \"Another document title\"\n                  :fulltext \"Some more \\\"fulltext\\\"; rabbit artificial machine bananas\"\n                  :has-class? true}])\n#'user/docs\n\nuser\u003e (docs-to-dataset docs \"bananas-model\" \"my-models\" :stemmer true :lowercase false)\n#\u003cInstances @relation 'docs-weka.filters.unsupervised.attribute.StringToWordVector...'\n\n@attribute class {no,yes}\n@attribute title-1 numeric\n@attribute title-Another numeric\n@attribute title-Document numeric\n@attribute title-document numeric\n@attribute title-titl numeric\n@attribute fulltext-Some numeric\n@attribute fulltext-This numeric\n@attribute fulltext-artifici numeric\n@attribute fulltext-banana numeric\n@attribute fulltext-fulltext numeric\n@attribute fulltext-is numeric\n@attribute fulltext-machin numeric\n@attribute fulltext-more numeric\n@attribute fulltext-rabbit numeric\n@attribute fulltext-the numeric\n\n@data\n{0 yes,1 0.480453,3 0.480453,7 0.480453,11 0.480453,15 0.480453}\n{2 0.480453,4 0.480453,6 0.480453,8 0.480453,9 0.480453,12 0.480453,13 0.480453,14 0.480453}\u003e\nuser\u003e\n```\n\nWords appearing in the dataset will only be those appearing in the\ndocuments (or a subset; by default, the most common 1000 words). This\npresents a problem when new documents are loaded and used in a\nclassifier trained on other documents. The classifier will not know\nhow to handle word attributes that were not present in the training\nset.\n\nThe `docs-to-dataset` function provides the ability to save the\ntraining documents dataset and \"filter\" the testing documents through\nthis dataset to ensure the same word attributes are extracted for both\nsets. The following example shows that the words \"foo, bar, baz, quux\"\nare ignored in the new (testing) documents, and all the original\nattributes in the training dataset are retained.\n\n```clojure\nuser\u003e (docs-to-dataset docs \"Topic\" \"Sports\" 1 \"/tmp\"\n                       :stemmer true :lowercase false :training true)\n#\u003cInstances @relation 'docs-weka.filters.unsupervised.attribute.StringToWordVector...'\n\n@attribute class {no,yes}\n@attribute title-1 numeric\n@attribute title-Another numeric\n@attribute title-Document numeric\n@attribute title-document numeric\n@attribute title-titl numeric\n@attribute fulltext-Some numeric\n@attribute fulltext-This numeric\n@attribute fulltext-artifici numeric\n@attribute fulltext-banana numeric\n@attribute fulltext-fulltext numeric\n@attribute fulltext-is numeric\n@attribute fulltext-machin numeric\n@attribute fulltext-more numeric\n@attribute fulltext-rabbit numeric\n@attribute fulltext-the numeric\n\n@data\n{2 0.480453,4 0.480453,6 0.480453,8 0.480453,9 0.480453,12 0.480453,13 0.480453,14 0.480453}\n{0 yes,1 0.480453,3 0.480453,7 0.480453,11 0.480453,15 0.480453}\u003e\n\nuser\u003e (def docs2 [{:title \"Document title 1 foo bar\"\n                   :fulltext \"baz rabbit quux\"\n                   :terms {\"Topic\" [\"Sports\"]}}])\n#'user/docs2\n\nuser\u003e (docs-to-dataset docs2 \"Topic\" \"Sports\" 1 \"/tmp\"\n                       :stemmer true :lowercase false :testing true)\n#\u003cInstances @relation 'docs-weka.filters.unsupervised.attribute.StringToWordVector...'\n\n@attribute class {no,yes}\n@attribute title-1 numeric\n@attribute title-Another numeric\n@attribute title-Document numeric\n@attribute title-document numeric\n@attribute title-titl numeric\n@attribute fulltext-Some numeric\n@attribute fulltext-This numeric\n@attribute fulltext-artifici numeric\n@attribute fulltext-banana numeric\n@attribute fulltext-fulltext numeric\n@attribute fulltext-is numeric\n@attribute fulltext-machin numeric\n@attribute fulltext-more numeric\n@attribute fulltext-rabbit numeric\n@attribute fulltext-the numeric\n\n@data\n{0 yes,1 0.480453,3 0.480453,14 0.480453}\u003e\nuser\u003e \n```\n\n### Using clusterers\n\n```clojure\nuser\u003e (use 'clj-ml.clusterers)\nnil\n\nuser\u003e (def ds (-\u003e (load-instances :arff \"file:///home/josh/git/clj-ml/iris.arff\")\n                  (dataset-remove-attribute-at 4)))\n#'user/ds\nuser\u003e ds\n#\u003cInstances @relation iris\n\n@attribute sepallength numeric\n@attribute sepalwidth numeric\n@attribute petallength numeric\n@attribute petalwidth numeric\n\n@data\n5.1,3.5,1.4,0.2\n4.9,3,1.4,0.2\n4.7,3.2,1.3,0.2\n4.6,3.1,1.5,0.2\n5,3.6,1.4,0.2\n5.4,3.9,1.7,0.4\n4.6,3.4,1.4,0.3\n...\n\nuser\u003e (def clusterer (make-clusterer :k-means {:number-clusters 3}))\n#'user/clusterer\n\nuser\u003e (clusterer-build clusterer ds)\nnil\n\nuser\u003e clusterer\n#\u003cSimpleKMeans \nkMeans\n======\n\nNumber of iterations: 6\nWithin cluster sum of squared errors: 6.998114004826762\nMissing values globally replaced with mean/mode\n\nCluster centroids:\n                           Cluster#\nAttribute      Full Data          0          1          2\n                   (150)       (61)       (50)       (39)\n=========================================================\nsepallength       5.8433     5.8885      5.006     6.8462\nsepalwidth         3.054     2.7377      3.418     3.0821\npetallength       3.7587     4.3967      1.464     5.7026\npetalwidth        1.1987      1.418      0.244     2.0795\n\n\n\u003e\n\nuser\u003e (def clustered-ds (clusterer-cluster clusterer ds))\n#'user/clustered-ds\n\nuser\u003e clustered-ds\n#\u003cClojureInstances @relation 'clustered iris'\n\n@attribute sepallength numeric\n@attribute sepalwidth numeric\n@attribute petallength numeric\n@attribute petalwidth numeric\n@attribute class {0,1,2}\n\n@data\n5.1,3.5,1.4,0.2,1\n4.9,3,1.4,0.2,1\n4.7,3.2,1.3,0.2,1\n4.6,3.1,1.5,0.2,1\n5,3.6,1.4,0.2,1\n5.4,3.9,1.7,0.4,1\n4.6,3.4,1.4,0.3,1\n5,3.4,1.5,0.2,1\n4.4,2.9,1.4,0.2,1\n...\n```\n\n## Example: Home price prediction\n\nhttp://www.ibm.com/developerworks/library/os-weka1/\n\n```clojure\nuser\u003e (def homes (make-dataset \"homes\" [:house-size :lot-size :bedrooms\n                                        :granite :bathroom :sellingPrice]\n                               [[3529, 9191, 6, 0, 0, 205000]\n                                [3247, 10061, 5, 1, 1, 224900]\n                                [4032, 10150, 5, 0, 1, 197900]\n                                [2397, 14156, 4, 1, 0,189900]\n                                [2200, 9600, 4, 0, 1, 195000] \n                                [3536, 19994, 6, 1, 1,325000] \n                                [2983, 9365, 5, 0, 1, 230000]]))\n#'user/homes\n\nuser\u003e (def homes (dataset-set-class homes :sellingPrice))\n#'user/homes\n\nuser\u003e homes\n#\u003cClojureInstances @relation homes\n\n@attribute house-size numeric\n@attribute lot-size numeric\n@attribute bedrooms numeric\n@attribute granite numeric\n@attribute bathroom numeric\n@attribute sellingPrice numeric\n\n@data\n3529,9191,6,0,0,205000\n3247,10061,5,1,1,224900\n4032,10150,5,0,1,197900\n2397,14156,4,1,0,189900\n2200,9600,4,0,1,195000\n3536,19994,6,1,1,325000\n2983,9365,5,0,1,230000\u003e\n\nuser\u003e (def reg (classifier-train (make-classifier :regression :linear) homes))\n#'user/reg\n\nuser\u003e reg\n#\u003cLinearRegression \nLinear Regression Model\n\nsellingPrice =\n\n    -26.6882 * house-size +\n      7.0551 * lot-size +\n  43166.0767 * bedrooms +\n  42292.0901 * bathroom +\n -21661.1208\u003e\nuser\u003e \n\nuser\u003e (classifier-predict-numeric reg (make-instance homes [3198, 9669, 5, 1, 1, nil]))\n219328.35717359098\n```\n\n## Example: Predicting survival on the Titanic\n\nhttps://www.kaggle.com/c/titanic-gettingStarted\n\nFirst globally replace all double quoted strings `\"\"foo\"\"` with\nbackslash quoted strings: `\\\"foo\\\"`. Weka does not handle the former.\n\n```clojure\nuser\u003e (require '[clj-ml.io :refer [load-instances]]\n               '[clj-ml.data :refer [dataset-set-class dataset-class-index dataset-class-name]]\n               '[clj-ml.filters :refer [make-apply-filter]]\n               '[clj-ml.classifiers :refer [classifier-evaluate make-classifier]])\nnil\nuser\u003e (def titanicds (load-instances :csv \"file:///home/josh/git/clj-ml/titanic-train.csv\"))\nuser\u003e titanicds\n#\u003cInstances @relation stream\n\n@attribute PassengerId numeric\n@attribute Survived numeric\n@attribute Pclass numeric\n@attribute Name {'Braund, Mr. Owen Harris','Cumings, Mrs. John Bradley (Florence Briggs Thayer)', ...}\n@attribute Sex {male,female}\n@attribute Age numeric\n@attribute SibSp numeric\n@attribute Parch numeric\n@attribute Ticket {'A/5 21171','PC 17599','STON/O2. 3101282',113803.0, ...}\n@attribute Fare numeric\n@attribute Cabin {C85,C123,E46,G6,C103,D56,A6,'C23 C25 C27', ...}\n@attribute Embarked {S,C,Q}\n\n@data\n1,0,3,'Braund, Mr. Owen Harris',male,22,1,0,'A/5 21171',7.25,?,S\n2,1,1,'Cumings, Mrs. John Bradley (Florence Briggs Thayer)',female,38,1,0,'PC 17599',71.2833,C85,C\n3,1,3,'Heikkinen, Miss. Laina',female,26,0,0,'STON/O2. 3101282',7.925,?,S\n4,1,1,'Futrelle, Mrs. Jacques Heath (Lily May Peel)',female,35,1,0,113803.0,53.1,C123,S\n5,0,3,'Allen, Mr. William Henry',male,35,0,0,373450.0,8.05,?,S\n6,0,3,'Moran, Mr. James',male,?,0,0,330877.0,8.4583,?,Q\n7,0,1,'McCarthy, Mr. Timothy J',male,54,0,0,17463.0,51.8625,E46,S\n8,0,3,'Palsson, Master. Gosta Leonard',male,2,3,1,349909.0,21.075,?,S\n9,1,3,'Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)',female,27,0,2,347742.0,11.1333,?,S\n10,1,2,'Nasser, Mrs. Nicholas (Adele Achem)',female,14,1,0,237736.0,30.0708,?,C\n11,1,3,'Sandstrom, Miss. Marguerite Rut',female,4,1,1,'PP 9549',16.7,G6,S\n...\n\u003e\n\n#'user/titanicds\nuser\u003e (def titanicds (dataset-set-class titanicds :Survived))\n#'user/titanicds\nuser\u003e (dataset-class-index titanicds)\n1\n\nuser\u003e (def titanicds (make-apply-filter :numeric-to-nominal\n                                        {:attributes [:Survived]}\n                                        titanicds))\n#'user/titanicds\nuser\u003e titanicds\n#\u003cInstances @relation stream-weka.filters.unsupervised.attribute.NumericToNominal-R2\n\n@attribute PassengerId numeric\n@attribute Survived {0,1}\n@attribute Pclass numeric\n...\n\u003e\n\nuser\u003e (def titanicds (make-apply-filter :replace-missing-values {} titanicds))\n\nuser\u003e (def titanicds (make-apply-filter :remove-attributes\n                                        {:attributes [:PassengerId :Name :Ticket :Cabin]}\n                                        titanicds))\n#'user/titanicds\nuser\u003e titanicds\n#\u003cInstances @relation 'stream-weka.filters.unsupervised.attribute.NumericToNominal...'\n\n@attribute Survived {0,1}\n@attribute Pclass numeric\n@attribute Sex {male,female}\n@attribute Age numeric\n@attribute SibSp numeric\n@attribute Parch numeric\n@attribute Fare numeric\n@attribute Embarked {S,C,Q}\n\n@data\n0,3,male,22,1,0,7.25,S\n1,1,female,38,1,0,71.2833,C\n1,3,female,26,0,0,7.925,S\n1,1,female,35,1,0,53.1,S\n0,3,male,35,0,0,8.05,S\n0,3,male,?,0,0,8.4583,Q\n...\n\u003e\n\nuser\u003e (dataset-class-index titanicds)\n0\nuser\u003e (dataset-class-name titanicds)\n:Survived\n\nuser\u003e (def evaluation (classifier-evaluate (make-classifier :decision-tree :random-forest)\n                                           :cross-validation titanicds 10))\n#'user/evaluation\nuser\u003e (println (:summary evaluation))\n\nCorrectly Classified Instances         727               81.5937 %\nIncorrectly Classified Instances       164               18.4063 %\nKappa statistic                          0.6039\nMean absolute error                      0.2409\nRoot mean squared error                  0.3819\nRelative absolute error                 50.9302 %\nRoot relative squared error             78.532  %\nTotal Number of Instances              891     \n\nnil\nuser\u003e (println (:confusion-matrix evaluation))\n=== Confusion Matrix ===\n\n   a   b   \u003c-- classified as\n 483  66 |   a = 0\n  98 244 |   b = 1\n\nnil\n```\n\nOk, looks good, let's try training on the full training data and\ntesting on the testing data.\n\n```clojure\nuser\u003e (require '[clj-ml.data :refer [dataset-as-maps dataset-seq]]\n               '[clj-ml.classifiers :refer [classifier-train classifier-classify]])\nuser\u003e (def titanic-testds (load-instances :csv \"file:///home/josh/git/clj-ml/titanic-test.csv\"))\nnil\nuser\u003e (def titanic-test-passids (map (comp int :PassengerId)\n                                     (dataset-as-maps titanic-testds)))\n#'user/titanic-test-passids\nuser\u003e titanic-test-passids\n(892 893 894 895 896 897 898 899 900 ...)\n\nuser\u003e (def titanic-testds (-\u003e\u003e titanic-testds\n                               (make-apply-filter :remove-attributes\n                                                  {:attributes [:PassengerId :Name :Ticket :Cabin]})\n                               (make-apply-filter :replace-missing-values {})\n                               (make-apply-filter :add-attribute\n                                                  {:type :nominal :name :Survived\n                                                   :column 0 :labels [\"0\" \"1\"]})))\n#'user/titanic-testds\n\nuser\u003e (def titanic-testds (dataset-set-class titanic-testds :Survived))\n#'user/titanic-testds\n\nuser\u003e titanic-testds\n#\u003cInstances @relation 'stream-weka.filters.unsupervised.attribute.Remove...'\n\n@attribute Survived {0,1}\n@attribute Pclass numeric\n@attribute Sex {male,female}\n@attribute Age numeric\n@attribute SibSp numeric\n@attribute Parch numeric\n@attribute Fare numeric\n@attribute Embarked {Q,S,C}\n\n@data\n?,3,male,34.5,0,0,7.8292,Q\n?,3,female,47,1,0,7,S\n?,2,male,62,0,0,9.6875,Q\n?,3,matitanle,27,0,0,8.6625,S\n?,3,female,22,1,1,12.2875,S\n?,3,male,14,0,0,9.225,S\n?,3,female,30,0,0,7.6292,Q\n...\n\u003e\n\nuser\u003e (def classifier (classifier-train (make-classifier :decision-tree :random-forest) titanicds))\n#'user/classifier\n\nuser\u003e (def preds (for [instance (dataset-seq titanic-testds)]\n                      (name (classifier-classify classifier instance))))\n#'user/preds\n\nuser\u003e preds\n(\"0\" \"1\" \"0\" \"0\" \"0\" \"0\" \"1\" \"0\" \"0\" \"0\" ...)\n\n#'user/preds\n\nuser\u003e (spit \"titanic-predictions.csv\"\n            (clojure.string/join \"\\n\" (cons \"Survived,PassengerId\"\n                                            (map (fn [c1 c2] (format \"%s,%d\" c1 c2))\n                                                 preds titanic-test-passids))))\nnil\n\nuser\u003e (println (slurp \"titanic-predictions.csv\"))\nSurvived,PassengerId\n0,892\n1,893\n0,894\n0,895\n0,896\n0,897\n1,898\n0,899\n0,900\n0,901\n0,902\n...\n```\n\n## How to add a Weka classifier\n\n- In `classifiers.clj`:\n  - Add the appropriate import to the top of the file.\n  - Create another implementation of `make-classifier-options` (using `defmethod`, like the others). At this point, you must decide the pair of keywords that identify your algorithm, such as `:decision-tree :c45`. List all the Weka options that the classifier accepts. Use `check-options` for options that are either present or absent, and `check-option-values` for options that require a value in addition to the option.\n  - Add documentation to the `(defmulti make-classifier ...)` docstring.\n  - Create another implementation of `make-classifier` (using `defmethod`, like the others).\n- Ideally, add some test cases in `classifers_test.clj`.\n\n\n## Thanks YourKit!\n\nYourKit is kindly supporting open source projects with its\nfull-featured Java Profiler.  YourKit, LLC is the creator of\ninnovative and intelligent tools for profiling Java and .NET\napplications. Take a look at YourKit's leading software products: \u003ca\nhref=\"http://www.yourkit.com/java/profiler/index.jsp\"\u003eYourKit Java\nProfiler\u003c/a\u003e and \u003ca\nhref=\"http://www.yourkit.com/.net/profiler/index.jsp\"\u003eYourKit .NET\nProfiler\u003c/a\u003e.\n\n## License\n\nMIT License\n\n## Authors\n\n* 2010: [Antonio Garrote](https://github.com/antoniogarrote)\n* 2010-2013: [Ben Mabey](https://github.com/bmabey)\n* 2013: [Joshua Eckroth](https://github.com/joshuaeckroth)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoshuaeckroth%2Fclj-ml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoshuaeckroth%2Fclj-ml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoshuaeckroth%2Fclj-ml/lists"}