Skip to content

Commit

Permalink
Merge pull request #85 from AP6YC/release/v0.6.0
Browse files Browse the repository at this point in the history
v0.6.0
  • Loading branch information
AP6YC authored Oct 11, 2022
2 parents 75f85cc + 5830ed7 commit 6daf99e
Show file tree
Hide file tree
Showing 59 changed files with 1,753 additions and 1,130 deletions.
7 changes: 7 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# -----------------------------------------------------------------------------
# LFS Settings
# -----------------------------------------------------------------------------

# LFS images
*.png filter=lfs diff=lfs merge=lfs -text
*.ico filter=lfs diff=lfs merge=lfs -text
2 changes: 1 addition & 1 deletion .github/workflows/CompatHelper.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COMPATHELPER_PRIV: ${{ secrets.COMPATHELPER_PRIV }} # optional
run: julia -e 'using CompatHelper; CompatHelper.main()'
run: julia -e 'using CompatHelper; CompatHelper.main()'
6 changes: 4 additions & 2 deletions .github/workflows/Documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@ jobs:
access_token: ${{ github.token }}

- uses: actions/checkout@v2
with:
lfs: 'true'
- uses: julia-actions/setup-julia@latest
with:
version: '1.6'
version: '1.8'
- name: Install dependencies
run: julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
- name: Build and deploy
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # For authentication with GitHub Actions token
DATADEPS_ALWAYS_ACCEPT: true
# DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} # For authentication with SSH deploy key
run: julia --project=docs/ docs/make.jl
run: julia --project=docs/ docs/make.jl
17 changes: 10 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
# IDE ignores
.vscode/

# Project ignores
_dev/

# DemoCards intermediate compilation directories
docs/src/democards/
docs/src/examples/

# Julia package development ignores
*.jl.*.cov
*.jl.cov
Expand All @@ -8,10 +18,3 @@
/docs/Manifest.toml
/docs/build/
/docs/site/

# Project ignores
data/mnist/
!data/.gitkeep

# IDE ignores
.vscode/
10 changes: 10 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Contributing to the Project

The `AdaptiveResonance.jl` project is open sourced and open to contribution!
If you would like to contribute to the project, you should know:

1. The [README](README.md) contains a quick summary of the contributing guidelines.
2. The [code of conduct](CODE_OF_CONDUCT.md) declares the behavior guidelines for contributors, mainly concerning respect and decorum.
3. The [contributing guide](https://ap6yc.github.io/AdaptiveResonance.jl/dev/man/contributing/) in the official documentation provides an in-depth guide to contributing, such as how to do GitFlow, how to develop in Julia, and how the internals of the package work.

In summary, the main point of contact is the [GitHub issues](https://github.com/AP6YC/AdaptiveResonance.jl/issues), and code development follows the GitFlow paradigm (i.e., create a `feature/...` branch off of the latest `develop` and submit a pull request back into `develop`).
5 changes: 3 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@ name = "AdaptiveResonance"
uuid = "3d72adc0-63d3-4141-bf9b-84450dd0395b"
authors = ["Sasha Petrenko"]
description = "A Julia package for Adaptive Resonance Theory (ART) algorithms."
version = "0.5.1"
version = "0.6.0"

[deps]
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
NumericalTypeAliases = "be9b823e-291e-41a1-b8ce-806204e78f92"
Parameters = "d96e819e-fc66-5662-9728-84c9c7592b0a"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
ProgressBars = "49802e3a-d2f1-5c88-81d8-b72133a6f568"
SharedArrays = "1a1011a3-84de-559e-8e89-a11a2f7dc383"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[compat]
DocStringExtensions = "0.8, 0.9"
NumericalTypeAliases = "0.1, 0.2"
Parameters = "0.12"
ProgressBars = "0.7, 0.8, 1"
julia = "1"
Expand Down
59 changes: 31 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# AdaptiveResonance
[![adaptiveresonance-header](docs/src/assets/header.png)][docs-dev-url]

A Julia package for Adaptive Resonance Theory (ART) algorithms.
d

| **Documentation** | **Testing Status** | **Coverage** | **Reference** |
|:------------------:|:----------------:|:------------:|:-------------:|
Expand Down Expand Up @@ -53,20 +52,19 @@ Please read the [documentation](https://ap6yc.github.io/AdaptiveResonance.jl/dev

## Contents

- [AdaptiveResonance](#adaptiveresonance)
- [Contents](#contents)
- [Overview](#overview)
- [Contributing](#contributing)
- [Installation](#installation)
- [Quickstart](#quickstart)
- [Implemented Modules](#implemented-modules)
- [Structure](#structure)
- [History](#history)
- [Acknowledgements](#acknowledgements)
- [Authors](#authors)
- [Software](#software)
- [Datasets](#datasets)
- [License](#license)
- [Contents](#contents)
- [Overview](#overview)
- [Contributing](#contributing)
- [Installation](#installation)
- [Quickstart](#quickstart)
- [Implemented Modules](#implemented-modules)
- [Structure](#structure)
- [History](#history)
- [Acknowledgements](#acknowledgements)
- [Authors](#authors)
- [Software](#software)
- [Datasets](#datasets)
- [License](#license)

## Overview

Expand Down Expand Up @@ -96,21 +94,23 @@ Patch versions are for bug fixes, minor versions are for backward-compatible cha
This project is distributed as a Julia package, available on [JuliaHub](https://juliahub.com/).
Its usage follows the usual Julia package installation procedure, interactively:

```julia
] add AdaptiveResonance
```julia-repl
julia> ]
(@v1.8) pkg> add AdaptiveResonance
```

or programmatically:

```julia
using Pkg
Pkg.add("AdaptiveResonance")
```julia-repl
julia> using Pkg
julia> Pkg.add("AdaptiveResonance")
```

You may also add the package directly from GitHub to get the latest changes between releases:

```julia
] add https://github.com/AP6YC/AdaptiveResonance.jl
```julia-repl
julia> ]
(@v1.8) pkg> add https://github.com/AP6YC/AdaptiveResonance.jl
```

## Quickstart
Expand Down Expand Up @@ -209,16 +209,19 @@ The following file tree summarizes the project structure:
```console
AdaptiveResonance
├── .github/workflows // GitHub: workflows for testing and documentation.
├── data // Data: CI data location.
├── docs // Docs: documentation for the module.
│ ├─── examples // DemoCards documentation examples.
│ └─── src // Documentation source files.
│ ├─── examples // DemoCards documentation examples.
│ └─── src // Documentation source files.
├── paper // JOSS: journal paper and citations.
├── src // Source: majority of source code.
│ ├─── ART // ART-based unsupervised modules.
│ └─── ARTMAP // ARTMAP-based supervised modules.
│ ├─── ART // ART-based unsupervised modules.
│ └─── ARTMAP // ARTMAP-based supervised modules.
├── test // Test: Unit, integration, and environment tests.
├── .appveyor // Appveyor: Windows-specific coverage.
├── .gitattributes // Git: LFS settings, languages, etc.
├── .gitignore // Git: .gitignore for the whole project.
├── CODE_OF_CONDUCT.md // Doc: the code of conduct for contributors.
├── CONTRIBUTING.md // Doc: contributing guide (points to this page).
├── LICENSE // Doc: the license to the project.
├── Project.toml // Julia: the Pkg.jl dependencies of the project.
└── README.md // Doc: this document.
Expand Down
Empty file removed data/.gitkeep
Empty file.
3 changes: 2 additions & 1 deletion docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[deps]
AdaptiveResonance = "3d72adc0-63d3-4141-bf9b-84450dd0395b"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
DemoCards = "311a05b2-6137-4a5a-b473-18580a3d38b5"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
Expand All @@ -10,4 +11,4 @@ MultivariateStats = "6f286f6a-111f-5878-ab1e-185364afe411"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"

[compat]
MLDatasets = "0.6"
MLDatasets = "0.7"
12 changes: 0 additions & 12 deletions docs/combo.jl

This file was deleted.

13 changes: 7 additions & 6 deletions docs/examples/adaptive_resonance/data_config.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# cover: ../assets/art.png
# date: 2021-12-2
# author: "[Sasha Petrenko](https://github.com/AP6YC)"
# julia: 1.6
# julia: 1.8
# description: This demo illustrates how the data configuration object works for data preprocessing in ART modules that require it.
# ---

Expand Down Expand Up @@ -46,16 +46,17 @@ fieldnames(AdaptiveResonance.DataConfig)

## Load data
using MLDatasets # Iris dataset
using DataFrames # DataFrames, necessary for MLDatasets.Iris()
using MLDataUtils # Shuffling and splitting

## We will download the Iris dataset for its small size and benchmark use for clustering algorithms.
## Get the iris dataset as a DataFrame
iris = Iris()
# We will download the Iris dataset for its small size and benchmark use for clustering algorithms.
## Get the iris dataset
iris = Iris(as_df=false)
## Manipulate the features and labels into a matrix of features and a vector of labels
features, labels = Matrix(iris.features)', vec(Matrix{String}(iris.targets))
features, labels = iris.features, iris.targets

# Because the MLDatasets package gives us Iris labels as strings, we will use the `MLDataUtils.convertlabel` method with the `MLLabelUtils.LabelEnc.Indices` type to get a list of integers representing each class:
labels = convertlabel(LabelEnc.Indices{Int}, labels)
labels = convertlabel(LabelEnc.Indices{Int}, vec(labels))
unique(labels)

# !!! note
Expand Down
16 changes: 9 additions & 7 deletions docs/examples/adaptive_resonance/incremental-batch.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# cover: assets/incremental-batch-cover.png
# date: 2021-12-1
# author: "[Sasha Petrenko](https://github.com/AP6YC)"
# julia: 1.6
# julia: 1.8
# description: This demo illustrates how to use incremental training methods vs. batch training for all ART modules.
# ---

Expand All @@ -23,17 +23,18 @@
# We begin with importing AdaptiveResonance for the ART modules and MLDatasets for some data utilities.
using AdaptiveResonance # ART
using MLDatasets # Iris dataset
using DataFrames # DataFrames, necessary for MLDatasets.Iris()
using MLDataUtils # Shuffling and splitting
using Printf # Formatted number printing

# We will download the Iris dataset for its small size and benchmark use for clustering algorithms.
## Get the iris dataset as a DataFrame
iris = Iris()
## Get the iris dataset
iris = Iris(as_df=false)
## Manipulate the features and labels into a matrix of features and a vector of labels
features, labels = Matrix(iris.features)', vec(Matrix{String}(iris.targets))
features, labels = iris.features, iris.targets

# Because the MLDatasets package gives us Iris labels as strings, we will use the `MLDataUtils.convertlabel` method with the `MLLabelUtils.LabelEnc.Indices` type to get a list of integers representing each class:
labels = convertlabel(LabelEnc.Indices{Int}, labels)
labels = convertlabel(LabelEnc.Indices{Int}, vec(labels))
unique(labels)

# Next, we will create a train/test split with the `MLDataUtils.stratifiedobs` utility:
Expand Down Expand Up @@ -73,7 +74,7 @@ n_train = length(y_train)
## Create a container for the training output labels
y_hat_incremental_train = zeros(Int, n_train)
## Iterate over all training samples
for ix = 1:length(y_train)
for ix in eachindex(y_train)
sample = X_train[:, ix]
label = y_train[ix]
y_hat_incremental_train[ix] = train!(art_incremental, sample, y=label)
Expand Down Expand Up @@ -128,12 +129,13 @@ perf_test_incremental = performance(y_hat_incremental, y_test)
using Printf # Formatted number printing
using MultivariateStats # Principal component analysis (PCA)
using Plots # Plotting frontend
gr() # Use the default GR backend explicitly

## Train a PCA model
M = fit(PCA, features; maxoutdim=2)

## Apply the PCA model to the testing set
X_test_pca = transform(M, X_test)
X_test_pca = MultivariateStats.transform(M, X_test)

# Now that we have the test points cast into a 2-D set of points, we can create a scatter plot that shows how each point is categorized by the modules.

Expand Down
14 changes: 8 additions & 6 deletions docs/examples/adaptive_resonance/options.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# cover: assets/options-cover.png
# date: 2021-12-2
# author: "[Sasha Petrenko](https://github.com/AP6YC)"
# julia: 1.6
# julia: 1.8
# description: This demo illustrates how to use options and modify the options for all ART and ARTMAP modules.
# ---

Expand Down Expand Up @@ -88,19 +88,21 @@ my_fuzzyart.opts.rho=0.6

# We begin with importing AdaptiveResonance for the ART modules and MLDatasets for some data utilities.
using MLDatasets # Iris dataset
using DataFrames # DataFrames, necessary for MLDatasets.Iris()
using MLDataUtils # Shuffling and splitting
using Printf # Formatted number printing
using MultivariateStats # Principal component analysis (PCA)
using Plots # Plotting frontend
gr() # Use the default GR backend explicitly

# We will download the Iris dataset for its small size and benchmark use for clustering algorithms.
## Get the iris dataset as a DataFrame
iris = Iris()
## Get the iris dataset
iris = Iris(as_df=false)
## Manipulate the features and labels into a matrix of features and a vector of labels
features, labels = Matrix(iris.features)', vec(Matrix{String}(iris.targets))
features, labels = iris.features, iris.targets

# Because the MLDatasets package gives us Iris labels as strings, we will use the `MLDataUtils.convertlabel` method with the `MLLabelUtils.LabelEnc.Indices` type to get a list of integers representing each class:
labels = convertlabel(LabelEnc.Indices{Int}, labels)
labels = convertlabel(LabelEnc.Indices{Int}, vec(labels))
unique(labels)

# Next, we will create a train/test split with the `MLDataUtils.stratifiedobs` utility:
Expand Down Expand Up @@ -152,7 +154,7 @@ perf_test_2 = performance(y_hat_2, y_test)
M = fit(PCA, features; maxoutdim=2)

## Apply the PCA model to the testing set
X_test_pca = transform(M, X_test)
X_test_pca = MultivariateStats.transform(M, X_test)

# We can now plot the PCA'ed test set and label them according to the two FuzzyART's
# We will do so by creating a function for the subplots first as they will share the same format, and we dare not duplicate code.
Expand Down
11 changes: 6 additions & 5 deletions docs/examples/art/ddvfa_supervised.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# cover: ../assets/ddvfa.png
# date: 2021-11-30
# author: "[Sasha Petrenko](https://github.com/AP6YC)"
# julia: 1.6
# julia: 1.8
# description: This demo shows how to use DDVFA for simple supervised learning by clustering Iris samples and mapping the modules internal categories to the true labels.
# ---

Expand All @@ -14,17 +14,18 @@
# We begin with importing AdaptiveResonance for the ART modules and MLDatasets for some data utilities.
using AdaptiveResonance # ART
using MLDatasets # Iris dataset
using DataFrames # DataFrames, necessary for MLDatasets.Iris()
using MLDataUtils # Shuffling and splitting
using Printf # Formatted number printing

# We will download the Iris dataset for its small size and benchmark use for clustering algorithms.
## Get the iris dataset as a DataFrame
iris = Iris()
## Get the iris dataset
iris = Iris(as_df=false)
## Manipulate the features and labels into a matrix of features and a vector of labels
features, labels = Matrix(iris.features)', vec(Matrix{String}(iris.targets))
features, labels = iris.features, iris.targets

# Because the MLDatasets package gives us Iris labels as strings, we will use the `MLDataUtils.convertlabel` method with the `MLLabelUtils.LabelEnc.Indices` type to get a list of integers representing each class:
labels = convertlabel(LabelEnc.Indices{Int}, labels)
labels = convertlabel(LabelEnc.Indices{Int}, vec(labels))
unique(labels)

# Next, we will create a train/test split with the `MLDataUtils.stratifiedobs` utility:
Expand Down
Loading

2 comments on commit 6daf99e

@AP6YC
Copy link
Owner Author

@AP6YC AP6YC commented on 6daf99e Oct 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register

Release notes:

This minor release provides backwards compatibility while significantly expanding documentation, increasing testing coverage, providing speed optimizations with rigorous typing, and more!

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/69917

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.6.0 -m "<description of version>" 6daf99e3a4da5d3372442af2492180551ccdf2f3
git push origin v0.6.0

Please sign in to comment.