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

关于房间传感器监测数据集的探索

1,背景描述

在建筑物中,供暖、通风和空调系统的能源消耗占据了很大比例。根据居住情况以需求为导向优化这些系统的使用,是一种提升能效的方法。
本数据集包含了某一房间 4 天内多个异构传感器测量的数据信息,如二氧化碳、温度、照明、声音和运动数据信息。基于这些数据,可以利用机器学习模型来预测估计房间内的居住者人数。

2,数据说明

字段说明
Date日期,格式为日-月-年(DD-MM-YYYY)
Time时间,格式为小时:分钟:秒(HH:MM:SS)
Temperature温度,单位为摄氏度(°C)
Light光照强度,单位为勒克斯(Lux)
Sound声音电压,从放大器输出读取并由ADC(模数转换器)测量,单位为伏特(V)
CO2二氧化碳浓度,单位为ppm(每百万份)
CO2 Slope在滑动窗口中获取的CO2值的斜率
PIR被动红外传感器的二进制值,表示是否检测到运动
Room_Occupancy_Count房间占用计数(目标值),真实情况下的房间占用人数(Target)
S1-S7 代表不同的传感器序号

3,数据来源

https://www.semanticscholar.org/paper/Machine-Learning-Based-Occupancy-Estimation-Using-Singh-Jain/e631ea26f0fd88541f42b4e049d63d6b52d6d3ac
https://www.kaggle.com/datasets/ruchikakumbhar/room-occupancy-estimation

4,问题描述

二分类分析
回归分析
时间序列分析
特征重要性分析

5,数据读取与预处理

import pandas as pd
file_path = '/home/mw/input/02072495/room occupancy.csv'
data = pd.read_csv(file_path)

data.head()

在这里插入图片描述

data.shape

在这里插入图片描述

data.info()

在这里插入图片描述

data.isnull().sum()

在这里插入图片描述

# 查看重复值
data.duplicated().sum()
# 描述性统计
data.describe()

在这里插入图片描述

# 合并日期和时间为单一的时间戳列
data['Datetime'] = pd.to_datetime(data['Date'] + ' ' + data['Time'], format='%d-%m-%Y %H:%M:%S')
data.drop(['Date', 'Time'], axis=1, inplace=True)
from scipy.stats import spearmanr
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

def plot_spearmanr(data, features, title, wide, height):
    # 计算Spearman相关矩阵和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(convert_pvalue_to_asterisks)

    # 转换为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()

#删除不是float的类型
features = data.drop(['Datetime'],axis=1).columns.tolist()
plot_spearmanr(data, features, 'Spearman correlation coefficient heat map between variables', 10, 13)

在这里插入图片描述
温度 (Temp) 相关性:

S1_Temp, S2_Temp, S3_Temp, S4_Temp 四个传感器的温度数据之间的相关性非常高(大部分在0.80以上),这表明这些特征之间有冗余。因此,可以考虑将它们合成一个新的特征,例如它们的均值或最大值,以减少冗余并保留有用的信息。
特别是S1_Temp和S2_Temp与目标变量(Room_Occupancy_Count)有比较强的正相关(接近0.6),所以温度可以作为一个重要特征保留。
光照强度 (Light):

光照数据(S1_Light, S2_Light, S3_Light, S4_Light)与目标变量的相关性较强(约0.7-0.8),而这些传感器的光照数据之间的相关性也很高。因此,类似温度,我们可以将它们合成一个特征,如光照的平均值或最大值。
声音电压 (Sound):

S1_Sound, S2_Sound, S3_Sound, S4_Sound 的相关性比较弱(大多数都小于0.5),它们与目标变量的相关性也较弱。你可以考虑将声音电压的均值作为一个新特征,但这可能不是最重要的特征,取决于你对声音与占用人数之间的关系是否重视。
二氧化碳浓度 (CO2) 和二氧化碳斜率 (CO2_Slope):

S5_CO2与目标变量的相关性较强(约0.65),且它和S5_C02_Slope的相关性也比较强。这两个特征很可能提供了关于房间占用人数的重要信息,建议保持这两个特征,或将S5_CO2和S5_CO2_Slope的加权平均作为一个新特征。
运动 (PIR):

S6_PIR 和 S7_PIR 的相关性较强(接近0.6),且这两个特征与目标变量有较强的正相关性(接近0.6)。运动检测器与房间占用人数的相关性表明,运动数据应该是非常重要的特征。

# 计算不同传感器的温度均值
data['Temp_Avg'] = data[['S1_Temp', 'S2_Temp', 'S3_Temp', 'S4_Temp']].mean(axis=1)

# 计算不同传感器的光照强度均值
data['Light_Avg'] = data[['S1_Light', 'S2_Light', 'S3_Light', 'S4_Light']].mean(axis=1)

# 计算不同传感器的声音电压均值
data['Sound_Avg'] = data[['S1_Sound', 'S2_Sound', 'S3_Sound', 'S4_Sound']].mean(axis=1)

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix
# 分别训练两个模型,选择效果更好的那个
X = data[['Temp_Avg', 'Light_Avg', 'Sound_Avg', 'S5_CO2', 'S5_CO2_Slope']]

# 用第一个传感器的数据
y1 = data['S6_PIR']
X_train, X_test, y_train, y_test = train_test_split(X, y1, test_size=0.2, random_state=42)
model1 = LogisticRegression()
model1.fit(X_train, y_train)
y_pred1 = model1.predict(X_test)
print(f"Accuracy for Sensor 1: {accuracy_score(y_test, y_pred1)}")

# 用第二个传感器的数据
y2 = data['S7_PIR']
X_train, X_test, y_train, y_test = train_test_split(X, y2, test_size=0.2, random_state=42)
model2 = LogisticRegression()
model2.fit(X_train, y_train)
y_pred2 = model2.predict(X_test)
print(f"Accuracy for Sensor 2: {accuracy_score(y_test, y_pred2)}")

在这里插入图片描述

data.drop(['S1_Light', 'S2_Light','S3_Light','S4_Light','S1_Temp','S2_Temp','S3_Temp','S4_Temp','S1_Sound','S2_Sound','S3_Sound','S4_Sound','S6_PIR'], axis=1, inplace=True)
data.head()

在这里插入图片描述
直接选择均值作为特征后续分析的理论基础,这样子可以去除冗余信息,保留关键信息,简化一下特征空间。

# 将时间特征提取为独立列
data['Year'] = data['Datetime'].dt.year
data['Month'] = data['Datetime'].dt.month
data['Day'] = data['Datetime'].dt.day
data['Hour'] = data['Datetime'].dt.hour
data['Minute'] = data['Datetime'].dt.minute
import matplotlib.pyplot as plt
import seaborn as sns

# 设置绘图风格
sns.set(style="whitegrid")

# 创建一个大图来显示不同特征与房间占用人数的关系
plt.figure(figsize=(14, 10))

# 温度与房间占用人数的关系
plt.subplot(3, 2, 1)
sns.boxplot(x='Room_Occupancy_Count', y='Temp_Avg', data=data, palette="coolwarm", linewidth=2.5, fliersize=8, notch=True)
plt.title('Room Occupancy Count vs Temperature', fontsize=16, weight='bold')
plt.xlabel('Room Occupancy Count', fontsize=14)
plt.ylabel('Temperature (°C)', fontsize=14)
plt.grid(True, linestyle='--', alpha=0.5)

# 光照与房间占用人数的关系
plt.subplot(3, 2, 2)
sns.boxplot(x='Room_Occupancy_Count', y='Light_Avg', data=data, palette="viridis", linewidth=2.5, fliersize=8, notch=True)
plt.title('Room Occupancy Count vs Light', fontsize=16, weight='bold')
plt.xlabel('Room Occupancy Count', fontsize=14)
plt.ylabel('Light (Lux)', fontsize=14)
plt.grid(True, linestyle='--', alpha=0.5)

# CO2浓度与房间占用人数的关系
plt.subplot(3, 2, 3)
sns.boxplot(x='Room_Occupancy_Count', y='S5_CO2', data=data, palette="magma", linewidth=2.5, fliersize=8, notch=True)
plt.title('Room Occupancy Count vs CO2', fontsize=16, weight='bold')
plt.xlabel('Room Occupancy Count', fontsize=14)
plt.ylabel('CO2 Concentration (ppm)', fontsize=14)
plt.grid(True, linestyle='--', alpha=0.5)

# 声音电压与房间占用人数的关系
plt.subplot(3, 2, 4)
sns.boxplot(x='Room_Occupancy_Count', y='Sound_Avg', data=data, palette="cubehelix", linewidth=2.5, fliersize=8, notch=True)
plt.title('Room Occupancy Count vs Sound', fontsize=16, weight='bold')
plt.xlabel('Room Occupancy Count', fontsize=14)
plt.ylabel('Sound (dB)', fontsize=14)
plt.grid(True, linestyle='--', alpha=0.5)

# CO2 Slope与房间占用人数的关系
plt.subplot2grid((3, 2), (2, 0), colspan=2)
sns.boxplot(x='Room_Occupancy_Count', y='S5_CO2_Slope', data=data, palette="cividis", linewidth=2.5, fliersize=8, notch=True)
plt.title('Room Occupancy Count vs CO2 Slope', fontsize=16, weight='bold')
plt.xlabel('Room Occupancy Count', fontsize=14)
plt.ylabel('CO2 Slope', fontsize=14)
plt.grid(True, linestyle='--', alpha=0.5)

# 调整布局,避免标签重叠
plt.tight_layout()

# 添加透明背景颜色以增强现代感
plt.gcf().patch.set_facecolor('whitesmoke')

# 展示图形
plt.show()

在这里插入图片描述

  1. 温度(Temperature)与房间占用人数(Room Occupancy Count)的关系
    分布差异:图中显示不同房间占用人数(0-3人)与温度的分布情况。我们可以看到随着房间占用人数增加,温度的分布范围变化较大。这表明房间温度可能与占用人数之间存在一定的关系,可能是因为房间内有更多人时,温度会有较高的波动。
    异常值:房间占用人数为0时,温度存在一些较低的异常值,可能是由于无人的房间在早晨或晚间出现低温。
  2. 光照(Light)与房间占用人数的关系
    明显的波动:随着房间占用人数的增加,光照强度的变化非常显著。特别是房间占用人数为3时,光照强度的分布幅度很大,这可能反映了房间内活动多、光照变化大。
    异常值:在房间占用人数较低时,光照强度值相对较小,这可能代表着房间的光源较弱,或是较长时间的低光环境。
  3. 二氧化碳浓度(CO2)与房间占用人数的关系
    CO2浓度与人数关系:可以看到,当房间内有更多人时,CO2浓度显著增加,这符合实际情况——人类活动产生二氧化碳,人数越多,CO2浓度越高。
    分布差异:在房间占用人数为0时,CO2浓度较低,而随着人数的增加,CO2浓度呈现显著的上升趋势。
  4. 声音电压(Sound)与房间占用人数的关系
    较高的人数会导致较大的波动:当房间占用人数为3时,声音电压的分布范围相对较大,可能是因为人数多的房间噪音更高。
    异常值:较低占用人数时,声音电压相对较小且存在少量的异常值,可能说明空房间或少人时,噪音较低。
  5. CO2斜率(CO2 Slope)与房间占用人数的关系
    与占用人数的正相关:CO2斜率与占用人数呈现出一定的正相关关系。较高的斜率值可能意味着房间内有更多人的时候,CO2浓度变化较为剧烈。
    对后续分析的启示
    特征关系:温度、光照、CO2浓度和声音电压等特征与房间占用人数之间存在明显的关系,这些特征可以作为有用的预测因子。
    特征选择:通过这些图形可以初步判断哪些特征具有较大区分度,可能有助于进行特征选择。例如,CO2浓度和温度可能对房间占用人数的预测有较强的影响。
    异常值分析:图中的异常值可能代表特殊情况,比如空房间或临时高光照和高噪音环境。这些异常值可能需要在建模时处理,确保它们不会影响模型的准确性。

6,二分类分析

# 为房间占用创建一个二进制列
data['Occupancy'] = data['Room_Occupancy_Count'].apply(lambda x: 'someone' if x > 0 else 'unmanned')

# 绘制房间占用率的分布图
plt.figure(figsize=(10, 6))
sns.countplot(data['Occupancy'], palette="viridis")
plt.title('Room occupancy distribution')
plt.xlabel('occupancy')
plt.ylabel('quantity')
plt.show()

在这里插入图片描述
从上面的条形图中可以看出,房间内“无人”的时间段比“有人”的时间段要多。

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix

# 将数据分为训练集和测试集
X = data[['Temp_Avg', 'Light_Avg', 'Sound_Avg', 'S5_CO2', 'S5_CO2_Slope']]  # 特征列
y = data['S7_PIR']  # 目标变量:是否检测到运动(0或1)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 建立Logistic Regression模型
model = LogisticRegression()
model.fit(X_train, y_train)

# 预测并评估模型
y_pred = model.predict(X_test)
print(f"Accuracy: {accuracy_score(y_test, y_pred)}")
print(f"Confusion Matrix:\n{confusion_matrix(y_test, y_pred)}")

在这里插入图片描述
精度为92.65%,意味着大多数情况下模型能够正确判断是否有运动,从而帮助优化空调和供暖系统的运行,减少不必要的能源浪费。

from sklearn.metrics import roc_curve, auc

# 计算ROC曲线的FPR和TPR
fpr, tpr, thresholds = roc_curve(y_test, model.predict_proba(X_test)[:, 1])

# 计算AUC
roc_auc = auc(fpr, tpr)

# 绘制ROC曲线
plt.figure(figsize=(10, 8))  # 增加图像尺寸以便更好地展示
plt.plot(fpr, tpr, color='darkorange', lw=2, label=f'ROC Curve (AUC = {roc_auc:.2f})')
plt.plot([0, 1], [0, 1], color='gray', linestyle='--', lw=2)  # 随机分类器线,使用更粗的线条

# 设置标题和标签,调整字体大小
plt.title('Receiver Operating Characteristic (ROC) Curve', fontsize=18, weight='bold')
plt.xlabel('False Positive Rate', fontsize=14)
plt.ylabel('True Positive Rate', fontsize=14)

# 设置图例,调整位置和字体
plt.legend(loc='lower right', fontsize=12, frameon=False)

# 添加网格线
plt.grid(True, linestyle='--', alpha=0.7, linewidth=0.7)

# 展示图像
plt.tight_layout()  # 确保所有标签都能正常显示
plt.show()

在这里插入图片描述

7,时间序列分析

import matplotlib.pyplot as plt
import seaborn as sns

# 设置更花哨的样式
sns.set(style="whitegrid", palette="muted")

# 创建一个大画布,包含多个子图
plt.figure(figsize=(14, 10))

# 温度变化趋势
plt.subplot(3, 2, 1)
sns.lineplot(x='Datetime', y='Temp_Avg', data=data, linewidth=2, color='blue')
plt.title('Temperature Over Time')
plt.xlabel('Time')
plt.ylabel('Temperature (°C)')

# 光照强度变化趋势
plt.subplot(3, 2, 2)
sns.lineplot(x='Datetime', y='Light_Avg', data=data, linewidth=2, color='orange')
plt.title('Light Intensity Over Time')
plt.xlabel('Time')
plt.ylabel('Light (Lux)')

# 声音电压变化趋势
plt.subplot(3, 2, 3)
sns.lineplot(x='Datetime', y='Sound_Avg', data=data, linewidth=2, color='green')
plt.title('Sound Voltage Over Time')
plt.xlabel('Time')
plt.ylabel('Sound (V)')

# CO2浓度变化趋势
plt.subplot(3, 2, 4)
sns.lineplot(x='Datetime', y='S5_CO2', data=data, linewidth=2, color='red')
plt.title('CO2 Concentration Over Time')
plt.xlabel('Time')
plt.ylabel('CO2 (ppm)')

# 使用subplot2grid来让最后一个图横跨两列
plt.subplot2grid((3, 2), (2, 0), colspan=2)  # 在第3行占用两列
sns.lineplot(x='Datetime', y='S5_CO2_Slope', data=data, linewidth=2, color='purple')
plt.title('CO2 Slope Over Time')
plt.xlabel('Time')
plt.ylabel('CO2 Slope')

# 调整布局,避免重叠
plt.tight_layout()
plt.show()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
温度(Temperature):图中显示了温度在某些时段内的剧烈波动,尤其是在2017年12月25日到2018年1月初,之后温度趋于平稳。这个波动可能表示设备故障或者传感器数据采集错误,值得进一步检查。

光照(Light Intensity):光照强度同样出现了显著的波动,且在某些时段光照值急剧增加,可能是房间内发生了大规模的活动,或者设备传感器报告了不正常的光照值。

声音(Sound Voltage):声音电压的波动较为剧烈,尤其在2017年12月25日到1月初期间,声音电压急剧上升。这可能表示房间内的噪音水平发生了剧烈变化,或者存在设备故障。

二氧化碳浓度(CO2):CO2浓度也显示出了剧烈的波动,尤其是在某些时段内(如12月25日),CO2浓度大幅上升。这可能是由于房间内有较多人活动导致的,或者传感器数据异常。

CO2斜率(CO2 Slope):CO2斜率图表呈现了不规则的波动,显示在某些时刻的变化速率较大。这与CO2浓度的剧烈波动相对应,可能是由于房间内人数变化或通风系统的波动。

可视化发现大量缺失值
由于在整个时间段的占比较大,用各类填充缺失值的算法显然是不切实际的,接下来我们截取一天看看各个指标数据

# 过滤2017年12月25日的数据
specific_day = data[data['Datetime'].dt.date == pd.to_datetime('2017-12-25').date()]

specific_day.set_index('Datetime', inplace=True)

# 提取五个特征
temperature = specific_day['Temp_Avg']
light = specific_day['Light_Avg']
sound = specific_day['Sound_Avg']
co2 = specific_day['S5_CO2']
co2_slope = specific_day['S5_CO2_Slope']

# 设置花哨的样式
sns.set(style="whitegrid", palette="muted")

# 创建画布,大小为16x12,调整子图布局
plt.figure(figsize=(16, 12))

# 绘制温度随时间的变化,设置不同的颜色
plt.subplot(3, 2, 1)
sns.lineplot(x=specific_day.index, y=temperature, color='royalblue', linewidth=3, linestyle='-', alpha=0.8)
plt.title('Temperature Over 24 Hours', fontsize=18, weight='bold', color='darkblue')
plt.xlabel('Time', fontsize=14, weight='bold', color='darkgreen')
plt.ylabel('Temperature (°C)', fontsize=14, weight='bold', color='darkgreen')
plt.xticks(rotation=45, fontsize=12, color='darkred')
plt.yticks(fontsize=12, color='darkred')
plt.grid(True, linestyle='--', alpha=0.5)

# 绘制光照强度随时间的变化,使用不同颜色
plt.subplot(3, 2, 2)
sns.lineplot(x=specific_day.index, y=light, linewidth=3, color='orange', alpha=0.8)
plt.title('Light Intensity Over 24 Hours', fontsize=18, weight='bold', color='orange')
plt.xlabel('Time', fontsize=14, weight='bold', color='darkgreen')
plt.ylabel('Light (Lux)', fontsize=14, weight='bold', color='darkgreen')
plt.xticks(rotation=45, fontsize=12, color='darkred')
plt.yticks(fontsize=12, color='darkred')
plt.grid(True, linestyle='--', alpha=0.5)

# 绘制声音电压随时间的变化,使用不同颜色
plt.subplot(3, 2, 3)
sns.lineplot(x=specific_day.index, y=sound, linewidth=3, color='green', alpha=0.8)
plt.title('Sound Voltage Over 24 Hours', fontsize=18, weight='bold', color='green')
plt.xlabel('Time', fontsize=14, weight='bold', color='darkgreen')
plt.ylabel('Sound (V)', fontsize=14, weight='bold', color='darkgreen')
plt.xticks(rotation=45, fontsize=12, color='darkred')
plt.yticks(fontsize=12, color='darkred')
plt.grid(True, linestyle='--', alpha=0.5)

# 绘制CO2浓度随时间的变化,使用不同颜色
plt.subplot(3, 2, 4)
sns.lineplot(x=specific_day.index, y=co2, linewidth=3, color='red', alpha=0.8)
plt.title('CO2 Concentration Over 24 Hours', fontsize=18, weight='bold', color='red')
plt.xlabel('Time', fontsize=14, weight='bold', color='darkgreen')
plt.ylabel('CO2 (ppm)', fontsize=14, weight='bold', color='darkgreen')
plt.xticks(rotation=45, fontsize=12, color='darkred')
plt.yticks(fontsize=12, color='darkred')
plt.grid(True, linestyle='--', alpha=0.5)

# 绘制CO2斜率随时间的变化,使用不同颜色
plt.subplot(3, 2, (5, 6))  # 合并(3,2,5) + (3,2,6)
sns.lineplot(x=specific_day.index, y=co2_slope, linewidth=3, color='purple', alpha=0.8)
plt.title('CO2 Slope Over 24 Hours', fontsize=18, weight='bold', color='purple')
plt.xlabel('Time', fontsize=14, weight='bold', color='darkgreen')
plt.ylabel('CO2 Slope', fontsize=14, weight='bold', color='darkgreen')
plt.xticks(rotation=45, fontsize=12, color='darkred')
plt.yticks(fontsize=12, color='darkred')
plt.grid(True, linestyle='--', alpha=0.5)

# 调整布局,避免重叠
plt.tight_layout()

# 显示图表
plt.show()

在这里插入图片描述
在这里插入图片描述

  1. 温度(Temperature)
    波动性:温度在12月25日的24小时内有显著的变化。温度在白天时间(大约12:00到15:00之间)上升,并在夜间(大约18:00之后)逐渐下降。
    这种波动可能是由于环境因素(如外部温度变化)或房间内的活动导致的(例如暖气、空调的使用)。
    信息:温度的变化有规律,且与其他特征(如光照)可能有较强的相关性。
  2. 光照强度(Light Intensity)
    强烈波动:光照强度在12月25日的24小时内呈现明显的波动,尤其是在白天(大约12:00到15:00),光照强度达到峰值。
    随着太阳的升起和落下,光照强度发生了显著的变化。夜间,光照强度几乎降到0。
    信息:光照强度与温度变化有直接关系,尤其是在室内可能与窗户的自然光照或人工照明系统相关。
  3. 声音电压(Sound Voltage)
    噪音波动:声音电压在24小时内波动非常剧烈,特别是某些时段(如12:25、16:25、18:25等)有较大的峰值。
    这些波动可能与房间内的人流量、设备操作或其他活动相关。声音的快速变化可能是由于物体的运动、环境噪声等因素。
    信息:声音变化的剧烈波动可能暗示房间内有较多的活动,或者传感器有时会出现过度灵敏的现象。
  4. CO2浓度(CO2 Concentration)
    CO2浓度的稳定性:CO2浓度几乎保持稳定,除了一些短暂的突发波动(特别是在12月25日的某些时段,如12:16和12:19等)。这些波动可能与房间内人员活动的增加相关(如人数增多或空气流通问题)。
    信息:CO2浓度较为平稳,但在某些时刻可能反映了房间内的活动变化。
  5. CO2斜率(CO2 Slope)
    斜率变化:CO2斜率的变化非常剧烈,尤其是在12:00到12:05和12:18到12:20之间的急剧波动。这可能反映了CO2浓度变化的速度,进而反映了房间内人员活动的变化。
    信息:CO2斜率的剧烈变化可能与房间内的人员流动、活动以及设备的开启关闭等因素密切相关。
    总结
    规律性与异常波动:温度、光照和CO2浓度在白天和夜晚呈现出较为规律的变化,但声音和CO2斜率则有更多的短期波动,提示房间内可能有很多间歇性的活动。
    活动与环境关系:声音、CO2浓度和CO2斜率的波动表明房间内可能有较多的活动,特别是在人流和活动频繁的时段(如白天)。光照和温度则可能受到外部环境或空调/取暖设备的影响。

8,随机森林–房屋占用分析

from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

# 使用房间占用人数(作为类别)进行分类预测
X = data[['Temp_Avg', 'Light_Avg', 'Sound_Avg', 'S5_CO2', 'S5_CO2_Slope','S7_PIR']]  # 特征列
y = data['Room_Occupancy_Count']  # 目标:房间占用人数(分类)

# 将数据分为训练集和测试集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 随机森林分类模型
rf_classifier = RandomForestClassifier(n_estimators=100, random_state=42)
rf_classifier.fit(X_train, y_train)

# 预测并评估
y_pred = rf_classifier.predict(X_test)
print(f"Accuracy: {accuracy_score(y_test, y_pred)}")

在这里插入图片描述

# 计算训练集准确率
train_accuracy = accuracy_score(y_train, rf_classifier.predict(X_train))
test_accuracy = accuracy_score(y_test, y_pred)

print(f"Training Accuracy: {train_accuracy}")
print(f"Test Accuracy: {test_accuracy}")

在这里插入图片描述

from sklearn.model_selection import cross_val_score

# 使用交叉验证评估模型
cv_scores = cross_val_score(rf_classifier, X, y, cv=5)  # 5折交叉验证
print(f"Cross-validation scores: {cv_scores}")
print(f"Mean cross-validation score: {cv_scores.mean()}")

在这里插入图片描述
观察发现随机森林模型准确率0.99,我们通过观察训练集、测试集又进行了交叉检验都发现模型准确率在0.96以上,说明没有过拟合。

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
from sklearn.ensemble import RandomForestClassifier

# 选择特征和目标变量
X = data[['Temp_Avg', 'Light_Avg', 'Sound_Avg', 'S5_CO2', 'S5_CO2_Slope','S7_PIR']]
y = data['Room_Occupancy_Count']

# 使用随机森林进行训练
rf_classifier = RandomForestClassifier(n_estimators=100, random_state=42)
rf_classifier.fit(X, y)

# 获取特征重要性
feature_importances = rf_classifier.feature_importances_

# 将特征和重要性组合成数据框
feature_importance_df = pd.DataFrame({
    'Feature': X.columns,
    'Importance': feature_importances
})

# 按重要性排序
feature_importance_df = feature_importance_df.sort_values(by='Importance', ascending=False)

# 绘制特征重要性图
plt.figure(figsize=(12, 8))
sns.set(style="whitegrid")

# 使用 barplot 绘制特征重要性
ax = sns.barplot(x='Importance', y='Feature', data=feature_importance_df, palette='coolwarm', ci=None, linewidth=2.5)

# 为条形添加阴影
for p in ax.patches:
    p.set_edgecolor('gray')
    p.set_linewidth(1.5)
    p.set_alpha(0.9)  # Slight transparency for the bars

# 在条形图上显示每个特征的重要性所占的比例
total_importance = feature_importance_df['Importance'].sum()
for p in ax.patches:
    width = p.get_width()  # 获取条形的宽度,即特征的重要性
    percentage = (width / total_importance) * 100  # 计算所占比例
    ax.text(width + 0.005, p.get_y() + p.get_height() / 2, f'{percentage:.2f}%',
            ha='left', va='center', fontsize=12, color='black', fontweight='bold')

# 添加标题和标签
plt.title('Feature Importance (Random Forest)', fontsize=18, fontweight='bold', color='darkblue')
plt.xlabel('Importance', fontsize=14, fontweight='bold', color='darkgreen')
plt.ylabel('Feature', fontsize=14, fontweight='bold', color='darkgreen')

# 调整轴标签大小
plt.xticks(fontsize=12, color='darkred')
plt.yticks(fontsize=12, color='darkred')

# 显示网格
plt.grid(True, linestyle='--', alpha=0.7)

# 调整布局
plt.tight_layout()

# 展示图形
plt.show()

在这里插入图片描述

  1. 光照(Light_Avg)是最重要的特征
    从图中可以看到,光照(Light_Avg)的特征重要性最高,达到 42.69%。这意味着光照强度是房间占用人数预测中最关键的特征之一。
    这表明光照强度与房间内活动密切相关,可能是因为光照变化与房间内是否有人有直接关系。比如,房间有人时光照可能会发生较大变化,而空房间的光照相对较为稳定。
  2. CO2斜率(S5_CO2_Slope)也有较高的重要性
    CO2斜率(S5_CO2_Slope)的特征重要性为 18.76%,排名第二。
    CO2浓度的变化(即斜率)可能与房间占用人数之间有较强的关系。由于人员活动会产生二氧化碳,随着房间内人员数量的增加,CO2的变化速度可能更为显著,因此 CO2 斜率成为了一个重要特征。
  3. 声音(Sound_Avg)也有一定影响
    声音电压(Sound_Avg)的特征重要性为 16.34%,排名第三。
    声音强度与房间占用人数相关性较强,特别是当房间内人数增加时,噪声通常会增大。因此,声音作为一个特征,能够在一定程度上反映房间是否有人。
  4. 温度(Temp_Avg)的重要性较低
    温度(Temp_Avg)的特征重要性为 12.18%,在所有特征中排名第四。
    尽管温度变化可能反映房间内的活动,但由于温度受多种因素影响(如外部气候条件、空调设置等),它可能没有像光照或CO2那样强烈地与房间占用人数相关。因此,它的特征重要性较低。
  5. PIR检测运动的特征重要性最低
    PIR传感器(S7_PIR)的特征重要性为 2.63%,是所有特征中最低的。
    PIR传感器只是简单地检测到运动,它并不能提供房间内人数的准确数字。虽然PIR在一定程度上可以反映房间内是否有活动,但它并不是一个强有力的指示器,尤其是在其他特征(如光照、CO2、声音等)能更好地反映房间占用情况的情况下。
    由于PIR无法直接告诉我们房间内有多少人,它的贡献在模型中的比重较小。

9,总结

上述的分析可能会有不好或者不精准的地方,希望各位读者朋友们帮忙指出。

在我阅读完数据来源中的论文时发现,上述的分析方法和逻辑跟原始研究背景和问题敲定有很大偏差,(这里我只能苦笑了),以下是原数据论文阅读理解

9.1 问题定义与研究背景
  • 核心问题:通过非侵入式传感器数据准确估计房间内人数,优化HVAC系统能源效率。
  • 研究动机:传统方法依赖侵入式设备(如摄像头、WiFi)存在隐私问题,且现有研究多集中于占用检测(是否有人),而非具体人数估计。
9.2 实验设计与数据采集
  • 传感器部署
    • 采用星型网络配置,部署7个异构传感器节点(S1-S7),包含CO₂、温度、光照、声音、PIR(被动红外)传感器。
    • 节点分工:
      • S1-S4(桌面节点):温度、光照、声音。
      • S5(中央节点):CO₂。
      • S6-S7(天花板节点):PIR,用于运动检测。
  • 数据采集
    • 采样周期为30秒,持续4天,覆盖不同占用场景。
    • 人工记录人员进出时间作为真实标签(0-3人)。
9.3 数据预处理与特征工程
  • 特征提取
    • CO₂斜率:通过滑动窗口(25个时间点)的线性回归计算CO₂浓度变化率,捕捉人数动态变化的影响。
    • 窗口选择依据:通过试错法优化分类准确率确定窗口大小。
9.4 模型选择与训练
  • 机器学习模型
    • 监督学习
      • LDA/QDA:基于多元高斯分布的线性/二次分类器,假设不同类别的协方差矩阵相同(LDA)或不同(QDA)。
      • SVM:支持向量机(线性核与RBF核),通过超平面划分多类数据(采用“一对多”策略)。
      • 随机森林(RF):集成决策树,通过投票机制提升鲁棒性。
    • 无监督学习
      • PCA:主成分分析,用于降维后评估模型性能。
  • 评估指标
    • 准确率、F1分数(宏平均,解决类别不平衡问题)、混淆矩阵。
    • 10折交叉验证(非打乱数据,因时间序列特性)。
9.5 实验分析与结果
  • 同质传感器融合
    • 单一传感器类型(如仅CO₂或光照)表现有限,光照传感器因人工操作依赖性高(如开关灯)易产生误判。
  • 异质传感器融合
    • 逐步融合多传感器数据(温度+CO₂斜率→加入声音→加入PIR→最终加入光照),性能逐步提升。
    • 最佳模型:SVM-RBF(所有16个特征),准确率98.4%,F1分数0.953。
  • 降维实验
    • 通过PCA将特征从12维(不含光照)降至4维,仍保持92%准确率,验证特征间强相关性。
9.6 局限性
  • 实验场景较小(6m×4.6m),未验证大规模场景适用性。
  • 光照传感器依赖人工操作,实际应用中需结合自动化控制。

Image Name
而对于我们上述的分析,我是将各个传感器进行了特征选择分析的,这也是最大的失误导致满盘皆错,自己还有许多不足之后也会慢慢弥补。

注意

# 若需要完整数据集以及代码请点击以下链接
https://mbd.pub/o/bread/aJWTmJpt

相关文章:

  • 3-知识图谱-知识图谱的存储与查询
  • [DeepSeek]二、大模型
  • 元脑服务器可用于DeepSeek部署
  • Java——多态
  • 【Leetcode 每日一题】2595. 奇偶位数
  • 阿里云ECS命名规则解析与规格选型实战指南
  • MySQL中 undolog和redolog区别
  • 《跟李沐学 AI》AlexNet论文逐段精读学习心得 | PyTorch 深度学习实战
  • RabbitMQ 消息队列
  • 蓝桥杯(B组)-每日一题(1093字符逆序)
  • Python 获取当前目录及上级目录
  • 类型系统下的语言分类与类型系统基础
  • 流行多模型对比分析
  • CPU与GPU之区别(The Difference between CPU and GPU)
  • 实战:功率分析仪3u3v测三相原理及接线
  • 金仓KDTS迁移工具启动报错kdts-app-console is already start, Please close it.
  • 【深度学习】手写数字识别任务
  • python读写各种格式文件
  • 中通云的容器化之旅:从单集群到多集群的演进
  • 第2章 深入理解Thread构造函数
  • 白云山一季度营收净利双降,此前称今年将挖掘盘活自身资源
  • 李在明涉嫌违反《公职选举法》案将于5月1日宣判
  • “自己生病却让别人吃药”——抹黑中国经济解决不了美国自身问题
  • 外交部回应涉长江和记出售巴拿马运河港口交易:望有关各方审慎行事,充分沟通
  • 为何未来的福利国家必须绿色且公平
  • 四川在浙江公开招募200名退休教师,赴川支教帮扶