分类与预测:
常用的分类与预测方法:
- 回归分析
- 决策树
- 人工神经网络
- 贝叶斯网络
- 支持向量机
常用的二分类Logistic回归的原理:
import pandas as pd
filename = '../data/bankloan.xls'
data = pd.read_excel(filename)
x = data.iloc[:,:8].as_matrix() #分片前8列 as_matrix()将dataframe转换为多维矩阵
y = data.iloc[:,8].as_matrix()
from sklearn.linear_model import LogisticRegression as LR
from sklearn.linear_model import RandomizedLogisticRegression as RLR
rlr = RLR()
rlr.fit(x, y)
rlr.get_support()
print(u'通过随机逻辑回归模型')
print(u'有效特征为:%s' % ','.join(data.columns[rlr.get_support()]))
x = data[data.columns[rlr.get_support()]].as_matrix()
lr = LR()
lr.fit(x, y)
print(u'逻辑回归模型训练结束')
print(u'模型的平均正确率:%s' % lr.score(x, y))
from sklearn.linear_model import RandomizedLogisticRegression as RLR
这个模块在新版本已经被删除 5-1代码没啥用了
决策树:
ID3算法:基于信息熵来选择最佳测试属性,它选择当前样本集中具有最大信息增益值属性作为测试属性;样本值得划分则依据测试属性的取值进行,测试属性有多少不同取值就将样本集划分为多少子样本集,同时决策树上相应于该样本集的结点长出新的叶子结点。
具体流程:
- 对当前样本集合,计算所有属性的信息增益。
- 选择信息增益最大的属性作为测试属性,把测试属性取值相同的样本化为同一个样本集。
- 若子样本集的类别属性只含有单个属性,则分支为叶子结点,判断其属性值并标上相应的符号,然后返回调回处,否则对子样本集递归调用本算法。
import pandas as pd
filename='../data/sales_data.xls'
data=pd.read_excel(filename,index_col=u'序号')
#变量赋值,数据是类别标签,先转换为数据
data[data==u'好']=1
data[data==u'是']=1
data[data==u'高']=1 #用1来表示“好”“是”“高”这三个属性
data[data!=1]=-1 #用-1来表示“坏”“否”“低”
x=data.iloc[:,:3].values.astype(int)
#筛选切片,选出所有行,第0至第2列的数据赋值给x
y=data.iloc[:,3].values.astype(int)
#选出所有行,第3列的数据赋值给y
#建立模型并训练模型
from sklearn.tree import DecisionTreeClassifier as DTC
dtc=DTC(criterion='entropy')
dtc.fit(x,y)
#可视化决策树
x=pd.DataFrame(x)
from sklearn.tree import export_graphviz
from six import StringIO #源代码不是这个 导入six
with open("tree.dot",'w') as f:
f=export_graphviz(dtc,feature_names=x.columns,out_file=f) #生成决策树到tree.dot文件
#运行以上代码后,在存放实验数据的路径下会生成一个tree.dot文件
人工神经网络:是模拟生物神经网络进行信息处理的一种属性模型
BP神经网络:
特征是利用输出后的误差来估计输出层的直接前导层的误差,再用这个误差估计更前一层的误差。
import pandas as pd
inputfile = '../data/sales_data.xls'
data = pd.read_excel(inputfile, index_col = u'序号')
data[data == u'好'] = 1
data[data == u'是'] = 1
data[data == u'高'] = 1
data[data != 1] = 0
x = data.iloc[:,:3].values.astype(int)
y = data.iloc[:,3].values.astype(int)
from keras.models import Sequential
from keras.layers.core import Dense, Activation
model = Sequential()
model.add(Dense(input_dim = 3, output_dim = 10))
model.add(Activation('relu'))
model.add(Dense(input_dim = 10, output_dim = 1))
model.add(Activation('sigmoid'))
model.compile(loss = 'binary_crossentropy', optimizer = 'adam', class_mode = 'binary')
model.fit(x, y, nb_epoch = 1000, batch_size = 10)
yp = model.predict_classes(x).reshape(len(y))
from cm_plot import *
cm_plot(y,yp).show()
报错:
常见的模型评价和在python中的表现:
逻辑回归:比较基础的线性分类模型
模型 | 模型特点 |
---|---|
逻辑回归 | 比较基础的线性分类模型,很多时候是有效的选择 |
SVM | 强大的模型,可以用来回归、预测、分类等,而根据选取不同的核函数。模型可以是线性的/非线性的 |
决策树 | 基于“分类讨论、逐步细化”思想的分类模型,模型直观,易解释 |
随机森林 | 思想跟决策树类似,精度通常比决策树要高,缺点是由于随机性,丧失了决策树的可解释性 |
朴素贝叶斯 | 基于概率思想的简单有效的分类模型,能够输出给容易理解的概率解释 |
神经网络 | 具有强大的拟合能力,可以用于拟合、分类等,它有很多个增强版本,如递神经网络、卷积神经网络、自编码器等,这些都是深度学习的模型基础 |
聚类分析
常用的聚类方法:
类别 | 包括的主要算法 |
---|---|
划分(分裂)方法 | K-Means算法、K-MEDOIDS算法、 CLARANS算法 |
层次分析方法 | BIRCH算法、CURE算法、CHAMELEON算法 |
基于密度的方法 | DBSCAN算法、DENCLUE算法、OPTICS算法 |
基于网格的方法 | STING算法、CLIOUE算法、WAVE-CLUSTER算法 |
基于模型的方法 | 统计学方法、神经网络方法 |
常用聚类算法:
算法名称 | 算法描述 |
---|---|
K-Means算法 | K-均值聚类也称快速聚类法,在最小化误差函数的基础上将数据划分为预定的类数K。该算法原理简单并便于处理大量数据 |
K-中心点 | K-均值算法对孤立点的敏感性,K-中心点算法不采用簇中对象的平均值作为簇中心,而选用簇中离平均值最近的对象作为簇中心 |
系统聚类 | 系统聚类也称多层次聚类,分类的单位由高到低呈树形结构,且所处的位置越低,其所包含的对象就越少,但这些对象间的共同特征越多。该聚类方法只适合在小数据量的时候使用,数据量大的时候速度会非常慢 |
K-Means算法:
算法过程:
- 从N个样本数据中随机选取K个对象作为初始聚类的中心
- 分别计算每个样本到各个聚类中心的距离,将对象分配到距离最近的聚类中
- 所有对象分配完成后,重新计算K个聚类的中心
- 与前一次计算得到的K个聚类中心比较,如果聚类中心发生变化,转过程(2),否则转过程(5)
- 当质心不发生变化时停止并输出聚类结果
import pandas as pd
#参数初始化
inputfile = '../data/consumption_data.xls' #销量及其他属性数据
outputfile = '../tmp/data_type.xls' #保存结果的文件名
k = 3 #聚类的类别
iteration = 500 #聚类最大循环次数
data = pd.read_excel(inputfile, index_col = 'Id') #读取数据
data_zs = 1.0*(data - data.mean())/data.std() #数据标准化
from sklearn.cluster import KMeans
model = KMeans(n_clusters = k, n_jobs = 4, max_iter = iteration) #分为k类,并发数4
model.fit(data_zs) #开始聚类
#简单打印结果
r1 = pd.Series(model.labels_).value_counts() #统计各个类别的数目 Series是一维数组 默认以0-n-1为index value_counts()查看表格某列中有多少个不同值
r2 = pd.DataFrame(model.cluster_centers_) #找出聚类中心
r = pd.concat([r2, r1], axis = 1) #横向连接r2和r1(axis=0是纵向),得到聚类中心对应的类别下的数目
r.columns = list(data.columns) + [u'类别数目'] #重命名表头
print(r)
#详细输出原始数据及其类别
r = pd.concat([data, pd.Series(model.labels_, index = data.index)], axis = 1) #详细输出每个样本对应的类别
r.columns = list(data.columns) + [u'聚类类别'] #重命名表头
r.to_excel(outputfile) #保存结果
def density_plot(data): #自定义作图函数
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号
p = data.plot(kind='kde', linewidth = 2, subplots = True, sharex = False)
[p[i].set_ylabel(u'密度') for i in range(k)]
plt.legend()#给图加上图例
return plt
pic_output = '../tmp/pd_' #概率密度图文件名前缀
for i in range(k):
density_plot(data[r[u'聚类类别']==i]).savefig(u'%s%s.png' %(pic_output, i))#保存图片在代码同一级目录下
聚类分析算法评价:
(1)Purity评价法
只需计算正确聚类数占总数的比例
(2)RI评价法
用排列组合原理对聚类进行评价的手段
(3)F值评价法
基于上述RI方法衍生出的一个方法
TSNE方法:提供数据降维方式,让我们可以在2维或者3维空间中展示聚类结果。
from sklearn.manifold import TSNE
tsne = TSNE()
tsne.fit_transform(data_zs) #进行数据降维
tsne = pd.DataFrame(tsne.embedding_, index = data_zs.index) #转换数据格式
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号
#不同类别用不同颜色和样式绘图
d = tsne[r[u'聚类类别'] == 0]
plt.plot(d[0], d[1], 'r.')
d = tsne[r[u'聚类类别'] == 1]
plt.plot(d[0], d[1], 'go')
d = tsne[r[u'聚类类别'] == 2]
plt.plot(d[0], d[1], 'b*')
plt.show()
关联规则:
算法名称 | 算法描述 |
---|---|
Apriori | 关联规则最常用也是最经典的挖掘频繁的算法,其核心思想是通过连接产生候选项及其支持度然后通过剪枝生成频繁项集 |
FP-Tree | 针对Apriori算法的固有的多次扫描事务数据集的缺陷,提出的不产生候选频繁项集的方法。Apriori算法和FP-Tree都是寻找频繁项集的算法 |
Eclat算法 | Eclat算法是一种深度优先算法,采用垂直数据表示形式,在概念格理论的基础上利用基于前缀的等价关系将搜索空间划分较小的子空间 |
灰色关联法 | 分析和确定各因素之间的影响程度或是若干个子因素对主因素的贡献度而进行的一种分析方法 |
Apriori算法:
核心思想:通过连接产生候选项与其支持度,然后通过剪枝生成频繁项集
关联规则的一般形式:
项集A、B同时发生的概率称为关联规则的支持度(也称相对支持度)
项集A发生,则项集B发生的概率为关联规则的置信度
最小支持度:表示项目集在统计意义上的最低重要性
最小置信度:表示关联规则的最低可靠性
同时满足最小支持度阙值和最小置信度阈值的规则则称作强规则
项集是项的集合,包含K个项的项集称为K项集
项集的出现频率是所有包含项集的事务计数,又称作绝对支持度或支持度计数。如果项集1的相对支持度满足预定义的最小支持度阈值,则I是频繁项集。频繁K项通常记作K
支持度计数
项集A的支持度计数是事务数据集中包含项集A的事务个数,简称为项集的频率或计数。
算法主要思想是找出存在于事务数据集中的最大的频繁项集,在利用得到的最大频繁项集与预先设定的最小置信度阈值生成强关联规则。
Apriori算法实现的过程:
(1)Apriori的性质:
频繁项集的所有非空子集也必须是频繁项集。根据该性质可以得出:向不是频繁项集1的项集中添加事务A,新的项集I U A一定也不是频繁项集。
(2)Apriori算法实现的两个过程如下
找出连接步
剪枝步
由频繁项集产生强关联规则
时序模式:
对纯随机序列,又称白噪声序列,序列的各项之间没有任何相关关系,序列在进行完全无需的随机波动,可以终止对该序列的分析。白噪声序列是没有信息可提取的平稳序列
对非平稳序列,由于它的均值和方差不稳定,处理方法一般是将其转变为平稳序列,这也就可以应用有关平稳实践序列的分析方法
平稳性检验:
- 根据时序图和自相关图的特征做出判断的图检验
- 构造检验统计量进行检验的方法,目前最常用的方法是单位根检验
时序图检验:
根据平稳时间序列的均值和方差都为常数的性质,平稳序列的时序图显示该序列值始终在一个常数附近随机波动,而且波动的范围有界,如果有明显的趋势性或者周期性,那他通常不是平稳序列
自相关图检验:
只有近期的序列值对现时值的影响比较明显,间隔越远的过去值对现时值的影响越小
单位根检验:
检验序列中是否存在单位根,如果存在就是非平稳时间序列
离群点检验:
常用离群点检测方法:
- 基于统计:构建概率分布模型,计算对象符合该模型的概率,把低概率的对象视为离群点
- 基于邻近度:在数据对象之间定义邻近性度量,把远离大部分点的对象视为离群点
- 基于密度:在低密度的对象是离群点
- 基于聚类:1种是丢弃远离其他簇的小簇 另一种是聚类所有对象,然后评估对象属于簇的程度
基于聚类诊断步骤:
- 进行聚类
- 计算各对象到它的最近质心的距离
- 计算各对象到它的最近质心的相对距离
- 与给定的阈值作比较
import numpy as np
import pandas as pd
#参数初始化
inputfile = '../data/consumption_data.xls' #销量及其他属性数据
k = 3 #聚类的类别
threshold = 2 #离散点阈值
iteration = 500 #聚类最大循环次数
data = pd.read_excel(inputfile, index_col = 'Id') #读取数据
data_zs = 1.0*(data - data.mean())/data.std() #数据标准化
from sklearn.cluster import KMeans
model = KMeans(n_clusters = k, n_jobs = 4, max_iter = iteration) #分为k类,并发数4
model.fit(data_zs) #开始聚类
#标准化数据及其类别
r = pd.concat([data_zs, pd.Series(model.labels_, index = data.index)], axis = 1) #每个样本对应的类别
r.columns = list(data.columns) + [u'聚类类别'] #重命名表头
norm = []
for i in range(k): #逐一处理
norm_tmp = r[['R', 'F', 'M']][r[u'聚类类别'] == i]-model.cluster_centers_[i]
norm_tmp = norm_tmp.apply(np.linalg.norm, axis = 1) #求出绝对距离 apply():当一个函数的参数存在于一个元组或者一个字典中时,用来间接的调用这个函数,并将元组或者字典中的参数按照顺序传递给参数 axis=1对列运算
norm.append(norm_tmp/norm_tmp.median()) #求相对距离并添加
norm = pd.concat(norm) #合并
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号
norm[norm <= threshold].plot(style = 'go') #正常点
discrete_points = norm[norm > threshold] #离群点
discrete_points.plot(style = 'ro')
for i in range(len(discrete_points)): #离群点做标记
id = discrete_points.index[i]
n = discrete_points.iloc[i]
plt.annotate('(%s, %0.2f)'%(id, n), xy = (id, n), xytext = (id, n))
plt.xlabel(u'编号')
plt.ylabel(u'相对距离')
plt.show()
输出:
比书上多一个离群点?(935,8.37)