我正在创建一个用于记录来自传感器的数据的系统。(只有一系列数字)
我希望能够让系统进入几天的“学习”模式,这样它就可以看到它的“正常”操作值是什么,并且一旦它脱离了这个模式,任何超过某个时间点的偏离行为都可以被标记出来。数据全部存储在MySQL数据库中。
欢迎任何关于如何进行这项工作的建议,以及关于该主题的进一步阅读的地点。
我更愿意使用python来完成这个任务。
在白天访问和使用的温度控制区域中,每5分钟显示一次数据的温度和湿度值。这意味着它在使用时会有波动,也会有一些温度变化。但是,需要检测任何与此不同的情况,例如冷却或供暖系统故障
发布于 2012-12-03 19:23:11
从本质上讲,您应该关注的是density estimation:确定某些变量行为的模型的任务,以便您可以查找偏离该模型的情况。
下面是一些非常简单的示例代码。我假设温度和湿度在其未变换的尺度上具有独立的正态分布:
import numpy as np
from matplotlib.mlab import normpdf
from itertools import izip
class TempAndHumidityModel(object):
def __init__(self):
self.tempMu=0
self.tempSigma=1
self.humidityMu=0
self.humiditySigma=1
def setParams(self, tempMeasurements, humidityMeasurements, quantile):
self.tempMu=np.mean(tempMeasurements)
self.tempSigma=np.std(tempMeasurements)
self.humidityMu=np.mean(humidityMeasurements)
self.humiditySigma=np.std(humidityMeasurements)
if not 0 < quantile <= 1:
raise ValueError("Quantile for threshold must be between 0 and 1")
self._thresholdDensity(quantile, tempMeasurements, humidityMeasurements)
def _thresholdDensity(self, quantile, tempMeasurements, humidityMeasurements):
tempDensities = np.apply_along_axis(
lambda x: normpdf(x, self.tempMu, self.tempSigma),0,tempMeasurements)
humidityDensities = np.apply_along_axis(
lambda x: normpdf(x, self.humidityMu, self.humiditySigma),0,humidityMeasurements)
densities = sorted(tempDensities * humidityDensities, reverse=True)
#Here comes the massive oversimplification: just choose the
#density value at the quantile*length position, and use this as the threshold
self.threshold = densities[int(np.round(quantile*len(densities)))]
def probOfObservation(self, temp, humidity):
return normpdf(temp, self.tempMu, self.tempSigma) * \
normpdf(humidity, self.humidityMu, self.humiditySigma)
def isNormalMeasurement(self, temp, humidity):
return self.probOfObservation(temp, humidity) > self.threshold
if __name__ == '__main__':
#Create some simulated data
temps = np.random.randn(100)*10 + 50
humidities = np.random.randn(100)*2 + 10
thm = TempAndHumidityModel()
#going to hard code in the 95% threshold
thm.setParams(temps, humidities, 0.95)
#Create some new data from same dist and see how many false positives
newTemps = np.random.randn(100)*10 + 50
newHumidities = np.random.randn(100)*2 + 10
numFalseAlarms = sum(~thm.isNormalMeasurement(t,h) for t,h in izip(newTemps,newHumidities))
print '{} false alarms!'.format(numFalseAlarms)
#Now create some abnormal data: mean temp drops to 20
lowTemps = np.random.randn(100)*10 + 20
normalHumidities = np.random.randn(100)*2 + 10
numDetections = sum(~thm.isNormalMeasurement(t,h) for t,h in izip(lowTemps,normalHumidities))
print '{} abnormal measurements flagged'.format(numDetections)输出示例:
>> 3 false alarms!
>> 77 abnormal measurements flagged现在,我不知道正态分布的假设是否适合您的数据(您可能想要将数据转换到不同的尺度上,以便它适合);假设温度和湿度之间的独立性可能是非常不准确的;我用来查找与所请求的分布分位数相对应的密度值的技巧应该被使用分布的逆CDF的东西所取代。但是,这应该会让您对要做什么有所了解。
另外请注意,有许多好的非参数密度估计器:kernel density estimators立即出现在我的脑海中。如果您的数据看起来不像任何标准分布,那么这些方法可能更合适。
发布于 2012-11-29 22:11:34
看起来您正在尝试执行anomaly detection,但是您对数据的描述并不明确。通常情况下,你应该从定义/约束数据“正常”的含义开始。
一旦回答了这些类型的问题,您就可以使用数据库中的一批数据来训练分类器或异常检测器,并使用结果来评估未来的日志输出。如果机器学习算法适用于您的数据,您可以考虑使用scikit-learn。对于统计模型,可以使用SciPy的stats子包。当然,对于python中的任何类型的数字数据操作,NumPy都是您的好朋友。
https://stackoverflow.com/questions/13627275
复制相似问题