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 me as a machine learning expert for assistance in selecting the best crop for his field. He has provided me 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, I will build multi-class classification models to predict the type of "crop" and identify the single most importance feature for predictive performance.
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn import metrics
# Loading the dataset
crops = pd.read_csv("soil_measures.csv")
# Preparing features and target
X = crops.drop('crop', axis=1).values
y = crops['crop'].values
# Splitting data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=42)
# Dictionary to store F1-scores for each feature
feature_performance = {}
# Looping through the features
for feature in ['N', 'P', 'K', 'ph']:
# Training logistic regression model
log_reg = LogisticRegression(multi_class='multinomial')
log_reg.fit(X_train[:, crops.columns.get_loc(feature)].reshape(-1, 1), y_train)
# Making predictions
y_pred = log_reg.predict(X_test[:, crops.columns.get_loc(feature)].reshape(-1, 1))
# Evaluating performance
f1_score = metrics.f1_score(y_test, y_pred, average='weighted')
feature_performance[feature] = f1_score # Store F1-score in the dictionary
print(f"F1-score for {feature}: {f1_score}")
# Finding the best predictive feature
best_feature = max(feature_performance, key=feature_performance.get)
best_score = feature_performance[best_feature]
best_predictive_feature = {best_feature:best_score}
print(best_predictive_feature)FEATURE IMPORTANCE ANALYSIS USING LOGISTIC REGRESSION
Objective
The goal of this analysis was to identify the most predictive soil nutrient feature for determining crop type using a logistic regression model. The features evaluated were nitrogen (N), phosphorus (P), potassium (K), and pH level (ph).
Methodology
Using a multinomial logistic regression approach from scikit-learn, we trained separate models for each feature to assess its individual predictive strength. The dataset was split into training (60%) and testing (40%) subsets. For each feature, an F1-score was computed with a weighted average to account for potential class imbalance in crop types.
Results
The F1-scores for each feature were as follows:
N (Nitrogen): 0.0989
P (Phosphorus): 0.1276
K (Potassium): 0.2491
ph (Soil pH): 0.0672
Conclusion
Among all the features, Potassium (K) yielded the highest weighted F1-score of 0.2491, indicating it is the most informative single predictor for crop classification in the given dataset. This insight can guide agronomists or ML modelers to prioritize potassium levels in further multi-feature modeling or agricultural decision-making processes.