Skip to content

Sowing Success: How Machine Learning Helps Farmers Select the Best Crops

Measuring essential soil metrics such as nitrogen, phosphorous, potassium levels, and pH value is an important aspect of assessing soil condition. However, it can be an expensive and time-consuming process, which can cause farmers to prioritize which metrics to measure based on their budget constraints.

Farmers have various options when it comes to deciding which crop to plant each season. Their primary objective is to maximize the yield of their crops, taking into account different factors. One crucial factor that affects crop growth is the condition of the soil in the field, which can be assessed by measuring basic elements such as nitrogen and potassium levels. Each crop has an ideal soil condition that ensures optimal growth and maximum yield.

A farmer reached out to you as a machine learning expert for assistance in selecting the best crop for his field. They've provided you with a dataset called soil_measures.csv, which contains:

  • "N": Nitrogen content ratio in the soil
  • "P": Phosphorous content ratio in the soil
  • "K": Potassium content ratio in the soil
  • "pH" value of the soil
  • "crop": categorical values that contain various crops (target variable).

Each row in this dataset represents various measures of the soil in a particular field. Based on these measurements, the crop specified in the "crop" column is the optimal choice for that field.

In this project, you will apply machine learning to build a multi-class classification model to predict the type of "crop", while using techniques to avoid multicollinearity, which is a concept where two or more features are highly correlated.

# All required libraries are imported here for you.
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
import seaborn as sns
from sklearn.metrics import f1_score
import numpy as np

# Load the dataset
crops = pd.read_csv("soil_measures.csv")
# Show the dataframe
crops
# Check the data type of the columns
crops.info()
# Check for missing values
crops.isnull().sum()

From the info() method or from df.isnull().sum() it can be confirmed that there are no missing values.

# Check for the unique label (crop types) values
crop_types = [crop for crop in crops['crop'].unique()]
print(f"Types of crops: {', '.join(crop_types)}")
crops

How to plot it using matplotlib and the plot() method from pandas?

# Count the number of occurrences of each unique crop type in the dataset
crops['crop'].value_counts()
# Plotting the frequency of each unique crop type in the dataset
crops['crop'].value_counts().plot(kind='bar')
plt.xlabel('Crop Types')  # Label for the x-axis
plt.ylabel('Frequency')  # Label for the y-axis
plt.title('Count of Unique Target Values')  # Title of the plot

The crop column is the target variable, and from the plot above we can conclude that the task we got is a balanced multi-class classification problem.

# Split the data into train and test set
X = crops.drop(columns=['crop'])
y = crops['crop']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

Train the Logistic Regression using all features 'N', 'P', 'K', 'ph'.

# Initialize the Logistic Regression model with specific parameters for multi-class classification
logistic_model = LogisticRegression(max_iter=2000, multi_class='multinomial')
# Fit the model using all features
logistic_model.fit(X_train, y_train)

# Predict the crop type using trained model
y_pred = logistic_model.predict(X_test)
# Calculate the F1 score to evaluate the model performance
f1_score_value = f1_score(y_test, y_pred, average=None)

print(f"Features: {', '.join(X.columns)}, F1 Score: {np.mean(f1_score_value)}")