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
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn import metrics
# Load the dataset
crops = pd.read_csv("soil_measures.csv")
# Write your code here
print(crops.info())
print(crops.describe())
print(crops.isnull().sum())
crops[['N', 'P', 'K', 'ph']].hist(figsize=(10, 8))
sns.heatmap(crops.corr(), annot=True, cmap="coolwarm")
for feature in ['N', 'P', 'K', 'ph']:
sns.boxplot(x='crop', y=feature, data=crops)
plt.title(f'{feature} by Crop Type')
plt.xticks(rotation=75)
plt.show()
encoder = LabelEncoder()
crops['crop_encoded'] = encoder.fit_transform(crops['crop'])
X = crops[['N', 'P', 'K', 'ph']]
y = crops['crop_encoded']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
features_dict = {}
for feature in ["N", "P", "K", "ph"]:
log_reg = LogisticRegression(multi_class="multinomial")
log_reg.fit(X_train[[feature]], y_train)
y_pred = log_reg.predict(X_test[[feature]])
f1 = metrics.f1_score(y_test, y_pred, average='weighted')
features_dict[feature] = f1
print(f"F1-score para {feature}: {f1}")
best_feature = max(features_dict, key=features_dict.get)
best_score = features_dict[best_feature]
best_predictive_feature = {best_feature: best_score}
print("\nLa mejor característica predictiva es:")
print(best_predictive_feature)¿Por qué utilizamos solo una característica y no todas?
En este ejercicio específico, el objetivo es identificar cuál es la característica individual que tiene el mayor poder predictivo para clasificar los tipos de cultivos. Por lo tanto, entrenamos modelos utilizando una sola característica a la vez para evaluar el rendimiento predictivo de cada una por separado.
Al entrenar el modelo con una sola característica, podemos medir directamente cuánto contribuye esa característica en particular a la capacidad del modelo para predecir el tipo de cultivo. Esto nos permite comparar las características entre sí y determinar cuál es la más informativa por sí sola.
¿Estamos suponiendo que las características son linealmente independientes?
No necesariamente. La independencia lineal se refiere a que una característica no puede ser expresada como una combinación lineal de otras características. En este caso, no estamos haciendo suposiciones sobre la independencia lineal de las características. Más bien, estamos evaluando cada característica individualmente para ver su impacto directo en la predicción.
Al utilizar una característica a la vez, simplemente estamos aislando su efecto para entender su capacidad predictiva sin la influencia de las demás características. Esto no implica ninguna suposición sobre las relaciones lineales entre las características.
¿Por qué no utilizamos todas las características juntas?
El objetivo principal aquí es identificar la característica individual más importante para la predicción. Si entrenáramos el modelo utilizando todas las características simultáneamente, podríamos obtener un mejor rendimiento general, pero no podríamos determinar fácilmente cuál es la característica que más contribuye al rendimiento del modelo sin realizar análisis adicionales, como calcular la importancia de las características o examinar los coeficientes del modelo.
Análisis adicional con todas las características:
Si estuviéramos interesados en maximizar el rendimiento predictivo, sería recomendable entrenar un modelo utilizando todas las características juntas. Luego, podríamos utilizar técnicas como:
Importancia de características en modelos de árbol: Los modelos como Bosques Aleatorios o Gradient Boosting proporcionan medidas de importancia de características. Análisis de coeficientes en modelos lineales: En la Regresión Logística multiclase, podemos examinar los coeficientes para entender el impacto de cada característica. Técnicas de selección de características: Métodos como la regresión Lasso o la selección hacia atrás pueden ayudar a identificar las características más relevantes cuando se consideran todas juntas.