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 build multi-class classification models to predict the type of "crop" and identify the single most importance 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, cross_val_score, KFold
from sklearn import metrics

# Load the dataset
crops = pd.read_csv("soil_measures.csv")
print(crops.info())
print(crops['crop'].unique())
crops['crop'].value_counts()

In an inintial inspection of the dataset, we found that there is no missing value in the dataframe, which is ideal for building machine learning models.

Nitrogen, Phosphorous, Potassium and pH value are correctly shown as number type.

22 different types of crops are recorded in the dataset, and the class are very balanced (each type of the crops all have 100 data points)

We will do an exploratory data analysis to check the quality of data and try to have an understanding of the whole dataset.

import plotly.express as px

nutritions = crops.drop('crop', axis=1)
nutritions = nutritions.melt(var_name='Variable', value_name='Value')
fig = px.box(nutritions, x='Variable', y='Value')
fig.show()
ph = nutritions[nutritions['Variable'] == 'ph']
fig_ph = px.box(ph, x='Variable', y='Value')
fig_ph.show()

K has some outliers. Ph in this dataset is distributed reasonably, between 3 to 10.

For the outliers in K. We would like to see if it is related to some certian crops.

high_k = crops[crops['K'] > 190]
high_k['crop'].value_counts()

This datasets contain some outliers in Potassium content level that is greater than 190. We found that the soil with extremely high level of potassium seems to be an ideal condition for growing grapes and apple.

Prediction Model for the Crops Types

Before building a model, we need to do some transformation on the dataset. We need to transform the crops column into numeric, as machine learning models do not surpport non-numeric data.

# Transform the target variable
crops['crop_code'], unique = pd.factorize(crops['crop'])

# Here is the dictionary of the label and its corresponding crop
print(dict(enumerate(unique)))

Then we start to build the model

#Split the data into train and test set
X = crops.drop(['crop', 'crop_code'], axis=1)
y = crops['crop_code']

print(X.shape, y.shape)