当前位置: 首页 > article >正文

基于统计分析与随机森林的环境条件对生菜生长的影响研究

1.项目背景

随着现代农业的发展,对植物生长过程中环境因素的影响有了越来越多的关注,基于2023年8月3日至2023年9月19日期间记录的70个不同生菜样本的生长数据进行分析,可以更好地理解温度、湿度、pH值和总溶解固体(TDS)等环境条件如何影响生菜的生长动态。

2.数据说明

字段说明
Plant_ID植物编号
Date日期
Temperature (°C)温度(摄氏度)
Humidity (%)湿度(百分比)
TDS Value (ppm)TDS值(ppm)
pH LevelpH值
Growth Days生长天数
Temperature (F)温度(华氏度)
Humidity湿度

3.Python库导入及数据读取

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.metrics import silhouette_score
from scipy.stats import spearmanr,mannwhitneyu
from imblearn.over_sampling import SMOTE
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report,confusion_matrix,roc_curve, auc
data = pd.read_csv("/home/mw/input/12228739/lettuce_dataset_updated.csv")  

直接执行这个代码的话,会报错:

Image Name
文件的编码格式与默认的 UTF-8 编码不兼容。为了正确加载数据,需要尝试不同的格式,一般常见的编码格式有:UTF-8、UTF-16、ISO-8859-1、GB2312 / GBK / GB18030、BIG5、ASCII。

data = pd.read_csv("/home/mw/input/12228739/lettuce_dataset_updated.csv", encoding='ISO-8859-1')

4.数据预览及预处理

print('查看数据信息:')
data.info()
查看数据信息:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3169 entries, 0 to 3168
Data columns (total 9 columns):
 #   Column            Non-Null Count  Dtype  
---  ------            --------------  -----  
 0   Plant_ID          3169 non-null   int64  
 1   Date              3169 non-null   object 
 2   Temperature (°C)  3169 non-null   float64
 3   Humidity (%)      3169 non-null   int64  
 4   TDS Value (ppm)   3169 non-null   int64  
 5   pH Level          3169 non-null   float64
 6   Growth Days       3169 non-null   int64  
 7   Temperature (F)   3169 non-null   float64
 8   Humidity          3169 non-null   float64
dtypes: float64(4), int64(4), object(1)
memory usage: 222.9+ KB
print(f'查看重复值:{data.duplicated().sum()}')
查看重复值:0

由于温度和湿度均有两列数据,只需要保留其中一列即可,这里选择保留百分比的湿度和摄氏度情况。

data['Date'] = pd.to_datetime(data['Date'])
data = data.drop(columns=['Temperature (F)','Humidity'])
feature_map = {
    'Temperature (°C)': '温度(摄氏度)',
    'Humidity (%)': '湿度(百分比)',
    'TDS Value (ppm)': 'TDS值(ppm)',
    'pH Level': 'pH值',
    'Growth Days': '生长天数'
}
plt.figure(figsize=(15, 10))
for i, (col, col_name) in enumerate(feature_map.items(), 1):
    plt.subplot(2, 3, i)
    sns.boxplot(y=data[col])
    plt.title(f'{col_name}的箱线图', fontsize=14)
    plt.ylabel('数值', fontsize=12)
    plt.grid(axis='y', linestyle='--', alpha=0.7)

plt.tight_layout()
plt.show()

数据干净,不存在异常值,由于原数据中并不能很好的体现不同环境下生菜生长需要的天数,所以需要通过对Plant_ID进行分组来研究。

# 按 Plant_ID 分组,计算所需统计指标
plant_stats = data.groupby('Plant_ID').agg({
    'Temperature (°C)': ['min', 'max', 'mean'],
    'Humidity (%)': ['min', 'max', 'mean'],
    'TDS Value (ppm)': ['min', 'max', 'mean'],
    'pH Level': ['min', 'max', 'mean'],
    'Growth Days': 'max'
})

# 重命名列,便于理解
plant_stats.columns = [
    '最低温度 (°C)', '最高温度 (°C)', '平均温度 (°C)',
    '最低湿度 (%)', '最高湿度 (%)', '平均湿度 (%)',
    '最低TDS值 (ppm)', '最高TDS值 (ppm)', '平均TDS值 (ppm)',
    '最低pH值', '最高pH值', '平均pH值',
    '最高生长天数'
]

plant_stats.reset_index(inplace=True)
plant_stats = plant_stats.round({'平均温度 (°C)': 1, '平均湿度 (%)': 0, '平均TDS值 (ppm)': 0, '平均pH值': 1})
plant_stats.head()
Plant_ID最低温度 (°C)最高温度 (°C)平均温度 (°C)最低湿度 (%)最高湿度 (%)平均湿度 (%)最低TDS值 (ppm)最高TDS值 (ppm)平均TDS值 (ppm)最低pH值最高pH值平均pH值最高生长天数
0120.133.530.6507964.0416789615.06.06.86.445
1220.133.530.6507965.0413797597.06.06.86.445
2320.133.530.6508069.0403799620.06.06.86.447
3420.133.530.6507863.0402794598.06.06.86.448
4520.133.530.6508065.0410778577.06.06.86.445

5.描述性统计

data.describe()
Plant_IDDateTemperature (°C)Humidity (%)TDS Value (ppm)pH LevelGrowth Days
count3169.00000031693169.0000003169.0000003169.0000003169.0000003169.000000
mean35.4417802023-08-25 03:23:07.06216448028.14222264.873462598.0454406.39921123.141054
min1.0000002023-08-03 00:00:0018.00000050.000000400.0000006.0000001.000000
25%18.0000002023-08-14 00:00:0023.60000057.000000498.0000006.20000012.000000
50%35.0000002023-08-25 00:00:0030.20000065.000000593.0000006.40000023.000000
75%53.0000002023-09-05 00:00:0031.50000073.000000699.0000006.60000034.000000
max70.0000002023-09-19 00:00:0033.50000080.000000800.0000006.80000048.000000
std20.243433NaN4.6705218.988985115.7130470.23441813.077107
  1. 样本量与时间范围:共 3169 条记录,时间跨度为 2023年8月3日至2023年9月19日,涵盖48天的生长记录。
  2. 温度 (°C):范围 18.0°C 至 33.5°C,平均值 28.14°C,标准差 4.67°C,总体处于生菜适宜生长的范围内。
  3. 湿度 (%):范围 50% 至 80%,平均值 64.87%,标准差 8.99%,湿度波动较大,可能与灌溉或环境调控有关。
  4. TDS 值 (ppm):范围 400 至 800 ppm,平均值 598.05 ppm,标准差 115.71 ppm,可能受施肥或水质影响。
  5. pH 值:范围 6.0 至 6.8,平均值 6.40,标准差 0.23,整体稳定,均处于生菜适宜的弱酸性范围。
  6. 生长天数:范围 1 天至 48 天,平均值 23.14 天,标准差 13.08 天,反映不同生菜生长阶段的差异。
plant_stats.describe()
Plant_ID最低温度 (°C)最高温度 (°C)平均温度 (°C)最低湿度 (%)最高湿度 (%)平均湿度 (%)最低TDS值 (ppm)最高TDS值 (ppm)平均TDS值 (ppm)最低pH值最高pH值平均pH值最高生长天数
count70.00000070.00000070.00000070.00000070.00000070.00000070.00000070.00000070.00000070.00000070.00000070.00000070.00000070.000000
mean35.50000019.56142931.25142928.12285750.18571479.61428664.885714408.957143791.885714597.9857146.0014296.7885716.39714345.271429
std20.3510850.8905783.7941504.0911420.3916840.6872091.4500669.9832268.40038416.0556030.0119520.0320460.0239050.700340
min1.00000018.00000024.60000021.00000050.00000077.00000063.000000400.000000765.000000567.0000006.0000006.7000006.30000045.000000
25%18.25000018.32500026.65000021.95000050.00000079.00000064.000000402.000000789.000000584.2500006.0000006.8000006.40000045.000000
50%35.50000020.10000033.50000030.60000050.00000080.00000065.000000405.000000795.000000598.0000006.0000006.8000006.40000045.000000
75%52.75000020.10000033.50000030.60000050.00000080.00000066.000000412.000000798.000000611.7500006.0000006.8000006.40000045.000000
max70.00000020.10000033.50000030.70000051.00000080.00000069.000000449.000000800.000000628.0000006.1000006.8000006.50000048.000000
  1. 样本量与数据描述:共 70 条记录,涵盖不同生菜种植样本的生长数据。

  2. 温度 (°C)

    • 最低温度:范围 18.0°C 至 20.1°C,平均值 19.56°C,标准差 0.89°C。
    • 最高温度:范围 24.6°C 至 33.5°C,平均值 31.25°C,标准差 3.79°C。
    • 平均温度:范围 21.0°C 至 30.7°C,平均值 28.12°C,标准差 4.09°C。
  3. 湿度 (%)

    • 最低湿度:范围 50% 至 51%,平均值 50.19%,标准差 0.39%。
    • 最高湿度:范围 77% 至 80%,平均值 79.61%,标准差 0.69%。
    • 平均湿度:范围 63% 至 69%,平均值 64.89%,标准差 1.45%。
  4. TDS 值 (ppm)

    • 最低TDS值:范围 400 至 449 ppm,平均值 408.96 ppm,标准差 9.98 ppm。
    • 最高TDS值:范围 765 至 800 ppm,平均值 791.89 ppm,标准差 8.40 ppm。
    • 平均TDS值:范围 567 至 628 ppm,平均值 597.99 ppm,标准差 16.06 ppm。
  5. pH 值

    • 最低pH值:范围 6.0 至 6.1,平均值 6.00,标准差 0.01。
    • 最高pH值:范围 6.7 至 6.8,平均值 6.79,标准差 0.03。
    • 平均pH值:范围 6.3 至 6.5,平均值 6.40,标准差 0.02。
  6. 生长天数:范围 45 天至 48 天,平均值 45.27 天,标准差 0.70 天,样本间差异较小。

6.斯皮尔曼相关性分析

def plot_spearmanr(data,features,title,wide,height):
    # 计算斯皮尔曼相关性矩阵和p值矩阵
    spearman_corr_matrix = data[features].corr(method='spearman')
    pvals = data[features].corr(method=lambda x, y: spearmanr(x, y)[1]) - np.eye(len(data[features].columns))

    # 转换 p 值为星号
    def convert_pvalue_to_asterisks(pvalue):
        if pvalue <= 0.001:
            return "***"
        elif pvalue <= 0.01:
            return "**"
        elif pvalue <= 0.05:
            return "*"
        return ""

    # 应用转换函数
    pval_star = pvals.applymap(lambda x: convert_pvalue_to_asterisks(x))

    # 转换成 numpy 类型
    corr_star_annot = pval_star.to_numpy()

    # 定制 labels
    corr_labels = spearman_corr_matrix.to_numpy()
    p_labels = corr_star_annot
    shape = corr_labels.shape

    # 合并 labels
    labels = (np.asarray(["{0:.2f}\n{1}".format(data, p) for data, p in zip(corr_labels.flatten(), p_labels.flatten())])).reshape(shape)

    # 绘制热力图
    fig, ax = plt.subplots(figsize=(height, wide), dpi=100, facecolor="w")
    sns.heatmap(spearman_corr_matrix, annot=labels, fmt='', cmap='coolwarm',
                vmin=-1, vmax=1, annot_kws={"size":10, "fontweight":"bold"},
                linecolor="k", linewidths=.2, cbar_kws={"aspect":13}, ax=ax)

    ax.tick_params(bottom=False, labelbottom=True, labeltop=False,
                left=False, pad=1, labelsize=12)
    ax.yaxis.set_tick_params(labelrotation=0)

    # 自定义 colorbar 标签格式
    cbar = ax.collections[0].colorbar
    cbar.ax.tick_params(direction="in", width=.5, labelsize=10)
    cbar.set_ticks([-1, -0.5, 0, 0.5, 1])
    cbar.set_ticklabels(["-1.00", "-0.50", "0.00", "0.50", "1.00"])
    cbar.outline.set_visible(True)
    cbar.outline.set_linewidth(.5)

    plt.title(title)
    plt.show()
features = plant_stats.drop(['Plant_ID'],axis=1).columns.tolist()
plot_spearmanr(plant_stats,features,'各变量之间的斯皮尔曼相关系数热力图',12,15)

生长天数与温度、湿度、TDS值、pH值均无显著的相关关系。

7.Mann-Whitney U检验

通过之前的分析发现,生长天数大多是在45天,如果超过45天,视为异常样本。

plant_stats['异常样本'] = (plant_stats['最高生长天数'] > 45).astype(int)
def mann_whitney_u_test(df, features, target_column):
    results = []

    # 遍历每一个特征,进行Mann-Whitney U检验
    for feature in features:
        # 获取目标变量为 0 和 1 的数据
        group0 = df[df[target_column] == 0][feature]
        group1 = df[df[target_column] == 1][feature]
        
        # 进行 Mann-Whitney U 检验
        u_stat, p_val = mannwhitneyu(group0, group1)
        
        # 将结果保存
        results.append([feature, u_stat, p_val])
    
    # 将结果转换为 DataFrame
    results_df = pd.DataFrame(results, columns=['Feature', 'U Statistic', 'P Value'])
    
    return results_df
# 获取 Mann-Whitney U 检验的结果
results_df = mann_whitney_u_test(plant_stats, features[:-1], '异常样本')
results_df
FeatureU StatisticP Value
0最低温度 (°C)322.50.975307
1最高温度 (°C)320.50.942425
2平均温度 (°C)275.00.336614
3最低湿度 (%)326.00.980887
4最高湿度 (%)256.00.165906
5平均湿度 (%)354.50.626596
6最低TDS值 (ppm)324.51.000000
7最高TDS值 (ppm)263.00.323278
8平均TDS值 (ppm)278.00.457655
9最低pH值330.00.694663
10最高pH值315.50.803445
11平均pH值313.50.673545

所有特征的p值均大于0.05,认为温度、湿度、TDS值、pH值对生菜的影响均不显著。

8.随机森林模型

x = plant_stats[features[:-1]]
y = plant_stats['异常样本']
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.3,random_state=15) #37分
smote = SMOTE(sampling_strategy='auto', random_state=15)
x_train_res, y_train_res = smote.fit_resample(x_train, y_train)
rf_molde = RandomForestClassifier(random_state=15)
rf_molde.fit(x_train_res, y_train_res)
y_pred_rf = rf_molde.predict(x_test)
class_report_rf = classification_report(y_test, y_pred_rf)
print('随机森林模型评估如下:')
print(class_report_rf)
随机森林模型评估如下:
              precision    recall  f1-score   support

           0       0.89      0.89      0.89        18
           1       0.33      0.33      0.33         3

    accuracy                           0.81        21
   macro avg       0.61      0.61      0.61        21
weighted avg       0.81      0.81      0.81        21
cm = confusion_matrix(y_test,y_pred_rf)

plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, fmt='g', cmap='Blues', 
            xticklabels=['预测值 0', '预测值 1'], 
            yticklabels=['真实值 0', '真实值 1'])
plt.title('随机森林模型预测的混淆矩阵')
plt.show()
#绘制ROC曲线
fpr, tpr, _ = roc_curve(y_test, y_pred_rf)
roc_auc = auc(fpr, tpr)

plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr, color='darkorange', lw=2, label='ROC曲线(面积 = %0.2f)' % roc_auc)
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlabel('假阳率')
plt.ylabel('真阳率')
plt.title('随机森林的ROC曲线')
plt.legend(loc="lower right")
plt.show()

模型预测效果一般,不算特别好,尤其在识别生长天数大于45天的样本。

feature_importances = rf_molde.feature_importances_
features_rf = pd.DataFrame({'特征': x.columns, '重要度': feature_importances})
features_rf.sort_values(by='重要度', ascending=False, inplace=True)
plt.figure(figsize=(10, 8))
sns.barplot(x='重要度', y='特征', data=features_rf)
plt.xlabel('重要度')
plt.ylabel('特征')
plt.title('随机森林特征图')
plt.show()

TDS是模型分类中最重要的特征,至于为啥之前的斯皮尔曼相关性分析、Mann-Whitney U检验没有捕捉到这个信息,是因为随机森林可以捕捉非线性关系,而斯皮尔曼相关性和 U 检验是基于单调关系或单变量的显著性分析。

9.总结

针对2023年8月3日至2023年9月19日期间70个不同生菜样本的研究分析得出以下结论:
通过斯皮尔曼相关性分析和 Mann-Whitney U 检验发现,温度、湿度、TDS值及pH值均未对生菜生长天数产生显著影响,然而,在对数据进行 SMOTE 过采样以平衡样本后,随机森林模型在识别异常样本(生长天数大于45天)方面表现仍较差,但整体 AUC 达到 0.61,模型表现尚可,并且分析显示 TDS 值在随机森林模型中起到了较为重要的作用。


http://www.kler.cn/a/457171.html

相关文章:

  • CSS2笔记
  • 解析 SQL 中的 NULL 与比较操作:NULL 值与任何值的比较会返回 UNKNOWN
  • 【加密算法简介】
  • mybatis-plus 用法总结
  • Hutool 发送 HTTP 请求的几种常见写法
  • Java反射案例:用反射机制调用某个对象的指定方法
  • Django 模型中使用选择(choices):全面指南
  • vue.js 工程化开发 脚手架 Vue CLl
  • MySQL日志之误删恢复数据
  • Soul App创始人张璐团队以科技守护真实,净化网络社交环境
  • Mac 12.1安装tiger-vnc问题-routines:CRYPTO_internal:bad key length
  • 【每日学点鸿蒙知识】Grid子项拖动、Swiper指示器、手势事件上报、指定使用发布版本API、打包签名失败报错109
  • 「Python数据科学」标量、向量、矩阵、张量与多维数组的辨析
  • WEB UI 常用类
  • 【每日学点鸿蒙知识】Web高度适配、变量声明规范、动画取消、签名文件、包体积优化相关
  • 亚马逊云科技陈晓建:每个应用程序都离不开生成式AI
  • MySQL-数据库,数据表备份
  • 智能化军事【四】AI芯片在智能化军事中的应用模式
  • 1012. 【USACO题库】1.3.4 Prime Cryptarithm牛式
  • 论文浅尝 | 编辑基于语言模型的知识图谱嵌入(AAAI2024)
  • 通用导出任何对象列表数据的excel工具类
  • 期权懂|期权新手入门知识:如何挑选期权活跃合约?
  • pytorch nn.Parameter模块介绍
  • Python|Pyppeteer实现自动化获取reCaptcha验证码图片以及提示词(29)
  • Debian-linux运维-ssh配置(兼容Jenkins插件的ssh连接公钥类型)
  • 【JS笔记】快速安装nodejs(九)