《Python数据分析与挖掘实战》Chapter8中医证型关联规则挖掘笔记

最近在学习《Python数据分析与挖掘实战》中的案例,写写自己的心得。

代码分为两大部分:1.读取数据并进行聚类分析

                                 2.应用Apriori关联规则挖掘规律

1.聚类部分函数分析:

def programmer_1():

    datafile = "C:/Users/longming/Desktop/chapter8/data/data.xls"
    processedfile = "C:/Users/longming/Desktop/chapter8/tmp/data_processed.xls"
    typelabel = {
        u"肝气郁结证型系数": "A",
        u"热毒蕴结证型系数": "B",
        u"冲任失调证型系数": "C",
        u"气血两虚证型系数": "D",
        u"脾胃虚弱证型系数": "E",
        u"肝肾阴虚证型系数": "F",
    }
    k = 4#聚类数目

    data = pd.read_excel(datafile)
    result = pd.DataFrame()
    #创建空数据帧
    #print(typelabel.items()) 测试.items()方法,返回以元组为元素的列表
    for key, item in typelabel.items():
        print(u"正在进行“%s”的聚类..." % key)
        # 进行聚类离散化
        kmodel = KMeans(n_clusters=k, n_jobs=4)
        print(data['key'])
        kmodel.fit(data[[key]].as_matrix())
        #转换为numpy数组.as_matrix()
        # 聚类中心
        r1 = pd.DataFrame(kmodel.cluster_centers_, columns=[item])
        # 分类统计
        r2 = pd.Series(kmodel.labels_).value_counts()
        r2 = pd.DataFrame(r2, columns=[item + "n"])
        # 合并为一个DataFrame
        r = pd.concat([r1, r2], axis=1).sort_values(item)
        r.index = list(range(1, 5))#设置行标签
        # 用来计算相邻两列的均值,以此作为边界点
        r[item] = pd.Series.rolling(r[item], 2).mean()
        # 将NaN值转为0.0,不用fillna的原因是数值类型是float64
        r.loc[1, item] = 0.0
        result = result.append(r.T)
    # 以ABCDEF排序
    result = result.sort_index()
    result.to_excel(processedfile)

其中24行的data[[key]].as_matrix(),df[['列名']]属于按列读取。

.as_matrix()保存为numpy数组。

2.Apriori关联规则算法

# 自定义连接函数
def connect_string(x, ms):
    x = list(map(lambda i: sorted(i.split(ms)), x))
    r = []
    for i in range(len(x)):
        for j in range(i + 1, len(x)):
            if x[i][:-1] == x[j][:-1] and x[i][-1] != x[j][-1]:
                r.append(x[i][:-1] + sorted([x[j][-1], x[i][-1]]))#长度+1
    #print(r)
    return r


# 寻找关联规则函数
def find_rule(d, support, confidence, ms=u"--"):
    result = pd.DataFrame(index=["support", "confidence"])
    print(result)
    # 第一批支持度筛选
    support_series = 1.0 * d.sum() / len(d)
    #dataframe.sum()返回一个含有列小计的Series,axis=0代表对列进行求和
    #调用DataFrame的sum方法将会返回一个含有列小计的Series:传入axis=1将会按行进行求和运算
    
    #print(support_series)
    #逐行计算
    column = list(support_series[support_series > support].index)
    #attribute:.index属于series,查找series的标签
    #print(column)
    k = 0

    while len(column) > 1:
        k = k + 1
        print(u"\n正在进行第%s次搜索..." % k)

        column = connect_string(column, ms)
        #print(column) 返回频繁项组合
        print(u"数目%s..." % len(column))
        index_lst = [ms.join(i) for i in column]
        #print(index_lst)
        # 新的支持度函数 .prod(axis=1)返回行方向乘积
        sf = lambda i: d[i].prod(axis=1, numeric_only=True)
        # 计算连接后的支持度,开始筛选
        d_2 = pd.DataFrame(list(map(sf, column)), index=index_lst).T
        #print(d_2) 
        support_series_2 = 1.0 * d_2[index_lst].sum() / len(d)
        #print(support_series_2)
        column = list(support_series_2[support_series_2 > support].index)
        #print(column)
        support_series = support_series.append(support_series_2)
        # print(support_series)
        column2 = []
        # 遍历所有可能的情况
        for i in column:
            i = i.split(ms)
            for j in range(len(i)):
                column2.append(i[:j] + i[j + 1:] + i[j:j + 1])
        #将column中的标签排列出更多组合
        #print(column2)
        # 置信度序列
        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[:-1])]
        #print(cofidence_series)
        # 置信度筛选
        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)))]
            #join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串。
    print(result)
    result = result.T.sort_values(["confidence", "support"], ascending=False)
    #.sort_values 按任意轴的值进行排序,ascending=False降序
    print(u"\nresult:")
    print(result)

    return result


def programmer_2():
    inputfile = "D:\Dream_way\python_data_analysis_and_mining_action-master\chapter8\data/apriori.txt"
    data = pd.read_csv(inputfile, header=None, dtype=object)
    #print(data)
    # 计时
    start = time.clock()
    print(u"\n转换原始数据至0-1矩阵...")
    # 0-1矩阵的转换
    ct = lambda x: pd.Series(1, index=x[pd.notnull(x)])
    b = list(map(ct, data.as_matrix()))
    #生成1维series,map()映射函数到特定对象
    #print(b)
    """ a = pd.DataFrame(b)
    print(a) """
    data = pd.DataFrame(b).fillna(0)
    #print(data)
    end = time.clock()
    print(u"\n转换完毕,用时:%0.2f s" % (end - start))
    # 删除中间变量b,节省内存
    del b

    # 定义支持度,置信度,连接符号
    support = 0.06
    confidence = 0.75
    ms = "---"

    # 计时
    start = time.clock()
    print(u"\n开始搜索关联规则...")
    find_rule(data, support, confidence, ms)
    end = time.clock()
    print(u"\n搜索完成,用时%0.2f s" % (end - start))

    一点理解:

data = pd.DataFrame(b).fillna(0)

 将一维Series转换成Dataframe,Nan值用 .fillna(0)方法填充

data此时结构如下所示:

      A2   B1   C3   D3   E1   F1   H1   B2   A1   C1   D1   E2   H2   A3   D2   E3   C2   H3   B4   E4   H4   D4   A4   B3   F2   C4   F3   F4
0    1.0  1.0  1.0  1.0  1.0  1.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
1    1.0  1.0  1.0  1.0  1.0  1.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
2    1.0  1.0  1.0  1.0  1.0  1.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
3    1.0  1.0  1.0  1.0  1.0  1.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
support_series = 1.0 * d.sum() / len(d)

这里的d是Dataframe格式,对于这种格式, .sum()返回一维Series格式。

3.Apriori算法解析

参考:1.https://wizardforcel.gitbooks.io/dm-algo-top10/content/apriori.html

           2.白宁超的官网https://bainingchao.github.io/2018/09/27/%E4%B8%80%E6%AD%A5%E6%AD%A5%E6%95%99%E4%BD%A0%E8%BD%BB%E6%9D%BE%E5%AD%A6%E5%85%B3%E8%81%94%E8%A7%84%E5%88%99Apriori%E7%AE%97%E6%B3%95/

建议参考第二个理解原理。

       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值