### Install dependencies Source: https://github.com/arvkevi/kneed/blob/main/CONTRIBUTING.md Command to install project dependencies including testing requirements. ```bash $ pip install -e .[testing] ``` -------------------------------- ### Quick Example of Knee-point Detection Source: https://github.com/arvkevi/kneed/blob/main/docs/index.md Demonstrates basic usage of KneeLocator to find the knee point in a concave and increasing curve. Ensure the kneed library is installed. ```python from kneed import KneeLocator, DataGenerator x, y = DataGenerator.figure2() kl = KneeLocator(x, y, curve="concave", direction="increasing") print(kl.knee) # 0.222 print(kl.knee_y) # 1.897 ``` -------------------------------- ### Install Dependencies for Testing Source: https://github.com/arvkevi/kneed/blob/main/docs/contributing.md Install the project dependencies, including testing packages, in editable mode. ```bash pip install -e .[testing] ``` -------------------------------- ### Install kneed Source: https://github.com/arvkevi/kneed/blob/main/docs/getting-started.md Installation commands for kneed using pip, conda, or source. ```bash pip install kneed # knee-detection only pip install kneed[plot] # also install matplotlib for visualizations ``` ```bash conda install -c conda-forge kneed ``` ```bash git clone https://github.com/arvkevi/kneed.git && cd kneed pip install -e . ``` -------------------------------- ### Install kneed from GitHub Source: https://github.com/arvkevi/kneed/blob/main/README.md Clone the kneed repository from GitHub and install it in editable mode. ```bash git clone https://github.com/arvkevi/kneed.git && cd kneed pip install -e . ``` -------------------------------- ### Install kneed via Pip Source: https://github.com/arvkevi/kneed/blob/main/README.md Install the kneed library using pip. Install with the [plot] extra to include matplotlib for visualizations. ```bash pip install kneed # knee-detection only pip install kneed[plot] # also install matplotlib for visualizations ``` -------------------------------- ### Install kneed via Conda Source: https://github.com/arvkevi/kneed/blob/main/README.md Install the kneed library and its plotting dependencies using Conda. ```bash conda install -c conda-forge kneed ``` -------------------------------- ### K-Means Elbow Method Example Source: https://context7.com/arvkevi/kneed/llms.txt Demonstrates using Kneed to find the optimal number of clusters in K-means by detecting the elbow point in the inertia curve. It uses `curve='convex'` and `direction='decreasing'` for inertia plots. Includes an example for noisy data using polynomial interpolation. ```python from sklearn.cluster import KMeans from sklearn.datasets import make_blobs from kneed import KneeLocator # Generate sample data with 4 clusters X, _ = make_blobs(n_samples=500, centers=4, n_features=2, random_state=42) # Compute inertia (within-cluster sum of squares) for k=1 to k=10 inertias = [] K = range(1, 11) for k in K: km = KMeans(n_clusters=k, random_state=42, n_init=10) km.fit(X) inertias.append(km.inertia_) # Find the elbow point # Use curve="convex" and direction="decreasing" for inertia curves kl = KneeLocator(list(K), inertias, curve="convex", direction="decreasing") print(f"Optimal number of clusters: {kl.elbow}") # Should be 4 # For noisy inertia values, use polynomial interpolation kl_smooth = KneeLocator( list(K), inertias, curve="convex", direction="decreasing", interp_method="polynomial" ) ``` -------------------------------- ### Install kneed Library Source: https://context7.com/arvkevi/kneed/llms.txt Install the kneed library using pip or conda. Include the [plot] extra for matplotlib support. ```bash pip install kneed ``` ```bash pip install kneed[plot] ``` ```bash conda install -c conda-forge kneed ``` -------------------------------- ### PCA Component Selection Example Source: https://context7.com/arvkevi/kneed/llms.txt Illustrates how to use Kneed to determine the optimal number of principal components by finding the knee point in the cumulative explained variance curve. It uses `curve='concave'` and `direction='increasing'` for cumulative variance. Shows adjusting sensitivity with the 'S' parameter. ```python from sklearn.decomposition import PCA from sklearn.datasets import load_digits import numpy as np from kneed import KneeLocator # Load dataset (64 features) X, _ = load_digits(return_X_y=True) # Fit PCA with all components pca = PCA().fit(X) # Calculate cumulative explained variance cumulative_variance = np.cumsum(pca.explained_variance_ratio_) n_components = range(1, len(cumulative_variance) + 1) # Find the knee point # Use curve="concave" and direction="increasing" for cumulative variance kl = KneeLocator( list(n_components), cumulative_variance.tolist(), curve="concave", direction="increasing" ) print(f"Optimal number of components: {kl.knee}") print(f"Variance explained at knee: {cumulative_variance[kl.knee - 1]:.2%}") # Adjust sensitivity for different knee detection aggressiveness kl_aggressive = KneeLocator( list(n_components), cumulative_variance.tolist(), curve="concave", direction="increasing", S=0.5 ) kl_conservative = KneeLocator( list(n_components), cumulative_variance.tolist(), curve="concave", direction="increasing", S=5 ) ``` -------------------------------- ### Perform basic knee point detection Source: https://github.com/arvkevi/kneed/blob/main/docs/getting-started.md Example of using KneeLocator to find the knee point in sample data. ```python from kneed import KneeLocator, DataGenerator # Generate sample data (Figure 2 from the Kneedle paper) x, y = DataGenerator.figure2() # Find the knee point kl = KneeLocator(x, y, curve="concave", direction="increasing") print(kl.knee) # 0.222 — the x value of the knee print(kl.knee_y) # 1.897 — the y value at the knee ``` -------------------------------- ### Import Kneed Library Source: https://github.com/arvkevi/kneed/blob/main/notebooks/decreasing_function_walkthrough.ipynb Imports the necessary KneeLocator class from the kneed library. Ensure kneed is installed and the path is correctly set. ```python import sys sys.path.append('..') from kneed import KneeLocator ``` -------------------------------- ### Installing Matplotlib for Plotting Source: https://github.com/arvkevi/kneed/blob/main/docs/user-guide/troubleshooting.md If you encounter `ModuleNotFoundError` when using plotting functions like `plot_knee()`, ensure that `matplotlib` is installed. It is an optional dependency required for visualization. ```bash pip install kneed[plot] ``` -------------------------------- ### Quick Start: Find Knee Point Source: https://github.com/arvkevi/kneed/blob/main/README.md Generate sample data and find the knee point using KneeLocator. The knee and knee_y attributes store the x and y coordinates of the detected knee point. ```python from kneed import KneeLocator, DataGenerator # Generate sample data x, y = DataGenerator.figure2() # Find the knee point kl = KneeLocator(x, y, curve="concave", direction="increasing") print(kl.knee) # 0.222 print(kl.knee_y) # 1.897 ``` -------------------------------- ### Debugging with Difference Curve Visualization Source: https://github.com/arvkevi/kneed/blob/main/docs/user-guide/troubleshooting.md Visualize the difference curve and its detected maxima/minima to understand the knee detection process. This requires `matplotlib` to be installed. ```python kl = KneeLocator(x, y, curve="concave", direction="increasing") # Plot the normalized difference curve import matplotlib.pyplot as plt plt.plot(kl.x_difference, kl.y_difference, label="difference curve") plt.plot(kl.x_difference_maxima, kl.y_difference_maxima, "ro", label="maxima") plt.plot(kl.x_difference_minima, kl.y_difference_minima, "go", label="minima") plt.legend() plt.title("Difference Curve") plt.show() ``` -------------------------------- ### Detecting Knees on a Bumpy Curve Source: https://github.com/arvkevi/kneed/blob/main/docs/user-guide/multi-knee.md This example demonstrates detecting multiple knee points on a curve with local maxima using `DataGenerator.bumpy()` and `online=True`. It prints the primary knee, all detected knees, and the total count. ```python from kneed import DataGenerator, KneeLocator x, y = DataGenerator.bumpy() kl = KneeLocator(x, y, curve="concave", direction="increasing", online=True) print(f"Primary knee: {kl.knee}") print(f"All knees: {sorted(kl.all_knees)}") print(f"Number of knees found: {len(kl.all_knees)}") ``` -------------------------------- ### Handling Flat or Linear Data Source: https://github.com/arvkevi/kneed/blob/main/docs/user-guide/troubleshooting.md If the input data is too flat or linear, no distinct knee point can be detected, resulting in `kl.knee` returning None. This example demonstrates a perfectly linear dataset where no knee is found. ```python import numpy as np x = np.arange(10) y = x # Perfectly linear — no knee kl = KneeLocator(x, y, curve="concave", direction="increasing") print(kl.knee) # None ``` -------------------------------- ### Get Optimal Knee Value Source: https://github.com/arvkevi/kneed/blob/main/notebooks/decreasing_function_walkthrough.ipynb Retrieves the identified optimal number of clusters (knee point) from the KneeLocator object. ```python kn.knee ``` -------------------------------- ### Create and Activate Virtual Environment Source: https://github.com/arvkevi/kneed/blob/main/docs/contributing.md Create a Python virtual environment named 'venv' and activate it. The activation command differs for Windows. ```bash python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate ``` -------------------------------- ### Create virtual environment Source: https://github.com/arvkevi/kneed/blob/main/CONTRIBUTING.md Command to create a virtual environment using virtualenv. ```bash $ virtualenv venv ``` -------------------------------- ### Initialize KneeLocator with sample data Source: https://github.com/arvkevi/kneed/blob/main/notebooks/walkthrough.ipynb Creates a KneeLocator object with sample x and y data, specifying sensitivity (S), curve type, and direction. ```python x = [3.07, 3.38, 3.55, 3.68, 3.78, 3.81, 3.85, 3.88, 3.9, 3.93] y = [0.0, 0.3, 0.47, 0.6, 0.69, 0.78, 0.845, 0.903, 0.95, 1.0] kl = KneeLocator(x, y, S=1.0, curve='convex', direction='increasing', interp_method='interp1d') ``` -------------------------------- ### Initialize Knee Finding Algorithm Source: https://github.com/arvkevi/kneed/blob/main/notebooks/kneedle_algorithm.ipynb Sets up the state variables and indices required for the iterative knee detection process. ```python # artificially place a local max at the last item in the x_difference array maxima_indices = np.append(maxima_indices, len(x_difference) - 1) minima_indices = np.append(minima_indices, len(x_difference) - 1) # placeholder for which threshold region i is located in. maxima_threshold_index = 0 minima_threshold_index = 0 curve = 'concave' direction = 'increasing' all_knees = set() all_norm_knees = set() ``` -------------------------------- ### Clone the repository Source: https://github.com/arvkevi/kneed/blob/main/CONTRIBUTING.md Commands to clone the forked repository to a local machine. ```bash $ git clone https://github.com/[YOURUSERNAME]/kneed $ cd kneed ``` -------------------------------- ### Import Dependencies Source: https://github.com/arvkevi/kneed/blob/main/notebooks/kneedle_algorithm.ipynb Initial imports for numerical operations and plotting. ```python import numpy as np import scipy import matplotlib.pyplot as plt %matplotlib inline ``` -------------------------------- ### Configure interp_method for KneeLocator Source: https://github.com/arvkevi/kneed/blob/main/docs/user-guide/parameters.md Demonstrates using interp1d and polynomial interpolation methods to fit data points. ```python from kneed import KneeLocator x = list(range(90)) y = [ 7304, 6978, 6666, 6463, 6326, 6048, 6032, 5762, 5742, 5398, 5256, 5226, 5001, 4941, 4854, 4734, 4558, 4491, 4411, 4333, 4234, 4139, 4056, 4022, 3867, 3808, 3745, 3692, 3645, 3618, 3574, 3504, 3452, 3401, 3382, 3340, 3301, 3247, 3190, 3179, 3154, 3089, 3045, 2988, 2993, 2941, 2875, 2866, 2834, 2785, 2759, 2763, 2720, 2660, 2690, 2635, 2632, 2574, 2555, 2545, 2513, 2491, 2496, 2466, 2442, 2420, 2381, 2388, 2340, 2335, 2318, 2319, 2308, 2262, 2235, 2259, 2221, 2202, 2184, 2170, 2160, 2127, 2134, 2101, 2101, 2066, 2074, 2063, 2048, 2031, ] kneedle = KneeLocator( x, y, S=1.0, curve="convex", direction="decreasing", interp_method="interp1d" ) kneedle.plot_knee_normalized() ``` ```python kneedle = KneeLocator( x, y, S=1.0, curve="convex", direction="decreasing", interp_method="polynomial", ) kneedle.plot_knee_normalized() ``` -------------------------------- ### Get Knee Point Y-coordinate Source: https://github.com/arvkevi/kneed/blob/main/README.md Retrieve the y-coordinate corresponding to the detected knee point using the 'knee_y' attribute of the KneeLocator object. ```python print(round(kneedle.knee_y, 3)) 1.897 ``` -------------------------------- ### Load Data from NumPy Arrays Source: https://github.com/arvkevi/kneed/blob/main/docs/examples/custom-data.md Initialize KneeLocator with NumPy arrays for x and y. This is efficient for numerical computations. ```python import numpy as np from kneed import KneeLocator x = np.linspace(0, 10, 100) y = np.log1p(x) # Logarithmic curve kl = KneeLocator(x, y, curve="concave", direction="increasing") print(f"Knee: x={round(kl.knee, 3)}") ``` -------------------------------- ### Input Data Generation Source: https://github.com/arvkevi/kneed/blob/main/README.md Utilize the DataGenerator class to create sample datasets for testing and demonstration. Ensure that the x and y arrays are of equal length. ```python from kneed import DataGenerator, KneeLocator x, y = DataGenerator.figure2() print([round(i, 3) for i in x]) print([round(i, 3) for i in y]) ``` -------------------------------- ### Run tests Source: https://github.com/arvkevi/kneed/blob/main/CONTRIBUTING.md Commands to execute the test suite using pytest. ```bash $ pytest ``` ```bash $ pytest tests/test_sample.py ``` -------------------------------- ### Handle edge cases and noisy data with KneeLocator Source: https://context7.com/arvkevi/kneed/llms.txt Demonstrates how to check for None when no knee is detected and how to use different interpolation methods for noisy data. ```python from kneed import KneeLocator import numpy as np # Linear data (no knee point) x_linear = list(range(10)) y_linear = list(range(10)) kl = KneeLocator(x_linear, y_linear, curve="concave", direction="increasing") print(f"Knee in linear data: {kl.knee}") # None # Check for None before using knee value if kl.knee is not None: print(f"Knee found at {kl.knee}") else: print("No knee detected in the data") # Very noisy data - use polynomial smoothing np.random.seed(42) x_noisy = np.arange(50) y_noisy = np.log(x_noisy + 1) + np.random.normal(0, 0.3, 50) kl_interp = KneeLocator( x_noisy, y_noisy, curve="concave", direction="increasing", interp_method="interp1d" ) kl_poly = KneeLocator( x_noisy, y_noisy, curve="concave", direction="increasing", interp_method="polynomial", polynomial_degree=3 ) print(f"Knee with interp1d: {kl_interp.knee}") print(f"Knee with polynomial: {kl_poly.knee}") ``` -------------------------------- ### Load Data from Lists Source: https://github.com/arvkevi/kneed/blob/main/docs/examples/custom-data.md Use lists for x and y data when initializing KneeLocator. Ensure data is numerical. ```python from kneed import KneeLocator x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] y = [1, 2, 3.5, 4.5, 5, 5.3, 5.5, 5.6, 5.65, 5.7] kl = KneeLocator(x, y, curve="concave", direction="increasing") print(f"Knee: x={kl.knee}, y={kl.knee_y}") ``` -------------------------------- ### Import argrelextrema from scipy.signal Source: https://github.com/arvkevi/kneed/blob/main/notebooks/walkthrough.ipynb Imports the argrelextrema function from scipy.signal, used for finding local extrema. ```python from scipy.signal import argrelextrema ``` -------------------------------- ### Clone kneed Repository Source: https://github.com/arvkevi/kneed/blob/main/docs/contributing.md Clone the kneed repository to your local machine. Replace '[YOURUSERNAME]' with your GitHub username. ```bash git clone https://github.com/[YOURUSERNAME]/kneed cd kneed ``` -------------------------------- ### Run All Tests Source: https://github.com/arvkevi/kneed/blob/main/docs/contributing.md Execute all tests in the project using pytest. ```bash pytest ``` -------------------------------- ### Run Specific Test File Source: https://github.com/arvkevi/kneed/blob/main/docs/contributing.md Execute tests from a specific file, such as 'tests/test_sample.py', using pytest. ```bash pytest tests/test_sample.py ``` -------------------------------- ### Load Data from CSV File Source: https://github.com/arvkevi/kneed/blob/main/docs/examples/custom-data.md Load data from a CSV file using numpy.genfromtxt and then use the first two columns as x and y for KneeLocator. ```python import numpy as np from kneed import KneeLocator # Load two columns from a CSV data = np.genfromtxt("my_data.csv", delimiter=",", skip_header=1) x = data[:, 0] y = data[:, 1] kl = KneeLocator(x, y, curve="concave", direction="increasing") print(f"Knee: x={kl.knee}") ``` -------------------------------- ### Iterating Through Sensitivity Values Source: https://github.com/arvkevi/kneed/blob/main/docs/user-guide/troubleshooting.md Experiment with different values of the 'S' parameter to find the optimal sensitivity for your specific dataset. This loop demonstrates how to test various 'S' values and observe their effect on knee detection. ```python for s in [1, 3, 5, 10]: kl = KneeLocator(x, y, curve="convex", direction="decreasing", S=s) print(f"S={s}: knee={kl.knee}") ``` -------------------------------- ### Display first 5 elements of generated data Source: https://github.com/arvkevi/kneed/blob/main/notebooks/walkthrough.ipynb Shows the first five elements of the generated x and y arrays. ```python x[:5],y[:5] ``` -------------------------------- ### Calculate Thresholds Source: https://github.com/arvkevi/kneed/blob/main/notebooks/kneedle_algorithm.ipynb Sets the sensitivity parameter and calculates the threshold for knee detection. ```python # Sensitivity parameter S # smaller values detect knees quicker S = 1.0 ``` ```python Tmx = y_difference_maxima - (S * np.abs(np.diff(x_normalized).mean())) ``` -------------------------------- ### Basic Knee Point Detection with KneeLocator Source: https://context7.com/arvkevi/kneed/llms.txt Instantiate KneeLocator with x and y data, specifying curve type and direction to find the knee point. Access coordinates via .knee and .knee_y. ```python from kneed import KneeLocator, DataGenerator # Generate sample data (Figure 2 from the Kneedle paper) x, y = DataGenerator.figure2() # Find the knee point for a concave increasing curve kl = KneeLocator(x, y, curve="concave", direction="increasing") # Access knee point coordinates print(f"Knee x-value: {kl.knee}") # 0.222 print(f"Knee y-value: {kl.knee_y}") # 1.897 # Normalized values (0-1 scale) print(f"Normalized knee: {kl.norm_knee}") print(f"Normalized knee y: {kl.norm_knee_y}") # Elbow aliases (equivalent to knee) print(f"Elbow: {kl.elbow}") # Same as kl.knee print(f"Elbow y: {kl.elbow_y}") # Same as kl.knee_y ``` -------------------------------- ### Detecting the Optimal K with KneeLocator Source: https://github.com/arvkevi/kneed/blob/main/docs/examples/kmeans-elbow.md Calculates inertia for a range of clusters and uses KneeLocator to identify the elbow point. ```python from sklearn.cluster import KMeans from sklearn.datasets import make_blobs from kneed import KneeLocator # Generate sample data with 4 clusters X, _ = make_blobs(n_samples=500, centers=4, n_features=2, random_state=42) # Compute inertia for k=1 to k=10 inertias = [] K = range(1, 11) for k in K: km = KMeans(n_clusters=k, random_state=42, n_init=10) km.fit(X) inertias.append(km.inertia_) # Find the elbow kl = KneeLocator(list(K), inertias, curve="convex", direction="decreasing") print(f"Optimal k: {kl.elbow}") # Should be 4 ``` -------------------------------- ### Use Detected Values with KneeLocator Source: https://context7.com/arvkevi/kneed/llms.txt Demonstrates how to use the detected curve and direction parameters with KneeLocator to find a knee point. ```python from kneed import KneeLocator # Assuming curve and direction are already determined # For example: direction = "increasing" curve = "concave" x_concave = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] y_concave = [0, 0.1, 0.5, 1.0, 1.5, 2.0, 2.3, 2.5, 2.6, 2.7, 2.8] # Use detected values with KneeLocator kl = KneeLocator(x_concave, y_concave, curve=curve, direction=direction) print(f"Knee found at: {kl.knee}") ``` -------------------------------- ### Prepare Data for KneeLocator Source: https://github.com/arvkevi/kneed/blob/main/notebooks/walkthrough.ipynb Prepares a list of y-values for use with KneeLocator. This snippet focuses on data preparation and does not call KneeLocator itself. ```python x = list(range(90)) y = [ 7304.99, 6978.98, 6666.61, 6463.2, 6326.53, 6048.79, 6032.79, 5762.01, 5742.77, 5398.22, 5256.84, 5226.98, 5001.72, 4941.98, 4854.24, 4734.61, 4558.75, 4491.1, 4411.61, 4333.01, 4234.63, 4139.1, 4056.8, 4022.49, 3867.96, 3808.27, 3745.27, 3692.34, 3645.55, 3618.28, 3574.26, 3504.31, 3452.44, 3401.2, 3382.37, 3340.67, 3301.08, 3247.59, 3190.27, 3179.99, 3154.24, 3089.54, 3045.62, 2988.99, 2993.61, 2941.35, 2875.6, 2866.33, 2834.12, 2785.15, 2759.65, 2763.2, 2720.14, 2660.14, 2690.22, 2635.71, 2632.92, 2574.63, 2555.97, 2545.72, 2513.38, 2491.57, 2496.05, 2466.45, 2442.72, 2420.53, 2381.54, 2388.09, 2340.61, 2335.03, 2318.93, 2319.05, 2308.23, 2262.23, 2235.78, 2259.27, 2221.05, 2202.69, 2184.29, 2170.07, 2160.05, 2127.68, 2134.73, 2101.96, 2101.44, 2066.4, 2074.25, 2063.68, 2048.12, 2031.87 ] ``` -------------------------------- ### Configure KneeLocator Parameters Source: https://context7.com/arvkevi/kneed/llms.txt Adjust KneeLocator behavior using sensitivity (S), interpolation method (interp_method), and polynomial degree. Higher S values are more conservative. ```python import numpy as np from kneed import KneeLocator # Generate test data np.random.seed(23) x = range(1, 1001) y = sorted(np.random.gamma(0.5, 1.0, 1000), reverse=True) # Basic parameters: curve and direction kl = KneeLocator( x, y, curve="convex", # "concave" for knees, "convex" for elbows direction="decreasing" # "increasing" or "decreasing" ) # Sensitivity parameter (S) - higher values are more conservative # S=1.0 (default) detects knees quickly # S=10+ is more conservative, requiring more "flat" points kl_sensitive = KneeLocator(x, y, curve="convex", direction="decreasing", S=1) kl_conservative = KneeLocator(x, y, curve="convex", direction="decreasing", S=10) print(f"Sensitive knee: {kl_sensitive.knee}") # 43 print(f"Conservative knee: {kl_conservative.knee}") # 258 # Interpolation method: "interp1d" (default) or "polynomial" # Polynomial smooths noisy data kl_smooth = KneeLocator( x, y, curve="convex", direction="decreasing", interp_method="polynomial", polynomial_degree=7 # Degree of polynomial fit (default: 7) ) ``` -------------------------------- ### Initialize KneeLocator Source: https://github.com/arvkevi/kneed/blob/main/notebooks/decreasing_function_walkthrough.ipynb Initializes the KneeLocator object with the range of k values and their distortions. 'S' controls the sensitivity, 'curve' specifies the shape of the curve, and 'direction' indicates whether the values are increasing or decreasing. ```python kn = KneeLocator(list(K), distortions, S=1.0, curve='convex', direction='decreasing') ``` -------------------------------- ### Print K and Distortions Source: https://github.com/arvkevi/kneed/blob/main/notebooks/decreasing_function_walkthrough.ipynb Prints the range of k values and their corresponding distortion values. Useful for debugging or further analysis. ```python print(K, '\n', distortions) ``` -------------------------------- ### Import necessary libraries for kneed Source: https://github.com/arvkevi/kneed/blob/main/notebooks/walkthrough.ipynb Imports DataGenerator for creating simulated datasets and KneeLocator for identifying knee points. Also imports libraries for plotting and numerical operations. ```python %matplotlib inline from kneed.data_generator import DataGenerator as dg from kneed.knee_locator import KneeLocator import seaborn as sns import matplotlib.pyplot as plt %matplotlib inline import numpy as np ``` -------------------------------- ### Initialize KneeLocator for concave curve Source: https://github.com/arvkevi/kneed/blob/main/notebooks/walkthrough.ipynb Initializes a KneeLocator object for a concave curve with polynomial interpolation. The 'increasing' direction is specified. ```python kneedle = KneeLocator(x, y, S=1.0, curve='concave', direction='increasing', interp_method='polynomial') ``` -------------------------------- ### Compare Online vs. Offline Knee Detection Source: https://github.com/arvkevi/kneed/blob/main/docs/user-guide/parameters.md Compare `online=True` for continuous correction with `online=False` (default) for returning the first identified knee. Requires `KneeLocator` and `matplotlib.pyplot`. ```python kl_online = KneeLocator(x, y, curve="convex", direction="decreasing", online=True) kl_offline = KneeLocator(x, y, curve="convex", direction="decreasing", online=False) ``` ```python import matplotlib.pyplot as plt plt.style.use("ggplot") plt.figure(figsize=(8, 6)) plt.plot(kl_online.x_normalized, kl_online.y_normalized) plt.plot(kl_online.x_difference, kl_online.y_difference) colors = ["r", "g"] for k, c, o in zip( [kl_online.norm_knee, kl_offline.norm_knee], ["r", "g"], ["online", "offline"] ): plt.vlines(k, 0, 1, linestyles="--", colors=c, label=o) plt.legend() ``` -------------------------------- ### Generate synthetic data with DataGenerator Source: https://github.com/arvkevi/kneed/blob/main/docs/api.md Utility class for creating synthetic datasets for testing purposes. ```python ::: kneed.data_generator.DataGenerator options: show_source: true members_order: source ``` -------------------------------- ### Validate and Prepare Input Source: https://github.com/arvkevi/kneed/blob/main/notebooks/kneedle_algorithm.ipynb Extracts data and ensures the x-axis values are sorted. ```python x,y = figure2() ``` ```python if not np.array_equal(np.array(x), np.sort(x)): raise ValueError('x needs to be sorted') ``` -------------------------------- ### Using Elbow Aliases Source: https://github.com/arvkevi/kneed/blob/main/docs/user-guide/multi-knee.md Equivalent properties like `all_elbows` and `all_elbows_y` are available if you prefer the terminology 'elbow' over 'knee'. ```python kl.all_elbows # same as kl.all_knees kl.all_elbows_y # same as kl.all_knees_y kl.all_norm_elbows # same as kl.all_norm_knees kl.all_norm_elbows_y # same as kl.all_norm_knees_y ``` -------------------------------- ### Display Dataset Scatter Plot Source: https://github.com/arvkevi/kneed/blob/main/notebooks/decreasing_function_walkthrough.ipynb Visualizes the input dataset using a scatter plot. Ensure matplotlib is imported. ```python %matplotlib inline ``` ```python # clustering dataset # determine k using elbow method from sklearn.cluster import KMeans from sklearn import metrics from scipy.spatial.distance import cdist import numpy as np import matplotlib.pyplot as plt x1 = np.array([3, 1, 1, 2, 1, 6, 6, 6, 5, 6, 7, 8, 9, 8, 9, 9, 8]) x2 = np.array([5, 4, 5, 6, 5, 8, 6, 7, 6, 7, 1, 2, 1, 2, 3, 2, 3]) plt.plot() plt.xlim([0, 10]) plt.ylim([0, 10]) plt.title('Dataset') plt.scatter(x1, x2) plt.show() ``` -------------------------------- ### Accessing All Detected Knees Source: https://github.com/arvkevi/kneed/blob/main/docs/user-guide/multi-knee.md In online mode (`online=True`), use `all_knees` and `all_knees_y` to retrieve the x and y values of all detected knee points. `all_knees` is a set of unique x values, while `all_knees_y` is a list of corresponding y values in order of detection. ```python kl = KneeLocator(x, y, curve="convex", direction="decreasing", online=True) # x values of all detected knees print(kl.all_knees) # set of x values print(kl.all_knees_y) # list of corresponding y values # Normalized values print(kl.all_norm_knees) # set of normalized x values print(kl.all_norm_knees_y) # list of normalized y values ``` -------------------------------- ### Fit Spline to Data Source: https://github.com/arvkevi/kneed/blob/main/notebooks/kneedle_algorithm.ipynb Uses interpolation to create a smooth curve from raw input points. ```python from scipy.interpolate import interp1d ``` ```python N = len(x) ``` ```python # Ds = the finite set of x- and y-values that define a smooth curve, # one that has been fit to a smoothing spline. uspline = interp1d(x, y) Ds_y = uspline(x) ``` ```python plt.plot(x, Ds_y); ``` -------------------------------- ### Find Optimal PCA Components with Kneed Source: https://github.com/arvkevi/kneed/blob/main/docs/examples/pca-components.md Use Kneed to identify the optimal number of principal components by finding the knee in the cumulative explained variance. Requires sklearn, numpy, and kneed. ```python from sklearn.decomposition import PCA from sklearn.datasets import load_digits import numpy as np from kneed import KneeLocator # Load dataset X, _ = load_digits(return_X_y=True) # Fit PCA with all components pca = PCA().fit(X) # Cumulative explained variance cumulative_variance = np.cumsum(pca.explained_variance_ratio_) n_components = range(1, len(cumulative_variance) + 1) # Find the knee kl = KneeLocator( list(n_components), cumulative_variance.tolist(), curve="concave", direction="increasing", ) print(f"Optimal components: {kl.knee}") ``` -------------------------------- ### Using Online Mode for Knee Detection Source: https://github.com/arvkevi/kneed/blob/main/docs/user-guide/troubleshooting.md When `online=True`, `KneeLocator` may provide a more significant knee point compared to offline mode, which returns the first detected knee. This is useful when multiple potential knees exist. ```python kl = KneeLocator(x, y, curve="convex", direction="decreasing", online=True) print(kl.knee) # Often a better result ``` -------------------------------- ### Identify Local Extrema Source: https://github.com/arvkevi/kneed/blob/main/notebooks/kneedle_algorithm.ipynb Finds local maxima and minima in the difference curve to identify potential knee points. ```python from scipy.signal import argrelextrema ``` ```python # local maxima for knees maxima_indices = argrelextrema(y_difference, np.greater)[0] x_difference_maxima = x_difference[maxima_indices] y_difference_maxima = y_difference[maxima_indices] # local minima minima_indices = argrelextrema(y_difference, np.less)[0] x_difference_minima = x_difference[minima_indices] y_difference_minima = y_difference_minima[minima_indices] ``` ```python plt.title("local maxima in difference curve"); plt.plot(x_normalized, y_normalized); plt.plot(x_difference, y_difference); plt.hlines(y_difference_maxima, plt.xlim()[0], plt.xlim()[1]); ``` -------------------------------- ### Add upstream remote Source: https://github.com/arvkevi/kneed/blob/main/CONTRIBUTING.md Command to add the upstream remote for synchronizing changes. ```bash $ git remote add upstream https://github.com/arvkevi/kneed ``` -------------------------------- ### Visualize PCA Component Selection Source: https://github.com/arvkevi/kneed/blob/main/docs/examples/pca-components.md Visualize the cumulative explained variance and the identified knee point using Matplotlib. This helps in understanding the PCA component selection. ```python import matplotlib.pyplot as plt plt.figure(figsize=(8, 5)) plt.plot(n_components, cumulative_variance, "bo-", markersize=3) plt.vlines(kl.knee, 0, 1, linestyles="--", colors="r", label=f"knee = {kl.knee}") plt.xlabel("Number of Components") plt.ylabel("Cumulative Explained Variance") plt.title("PCA Component Selection") plt.legend() plt.show() ``` -------------------------------- ### Offline Knee Detection (Default) Source: https://github.com/arvkevi/kneed/blob/main/docs/user-guide/multi-knee.md Use `online=False` to detect only the first knee point in a curve. This is the default behavior. ```python import numpy as np from kneed import KneeLocator np.random.seed(23) x = range(1, 1001) y = sorted(np.random.gamma(0.5, 1.0, 1000), reverse=True) kl = KneeLocator(x, y, curve="convex", direction="decreasing", online=False) print(kl.knee) # Returns the first knee found ``` -------------------------------- ### Calculate average knee over multiple iterations Source: https://github.com/arvkevi/kneed/blob/main/notebooks/walkthrough.ipynb Iterates 50 times, generating noisy Gaussian data and finding the knee point for each iteration, storing the results in a list. ```python knees = [] for i in range(50): x,y = dg.noisy_gaussian(N=1000) kneedle = KneeLocator(x, y, direction='increasing', curve='concave', interp_method='polynomial') knees.append(kneedle.knee) ``` -------------------------------- ### Retrieve the knee value Source: https://github.com/arvkevi/kneed/blob/main/notebooks/kneedle_algorithm.ipynb Displays the calculated knee value. ```python knee ``` -------------------------------- ### Plotting Knee Detection Results Source: https://context7.com/arvkevi/kneed/llms.txt Shows how to use the built-in plotting methods of KneeLocator to visualize the raw data with the detected knee point, and also the normalized curve and difference curve for deeper analysis. Requires matplotlib. ```python from kneed import KneeLocator, DataGenerator x, y = DataGenerator.figure2() kl = KneeLocator(x, y, curve="concave", direction="increasing") # Plot raw data with knee point marked kl.plot_knee() # Plot with custom figure size and labels kl.plot_knee( figsize=(10, 6), title="My Knee Point Analysis", xlabel="X Values", ylabel="Y Values" ) # Plot normalized curve and difference curve # Shows the internal workings of the Kneedle algorithm kl.plot_knee_normalized() # With custom labels kl.plot_knee_normalized( figsize=(8, 8), title="Normalized Knee Point", xlabel="Normalized X", ylabel="Normalized Y" ) ``` -------------------------------- ### Initialize KneeLocator Source: https://github.com/arvkevi/kneed/blob/main/docs/api.md The primary class for identifying knee or elbow points in a curve. ```python ::: kneed.knee_locator.KneeLocator options: show_source: true members_order: source ``` -------------------------------- ### Visualize Raw Knee Point Source: https://github.com/arvkevi/kneed/blob/main/README.md Generate a plot displaying the raw input data and the detected knee point using the plot_knee() method. ```python # Raw data and knee. kneedle.plot_knee() ``` -------------------------------- ### Add Upstream Remote Source: https://github.com/arvkevi/kneed/blob/main/docs/contributing.md Optionally, add the upstream remote to track changes from the original kneed repository. ```bash git remote add upstream https://github.com/arvkevi/kneed ``` -------------------------------- ### Find Knee and Elbow Points Source: https://github.com/arvkevi/kneed/blob/main/README.md Instantiate KneeLocator with x, y, and curve/direction parameters to find the knee point. The 'knee' and 'elbow' attributes store the x-coordinate of the maximum curvature. ```python kneedle = KneeLocator(x, y, S=1.0, curve="concave", direction="increasing") print(round(kneedle.knee, 3)) 0.222 print(round(kneedle.elbow, 3)) 0.222 ``` -------------------------------- ### Tune Knee Detection Sensitivity (S) Source: https://github.com/arvkevi/kneed/blob/main/docs/user-guide/parameters.md Adjust the sensitivity parameter `S` to control how aggressive knee detection is. Smaller `S` values detect knees quicker; larger values are more conservative. Requires `numpy` and `KneeLocator`. ```python import numpy as np from kneed import KneeLocator np.random.seed(23) sensitivity = [1, 3, 5, 10, 100, 200, 400] knees = [] norm_knees = [] n = 1000 x = range(1, n + 1) y = sorted(np.random.gamma(0.5, 1.0, n), reverse=True) for s in sensitivity: kl = KneeLocator(x, y, curve="convex", direction="decreasing", S=s) knees.append(kl.knee) norm_knees.append(kl.norm_knee) print(knees) # [43, 137, 178, 258, 305, 482, 482] print([nk.round(2) for nk in norm_knees]) # [0.04, 0.14, 0.18, 0.26, 0.3, 0.48, 0.48] ``` ```python import matplotlib.pyplot as plt plt.style.use("ggplot") plt.figure(figsize=(8, 6)) plt.plot(kl.x_normalized, kl.y_normalized) plt.plot(kl.x_difference, kl.y_difference) colors = ["r", "g", "k", "m", "c", "orange"] for k, c, s in zip(norm_knees, colors, sensitivity): plt.vlines(k, 0, 1, linestyles="--", colors=c, label=f"S = {s}") plt.legend() ``` -------------------------------- ### Visualize knee point results Source: https://github.com/arvkevi/kneed/blob/main/docs/getting-started.md Methods for plotting the raw data or normalized curves with the detected knee point. ```python # Plot the raw data with the knee point marked kl.plot_knee() ``` ```python # Plot the normalized curve and difference curve kl.plot_knee_normalized() ``` -------------------------------- ### Online Mode for Multiple Knee Detection Source: https://context7.com/arvkevi/kneed/llms.txt Use online=True to detect all knee points in a curve and access them via .all_knees and .all_knees_y. The .knee attribute still returns the most significant knee. ```python import numpy as np from kneed import KneeLocator, DataGenerator np.random.seed(23) x = range(1, 1001) y = sorted(np.random.gamma(0.5, 1.0, 1000), reverse=True) # Offline mode (default): returns first knee found kl_offline = KneeLocator(x, y, curve="convex", direction="decreasing", online=False) print(f"Offline mode knee: {kl_offline.knee}") # Online mode: scans entire curve, returns last (most significant) knee kl_online = KneeLocator(x, y, curve="convex", direction="decreasing", online=True) print(f"Online mode knee: {kl_online.knee}") # Access all detected knees (online mode only) print(f"All knees (x values): {sorted(kl_online.all_knees)}") print(f"All knees (y values): {kl_online.all_knees_y}") print(f"Number of knees found: {len(kl_online.all_knees)}") # Normalized knee values print(f"All normalized knees: {kl_online.all_norm_knees}") # Elbow aliases work the same way print(f"All elbows: {kl_online.all_elbows}") # Same as all_knees print(f"All elbows y: {kl_online.all_elbows_y}") # Same as all_knees_y ``` -------------------------------- ### Auto-detect curve parameters Source: https://github.com/arvkevi/kneed/blob/main/docs/getting-started.md Use find_shape to automatically determine the curve and direction parameters for KneeLocator. ```python from kneed import find_shape direction, curve = find_shape(x, y) kl = KneeLocator(x, y, curve=curve, direction=direction) ``` -------------------------------- ### Find local minima in y_difference Source: https://github.com/arvkevi/kneed/blob/main/notebooks/walkthrough.ipynb Uses argrelextrema to find the indices of local minima in the y_difference array. ```python argrelextrema(kl.y_difference, np.less) ``` -------------------------------- ### Convex Decreasing Curve Detection Source: https://github.com/arvkevi/kneed/blob/main/docs/user-guide/curve-types.md Use for diminishing decline curves (classic elbow method) where the elbow is where the decline slows. Requires importing KneeLocator and DataGenerator. ```python x, y = dg.convex_decreasing() kl = KneeLocator(x, y, curve="convex", direction="decreasing") kl.plot_knee() print(f"Elbow at x={kl.elbow}") ``` -------------------------------- ### Load Data from Pandas DataFrame Source: https://github.com/arvkevi/kneed/blob/main/docs/examples/custom-data.md Read a CSV into a Pandas DataFrame and extract specific columns as NumPy arrays for KneeLocator. ```python import pandas as pd from kneed import KneeLocator df = pd.read_csv("my_data.csv") kl = KneeLocator( df["x_column"].values, df["y_column"].values, curve="concave", direction="increasing", ) print(f"Knee: x={kl.knee}") ``` -------------------------------- ### KneeLocator Class Initialization Source: https://context7.com/arvkevi/kneed/llms.txt The KneeLocator class is the primary interface for detecting knee or elbow points. It requires x and y data arrays and parameters defining the curve shape. ```APIDOC ## KneeLocator Initialization ### Description Instantiate the KneeLocator class to identify the point of maximum curvature in a given dataset. ### Parameters #### Constructor Parameters - **x** (array-like) - Required - The x-coordinates of the curve. - **y** (array-like) - Required - The y-coordinates of the curve. - **curve** (string) - Required - The shape of the curve: 'concave' or 'convex'. - **direction** (string) - Required - The direction of the curve: 'increasing' or 'decreasing'. - **S** (float) - Optional - Sensitivity parameter. Higher values are more conservative. - **interp_method** (string) - Optional - Interpolation method: 'interp1d' or 'polynomial'. - **online** (boolean) - Optional - If True, detects all knee points; if False, stops at the first one. ### Response #### Attributes - **knee** (float) - The x-value of the detected knee point. - **knee_y** (float) - The y-value of the detected knee point. - **all_knees** (list) - List of all detected knee points (if online=True). ``` -------------------------------- ### Convex Increasing Curve Detection Source: https://github.com/arvkevi/kneed/blob/main/docs/user-guide/curve-types.md Use for accelerating growth curves where the elbow is where the growth accelerates. Requires importing KneeLocator and DataGenerator. ```python x, y = dg.convex_increasing() kl = KneeLocator(x, y, curve="convex", direction="increasing") kl.plot_knee() print(f"Elbow at x={kl.elbow}") ```