Python数据分析实战之用户模式识别
实战项目利用防窃漏电模型,通过采集电量异常、负荷异常、终端报警、主站报警、线损异常等信息,建立数据分析模型 构建基于指标加权的用电异常分析模型,实现检查客户是否存在违章用电情况。
利用拉格朗日插值对空白数据进行填补
自定义函数利用scipy中自带的拉格朗日插值函数对空白数据进行填补,主要是取前后5个数进行插值填补。
def data_make(): #对数据进行预处理 利用拉格朗日插值法
inputdata = "G:\\机器学习\\python_data_analysis_and_mining_action-master\\chapter6\\data\\missing_data.xls"
outputdata = "G:\\机器学习\\python_data_analysis_and_mining_action-master\\chapter6\\tmp\\data_processed.xls"
data = pd.read_excel(inputdata,header=None)
#自定义列向量插值函数
#s为列向量,n为被插值的对象,k为前后的数据个数
def interpolate(s,n,k=5):
y = s[list(range(n-k,n))+list(range(n+1,n+1+k))]
y = y[y.notnull()] #剔除空值
return lagrange(y.index,list(y))(n) #插值并返回插值结果
for i in data.columns:
for j in range(len(data)):
if(data[i].isnull())[j]:
data[i][j] = interpolate(data[i],j)
data.to_excel(outputdata,header=None,index=False) #输入的结果保存在输出路径中
编写混淆矩阵
def cm_plot(y, yp):
cm = confusion_matrix(y, yp)
plt.matshow(cm, cmap=plt.cm.Greens)
plt.colorbar()
for x in range(len(cm)):
for y in range(len(cm)):
plt.annotate(
cm[x, y],
xy=(x, y),
horizontalalignment='center',
verticalalignment='center')
plt.ylabel('True label')
plt.xlabel('Predicted label')
return plt
利用神经网络算法进行模型训练和预测
利用LM算法对数据进行模型训练,之后在进行预测,画出ROC曲线。
def LM(train_data,test_data):
netfile = "net.model"#构建神经网络模型存储路径
net = Sequential() #建立神经网络
net.add(Dense(10, input_shape=(3, ))) #输入层3,隐藏层10
net.add(Activation('relu')) #隐藏层使用relu函数 准确率比较高
net.add(Dense(1, input_shape=(10, )))
net.add(Activation('sigmoid')) #使用sigmoid激活函数
net.compile(loss='binary_crossentropy',
optimizer='adam',
sample_weight_mode="binary") #编译模型,使用adam函数求解
net.fit(train_data[:,:3],train_data[:,3],nb_epoch=1000,batch_size=1) #训练模型,迭代1000次
net.save_weights(netfile) #保存模型
#在keras中predict是给出概率,而predict_classes只是给出预测的类别,还是n*1的所以需要reshape
predict_result = net.predict_classes(train_data[:,:3]).reshape(len(train_data))
cm_plot(train_data[:, 3], predict_result).show() #导入自行编写的混淆矩阵可视化函数显示
predict_result = net.predict(test_data[:, :3]).reshape(len(test_data)) #预测概率
fpr, tpr, thresholds = roc_curve(test_data[:, 3], predict_result, pos_label=1)
plt.plot(fpr, tpr, linewidth=2, label='ROC of LM')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.ylim(0, 1.05)
plt.xlim(0, 1.05)
plt.legend(loc=4)
plt.show()
print(thresholds)
主函数
传入处理好的数据,并对数据进行打乱,分成训练数据和测试数据。
if __name__ == '__main__':
data_make()
datafile = "G:\\机器学习\\python_data_analysis_and_mining_action-master\\chapter6\\data\\model.xls"
data = pd.read_excel(datafile)
data = data.as_matrix()#将表格转换为矩阵
shuffle(data)#随机打乱数据
p = 0.8
train_data = data[:int(len(data)*p)]
test_data = data[int(len(data)*p):,:]
LM(train_data,test_data)
总代码如下:
import pandas as pd
from random import shuffle#导入随机函数shuffle,用来打乱数据顺序
from keras.models import Sequential#导入神经网络初始化函数
from keras.layers.core import Dense,Activation
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix, roc_curve
from scipy.interpolate import lagrange#导入拉格朗日插值法
def data_make(): #对数据进行预处理 利用拉格朗日插值法
inputdata = "G:\\机器学习\\python_data_analysis_and_mining_action-master\\chapter6\\data\\missing_data.xls"
outputdata = "G:\\机器学习\\python_data_analysis_and_mining_action-master\\chapter6\\tmp\\data_processed.xls"
data = pd.read_excel(inputdata,header=None)
#自定义列向量插值函数
#s为列向量,n为被插值的对象,k为前后的数据个数
def interpolate(s,n,k=5):
y = s[list(range(n-k,n))+list(range(n+1,n+1+k))]
y = y[y.notnull()] #剔除空值
return lagrange(y.index,list(y))(n) #插值并返回插值结果
for i in data.columns:
for j in range(len(data)):
if(data[i].isnull())[j]:
data[i][j] = interpolate(data[i],j)
data.to_excel(outputdata,header=None,index=False) #输入的结果保存在输出路径中
def cm_plot(y, yp):
cm = confusion_matrix(y, yp)
plt.matshow(cm, cmap=plt.cm.Greens)
plt.colorbar()
for x in range(len(cm)):
for y in range(len(cm)):
plt.annotate(
cm[x, y],
xy=(x, y),
horizontalalignment='center',
verticalalignment='center')
plt.ylabel('True label')
plt.xlabel('Predicted label')
return plt
def LM(train_data,test_data):
netfile = "net.model"#构建神经网络模型存储路径
net = Sequential() #建立神经网络
net.add(Dense(10, input_shape=(3, ))) #输入层3,隐藏层10
net.add(Activation('relu')) #隐藏层使用relu函数 准确率比较高
net.add(Dense(1, input_shape=(10, )))
net.add(Activation('sigmoid')) #使用sigmoid激活函数
net.compile(loss='binary_crossentropy',
optimizer='adam',
sample_weight_mode="binary") #编译模型,使用adam函数求解
net.fit(train_data[:,:3],train_data[:,3],nb_epoch=1000,batch_size=1) #训练模型,迭代1000次
net.save_weights(netfile) #保存模型
#在keras中predict是给出概率,而predict_classes只是给出预测的类别,还是n*1的所以需要reshape
predict_result = net.predict_classes(train_data[:,:3]).reshape(len(train_data))
cm_plot(train_data[:, 3], predict_result).show() #导入自行编写的混淆矩阵可视化函数显示
predict_result = net.predict(test_data[:, :3]).reshape(len(test_data)) #预测概率
fpr, tpr, thresholds = roc_curve(test_data[:, 3], predict_result, pos_label=1)
plt.plot(fpr, tpr, linewidth=2, label='ROC of LM')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.ylim(0, 1.05)
plt.xlim(0, 1.05)
plt.legend(loc=4)
plt.show()
print(thresholds)
if __name__ == '__main__':
data_make()
datafile = "G:\\机器学习\\python_data_analysis_and_mining_action-master\\chapter6\\data\\model.xls"
data = pd.read_excel(datafile)
data = data.as_matrix()#将表格转换为矩阵
shuffle(data)#随机打乱数据
p = 0.8
train_data = data[:int(len(data)*p)]
test_data = data[int(len(data)*p):,:]
LM(train_data,test_data)
LM预测结果
混淆矩阵:
由此可见LM算法的准确率。
Roc曲线: