python數據分析與挖掘 --- 代碼修正與項目練習

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

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

 

 

待更...

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章