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 build multi-class classification models to predict the type of "crop"
and identify the single most important feature for predictive performance.
# All required libraries are imported here for you.
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn import metrics
# Load the dataset
crops = pd.read_csv("soil_measures.csv")
# Write your code here
crops.head()
# Inspecting the data for dtypes and null values
crops.info()
The data types for all of the predictive features are numeric, so we will not be needing to transform them. Furthermore, there aren't any null values present in the data. The only thing that we need to do is to transform our target variable, "crop", into a numeric target variable.
# We have exactly 100 rows for 22 different types of crops
crops["crop"].value_counts()
# Creating a single column with target values
import numpy as np
target_list = pd.get_dummies(crops["crop"], drop_first=False)
target_list
target = target_list.apply(np.argmax, axis=1)
# Visual Inspection
target_list
# Flatten the One-Hot-Encoded target variable into a single target column so that the model can interpret it properly
target
# Train-test split in preparation for modeling
x_crops = ['N', "P", "K", "ph"]
variable_accuracy = {}
# Loop through the variables
for crop in x_crops:
# Create feature and target
X = crops[[crop]]
y = target
# Split the Data
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 42, stratify=y, shuffle=True, test_size = .3)
# Instantiate a model object
logreg = LogisticRegression(multi_class="multinomial")
# Fit the data
logreg.fit(X_train, y_train)
# Assess Accuracy Score
acc = metrics.accuracy_score(y_test, logreg.predict(X_test))
# Add the feature name and accuracy score to the dictionary container, then loop with next feature until completion
variable_accuracy[crop] = acc
#Using univariate multi-class Logistic Regression, Potassium is the best predictive feature using Accuracy as the target metric
variable_accuracy
# Final Dictionary Assignment - Potassium 29.4% Accurate
best_predictive_feature = {'K': 0.29393939393939394}