Table of Contents
写在前面:
环境:
chapter3
chapter4
chapter5
chapter6
chapter7
chapter8
chapter9
chapter10
chapter11
待更...
博主在使用《python数据分析与挖掘》过程中发现书籍附上的代码存在部分问题(Python版本、语法错误、书写不规范、注释不够详尽等),根据自身情况对代码进行修正,同时分享出来供大家一起研究与探讨。文章只提供代码,数据集还需要到书籍官网下载http://www.tipdm.org/ts/661.jhtml
代码导入数据集的的过程,参考CMD文件夹的切换模式(命令行语法)
解释器:Python 3
开发IDE:pycharm
解释器:anaconda3
----------------------------3-1_abnormal_check:---------------------------------------
# -*- coding: utf-8 -*-
import pandas as pd
catering_sale = '../data/catering_sale.xls' # 餐饮数据
data = pd.read_excel(catering_sale, index_col=u'日期') # 读取数据,指定“日期”列为索引列
import matplotlib.pyplot as plt # 导入图像库
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.figure() # 建立图像
p = data.boxplot(return_type='dict') # 画箱线图,直接使用DataFrame的方法
x = p['fliers'][0].get_xdata() # 'flies'即为异常值的标签
y = p['fliers'][0].get_ydata()
y.sort() # 从小到大排序,该方法直接改变原对象
print(len(x))
# 用annotate添加注释
# 其中有些相近的点,注解会出现重叠,难以看清,需要一些技巧来控制。
# 以下参数都是经过调试的,需要具体问题具体调试。
for i in range(len(x)):
if i > 0:
plt.annotate(y[i], xy=(x[i], y[i]), xytext=(x[i]+0.05 - 0.8 / (y[i]-y[i-1]), y[i]))
else:
plt.annotate(y[i], xy=(x[i], y[i]), xytext=(x[i]+0.08, y[i]))
plt.show() # 展示箱线图
----------------------------------3-2_statistics_analyze-----------------------------------------------------------------------
# -*- coding: utf-8 -*-
# 餐饮销量数据统计量分析
from __future__ import print_function
import pandas as pd
catering_sale = '../data/catering_sale.xls' # 餐饮数据
data = pd.read_excel(catering_sale, index_col=u'日期') # 读取数据,指定“日期”列为索引列
print(data.shape)
data = data[(data[u'销量'] > 400) & (data[u'销量'] < 5000)] # 过滤异常数据
print(data.shape)
statistics = data.describe() # 保存基本统计量
print(statistics)
statistics.loc['range'] = statistics.loc['max']-statistics.loc['min'] # 极差
statistics.loc['var'] = statistics.loc['std']/statistics.loc['mean'] # 变异系数
statistics.loc['dis'] = statistics.loc['75%']-statistics.loc['25%'] # 四分位数间距
print(statistics)
----------------------------------3-3_dish_pareto--------------------------------------------------------------------
# -*- coding: utf-8 -*-
# 菜品盈利数据 帕累托图
from __future__ import print_function
import pandas as pd
"""
在开头加上from __future__ import print_function这句之后,
即使在python2.X,使用print就得像python3.X那样加括号使用。
python2.X中print不需要括号,而在python3.X中则需要。
"""
# 初始化参数
dish_profit = '../data/catering_dish_profit.xls' # 餐饮菜品盈利数据
data = pd.read_excel(dish_profit, index_col='菜品名')
print(data)
data = data[u'盈利'].copy()
print(data)
data.sort_values(ascending=False)
import matplotlib.pyplot as plt # 导入图像库
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.figure()
data.plot(kind='bar')
plt.ylabel(u'盈利(元)')
p = 1.0*data.cumsum()/data.sum() # cumsum()数据累加
p.plot(color='r', secondary_y=True, style='-o', linewidth=2) # secondary_y为使用第二个y坐标轴
plt.annotate(format(p[6], '.4%'), xy=(6, p[6]), xytext=(6*0.9, p[6]*0.9),
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2")) # 添加注释,即85%处的标记。这里包括了指定箭头样式。
plt.ylabel(u'盈利(比例)')
plt.show()
----------------------------------3-4_correlation_analyze------------------------------------------------------------
# -*- coding: utf-8 -*-
# 餐饮销量数据相关性分析
from __future__ import print_function
import pandas as pd
catering_sale = '../data/catering_sale_all.xls' # 餐饮数据,含有其他属性
data = pd.read_excel(catering_sale, index_col=u'日期') # 读取数据,指定“日期”列为索引列
print(data)
data.corr() # 相关系数矩阵,即给出了任意两款菜式之间的相关系数
print(data.corr()[u'百合酱蒸凤爪']) # 只显示“百合酱蒸凤爪”与其他菜式的相关系数
print(data[u'百合酱蒸凤爪'].corr(data[u'翡翠蒸香茜饺'])) # 计算“百合酱蒸凤爪”与“翡翠蒸香茜饺”的相关系数
print(data.corr()[u'翡翠蒸香茜饺'])
------------------------草稿本--------------------------------------
# p28页
# from sklearn import datasets
# from sklearn import svm
# iris = datasets.load_iris()
# print(iris.data.shape)
# clf = svm.LinearSVC()
# clf.fit(iris.data, iris.target)
# clf.predict([[5.0, 3.6, 1.3, 0.25]])
# print(clf.coef_)
# p57——(1)
# import matplotlib.pyplot as plt
# import numpy as np
# x = np.random.randn(1000) # 1000个正态分布随机数在
# plt.hist(x, 100) # 分为100组
# plt.show()
# p57——(2)
# import matplotlib.pyplot as plt
# import numpy as np
# import pandas as pd
# x = np.random.randn(1000)
# D = pd.DataFrame([x, x + 1, x]).T # 构造三列dataframe
# print(D[1:12])
# D.plot(kind='box')
# plt.show()
# p59
# import matplotlib.pyplot as plt
# import numpy as np
# import pandas as pd
# plt.rcParams['font.sans-serif'] = ['Simhei']
# plt.rcParams['axes.unicode_minus'] = False
# error = np.random.randn(10) # 定义误差列
# print(error)
# y = pd.Series(np.sin(np.arange(10))) # 均值数据列
# print(y)
# y.plot(yerr=error) # 绘图(yerr=error 文档不详)
# plt.show()
---------------------------------------4-1_lagrange_newton_interp-------------------------------------
# 拉格朗日插值代码
import pandas as pd # 导入数据分析库Pandas
from scipy.interpolate import lagrange # 导入拉格朗日插值函数
inputfile = '../data/catering_sale.xls' # 销量数据路径
outputfile = '../tmp/sales.xls' # 输出数据路径
data = pd.read_excel(inputfile) # 读入数据
print(data.shape)
data[u'销量'][(data[u'销量'] < 400) | (data[u'销量'] > 5000)] = None # 过滤异常值,将其变为空值
# 自定义列向量插值函数
# s为列向量,n为被插值的位置,k为取前后的数据个数,默认为5
def ployinterp_column(s, n, k=5):
y = s[list(range(n-k, n)) + list(range(n+1, n+1+k))] # 取数
print(y) # 查看选取的数据
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] = ployinterp_column(data[i], j)
data.to_excel(outputfile) # 输出结果,写入文件
print(data.columns)
print(len(data))
---------------------------------------4-2_data_normalization----------------------------------------------------
# -*- coding: utf-8 -*-
# 数据规范化
import pandas as pd
import numpy as np
datafile = '../data/normalization_data.xls' # 参数初始化
data = pd.read_excel(datafile, header=None) # 读取数据
print(data)
print((data - data.min())/(data.max() - data.min())) # 最小-最大规范化
print((data - data.mean())/data.std()) # 零-均值规范化 TODO 常用
print(data/10**np.ceil(np.log10(data.abs().max()))) # 小数定标规范化
---------------------------------------4-3_data_discretization--------------------------------------------
# -*- coding: utf-8 -*-
# 数据离散化
import pandas as pd
datafile = '../data/discretization_data.xls' # 参数初始化
data = pd.read_excel(datafile) # 读取数据
data = data[u'肝气郁结证型系数'].copy() # 将这一列的数据抓出来
k = 4 # 分成4个区间
d1 = pd.cut(data, k, labels=range(k)) # 等宽离散化,各个类比依次命名为0,1,2,3
# print(d1)
print(pd.value_counts(d1))
# 等频率离散化,qcut函数就是用来做按照分位数切割的
# 如果是分成4个区间,可以使用qcut函数,4表示按照4分位数进行切割
d2 = pd.qcut(data, 4, labels=range(k))
# print(d2)
print(pd.value_counts(d2))
# 如果想分成10个等份,则如下
w = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
d3 = pd.qcut(data, w, labels=range(10))
# print(d3)
print(pd.value_counts(d3))
# 也可以按照任意的分位数进行分割,使得每个区间按照自己设定的个数展示
w = [0, 0.1, 0.5, 0.9, 1]
d4 = pd.qcut(data, w, labels=range(4)) # labels是可以替换的,如:labels=['hao','zhong','yiban','huai']
# print(d4)
print(pd.value_counts(d4))
# 基于聚类的划分
from sklearn.cluster import KMeans # 引入KMeans
kmodel = KMeans(n_clusters=k, n_jobs=1) # 建立模型,n_jobs是并行数,一般等于CPU数较好
kmodel.fit(data.reshape((len(data), 1))) # 训练模型
c = pd.DataFrame(kmodel.cluster_centers_).sort_values(0) # 输出聚类中心,并且排序(默认是随机序的)
w = pd.rolling_mean(c, 2).iloc[1:] # 相邻两项求中点,作为边界点
w = [0] + list(w[0]) + [data.max()] # 把首末边界点加上
d3 = pd.cut(data, w, labels=range(k))
def cluster_plot(d, k): # 自定义作图函数来显示聚类结果
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.figure(figsize=(8, 3))
for j in range(0, k):
plt.plot(data[d == j], [j for i in d[d == j]], 'o')
plt.ylim(-0.5, k - 0.5)
return plt
cluster_plot(d1, k).show()
cluster_plot(d2, k).show()
cluster_plot(d3, k).show()
---------------------------------------4-4_line_rate_construct-------------------------------------------
# -*- coding: utf-8 -*-
# 线损率属性构造
import pandas as pd
# 参数初始化
inputfile= '../data/electricity_data.xls' # 供入供出电量数据
outputfile = '../tmp/electricity_data.xls' # 属性构造后数据文件
data = pd.read_excel(inputfile) # 读入数据
data[u'线损率'] = (data[u'供入电量'] - data[u'供出电量'])/data[u'供入电量']
data.to_excel(outputfile, index=False) # 保存结果
---------------------------------------4-5_wave_analyze-----------------------------------------------------
# -*- coding: utf-8 -*-
# 利用小波分析进行特征分析
# 参数初始化
inputfile= '../data/leleccum.mat' # 提取自Matlab的信号文件
from scipy.io import loadmat # mat是MATLAB专用格式(二进制文件),需要用loadmat读取它
mat = loadmat(inputfile)
signal = mat['leleccum'][0]
import pywt # 导入PyWavelets
coeffs = pywt.wavedec(signal, 'bior3.7', level=5)
# 返回结果为level+1个数字,第一个数组为逼近系数数组,后面的依次是细节系数数组
---------------------------------------4-6_principal_component_analyze-------------------------------------------
# -*- coding: utf-8 -*-
# 主成分分析 降维
import pandas as pd
# 参数初始化
inputfile = '../data/principal_component.xls'
outputfile = '../tmp/dimention_reducted.xls' #降维后的数据
data = pd.read_excel(inputfile, header=None) # 读入数据
from sklearn.decomposition import PCA
pca = PCA()
pca.fit(data)
print(pca.components_) # 返回模型的各个特征向量
print("")
print(pca.explained_variance_ratio_) # 返回各个成分各自的方差百分比
print("")
pca = PCA(3)
pca.fit(data)
low_b = pca.transform(data) # 降低维度
pd.DataFrame(low_b).to_excel(outputfile) # 保存结果
print(pca.inverse_transform(low_b)) # 函数来复原数据
---------------------------------------------------5-1_logistic_regression----------------------------------------------------------------------------
# -*- coding: utf-8 -*-
# 逻辑回归 建模
import pandas as pd
# 参数初始化
filename = '../data/bankloan.xls'
data = pd.read_excel(filename)
x = data.iloc[:, :8] #
# x = data.iloc[:, :8].as_matrix() # .as_matrix() 将DataFrame转化为ndarray
y = data.iloc[:, 8].as_matrix() # 第九列数据为因变量
print(type(data)) #
from sklearn.linear_model import LogisticRegression as LR
from sklearn.linear_model import RandomizedLogisticRegression as RLR
rlr = RLR() # 建立随机回归模型,筛选变量 可以使用参数设置阈值:selection_threshold=0.5等
# 默认为selection_threshold=0.25
rlr.fit(x, y) # 训练模型
rlr.get_support() # 获取特征筛选结果,也可以通过 .scores_ 方法获取各个特征的分数
print(u'通过随机回归模型筛选特征结束')
import numpy as np
print(u'有效特征为:%s' % ','.join(np.array(data.iloc[:, :8].columns)[rlr.get_support()]))
x = data[np.array(data.iloc[:, :8].columns)[rlr.get_support()]].as_matrix() # 筛选好特征
print(type(x)) #
lr = LR() # 建立逻辑货柜模型
lr.fit(x, y) # 用筛选后的特征数据来训练模型
print(u'逻辑回归模型训练结束。')
print(u'模型正确率为: %s' % lr.score(x, y)) # 给出模型的平均正确率,本例为81.4%
------------------------------------------------------5-2_decision_tree------------------------------------------------------------------
# -*- coding: utf-8 -*-
# 使用ID3决策树算法预测销售高低
import pandas as pd
# 参数初始化
inputfile = '../data/sales_data.xls'
data = pd.read_excel(inputfile, index_col=u'序号') # 导入数据
# 数据是类别标签,将他转化为数据
# 用1表示‘好’ ‘是’ ‘高’ 这三个属性,用-1 表示‘坏’ ‘否’ ‘低’
data[data == u'好'] = 1
data[data == u'是'] = 1
data[data == u'高'] = 1
data[data != 1] = -1
x = data.iloc[:, :3].as_matrix().astype(int) # astype 函数将数据转换为指定类型
y = data.iloc[:, 3].as_matrix().astype(int)
print(type(x))
from sklearn.tree import DecisionTreeClassifier as DTC
dtc = DTC(criterion='entropy') # 建立决策树模型,基于信息熵 entropy(熵)
dtc.fit(x, y) # 训练模型
# 导入相关函数,可视化决策树
# 导入结果是一个dot文件,需要安装 Graphviz 才能将他转化为PDF 或 PNG等格式
from sklearn.tree import export_graphviz
x = pd.DataFrame(x)
from sklearn.externals.six import StringIO
x = pd.DataFrame(x)
with open("tree.dot", 'w') as f:
f = export_graphviz(dtc, feature_names=x.columns, out_file=f)
--------------------------------------------------------
5-3_neural_network 待更...
-----------------------------------------------------------------------
--------------------------------------------------------5-4_k_means----------------------------------------------------------------------------
# -*- coding: utf-8 -*-
# 使用K-Means算法聚类消费行为特征数据
"""
当.py文件被直接运行时,if __name__ == '__main__'之下的代码块将被运行;
当.py文件以模块形式被导入时,if __name__ == '__main__'之下的代码块不被运行。
"""
if __name__ == '__main__':
import pandas as pd
k = 3 # 聚类的类别
iteration = 500 # 聚类最大循环次数
def initData():
# 参数初始化
inputfile = '../data/consumption_data.xls' # 销量及其他属性数据
outputfile = '../tmp/data_type.xls' # 保存结果的文件名
data = pd.read_excel(inputfile, index_col='Id') # 读取数据
data_zs = 1.0 * (data - data.mean()) / data.std() # 数据标准化,0-均值规范化
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() # 统计各个类别的数目
print(r1)
r2 = pd.DataFrame(model.cluster_centers_) # 找出聚类中心
print(r2)
r = pd.concat([r2, r1], axis=1) # 横向连接(0是纵向),得到聚类中心对应的类别下的数目
print(r)
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) # 保存结果
pic_output = '../tmp/pd_' # 概率密度图文件名前缀
for i in range(k):
density_plot(data[r[u'聚类类别'] == i]).savefig(u'%s%s.png' % (pic_output, i))
def density_plot(data): # 自定义作图函数
global k
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) # subplots = True制作子图 sharex = False是不共享X轴刻度
[p[i].set_ylabel(u'密度') for i in range(k)]
plt.legend() # 加不加这句代码都不影响
return plt
# if __name__ == '__main__': # 命令可以放在开头以及结尾,
# 面向对象编程
initData() # 调用函数
-------------------------------------------5-5_tsne------------------------------------------------------
# -*- coding: utf-8 -*-
# 接k_means.py
# 也可以面向对象编程,参考5-4_k_means.py
if __name__ == '__main__':
import pandas as pd
k = 3 # 聚类的类别
iteration = 500 # 聚类最大循环次数
inputfile = '../data/consumption_data.xls' # 销量及其他属性数据
data = pd.read_excel(inputfile, index_col='Id') # 读取数据
data_zs = 1.0 * (data - data.mean()) / data.std() # 数据标准化,0-均值规范化
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() # 统计各个类别的数目
print(r1)
r2 = pd.DataFrame(model.cluster_centers_) # 找出聚类中心
print(r2)
r = pd.concat([r2, r1], axis=1) # 横向连接(0是纵向),得到聚类中心对应的类别下的数目
print(r)
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'聚类类别'] # 重命名表头
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_5_6~~~~~~定义函数 --------------------------------------------------------------------------
# -*- coding: utf-8 -*-
from __future__ import print_function
import pandas as pd
# 自定义连接函数,用于实现L_{k-1}到C_k的连接
def connect_string(x, ms):
x = list(map(lambda i: sorted(i.split(ms)), x))
l = len(x[0])
r = []
for i in range(len(x)):
for j in range(i, len(x)):
if x[i][:l-1] == x[j][:l-1] and x[i][l-1] != x[j][l-1]:
r.append(x[i][:l-1]+sorted([x[j][l-1], x[i][l-1]]))
return r
# 寻找关联规则的函数
def find_rule(d, support, confidence, ms=u'--'):
result = pd.DataFrame(index=['support', 'confidence']) # 定义输出结果
support_series = 1.0*d.sum()/len(d) # 支持度序列
column = list(support_series[support_series > support].index) # 初步根据支持度筛选
k = 0
while len(column) > 1:
k = k+1
print(u'\n正在进行第%s次搜索...' % k)
column = connect_string(column, ms)
print(u'数目:%s...' % len(column))
sf = lambda i: d[i].prod(axis=1, numeric_only=True) # 新一批支持度的计算函数
# 创建连接数据,这一步耗时、耗内存最严重。当数据集较大时,可以考虑并行运算优化。
d_2 = pd.DataFrame(list(map(sf, column)), index=[ms.join(i) for i in column]).T
support_series_2 = 1.0*d_2[[ms.join(i) for i in column]].sum()/len(d) # 计算连接后的支持度
column = list(support_series_2[support_series_2 > support].index) # 新一轮支持度筛选
support_series = support_series.append(support_series_2)
column2 = []
for i in column: # 遍历可能的推理,如{A,B,C}究竟是A+B-->C还是B+C-->A还是C+A-->B?
i = i.split(ms)
for j in range(len(i)):
column2.append(i[:j]+i[j+1:]+i[j:j+1])
cofidence_series = pd.Series(index=[ms.join(i) for i in column2]) # 定义置信度序列
for i in column2: # 计算置信度序列
cofidence_series[ms.join(i)] = \
support_series[ms.join(sorted(i))]/support_series[ms.join(i[:len(i)-1])]
for i in cofidence_series[cofidence_series > confidence].index: # 置信度筛选
result[i] = 0.0
result[i]['confidence'] = cofidence_series[i]
result[i]['support'] = support_series[ms.join(sorted(i.split(ms)))]
result = result.T.sort_values(['confidence', 'support'], ascending=False) # 结果整理,输出
print(u'\n结果为:')
print(result)
return result
--------------------------------------------- cal_apriori~~~~~~调用apriori函数 -------------------------------------------------------------
# -*- coding: utf-8 -*-
# 使用Apriori算法挖掘菜品订单关联规则
from __future__ import print_function
import pandas as pd
from apriori_5_6 import * # 导入文件夹内自行编写的apriori_5_6函数
inputfile = '../data/menu_orders.xls'
outputfile = '../tmp/apriori_rules.xls' # 结果文件
data = pd.read_excel(inputfile, header=None)
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(list(b)).fillna(0) # 实现矩阵转换,空值用0填充
print(u'\n转换完毕。')
del b # 删除中间变量b,节省内存
support = 0.2 # 最小支持度
confidence = 0.5 # 最小置信度
ms = '---' # 连接符,默认'--',用来区分不同元素,如A--B。需要保证原始表格中不含有该字符
find_rule(data, support, confidence, ms).to_excel(outputfile) # 保存结果
--------------------------------------------------------5-7_arima_test---------------------------------------------------------------------
# -*- coding: utf-8 -*-
# arima时序模型
import pandas as pd
# 参数初始化
discfile = '../data/arima_data.xls'
forecastnum = 5
# 读取数据,指定日期列为指标,Pandas自动将“日期”列识别为Datetime格式
data = pd.read_excel(discfile, index_col=u'日期')
# 时序图
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
data.plot()
plt.show()
# 自相关图
from statsmodels.graphics.tsaplots import plot_acf
plot_acf(data).show()
# 平稳性检测
from statsmodels.tsa.stattools import adfuller as ADF
print(u'原始序列的ADF检验结果为:', ADF(data[u'销量']))
# 返回值依次为adf、pvalue、usedlag、nobs、critical values、icbest、regresults、resstore
# 差分后的结果
D_data = data.diff().dropna()
D_data.columns = [u'销量差分']
D_data.plot() # 时序图
plt.show()
plot_acf(D_data).show() # 自相关图
from statsmodels.graphics.tsaplots import plot_pacf
plot_pacf(D_data).show() # 偏自相关图
print(u'差分序列的ADF检验结果为:', ADF(D_data[u'销量差分'])) # 平稳性检测
# 白噪声检验
from statsmodels.stats.diagnostic import acorr_ljungbox
print(u'差分序列的白噪声检验结果为:', acorr_ljungbox(D_data, lags=1)) # 返回统计量和p值
from statsmodels.tsa.arima_model import ARIMA
data[u'销量'] = data[u'销量'].astype(float)
# 定阶
pmax = int(len(D_data)/10) # 一般阶数不超过length/10
qmax = int(len(D_data)/10) # 一般阶数不超过length/10
bic_matrix = [] # bic矩阵
for p in range(pmax+1):
tmp = []
for q in range(qmax+1):
try: # 存在部分报错,所以用try来跳过报错。
tmp.append(ARIMA(data, (p,1,q)).fit().bic)
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))
model = ARIMA(data, (p, 1, q)).fit() # 建立ARIMA(0, 1, 1)模型
model.summary2() # 给出一份模型报告
model.forecast(5) # 作为期5天的预测,返回预测结果、标准误差、置信区间。
-------------------------------------------------------5-8_discrete_point_test--------------------------------------------------------------------
# -*- coding: utf-8 -*-
# 使用K-Means算法聚类消费行为特征数据
# 聚类结果参见 5-4_k_means.py
if __name__ == '__main__':
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) # 求出绝对距离
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()