import pandas as pd
import matplotlib.pyplot as plt
import numpy as np #数值计算库
data = pd.read_excel(r'C:\Users\隋舒婷\Desktop\16-17一年内的数据预处理之后一开始的.xlsx')
def localoutlierfactor(data, predict, k):
#输入:训练样本,测试样本, k 值;输出:每一个测试样本 LOF 值及对应的第 k 距离
from sklearn.neighbors import LocalOutlierFactor
clf = LocalOutlierFactor(n_neighbors=k + 1, algorithm='auto', contamination=0.1, n_jobs=-1)
#n_neighbors = 20:即上文提及的 k ,检测的邻域点个数超过样本数则使用所有的样本进行检测
#algorithm = 'auto':使用的求解算法,使用默认值即可
#contamination = 0.1:范围为 (0, 0.5),表示样本中的异常点比例,默认为 0.1
#n_jobs = -1:并行任务数,设置为-1表示使用所有CPU进行工作
clf.fit(data)
#无监督学习,只需要传入训练数据data,传入的数据维度至少是 2 维
# 记录 k 邻域距离
predict['k distances'] = clf.kneighbors(predict)[0].max(axis=1)
#获取第 k 距离邻域内的每一个点到中心点的距离,并按从小到大排序
# 记录 LOF 离群因子,做相反数处理
predict['local outlier factor'] = -clf._decision_function(predict.iloc[:, :-1])
return predict
#clf._decision_function 的输出方式更为灵活:若使用 clf._predict(data) 函数,则按照原先设置的 contamination 输出判断结果(按比例给出判断结果,异常点返回-1,非异常点返回1)
def plot_lof(result, method):
#输入:LOF值、阈值 输出:以索引为横坐标的LOF值分布图
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.figure(figsize=(8, 4)).add_subplot(111)
plt.scatter(result[result['local outlier factor'] > method].index,
result[result['local outlier factor'] > method]['local outlier factor'], c='red', s=50,
marker='.', alpha=None,
label='离群点')
plt.scatter(result[result['local outlier factor'] <= method].index,
result[result['local outlier factor'] <= method]['local outlier factor'], c='black', s=50,
marker='.', alpha=None, label='正常点')
plt.hlines(method, -2, 2 + max(result.index), linestyles='--')
plt.xlim(-2, 2 + max(result.index))
plt.title('LOF局部离群点检测', fontsize=13)
plt.ylabel('局部离群因子', fontsize=15)
plt.legend()
plt.show()
def lof(data, predict=None, k=20, method=0.1958, plot=False):
#输入:训练样本,测试样本, k值,离群阈值,是否绘制LOF图
#输出:离群点、正常点分类情况
#没有输入测试样本时,默认测试样本 = 训练样本
import pandas as pd
# 判断是否传入测试数据,若没有传入则测试数据赋值为训练数据
try:
if predict == None:
predict = data.copy()
except Exception:
pass
predict = pd.DataFrame(predict)
# 计算 LOF 离群因子
predict = localoutlierfactor(data, predict, k)
if plot == True:
plot_lof(predict, method)
# 根据阈值划分离群点与正常点
outliers = predict[predict['local outlier factor'] > method].sort_values(by='local outlier factor')
inliers = predict[predict['local outlier factor'] <= method].sort_values(by='local outlier factor')
return outliers, inliers
posi = pd.read_excel(r'C:\Users\隋舒婷\Desktop\16-17一年内的数据预处理之后一开始的.xlsx')
lon = np.array(posi["风速v-win"][:]) # 经度
lat = np.array(posi["p_ACT"][:]) # 纬度
A = list(zip(lat, lon)) # 按照纬度-经度匹配
# 获取p_ACT任务密度,取第5邻域,阈值为2(LOF大于2认为是离群值)
outliers1, inliers1 = lof(A, k=20, method=0.00001)
print(22,outliers1)
print(22,inliers1)
pd.DataFrame(inliers1).to_excel(r'C:\Users\隋舒婷\Desktop\111.xlsx')
#
# for k in [3,5,10]:
# plt.figure('k=%d'%k)
# outliers1, inliers1 = lof(A, k=k, method = 2)
# plt.scatter(np.array(A)[:,0],np.array(A)[:,1],s = 10,c='b',alpha = 0.5)
# plt.scatter(outliers1[0],outliers1[1],s = 10+outliers1['local outlier factor']*100,c='r',alpha = 0.2)
# plt.title('k=%d' % k)
- 1
- 2
- 3
前往页