第6章:分类-窃电用户自动识别
目标
模型构建LM-NET和CART
数据划分
LM神经网络
cart决策树
模型评价ROC
第7章:聚类-航空公司客户价值分析
1RFM模型-传统
目标
1分析方法与过程-数据预处理
2构建kmeans模型(无代码:参考模型章节
第8章:关联规则-中医证型挖掘
目标:
过程
属性离散化
模型-关联规则有问题-
第9章:分类-基于水色图像的水质评价
Svm模型
第10章 :家用电器用户行为分析与时间识别
目标
过程
1数据抽取:无放回随机抽样法
2探索分析
3数据预处理
4构建专家样本:找资料进行合适的数据构造
模型
阈值寻优模型
用水事件的划分-阈值处理
洗浴识别模型-BP神经网络分类
模型检验-准确率
第11章 :时间序列-应用系统负载分析与容量预测
目标
分析
探索分析:周期性分析
数据预处理
容量预测模型
平稳性检验:
白噪声检验:
AIC定阶
模型检验
模型预测
模型评价与应用
第12章 :电子商务网站用户行为分析及服务推荐(基于协同过滤算法)
https://blog.csdn.net/u012063773/article/details/79324194
目的
数据探索
导入sql数据
网页类型统计
数据预处理
模型构建-具体参考链接网页
第13章 :预测-财政收入影响因素分析及预测模型
目标
数据探索分析
数据预处理
模型
变量选择模型lasso或者AdaptiveLasso
灰色预测与神经网络的组合模型
第14章 :层次聚类-基于基站定位数据的商圈分析
目标
探索分析
模型-层次聚类
1、 谱聚类
2层次聚类
第15章:电商产品评论数据情感分析代码详解目标
数据预处理
2文本去重
4结巴分词
模型-LDA
归纳出窃漏电用户的关键特征,构建窃漏电用户的识别模型;
利用实时监测数据,调用窃漏电用户识别模型实现实时诊断。
先按照前面的几章节处理数据
import pandas as pd
from random import shuffle
datafile = '../data/model.xls'
data = pd.read_excel(datafile)
data = data.as_matrix()
shuffle(data)
p = 0.8 #设置训练数据比例
train = data[:int(len(data)*p),:]
test = data[int(len(data)*p):,:]
from keras.models import Sequential #导入神经网络初始化函数
from keras.layers.core import Dense, Activation #导入神经网络层函数、激活函数
net = Sequential() #建立神经网络
net.add(Dense(10,input_dim=3)) #添加输入层(3节点)到隐藏层(10节点)的连接
net.add(Activation('relu')) #隐藏层使用relu激活函数
net.add(Dense(1,input_dim=10)) #添加隐藏层(10节点)到输出层(1节点)的连接
net.add(Activation('sigmoid')) #输出层使用sigmoid激活函数
net.compile(loss = 'binary_crossentropy', optimizer = 'adam') #, class_mode = "binary"编译模型,使用adam方法求解
net.fit(train[:,:3], train[:,3], epochs=1000, batch_size=1) #训练模型,循环1000次
netfile = '../tmp/net1.model' #构建的神经网络模型存储路径
net.save_weights(netfile) #保存模型
predict_result = net.predict_classes(train[:,:3]).reshape(len(train)) #预测结果变形
'''这里要提醒的是,keras用predict给出预测概率,predict_classes才是给出预测类别,而且两者的预测结果都是n x 1维数组,而不是通常的 1 x n'''
from cm_plot import * #导入自行编写的混淆矩阵可视化函数
cm_plot(train[:,3], predict_result).show() #显示混淆矩阵可视化结果
#构建CART决策树模型
from sklearn.tree import DecisionTreeClassifier #导入决策树模型
tree = DecisionTreeClassifier() #建立决策树模型
tree.fit(train[:,:3], train[:,3]) #训练
#保存模型
from sklearn.externals import joblib
joblib.dump(tree, '../tmp/tree.pkl')#模型持久化的操作,导入joblib即
predict_result=tree.predict(train[:,:3])#注意到Scikit-Learn使用predict方法直接给出预测结果。
from sklearn.metrics import roc_curve #导入ROC曲线函数
fpr, tpr, thresholds = roc_curve(test[:,3], predict_result, pos_label=1)
plt.plot(fpr, tpr, linewidth=2, label = 'ROC of CART', color = 'green') #作出ROC曲线
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() #显示作图结果
广泛用于分析客户价值的是RFM模型,它是通过三个指标(最近消费时间间隔(Recency)、消费频率(Frequency)、消费金额(Monetary))来进行客户细分,识别出高价值的客户。
借助航空公司客户数据,对客户进行分类;
对不同的客户类别进行特征分析,比较不同类客户的客户价值;
对不同价值的客户类别提供个性化服务,制定相应的营销策略。
初步分析:提出适用航空公司的LRFMC模型
因消费金额指标在航空公司中不适用,故选择客户在一定时间内累积的飞行里程M和客户乘坐舱位折扣系数的平均值C两个指标代替消费金额。此外,考虑航空公司会员加入时间在一定程度上能够影响客户价值,所以在模型中增加客户关系长度L,作为区分客户的另一指标,因此构建出LRFMC模型。
采用聚类的方法对客户进行细分,并分析每个客户群的特征,识别其客户价值。
1数据探索describe(代码省略)
2数据清洗:选取需要的特征
#选择需要的数据
data = data[data['SUM_YR_1'].notnull()&data['SUM_YR_2'].notnull()] #丢弃票价为空的记录
#丢弃票价为零,或者平均折扣率与总飞行公里数不0的记录。
index1 = data['SUM_YR_1'] != 0#只保留票价非零的,或者平均折扣率与总飞行公里数同时为0的记录。
index2 = data['SUM_YR_2'] != 0
index3 = (data['SEG_KM_SUM'] == 0) & (data['avg_discount'] == 0) #该规则是“与”
data = data[index1 | index2 | index3] #该规则是“或”
3属性规约:原始数据中属性太多,根据LRFMC模型,选择与其相关的六个属性,删除不相关、弱相关或冗余的属性。
4、数据变换
(1)属性构造
L = LOAD_TIME - FFP_DATE
会员入会时间距观测窗口结束的月数 = 观测窗口的结束时间 - 入会时间[单位:月
R = LAST_TO_END
客户最近一次乘坐公司飞机距观测窗口结束的月数 = 最后一次乘机时间至观察窗口末端时长[单位:月]
F = FLIGHT_COUNT
客户在观测窗口内乘坐公司飞机的次数 = 观测窗口的飞行次数[单位:次]
M = SEG_KM_SUM
客户在观测时间内在公司累计的飞行里程 = 观测窗口总飞行公里数[单位:公里]
C = AVG_DISCOUNT
客户在观测时间内乘坐舱位所对应的折扣系数的平均值 = 平均折扣率[单位:无]
(2)数据标准化
客户K-Means聚类-客户价值分析-模型应用
借助三阴乳腺癌患者的病理信息,挖掘患者的症状与中医证型之间的关联关系;
对截断治疗提供依据,挖掘潜性证素。
数据收集-数据清洗-
数据规约:删除不相关属性,选取其中六种证型得分、患者编号和TNM分期属性。
数据变换:
(1)属性构造:为了更好的反应出中医证素分布的特征,采用证型系数代替具体单证型的证素得分,证型相关系数计算公式如下:证型系数 = 该证型得分/该证型总分
Aprior关联规则无法处理连续型变量,需要聚类进行离散化处理
#-*- coding: utf-8 -*-
'''
聚类离散化,最后的result的格式为:
1 2 3 4
A 0 0.178698 0.257724 0.351843
An 240 356.000000 281.000000 53.000000
即(0, 0.178698]有240个,(0.178698, 0.257724]有356个,依此类推。
'''
import pandas as pd
from sklearn.cluster import KMeans #导入K均值聚类算法
datafile = '../data/data.xls' #待聚类的数据文件
processedfile = '../tmp/data_processed.xls' #数据处理后文件
typelabel ={u'肝气郁结证型系数':'A', u'热毒蕴结证型系数':'B', u'冲任失调证型系数':'C', u'气血两虚证型系数':'D', u'脾胃虚弱证型系数':'E', u'肝肾阴虚证型系数':'F'}
k = 4 #需要进行的聚类类别数
#读取数据并进行聚类分析
data = pd.read_excel(datafile) #读取数据
keys = list(typelabel.keys())#标题6个类别变成列表
result = pd.DataFrame()
if __name__ == '__main__': #判断是否主窗口运行,如果是将代码保存为.py后运行,则需要这句,如果直接复制到命令窗口运行,则不需要这句。
for i in range(len(keys)):
#调用k-means算法,进行聚类离散化
print(u'正在进行“%s”的聚类...' % keys[i])
kmodel = KMeans(n_clusters = k, n_jobs = 4) #n_jobs是并行数,一般等于CPU数较好
kmodel.fit(data[[keys[i]]].as_matrix()) #训练模型
r1 = pd.DataFrame(kmodel.cluster_centers_, columns = [typelabel[keys[i]]]) #聚类中心
r2 = pd.Series(kmodel.labels_).value_counts() #分类统计
r2 = pd.DataFrame(r2, columns = [typelabel[keys[i]]+'n']) #转为DataFrame,记录各个类别的数目
r = pd.concat([r1, r2], axis = 1).sort(typelabel[keys[i]]) #匹配聚类中心和类别数目
r.index = [1, 2, 3, 4]
r[typelabel[keys[i]]] = pd.rolling_mean(r[typelabel[keys[i]]], 2) #rolling_mean()用来计算相邻2列的均值,以此作为边界点。
r[typelabel[keys[i]]][1] = 0.0 #这两句代码将原来的聚类中心改为边界点。
result = result.append(r.T)
result = result.sort() #以Index排序,即以A,B,C,D,E,F顺序排
result.to_excel(processedfile)
#-*- coding: utf-8 -*-
from __future__ import print_function
import pandas as pd
from apriori import * #导入自行编写的apriori函数
import time #导入时间库用来计算用时
inputfile = '../data/apriori.txt' #输入事务集文件
data = pd.read_csv(inputfile, header=None, dtype = object)
start = time.clock() #计时开始
print(u'\n转换原始数据至0-1矩阵...')
ct = lambda x : pd .Series(1, index = x[pd.notnull(x)]) #转换0-1矩阵的过渡函数
b = map(ct, data.as_matrix()) #用map方式执行
data = pd.DataFrame(b).fillna(0) #实现矩阵转换,空值用0填充
end = time.clock() #计时结束
print(u'\n转换完毕,用时:%0.2f秒' %(end-start))
del b #删除中间变量b,节省内存
support = 0.06 #最小支持度
confidence = 0.75 #最小置信度
ms = '---' #连接符,默认'--',用来区分不同元素,如A--B。需要保证原始表格中不含有该字符
start = time.clock() #计时开始
print(u'\n开始搜索关联规则...')
find_rule(data, support, confidence, ms)
end = time.clock() #计时结束
print(u'\n搜索完成,用时:%0.2f秒' %(end-start))
图像特征:颜色,纹理,形状,空间,颜色有鲁棒性,本案例水色图样均匀看颜色
颜色特征:颜色直方图法、颜色矩
图像切割
特征提取:三阶分别表示:明暗,颜色分布范围,分布的对称性
构建模型:LM水质评价分类模型
#-*- coding: utf-8 -*-
import pandas as pd
inputfile = '../data/moment.csv' #数据文件
outputfile1 = '../tmp/cm_train.xls' #训练样本混淆矩阵保存路径
outputfile2 = '../tmp/cm_test.xls' #测试样本混淆矩阵保存路径
data = pd.read_csv(inputfile, encoding = 'gbk') #读取数据,指定编码为gbk
data = data.as_matrix()
from numpy.random import shuffle #引入随机函数
shuffle(data) #随机打乱数据
data_train = data[:int(0.8*len(data)), :] #选取前80%为训练数据
data_test = data[int(0.8*len(data)):, :] #选取前20%为测试数据
#构造特征和标签
x_train = data_train[:, 2:]*30
y_train = data_train[:, 0].astype(int)
x_test = data_test[:, 2:]*30
y_test = data_test[:, 0].astype(int)
#导入模型相关的函数,建立并且训练模型
from sklearn import svm
model = svm.SVC()
model.fit(x_train, y_train)
import pickle
pickle.dump(model, open('../tmp/svm.model', 'wb'))
#最后一句保存模型,以后可以通过下面语句重新加载模型:
#model = pickle.load(open('../tmp/svm.model', 'rb'))
#导入输出相关的库,生成混淆矩阵
from sklearn import metrics
cm_train = metrics.confusion_matrix(y_train, model.predict(x_train)) #训练样本的混淆矩阵
cm_test = metrics.confusion_matrix(y_test, model.predict(x_test)) #测试样本的混淆矩阵
#保存结果
pd.DataFrame(cm_train, index = range(1, 6), columns = range(1, 6)).to_excel(outputfile1)
pd.DataFrame(cm_test, index = range(1, 6), columns = range(1, 6)).to_excel(outputfile2)
根据热水器采集到的数据,划分一次完整用水事件;
在划分好的一次完整用水事件中,识别出洗浴事件。
为了探究用户真实用水停顿时间间隔的分布情况,统计用水停顿的时间间隔并作频率分布直方图。
停顿时间间隔为0~0.3分钟的频率很高,根据日常用水经验可以判断其为一次用水时间中的停顿;停顿时间间隔为6~13分钟的频率较低,分析其为两次用水事件之间的停顿间隔。两次用水事件的停顿时间间隔分布在3~7分钟与现场实验统计用水停顿的时间间隔近似。
数据规约
1数据规约
属性规约:因“热水器编号”、“即热”、“即时洗” 、“有无水流” 、“预约洗”、 “节能模式”对建模无作用,可以去除。
数值规约:当热水器“开关机状态”为“关”且水流量为0时,说明热水器不处于工作状态,数据记录可以规约掉。
2数据变换
1)一次完整用水事件的划分:不用水时间>阈值,就是停止用水,不是暂时停止
2)用水事件阈值寻优:根据水流量和停顿时间间隔的阈值划分一次完整的用水事件。
3)属性构造:根据用水行为,需构造四类指标:时长指标、频率指标、用水的量化指标以及用水的波动指标。
4)候选洗浴事件:体积和(总)用水时长<某个值不算
现实中:经过实验分析,热水器设定温度为50摄氏度时,一次普通的洗浴时长为15分钟,总用水时长10分钟左右,热水的使用量为10~15升。
3 缺失值处理
结合实际问题添加:因存在网络故障等原因,导致用水数据状态记录缺失的情况,需要对缺失的数据状态记录进行添加。其添加方法:用水状态记录缺失的情况下,填充一条状态记录使水流量为0,发生时间加2秒,其余属性状态不变。
#阈值寻优模型
import numpy as np
import pandas as pd
inputfile = '../data/water_heater.xls' #输入数据路径,需要使用Excel格式
threshold = pd.Timedelta(minutes = 5) #专家阈值
data = pd.read_excel(inputfile)
data[u'发生时间'] = pd.to_datetime(data[u'发生时间'], format = '%Y%m%d%H%M%S')
data = data[data[u'水流量'] > 0] #只要流量大于0的记录
#计算时间在某个阈值的数目
def event_num(ts):
d = data[u'发生时间'].diff() > ts #相邻时间作差分,比较是否大于阈值
return d.sum() + 1 #这样直接返回事件数
dt = [pd.Timedelta(minutes = i) for i in np.arange(1, 9, 0.25)]#list,1-9分钟,每一刻一次[Timedelta('0 days 00:01:00'), Timedelta('0 days 00:01:15'),
h = pd.DataFrame(dt, columns = [u'阈值']) #定义阈值列,
h[u'事件数'] = h[u'阈值'].apply(event_num) #计算每个阈值对应的事件数
h[u'斜率'] = h[u'事件数'].diff()/0.25 #计算每两个相邻点对应的斜率
n=4#获取比较平缓的时间,斜率,找斜率指标最小
h[u'斜率指标'] = pd.rolling_mean(h[u'斜率'].abs(),n) #采用后n个的斜率绝对值平均作为斜率指标
ts = h[u'阈值'][h[u'斜率指标'].idxmin() - n]
#注:用idxmin返回最小值的Index,由于rolling_mean()自动计算的是前n个斜率的绝对值平均,所以结果要进行平移(-n)
if ts > threshold:
ts = pd.Timedelta(minutes = 4)#小于5,经过专家验证
print(ts)
#用水事件划分
import pandas as pd
threshold = pd.Timedelta('4 min') #阈值为分钟Timedelta
inputfile = '../data/water_heater.xls' #输入数据路径,需要使用Excel格式
outputfile = '../tmp/dividsequence.xls' #输出数据路径,需要使用Excel格式
data = pd.read_excel(inputfile)
data[u'发生时间'] = pd.to_datetime(data[u'发生时间'], format = '%Y%m%d%H%M%S')#to_datetime
data = data[data[u'水流量'] > 0] #只要流量大于0的记录
d = data[u'发生时间'].diff() > threshold #相邻时间作差分,比较是否大于阈值
data[u'事件编号'] = d.cumsum() + 1 #通过累积求和的方式为事件编号,true一次就+1
data.to_excel(outputfile)
#建立、训练多层神经网络,并完成模型的检验
import pandas as pd
inputfile1='../data/train_neural_network_data.xls' #训练数据
inputfile2='../data/test_neural_network_data.xls' #测试数据
testoutputfile = '../tmp/test_output_data1.xls' #测试数据模型输出文件
data_train = pd.read_excel(inputfile1) #读入训练数据(由日志标记事件是否为洗浴)
data_test = pd.read_excel(inputfile2) #读入测试数据(由日志标记事件是否为洗浴)
y_train = data_train.iloc[:,4].as_matrix() #训练样本标签列
x_train = data_train.iloc[:,5:17].as_matrix() #训练样本特征
y_test = data_test.iloc[:,4].as_matrix() #测试样本标签列
x_test = data_test.iloc[:,5:17].as_matrix() #测试样本特征
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
model = Sequential() #建立模型
model.add(Dense(17,input_dim=11)) #添加输入层、隐藏层的连接
model.add(Activation('relu')) #以Relu函数为激活函数
model.add(Dense(10,input_dim=17)) #添加隐藏层、隐藏层的连接
model.add(Activation('relu')) #以Relu函数为激活函数
model.add(Dense(1,input_dim=10)) #添加隐藏层、输出层的连接
model.add(Activation('sigmoid')) #以sigmoid函数为激活函数
#编译模型,损失函数为binary_crossentropy,用adam法求解
model.compile(loss='binary_crossentropy', optimizer='adam', class_mode="binary") #, class_mode="binary"去掉不知道行不行
model.fit(x_train, y_train, epochs = 100, batch_size = 1) #训练模型
model.save_weights('../tmp/net.model') #保存模型参数
#model.load_weights('../tmp/net.model')
r = pd.DataFrame(model.predict_classes(x_test), columns = [u'预测结果'])
pd.concat([data_test.iloc[:,:5], r], axis = 1).to_excel(testoutputfile)
model.predict(x_test)
针对历史磁盘数据,采用数据挖掘的方法,预测应用系统服务器磁盘已使用空间大小;
根据用户需求设置不同的预警等级,将预测值与容量值进行比较,对其结果进行预警判断,为系统管理员提供定制化的预警提示;
在不考虑人为因素的影响时,存储空间随时间变化存在很强的关联性,且历史数据对未来的发展存在一定的影响,故可采用时间序列分析法对磁盘已使用空间进行预测分析。
对数据进行周期性分析,探索数据的平稳性
import pandas as pd
datafile = '../data/discdata.xls'
data = pd.read_excel(datafile)
data1 = data[(data['ENTITY'] == 'C:\\') & (data['TARGET_ID'] == 184)]
import datetime
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(2, 1, 1)
ax.set_title(u'C盘空间')
ax.set(xlabel=u'时间', ylabel=u'C磁盘空间')
# 图上时间间隔显示为10天
ax.xaxis.set_major_locator(mdates.DayLocator(bymonthday=range(1, 32), interval=10))
ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m-%d"))
plt.rc('figure', figsize=(9, 7))
plt.subplots_adjust(bottom=0.13, top=0.95)
ax.plot(data1['COLLECTTIME'], data1['VALUE'], 'ro-', )
fig.autofmt_xdate() # 自动根据标签长度进行旋转
'''''for label in ax.xaxis.get_ticklabels(): #此语句完成功能同上
label.set_rotation(45)
'''
plt.savefig('c.jpg')
plt.show()
1数据清洗
实际业务中,监控系统会每天定时对磁盘的信息进行收集,但是磁盘容量属性一般情况下都是一个定值(不考虑中途扩容的情况),因此磁盘原始数据中会存在磁盘容量的重复数据。
剔除磁盘容量的重复数据。
将所有服务器的磁盘容量作为一个固定值,方便模型预警时需要。
data.drop_duplicates(data.columns[:-1],inplace=True)
属性构造:因每台服务器的磁盘信息可以通过表中NAME,TARGET_ID,ENTITY三个属性进行区分,且每台服务器的上述三个属性值是不变的,所以可以将三个属性的值进行合并。 (实质是将行转换成列)
#属性变换
#参数初始化
data = data[data['TARGET_ID'] == 184].copy() #只保留TARGET_ID为184的数据
data_group = data.groupby('COLLECTTIME') #以时间分组
def attr_trans(x): #定义属性变换函数
result = pd.Series(index = ['SYS_NAME', 'CWXT_DB:184:C:\\', 'CWXT_DB:184:D:\\', 'COLLECTTIME'])
result['SYS_NAME'] = x['SYS_NAME'].iloc[0]
result['COLLECTTIME'] = x['COLLECTTIME'].iloc[0]
result['CWXT_DB:184:C:\\'] = x['VALUE'].iloc[0]
result['CWXT_DB:184:D:\\'] = x['VALUE'].iloc[1]
return result
data_processed = data_group.apply(attr_trans) #逐组处理
data_processed.to_excel(transformeddata, index = False)
模型流程图
为了确定原始数据序列中没有随机趋势或趋势,需要对数据进行平稳性检验,否则将会产生“伪回归”的现象。方法:单位跟检验或者观察时序图。
#-*- coding: utf-8 -*-
#平稳性检验
import pandas as pd
#参数初始化
discfile = '../data/discdata_processed.xls'
predictnum =5 #不使用最后5个数据
data = pd.read_excel(discfile)
data = data.iloc[: len(data)-5] #不检测最后5个数据
#平稳性检测
from statsmodels.tsa.stattools import adfuller as ADF
diff = 0
adf = ADF(data['CWXT_DB:184:D:\\'])
while adf[1] > 0.05:
diff = diff + 1
adf = ADF(data['CWXT_DB:184:D:\\'].diff(diff).dropna())
print(u'原始序列经过%s阶差分后归于平稳,p值为%s' %(diff, adf[1]))
为了验证序列中有用的信息是否已被提取完毕,需要对序列进行白噪声检验。如果序列检验为白噪声序列,就说明序列中有用的信息已经被提取完毕了,剩下的全是随机扰动,无法进行预测和使用。方法:一般采用LB统计量检验方法。
白噪声过程:对对于一个纯随机过程来说,其期望为0,方差为常数
#参数初始化
discfile = '../data/discdata_processed.xls'
data = pd.read_excel(discfile)
data = data.iloc[: len(data)-5] #不使用最后5个数据
#白噪声检测
from statsmodels.stats.diagnostic import acorr_ljungbox
[[lb], [p]] = acorr_ljungbox(data['CWXT_DB:184:D:\\'], lags = 1)
if p < 0.05:print(u'原始序列为非白噪声序列,对应的p值为:%s' %p)
else:print(u'原始该序列为白噪声序列,对应的p值为:%s' %p)
[[lb], [p]] = acorr_ljungbox(data['CWXT_DB:184:D:\\'].diff().dropna(), lags = 1)
if p < 0.05: print(u'一阶差分序列为非白噪声序列,对应的p值为:%s' %p)
else: print(u'一阶差分该序列为白噪声序列,对应的p值为:%s' %p)
通过AIC、BIC信息准则或者观测自相关图和偏自相关图确定P、Q的参数,识别其模型属于AR、MA和ARMA中的哪一种模型。
AIC信息准则即Akaike information criterion,是衡量统计模型拟合优良性的一种标准,所以优先考虑的模型应是AIC值最小的那一个,
参数估计:估计模型的其他参数。可以采用极大似然估计、条件最小二乘法确定。
#-*- coding: utf-8 -*-
#确定最佳p、d、q值
import pandas as pd
#参数初始化
discfile = '../data/discdata_processed.xls'
data = pd.read_excel(discfile, index_col = 'COLLECTTIME')
xdata = data['CWXT_DB:184:D:\\']
from statsmodels.tsa.arima_model import ARIMA
#定阶
pmax = int(len(xdata)/10) #一般阶数不超过length/10
qmax = int(len(xdata)/10) #一般阶数不超过length/10
bic_matrix = [] #bic矩阵
for p in range(pmax+1):
tmp = []
for q in range(qmax+1):
try: #存在部分报错,所以用try来跳过报错。
tmp.append(ARIMA(xdata, (p,1,q)).fit().bic)
#tmp.append(ARMA(xdata2, (p,q)).fit().aic) # AIC方式
#tmp.append(ARMA(xdata2, (p,q)).fit().hq) # HQ方式
except:
tmp.append(None)
bic_matrix.append(tmp)
bic_matrix = pd.DataFrame(bic_matrix) #从中可以找出最小值
p,q = bic_matrix.stack().idxmin() #先用stack展平,然后用idxmin找出最小值位置。
print(u'BIC最小的p值和q值为:%s、%s' %(p,q))
#BIC最小的p值和q值为:0、2
确定模型后,需要检验其残差序列是否是白噪声,若不是,说明,残差中还存在有用的信息,需要修改模型或者进一步提取。若其残差不是白噪声,重新更换p,q的值,重新确定
#模型检验
import pandas as pd
#参数初始化
discfile = '../data/discdata_processed.xls'
lagnum = 12 #残差延迟个数
data = pd.read_excel(discfile, index_col = 'COLLECTTIME')
data = data.iloc[: len(data)-5] #不使用最后5个数据
xdata = data['CWXT_DB:184:D:\\']
from statsmodels.tsa.arima_model import ARIMA #建立ARIMA(0,1,1)模型
arima = ARIMA(xdata, (0, 1, 1)).fit() #建立并训练模型
xdata_pred = arima.predict(typ = 'levels') #预测
pred_error = (xdata_pred - xdata).dropna() #计算残差
from statsmodels.stats.diagnostic import acorr_ljungbox #白噪声检验
lb, p= acorr_ljungbox(pred_error, lags = lagnum)
h = (p < 0.05).sum() #p值小于0.05,认为是非白噪声。
if h > 0:print(u'模型ARIMA(0,1,1)不符合白噪声检验')
else:print(u'模型ARIMA(0,1,1)符合白噪声检验')
model = ARIMA(data, (p,1,q)).fit() #建立ARIMA(0, 1, 1)模型
model.summary2() #给出一份模型报告
model.forecast(5) #作为期5天的预测,返回预测结果、标准误差、置信区间。
file = '../data/predictdata.xls'
data = pd.read_excel(file)
#计算误差
abs_ = (data[u'预测值'] - data[u'实际值']).abs()
mae_ = abs_.mean() # mae
rmse_ = ((abs_**2).mean())**0.5 # rmse
mape_ = (abs_/data[u'实际值']).mean() # mape
print(u'平均绝对误差为:%0.4f,\n均方根误差为:%0.4f,\n平均绝对百分误差为:%0.6f。' %(mae_, rmse_, mape_))
应用:根据预测的使用率进行警报
了解用户行为以及网站关心内容
借助访问记录,发现访问习惯,进行推荐
import pandas as pd
from sqlalchemy import create_engine
engine = create_engine('mysql+pymysql://root:[email protected]:3306/test?charset=utf8')
sql = pd.read_sql('all_gzdata', engine, chunksize = 10000)
'''
用create_engine建立连接,连接地址的意思依次为“数据库格式(mysql)+程序名(pymysql)+账号密码@地址端口/数据库名(test)”,最后指定编码为utf8;
all_gzdata是表名,engine是连接数据的引擎,chunksize指定每次读取1万条记录。这时候sql是一个容器,未真正读取数据。
'''
counts = [ i['fullURLId'].value_counts() for i in sql] #逐块统计
counts = pd.concat(counts).groupby(level=0).sum() #level=0,合并统计结果,把相同的统计项合并(即按index分组并求和)
counts = counts.reset_index() #重新设置index,将原来的index作为counts的一列。
counts.columns = ['index', 'num'] #重新设置列名,主要是第二列,默认为0
counts['type'] = counts['index'].str.extract('(\d{3})') #提取前三个数字作为类别id
counts_ = counts[['type', 'num']].groupby('type').sum() #按类别合并
counts_['ratio']=counts_/counts_.sum() #增加比例列
counts_.sort('num', ascending = False) #降序排列
#统计其他类别的情况def counts_type(type):
counts_type=counts[counts['type']==type][['index', 'num']]
counts_type['ratio']=counts_type['num']/counts_type['num'].sum()
return counts_type.sort_values('num', ascending = False)
counts_type('102')
#统计107类别的情况
def count107(i): #自定义统计函数
j = i[['fullURL']][i['fullURLId'].str.contains('107')].copy() #找出类别包含107的网址
j['type'] = None #添加空列
j['type'][j['fullURL'].str.contains('info/.+?/')] = u'知识首页'
j['type'][j['fullURL'].str.contains('info/.+?/.+?')] = u'知识列表页'
j['type'][j['fullURL'].str.contains('/\d+?_*\d+?\.html')] = u'知识内容页'
return j['type'].value_counts()
counts2 = [count107(i) for i in sql] #逐块统计
counts2 = pd.concat(counts2).groupby(level=0).sum() #合并统计结果
#瞎逛统计,没有单击具体的页面(html结尾),他们单机的大部分是目录网页
sql = pd.read_sql('all_gzdata', engine, chunksize = 10000)
counts5 = [ i['fullURLId'][(i['fullURL'].str.contains('html'))==0].value_counts() for i in sql]#没有点击以html结尾的具体页面
counts5= pd.concat(counts5).groupby(level=0).sum()
counts5 = pd.DataFrame(counts5)
counts5['type'] = counts5.index.str.extract('(\d{3})') #提取前三个数字作为类别id
counts5_ = counts5[['type', 'fullURLId']].groupby('type').sum()#按类别合并
counts5_['ratio']=counts5_/counts5_.sum() #增加比例列
counts5_.sort_values('fullURLId', ascending = False) #按类型编码顺序排序
#点击次数统计
sql = pd.read_sql('all_gzdata', engine, chunksize = 10000)
c = [i['realIP'].value_counts() for i in sql] #统计各个IP出现次数
count6 = pd.concat(c).groupby(level=0).sum() #合并统计结果
count6 = pd.DataFrame(count6) #将Series转为DataFrame
count6[1] = 1 #添加一列全为1
count6_=count6.groupby('realIP').sum() #统计各个不同点击数 出现的次数
count6_['ratio1']=count6_[1]/count6_[1].sum()
count6_['ratio2']=count6_[1]*count6_.index/(count6_[1]*count6_.index).sum()
count6_.head(10)
可以看出80%的用户只提供了30%的浏览量,点击次数最大值为42790次,是律师浏览的信息。
1、clean合理删除数据
for i in sql:
d = i[['realIP', 'fullURL']] #只要网址列
d = d[d['fullURL'].str.contains('\.html')].copy() #只要含有.html的网址
#保存到数据库的cleaned_gzdata表中(如果表不存在则自动创建)
d.to_sql('cleaned_gzdata', engine, index = False, if_exists = 'append')
2、改变数据删除重复:由于用户在浏览网页时存在翻页情况,不同的网址属于同一类型的网页,针对这些网页需要还原其原始类别。
sql = pd.read_sql('cleaned_gzdata', engine, chunksize = 10000)
for i in sql: #逐块变换并去重
d = i.copy()
d['fullURL'] = d['fullURL'].str.replace('_\d{0,2}.html', '.html') #将下划线后面部分去掉,规范为标准网址
d = d.drop_duplicates() #删除重复记录
d.to_sql('changed_gzdata', engine, index = False, if_exists = 'append') #保存
3、分类:目标是为用户提供个性化推荐,要进一步对数据进行分类。
sql = pd.read_sql('changed_gzdata', engine, chunksize = 10000)
for i in sql: #逐块变换并去重
d = i.copy()
d['type_1'] = d['fullURL'] #复制一列
d['type_1'][d['fullURL'].str.contains('(ask)|(askzt)')] = 'zixun' #将含有ask、askzt关键字的网址的类别一归为咨询(后面的规则就不详细列出来了,实际问题自己添加即可)
d.to_sql('splited_gzdata', engine, index = False, if_exists = 'append') #保存
基于物品的协同过滤推荐、随机推荐、按照流行度推荐
基于物品的协同过滤推荐要分为两步:
1. 计算物品之间的相似度;
2. 根据物品相似度和用户的历史行为给用户生成推荐列表
由于用户行为是二元选择(0或者1),此处选择采用杰卡德相似系数法计算物品的相似度。
import numpy as np
def Jaccard(a, b): #自定义相似系数
return 1.0*(a*b).sum()/(a+b-a*b).sum()
class Recommender():
sim = None #相似度矩阵
def similarity(self, x, distance): #计算相似度矩阵的函数
y = np.ones((len(x), len(x)))
for i in range(len(x)):
for j in range(len(x)):
y[i,j] = distance(x[i], x[j])
return y
def fit(self, x, distance = Jaccard): #训练函数
self.sim = self.similarity(x, distance)
def recommend(self, a): #推荐函数
return np.dot(self.sim, a)*(1-a)
(1) 梳理影响地方财政收入的关键特征,分析识别影响地方财政收入的关键特征的选择模型
(2) 结合(1)的分析,对某市2015年财政总收入以及各个类别收入进行预测。
影响财政收入(y)的因素很多,经查阅资料选以下因素为自变量
社会从业人数(x1)在岗职工工资总额(x2)社会消费品零售总额(x3)城镇居民人均可支配收入(x4)城镇居民人均消费性支出(x5)年末总人口(x6)全社会固定资产投入(x7)地区生产总值(x8)第一产业产值(x9)税收(x10)居民消费价格指数(x11)第三产业与第二产业产值比(x12)居民消费水平(x13)
描述性分析describe
inputfile = '../data/data1.csv' #输入的数据文件
data = pd.read_csv(inputfile) #读取数据
r = [data.min(), data.max(), data.mean(), data.std()] #依次计算最小值、最大值、均值、标准差
r = pd.DataFrame(r, index = ['Min', 'Max', 'Mean', 'STD']).T #计算相关系数矩阵
np.round(r, 2) #保留两位小数
相关性分析data.corr(method='pearson'):x11与财政收入的线性关系不显著
#标准化处理
dataNM=(data-data.min())/(data.max()-data.min())
data = pd.read_csv( '../data/data1.csv') #读取数据
#导入AdaptiveLasso算法,要在较新的Scikit-Learn才有。
from sklearn.linear_model import AdaptiveLasso#import Lasso
model = AdaptiveLasso(gamma=1)##model=Lasso()
model.fit(data.iloc[:,0:13],data['y'])
q=model.coef_ #各个特征的系数
#-*- coding: utf-8 -*-
def GM11(x0): #自定义灰色预测函数
import numpy as np
x1 = x0.cumsum() #1-AGO序列
z1 = (x1[:len(x1)-1] + x1[1:])/2.0 #紧邻均值(MEAN)生成序列
z1 = z1.reshape((len(z1),1))
B = np.append(-z1, np.ones_like(z1), axis = 1)
Yn = x0[1:].reshape((len(x0)-1, 1))
[[a],[b]] = np.dot(np.dot(np.linalg.inv(np.dot(B.T, B)), B.T), Yn) #计算参数
f = lambda k: (x0[0]-b/a)*np.exp(-a*(k-1))-(x0[0]-b/a)*np.exp(-a*(k-2)) #还原值
delta = np.abs(x0 - np.array([f(i) for i in range(1,len(x0)+1)]))
C = delta.std()/x0.std()
P = 1.0*(np.abs(delta - delta.mean()) < 0.6745*x0.std()).sum()/len(x0)
return f, a, b, x0[0], C, P #返回灰色预测函数、a、b、首项、方差比、小残差概率
from GM11 import GM11 #引入自己编写的灰色预测函数
inputfile = '../data/data1.csv' #输入的数据文件
outputfile = '../tmp/data1_GM11.xls' #灰色预测后保存的路径
data = pd.read_csv(inputfile) #读取一部分数据
data.index = range(1994, 2014)
data.loc[2014] = None
data.loc[2015] = None
l=['x1','x2','x3','x4','x5','x6','x7']
for i in l:
f = GM11(data[i][np.arange(1994, 2014)].as_matrix())[0]#range改成np.arange,key错误
data[i][2014] = f(len(data)-1) #2014年预测结果
data[i][2015] = f(len(data)) #2015年预测结果
data[i] = data[i].round(2) #保留两位小数
data[l+['y']].to_excel(outputfile) #结果输出
#-*- coding: utf-8 -*-
import pandas as pd
inputfile = '../tmp/data1_GM11.xls' #灰色预测后保存的路径
outputfile = '../data/revenue.xls' #神经网络预测后保存的结果
modelfile = '../tmp/1-net.model' #模型保存路径
data = pd.read_excel(inputfile) #读取数据
feature = ['x1', 'x2', 'x3', 'x4', 'x5', 'x7'] #特征所在列
#统计
data_train = data.loc[range(1994,2014)].copy() #取2014年前的数据建模
data_mean = data_train.mean()
data_std = data_train.std()
data_train = (data_train - data_mean)/data_std #数据标准化
x_train = data_train[feature].as_matrix() #特征数据
y_train = data_train['y'].as_matrix() #标签数据
from keras.models import Sequential
from keras.layers.core import Dense, Activation
model = Sequential() #建立模型
model.add(Dense(12,input_dim=6))
model.add(Activation('relu')) #用relu函数作为激活函数,能够大幅提供准确度
model.add(Dense(1,input_dim=12))
model.compile(loss='mean_squared_error', optimizer='adam') #编译模型
model.fit(x_train, y_train, epochs = 10000, batch_size = 16) #训练模型,学习一万次
model.save_weights(modelfile) #保存模型参数
#预测,并还原结果。
x = ((data[feature] - data_mean[feature])/data_std[feature]).as_matrix()
data[u'y_pred'] = model.predict(x) * data_std['y'] + data_mean['y']#.tolist()
data.to_excel(outputfile)
import matplotlib.pyplot as plt #画出预测结果图
p = data[['y','y_pred']].plot(subplots = True, style=['b-o','r-*'])
plt.show()
1对用户的历史定位数据,采用数据挖掘技术,对基站进行分群
2对不同的商圈分群进行特征分析,比较不同商圈类别的价值,选择合适区域进行针对性的营销活动
1、提取出基站范围内区域的人流特征:分类人流特征的四个指标,工作日上班时间人均停留时间、凌晨人均停留时间、周末人均停留时间和日均人流量。
2、由于各个属性之间的差异较大。为了消除数量级数据带来的影响,在聚类之前,需要进行离差标准化处理
data = (data - data.min())/(data.max() - data.min()) #离差标准化
建模数据进行基于基站数据的商圈聚类,画出谱系聚类图
standardizedfile = '../data/standardized.xls' #标准化后的数据文件
data = pd.read_excel(standardizedfile, index_col = u'基站编号') #读取数据
import matplotlib.pyplot as plt
from scipy.cluster.hierarchy import linkage,dendrogram
#这里使用scipy的层次聚类函数
Z = linkage(data, method = 'ward', metric = 'euclidean') #谱系聚类图
P = dendrogram(Z, 0) #画谱系聚类图
plt.show()
从图中可以看出,可以把聚类类别数取3类,再使用层次聚类算法进行训练模型
standardizedfile = '../data/standardized.xls' #标准化后的数据文件
k = 3 #聚类数
data = pd.read_excel(standardizedfile, index_col = u'基站编号') #读取数据
from sklearn.cluster import AgglomerativeClustering #导入sklearn的层次聚类函数
model = AgglomerativeClustering(n_clusters = k, linkage = 'ward')
model.fit(data) #训练模型
#详细输出原始数据及其类别
r = pd.concat([data, pd.Series(model.labels_, index = data.index)], axis = 1) #详细输出每个样本对应的类别
r.columns = list(data.columns) + [u'聚类类别'] #重命名表头
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号
style = ['ro-', 'go-', 'bo-']
xlabels = [u'工作日人均停留时间', u'凌晨人均停留时间', u'周末人均停留时间', u'日均人流量']
pic_output = '../tmp/type_' #聚类图文件名前缀
for i in range(k): #逐一作图,作出不同样式
plt.figure()
tmp = r[r[u'聚类类别'] == i].iloc[:,:4] #提取每一类
for j in range(len(tmp)):
plt.plot(range(1, 5), tmp.iloc[j], style[i])
plt.xticks(range(1, 5), xlabels, rotation = 20) #坐标标签
plt.title(u'商圈类别%s' %(i+1)) #我们计数习惯从1开始
plt.subplots_adjust(bottom=0.15) #调整底部
plt.savefig(u'%s%s.png' %(pic_output, i+1)) #保存图片
1抽取品牌是美的的数据
inputfile = '../data/huizong.csv' #评论汇总文件
outputfile = '../data/meidi_jd.txt' #评论提取后保存路径
data = pd.read_csv(inputfile, encoding = 'utf-8')
data = data[[u'评论']][data[u'品牌'] == u'美的']
data.to_csv(outputfile, index = False, header = False, encoding = 'utf-8')
inputfile = '../data/meidi_jd.txt' #评论文件
outputfile = '../data/meidi_jd_process_1.txt' #评论处理后保存路径
data = pd.read_csv(inputfile, encoding = 'utf-8', header = None,sep='\t')
l1 = len(data)
data = pd.DataFrame(data[0].unique())
l2 = len(data)
data.to_csv(outputfile, index = False, header = False, encoding = 'utf-8')
print(u'删除了%s条评论。' %(l1 - l2))
3把评论前面的评分删除
inputfile1 = '../data/meidi_jd_process_end_负面情感结果.txt'
outputfile1 = '../data/meidi_jd_neg.txt'
data1 = pd.read_csv(inputfile1, encoding = 'utf-8', header = None) #读入数据
data1 = pd.DataFrame(data1[0].str.replace('.*?\d+?\\t ', '')) #用正则表达式修改数据,删除平分负数
data1.to_csv(outputfile1, index = False, header = False, encoding = 'utf-8')
inputfile1 = '../data/meidi_jd_neg.txt'
outputfile1 = '../data/meidi_jd_neg_cut.txt'
data1 = pd.read_csv(inputfile1, encoding = 'utf-8', header = None) #读入数据
mycut = lambda s: ' '.join(jieba.cut(s)) #自定义简单分词函数
data1 = data1[0].apply(mycut) #通过“广播”形式分词,加快速度。
K-means是聚类的,他主要是处理数据的,对数据进行聚类。
LDA其实也是聚类的,主要是处理字符串的,对字符串进行聚类
#参数初始化
negfile = '../data/meidi_jd_neg_cut.txt'
posfile = '../data/meidi_jd_pos_cut.txt'
stoplist = '../data/stoplist.txt'
neg = pd.read_csv(negfile, encoding = 'utf-8', header = None) #读入数据
stop = pd.read_csv(stoplist, encoding = 'utf-8', header = None, sep = 'tipdm')
#sep设置分割词,由于csv默认以半角逗号为分割词,而该词恰好在停用词表中,因此会导致读取出错
#所以解决办法是手动设置一个不存在的分割词,如tipdm。
stop = [' ', ''] + list(stop[0]) #Pandas自动过滤了空格符,这里手动添加
neg[1] = neg[0].apply(lambda s: s.split(' ')) #定义一个分割函数,然后用apply广播
neg[2] = neg[1].apply(lambda x: [i for i in x if i not in stop]) #逐词判断是否停用词,思路同上
from gensim import corpora, models
#负面主题分析
neg_dict = corpora.Dictionary(neg[2]) #建立词典
neg_corpus = [neg_dict.doc2bow(i) for i in neg[2]] #建立语料库
neg_lda = models.LdaModel(neg_corpus, num_topics = 3, id2word = neg_dict) #LDA模型训练
for i in range(3):
neg_lda.print_topic(i) #输出每个主题