Interactive web application to explore both crisp C-Means and Fuzzy C-Means clustering in 2D.
It lets you add points and centroids, iterate the algorithm, visualize cluster assignment, and inspect distance/membership matrices and cost function updates in real time.
- Purpose
- Tech stack
- Architecture
- Project structure
- Execution flow
- Implemented algorithms
- How to use the app
- Setup and scripts
- Design decisions
- Current limitations
- Suggested roadmap
This project is focused on learning and visual exploration of clustering:
- Compare hard assignment (crisp) vs soft assignment (fuzzy).
- Observe how centroids move across iterations.
- Understand cost function evolution.
- Frontend: React 18 + TypeScript + Vite.
- UI: Ant Design + Tailwind CSS.
- Charts: Chart.js + react-chartjs-2.
- Code quality: ESLint + TypeScript strict mode.
The app follows a clear separation between presentation and numeric logic:
- UI layer (components): receives user input and renders tables/charts.
- State and orchestration layer (hook): centralizes points, centroids, and iteration flow.
- Algorithm layer (utils): computes distances, memberships, centroids, and cost.
UI (App + components)
-> useCMeans (state + algorithm selection)
-> CMeans / fuzzyCMeans (math computation)
-> outputs: matrices, new centroids, cost
-> UI re-renders with updated outputs
.
|-- index.html
|-- package.json
|-- vite.config.ts
|-- tailwind.config.js
|-- src
| |-- App.tsx # main UI composition
| |-- main.tsx # React bootstrap
| |-- index.css # Tailwind directives
| |-- vite-env.d.ts # global types (Point)
| |-- components
| | |-- InputPoint.tsx # manual/random point and centroid input
| | |-- PointTable.tsx # points/centroids table
| | |-- MatrixTable.tsx # distance/membership matrix table
| | |-- DataChart.tsx # scatter plot with dominant-cluster coloring
| |-- utils
| | |-- CMeans.ts # crisp C-Means algorithm
| | |-- FuzzyCmeans.ts # Fuzzy C-Means algorithm
| | |-- useCmeans.ts # orchestration/state hook
- User adds points and centroids from the UI.
- The
useCMeanshook recomputes derived values throughuseMemowhen state changes. - Depending on the selected algorithm, it runs
CMeansorfuzzyCMeans. - The following outputs are produced:
- distance matrix,
- membership matrix,
- new centroids,
- cost values and total cost.
- When clicking Iterate, centroids are replaced by
newCentroids. - UI immediately reflects updated tables, chart, and cost.
- Distance: Euclidean in 2D.
- Membership: binary (each point belongs to the closest centroid).
- Centroid update: arithmetic mean of assigned points.
- Cost: sum of distances for active assignments.
- Fixed fuzzification parameter:
$m = 2$ . - Soft membership:
- Centroid update weighted by
$u_{ij}^m$ . - Fuzzy objective function:
- Add points in Add Point (manual or random).
- Add centroids in Add Centroid (manual or random).
- Observe distribution in the scatter chart.
- Click Iterate to run one algorithm step.
- Repeat until centroids/cost stabilize.
- Use Reset to start over.
- Node.js 18 or newer.
- npm 9 or newer.
npm installnpm run dev # Vite development server
npm run build # TypeScript check + production build
npm run preview # preview production build
npm run lint # ESLint static analysisBy default, development server runs at http://localhost:5173.
- Single domain hook (
useCMeans) to centralize state and iteration rules. - Pure utility functions in
utilsto keep math logic testable and React-agnostic. - Dominant-cluster color mapping in chart to improve fuzzy result readability.
- Matrix tables to make each iteration traceable.
- UI starts in
fuzzymode by default and does not yet expose an algorithm selector. - No persistence or export for experiment sessions.
- No per-point or per-centroid edit/delete actions (only global reset).
- No unit/integration test suite yet.
- Add a UI selector to switch between
crispandfuzzy. - Expose fuzzification parameter
$m$ in the UI. - Add iteration history (centroids and cost per step).
- Export data and matrices to CSV/JSON.
- Add tests for
utilsanduseCMeans.