程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

如何用DBSCAN算法對時間序列的異常數據清洗?(語言-python)

編輯:Python
問題遇到的現象和發生背景

①如何用DBSCAN算法對時間序列的異常數據清洗呢?我的數據格式如下圖:(請問需要把日期型變量轉為數值型嗎?怎麼實現呢)

問題相關代碼,請勿粘貼截圖

②下面是我找到的DBSCAN算法相關代碼,原碼是從txt文件中輸入數據,請問如果我要從我的excel輸入數據應該改哪裡呢?

import numpy as np
import matplotlib.pyplot as plt
import math
import time
UNCLASSIFIED = False
NOISE = 0
def loadDataSet(fileName, splitChar='\t'):#定義一個兩參數的函數
"""
輸入:文件名
輸出:數據集
描述:從文件讀入數據集
"""
dataSet = [] #創建一個空列表
with open(fileName) as fr:#打開文件賦給fr
for line in fr.readlines():#將文本文件每一行都作為獨立的字符串對象並將這些對象放入列表返回。遍歷給line
curline = line.strip().split(splitChar)#strip()如果不帶參數,默認是清除兩邊的空白符,split(splitChar)
#將line字符串按照splitChar='\t'切分成多個字符串存在一個列表中,賦給curline
fltline = list(map(float, curline))#切分出的列表的每個值,用float函數把它們轉成float型, list()函數把map函數返回的迭代器遍歷展開成一個列表賦給fltline
dataSet.append(fltline)#添加到之前創建的空列表dataSet裡
return dataSet
def dist(a, b):
"""
輸入:向量A, 向量B
輸出:兩個向量的歐式距離
"""
return math.sqrt(np.power(a - b, 2).sum())
def eps_neighbor(a, b, eps):
"""
輸入:向量A, 向量B
輸出:是否在eps范圍內
"""
return dist(a, b) < eps
def region_query(data, pointId, eps):
"""
輸入:數據集, 查詢點id, 半徑大小
輸出:在eps范圍內的點的id
"""
nPoints = data.shape[1]
seeds = []
for i in range(nPoints):
if eps_neighbor(data[:, pointId], data[:, i], eps):
seeds.append(i)
return seeds
def expand_cluster(data, clusterResult, pointId, clusterId, eps, minPts):
"""
輸入:數據集, 分類結果, 待分類點id, 簇id, 半徑大小, 最小點個數
輸出:能否成功分類
"""
seeds = region_query(data, pointId, eps)
if len(seeds) < minPts: # 不滿足minPts條件的為噪聲點
clusterResult[pointId] = NOISE
return False
else:
clusterResult[pointId] = clusterId # 劃分到該簇
for seedId in seeds:
clusterResult[seedId] = clusterId

 while len(seeds) > 0: # 持續擴張 currentPoint = seeds[0] queryResults = region_query(data, currentPoint, eps) if len(queryResults) >= minPts: for i in range(len(queryResults)): resultPoint = queryResults[i] if clusterResult[resultPoint] == UNCLASSIFIED: seeds.append(resultPoint) clusterResult[resultPoint] = clusterId elif clusterResult[resultPoint] == NOISE: clusterResult[resultPoint] = clusterId seeds = seeds[1:] return True

def dbscan(data, eps, minPts):
"""
輸入:數據集, 半徑大小, 最小點個數
輸出:分類簇id
"""
clusterId = 1
nPoints = data.shape[1]
clusterResult = [UNCLASSIFIED] * nPoints
for pointId in range(nPoints):
point = data[:, pointId]
if clusterResult[pointId] == UNCLASSIFIED:
if expand_cluster(data, clusterResult, pointId, clusterId, eps, minPts):
clusterId = clusterId + 1
return clusterResult, clusterId - 1

def plotFeature(data, clusters, clusterNum):
nPoints = data.shape[1]
matClusters = np.mat(clusters).transpose()
fig = plt.figure()
scatterColors = ['black', 'blue', 'green', 'yellow', 'red', 'purple', 'orange', 'brown']
ax = fig.add_subplot(111)
for i in range(clusterNum + 1):
colorSytle = scatterColors[i % len(scatterColors)]
subCluster = data[:, np.nonzero(matClusters[:, 0].A == i)]
ax.scatter(subCluster[0, :].flatten().A[0], subCluster[1, :].flatten().A[0], c=colorSytle, s=50)
def main():
dataSet = loadDataSet('788points.txt', splitChar=',')
dataSet = np.mat(dataSet).transpose()
# print(dataSet)
clusters, clusterNum = dbscan(dataSet, 2, 3)
print("cluster Numbers = ", clusterNum)
# print(clusters)
count=0 # Modified_用於將結果輸出到文件
m=open('788points.txt').read().splitlines() # Modified_用於將結果輸出到文件
out=open('788points_DBSCAN.txt','w') # Modified_用於將結果輸出到文件
for n in m: # Modified_用於將結果輸出到文件
out.write(n+',{0}\n'.format(clusters[count]))
count+=1
out.close() # Modified_用於將結果輸出到文件
plotFeature(dataSet, clusters, clusterNum)
if name == 'main':
start = time.process_time() # Modified_將time.clock()替換為time.process_time()
main()
end = time.process_time() # Modified_將time.clock()替換為time.process_time()
print('finish all in %s' % str(end - start))
plt.show()

運行結果及報錯內容

③下面是我用這個代碼運行出來的結果:因為前面提到的不知道怎麼把日期型改成數值型,我把時間改成了123456...不知道對不對。(調了很久那兩個參數),我感覺下面的點應該都是黑色(噪聲點)才對,可是就是調不出這種效果來該怎麼辦?

④還有一個問題就是這行代碼scatterColors = ['black', 'blue', 'green', 'yellow', 'red', 'purple', 'orange', 'brown'] dbscan是自動分類的(事先不知道分幾類),為什麼這裡可以提前指定分8類顏色呢?

我的解答思路和嘗試過的方法
我想要達到的結果

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved