Table of Contents
寫在前面:
博主在使用《python數據分析與挖掘》過程中發現書籍附上的代碼存在部分問題(Python版本、語法錯誤、書寫不規範、註釋不夠詳盡等),根據自身情況對代碼進行修正,同時分享出來供大家一起研究與探討。文章只提供代碼,數據集還需要到書籍官網下載http://www.tipdm.org/ts/661.jhtml
代碼導入數據集的的過程,參考CMD文件夾的切換模式(命令行語法)
環境:
解釋器:Python 3
開發IDE:pycharm
解釋器:anaconda3
chapter3
----------------------------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()
chapter4
---------------------------------------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)) # 函數來複原數據
chapter5
---------------------------------------------------5-1_logistic_regression----------------------------------------------------------------------------
# -*- coding: utf-8 -*-
# 邏輯迴歸 建模
import pandas as pd
# 參數初始化
filename = '../data/bankloan.xls'
data = pd.read_excel(filename)
x = data.iloc[:, :8] # <class 'pandas.core.frame.DataFrame'>
# x = data.iloc[:, :8].as_matrix() # .as_matrix() 將DataFrame轉化爲ndarray
y = data.iloc[:, 8].as_matrix() # 第九列數據爲因變量
print(type(data)) # <class 'pandas.core.frame.DataFrame'>
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)) # <class 'numpy.ndarray'>
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()
chapter6
chapter7
chapter8
chapter9
chapter10
chapter11
待更...