In [1]:
pip list
Package                            Version            
---------------------------------- -------------------
alabaster                          0.7.12             
anaconda-client                    1.7.2              
anaconda-navigator                 1.9.12             
anaconda-project                   0.8.3              
argh                               0.26.2             
asn1crypto                         1.3.0              
astroid                            2.3.3              
astropy                            4.0                
atomicwrites                       1.3.0              
attrs                              19.3.0             
autopep8                           1.4.4              
Babel                              2.8.0              
backcall                           0.1.0              
backports.functools-lru-cache      1.6.1              
backports.shutil-get-terminal-size 1.0.0              
backports.tempfile                 1.0                
backports.weakref                  1.0.post1          
bcrypt                             3.1.7              
beautifulsoup4                     4.8.2              
bitarray                           1.2.1              
bkcharts                           0.2                
bleach                             3.1.0              
bokeh                              1.4.0              
boto                               2.49.0             
Bottleneck                         1.3.2              
certifi                            2019.11.28         
cffi                               1.14.0             
chardet                            3.0.4              
chart-studio                       1.1.0              
Click                              7.0                
cloudpickle                        1.3.0              
clyent                             1.2.2              
colorama                           0.4.3              
colorlover                         0.3.0              
comtypes                           1.1.7              
conda                              4.8.2              
conda-build                        3.18.11            
conda-package-handling             1.6.0              
conda-verify                       3.4.2              
contextlib2                        0.6.0.post1        
cryptography                       2.8                
cycler                             0.10.0             
Cython                             0.29.15            
cytoolz                            0.10.1             
dask                               2.11.0             
decorator                          4.4.1              
defusedxml                         0.6.0              
diff-match-patch                   20181111           
distributed                        2.11.0             
docutils                           0.16               
entrypoints                        0.3                
et-xmlfile                         1.0.1              
fastcache                          1.1.0              
filelock                           3.0.12             
flake8                             3.7.9              
Flask                              1.1.1              
fsspec                             0.6.2              
future                             0.18.2             
gevent                             1.4.0              
glob2                              0.7                
graphviz                           0.19               
greenlet                           0.4.15             
h5py                               2.10.0             
HeapDict                           1.0.1              
html5lib                           1.0.1              
hypothesis                         5.5.4              
idna                               2.8                
imageio                            2.6.1              
imagesize                          1.2.0              
importlib-metadata                 1.5.0              
intervaltree                       3.0.2              
ipykernel                          5.1.4              
ipython                            7.12.0             
ipython-genutils                   0.2.0              
ipywidgets                         7.5.1              
isort                              4.3.21             
itsdangerous                       1.1.0              
jdcal                              1.4.1              
jedi                               0.14.1             
Jinja2                             2.11.1             
joblib                             0.14.1             
json5                              0.9.1              
jsonschema                         3.2.0              
jupyter                            1.0.0              
jupyter-client                     5.3.4              
jupyter-console                    6.1.0              
jupyter-core                       4.6.1              
jupyterlab                         1.2.6              
jupyterlab-server                  1.0.6              
keyring                            21.1.0             
kiwisolver                         1.1.0              
lazy-object-proxy                  1.4.3              
libarchive-c                       2.8                
llvmlite                           0.31.0             
locket                             0.2.0              
lxml                               4.5.0              
MarkupSafe                         1.1.1              
matplotlib                         3.1.3              
mccabe                             0.6.1              
menuinst                           1.4.16             
mistune                            0.8.4              
mkl-fft                            1.0.15             
mkl-random                         1.1.0              
mkl-service                        2.3.0              
mlxtend                            0.19.0             
mock                               4.0.1              
more-itertools                     8.2.0              
mpmath                             1.1.0              
msgpack                            0.6.1              
multipledispatch                   0.6.0              
navigator-updater                  0.2.1              
nbconvert                          5.6.1              
nbformat                           5.0.4              
nbmerge                            0.0.4              
networkx                           2.4                
nltk                               3.4.5              
nose                               1.3.7              
notebook                           6.0.3              
numba                              0.48.0             
numexpr                            2.7.1              
numpy                              1.18.1             
numpydoc                           0.9.2              
olefile                            0.46               
openpyxl                           3.0.3              
packaging                          20.1               
pandas                             1.0.1              
pandasql                           0.7.3              
pandocfilters                      1.4.2              
paramiko                           2.7.1              
parso                              0.5.2              
partd                              1.1.0              
path                               13.1.0             
pathlib2                           2.3.5              
pathtools                          0.1.2              
patsy                              0.5.1              
pep8                               1.7.1              
pexpect                            4.8.0              
pickleshare                        0.7.5              
Pillow                             7.0.0              
pip                                20.0.2             
pkginfo                            1.5.0.1            
plotly                             5.5.0              
pluggy                             0.13.1             
ply                                3.11               
prometheus-client                  0.7.1              
prompt-toolkit                     3.0.3              
psutil                             5.6.7              
py                                 1.8.1              
pycodestyle                        2.5.0              
pycosat                            0.6.3              
pycparser                          2.19               
pycrypto                           2.6.1              
pycurl                             7.43.0.5           
pydocstyle                         4.0.1              
pyflakes                           2.1.1              
Pygments                           2.5.2              
pylint                             2.4.4              
PyNaCl                             1.3.0              
pyodbc                             4.0.0-unsupported  
pyOpenSSL                          19.1.0             
pyparsing                          2.4.6              
pyreadline                         2.1                
pyrsistent                         0.15.7             
PySocks                            1.7.1              
pytest                             5.3.5              
pytest-arraydiff                   0.3                
pytest-astropy                     0.8.0              
pytest-astropy-header              0.1.2              
pytest-doctestplus                 0.5.0              
pytest-openfiles                   0.4.0              
pytest-remotedata                  0.3.2              
python-dateutil                    2.8.1              
python-jsonrpc-server              0.3.4              
python-language-server             0.31.7             
pytz                               2019.3             
PyWavelets                         1.1.1              
pywin32                            227                
pywin32-ctypes                     0.2.0              
pywinpty                           0.5.7              
PyYAML                             5.3                
pyzmq                              18.1.1             
QDarkStyle                         2.8                
QtAwesome                          0.6.1              
qtconsole                          4.6.0              
QtPy                               1.9.0              
requests                           2.22.0             
retrying                           1.3.3              
rope                               0.16.0             
Rtree                              0.9.3              
ruamel-yaml                        0.15.87            
scikit-image                       0.16.2             
scikit-learn                       0.22.1             
scipy                              1.4.1              
seaborn                            0.10.0             
Send2Trash                         1.5.0              
setuptools                         45.2.0.post20200210
simplegeneric                      0.8.1              
singledispatch                     3.4.0.3            
six                                1.14.0             
snowballstemmer                    2.0.0              
sortedcollections                  1.1.2              
sortedcontainers                   2.1.0              
soupsieve                          1.9.5              
Sphinx                             2.4.0              
sphinxcontrib-applehelp            1.0.1              
sphinxcontrib-devhelp              1.0.1              
sphinxcontrib-htmlhelp             1.0.2              
sphinxcontrib-jsmath               1.0.1              
sphinxcontrib-qthelp               1.0.2              
sphinxcontrib-serializinghtml      1.1.3              
sphinxcontrib-websupport           1.2.0              
spyder                             4.0.1              
spyder-kernels                     1.8.1              
SQLAlchemy                         1.3.13             
statsmodels                        0.11.0             
sympy                              1.5.1              
tables                             3.6.1              
tblib                              1.6.0              
tenacity                           8.0.1              
terminado                          0.8.3              
testpath                           0.4.4              
toolz                              0.10.0             
tornado                            6.0.3              
tqdm                               4.42.1             
traitlets                          4.3.3              
ujson                              1.35               
unicodecsv                         0.14.1             
urllib3                            1.25.8             
watchdog                           0.10.2             
wcwidth                            0.1.8              
webencodings                       0.5.1              
Werkzeug                           1.0.0              
wheel                              0.34.2             
widgetsnbextension                 3.5.1              
win-inet-pton                      1.1.0              
win-unicode-console                0.5                
wincertstore                       0.2                
wrapt                              1.11.2             
xlrd                               1.2.0              
XlsxWriter                         1.2.7              
xlwings                            0.17.1             
xlwt                               1.3.0              
xmltodict                          0.12.0             
yapf                               0.28.0             
zict                               1.0.0              
zipp                               2.2.0              
Note: you may need to restart the kernel to use updated packages.

构建 FP 树

辅助类:FP树的数据结构

In [2]:
class treeNode:
    """
    parameters:
                nameValue:当前节点项名称
                numOccur:项的频数
                parentNode:当前结点的父节点
    """
    def __init__(self, nameValue, numOccur, parentNode):
        self.name = nameValue                 # 当前节点项名称
        self.count = numOccur                 # 项的频数
        self.nodeLink = None                  # 用于连接相似元素项(FP树蓝色的虚线)
        self.parent = parentNode              # 当前父节点
        self.children = {}                    # 用于存放子节点的字典
    
    def increase(self, numOccur):
        self.count += numOccur
    
    def show(self, ind=1):
        print(' '*ind, self.name, ' ', self.count)
        for child in self.children.values():
            child.show(ind+1) #子节点向右缩减
In [3]:
#创建一个单节点
rootNode = treeNode('这是父节点',9,None)

#创建一个子节点
rootNode.children['这是子节点'] = treeNode('这是子节点',13,None)

#显示节点
rootNode.show()
  这是父节点   9
   这是子节点   13
In [4]:
#再增加一个子节点
rootNode.children['这是另一个子节点'] = treeNode('这是另一个子节点',3,None)

#显示节点
rootNode.show()
  这是父节点   9
   这是子节点   13
   这是另一个子节点   3

辅助函数1:创建数据集

In [5]:
def loadSimpDat():
    """
    Return:
            simpDat:list,数据集
    """

    simpDat = [
                ['I1', 'I2', 'I5'],
                ['I2', 'I4'],
                ['I2', 'I3'],
                ['I1', 'I2', 'I4'],
                ['I1', 'I3'],
                ['I2', 'I3'],
                ['I1', 'I3'],
                ['I1', 'I2', 'I3', 'I5'],
                ['I1', 'I2', 'I3']
            ]
    return simpDat

主函数:创建数据集

In [6]:
simpDat = loadSimpDat()
simpDat
Out[6]:
[['I1', 'I2', 'I5'],
 ['I2', 'I4'],
 ['I2', 'I3'],
 ['I1', 'I2', 'I4'],
 ['I1', 'I3'],
 ['I2', 'I3'],
 ['I1', 'I3'],
 ['I1', 'I2', 'I3', 'I5'],
 ['I1', 'I2', 'I3']]

辅助函数2:格式化数据集

现在输入的数据集是列表,需要进行格式化操作,将其转变为固定格式(frozenset)
转换为 项列表 : 频数 的形式。

In [7]:
def createInitSet(dataSet):
    """
    parameters:
            dataSet:list,数据集
    Return:
            retDict:dict,格式化后的数据集
    """
    retDict = {}
    for trans in dataSet:
        fset = frozenset(trans)
        retDict.setdefault(fset, 0) # python字典自带函数,如果字典中包含有给定键,则返回该键对应的值,否则(不存在于字典中),添加键并将值设为默认值,返回为该键设置的值。
        retDict[fset] += 1
    return retDict
In [8]:
retDict = createInitSet(simpDat) # 辅助函数2:格式化数据集
retDict
Out[8]:
{frozenset({'I1', 'I2', 'I5'}): 1,
 frozenset({'I2', 'I4'}): 1,
 frozenset({'I2', 'I3'}): 2,
 frozenset({'I1', 'I2', 'I4'}): 1,
 frozenset({'I1', 'I3'}): 2,
 frozenset({'I1', 'I2', 'I3', 'I5'}): 1,
 frozenset({'I1', 'I2', 'I3'}): 1}

辅助函数3:更新头指针表

确保FP树中每一条蓝色的虚线都指向树中的每一个结点。
Ps:这一部分涉及到数据结构中的指针指向问题。看不懂的需要自行复习指针内容。

In [9]:
def updateHeader(nodeToTest, targetNode):
    """
    parameters:
        targetNode:treeNode自定义的数据结构,
        targetNode:treeNode自定义的数据结构,目标结点
    """
    while (nodeToTest.nodeLink != None):   # nodeToTest的下一个相似项不为空,即不是最后一个结点。最后一个目标结点的nodeLink为null
        nodeToTest = nodeToTest.nodeLink   # nodeToTest指向nodeToTest的nodeLink,相当于结点指针后移。
    nodeToTest.nodeLink = targetNode       # 最后一个结点的nodeLink存放targetNode的地址。

辅助函数4:FP树的生长函数

首先测试事务中第一个元素项是不是子节点,
如果是子节点,则更新count参数(+1);
如果不是子节点,则创建一个新的treeNode作为子节点添加到树中。此时,头指针表也要跟着更新以指向新的节点(调用updateHeader()函数)。如果item中不止一个元素项的话,则将剩下的元素项作为参数进行迭代。

In [10]:
def updateTree(items, myTree, headerTable, count):
    """
    Parameters:
        items:项名称
        myTree:treeNode类的对象,FP树
        headerTable:dict,头指针表
        count:int,计数
    """
    # 检查事务项中的第一个元素是否作为树的直接子节点存在
    if items[0] in myTree.children:                                   
        # 如果是子节点,则更新count参数(+1);
        myTree.children[items[0]].increase(count)
    else:
        # 不存在则更新树结构
        myTree.children[items[0]] = treeNode(items[0], count, myTree) # 创建一个新的treeNode作为子节点添加到树中
        # 更新表结构
        if headerTable[items[0]][1] == None:                          # 如果头指针表未更新,即未指向新的结点。
            headerTable[items[0]][1] = myTree.children[items[0]]      
        else:
            updateHeader(headerTable[items[0]][1], myTree.children[items[0]])
    # 递归调用此树生长函数
    if len(items) > 1:
        updateTree(items[1:], myTree.children[items[0]], headerTable, count) # 递归使得FP树生长。

辅助函数5:创建树

In [11]:
def createTree(dataSet, minSup=1):
    """
    Parameters:
        dataSet:dict,格式化后的数据集
        minSup:int,最小支持度
    Return:
        myTree:treeNode类的对象,FP树
        headerTable:dict,头指针表
    """
     
    # 连续两次遍历数据集。第一次获取所有数据项及个数;第二次会支持度过滤。
    # 获取所有数据项及个数
    headerTable = {}
    for trans in dataSet:
        for item in trans:
            headerTable[item] = headerTable.get(item, 0) + dataSet[trans]
    
    # 支持度过滤
    for k in headerTable.keys():
        if headerTable[k] < minSup: 
            continue
     
    # 单元素的频繁项集(不含次数)
    freqItemSet = set(headerTable.keys())
    
    # 如果所有数据都不满足最小支持度,则退出
    if len(freqItemSet) == 0: 
        return None, None
    
    # 对表数据结构进行格式化,使之能够存放指针。
    for k in headerTable:
        headerTable[k] = [headerTable[k], None]
     
    # 新建初始化树节点
    retTree = treeNode('φ', 1, None)
    
    #第二次遍历数据集,构建fp-tree
    for tranSet, count in dataSet.items():
        # 根据最小支持度处理一条训练样本,字典中 key:项名称,value:该样例的的全局支持度
        localD = {}                # 当前事务的单元素集(含次数)
        for item in tranSet:
            if item in freqItemSet:
                localD[item] = headerTable[item][0]
        
        if len(localD) > 0:
            # 根据全局频繁项对localD(每个事务中)的所有元素进行降序排序
            orderedItems = [v[0] for v in sorted(localD.items(), key=lambda p: p[1], reverse=True)]
            # 更新 FP 树
            updateTree(orderedItems, retTree, headerTable, count)
     
    # 返回FP树和表头结构       
    return retTree, headerTable

主函数:创建FP树

In [12]:
myTree, headerTable = createTree(retDict,minSup=2) # 主函数:创建树
In [13]:
myTree.show() # 显示FP树
  φ   1
   I2   7
    I1   4
     I5   1
     I4   1
     I3   2
      I5   1
    I4   1
    I3   2
   I1   2
    I3   2
In [14]:
headerTable   # 记录每个数据项的支持度
Out[14]:
{'I2': [7, <__main__.treeNode at 0x25b62ff9088>],
 'I1': [6, <__main__.treeNode at 0x25b62ff90c8>],
 'I5': [2, <__main__.treeNode at 0x25b62ff9188>],
 'I4': [2, <__main__.treeNode at 0x25b62ff9048>],
 'I3': [6, <__main__.treeNode at 0x25b62ff9108>]}

image.png

二、从FP树中挖掘频繁项集

条件模式基的抽取

辅助函数6:

In [15]:
def ascendTree(leafNode, prefixPath):
    """
    获取FP树某个叶子节点的前缀路径
    """

    if leafNode.parent != None:
        prefixPath.append(leafNode.name)
        ascendTree(leafNode.parent, prefixPath)      

辅助函数7:创建条件模式基

In [16]:
def findPrefixPath(basePat, headerTable):
    """
    Parameters:
        basePat:string,项名称
        headerTable:dict,头指针表
    Return:
        condPats:dict,
    """
    condPats = {}
    treeNode = headerTable[basePat][1]
    
    while treeNode != None:
        prefixPath = []
        ascendTree(treeNode, prefixPath)
        if len(prefixPath) > 1:
            condPats[frozenset(prefixPath[1:])] = treeNode.count
        treeNode = treeNode.nodeLink
    return condPats

主函数:创建条件模式基

项:Head Table item列第一个不要,剩下的倒叙写。
可参考:https://gaozhiyuan.me/machine-learning/fp-growth.html#FP3

In [17]:
condPats = findPrefixPath('I5', headerTable)
print('I5', condPats)

condPats = findPrefixPath('I4', headerTable)
print('I4', condPats)

condPats = findPrefixPath('I3', headerTable)
print('I3', condPats)

condPats = findPrefixPath('I1', headerTable)
print('I1', condPats)
I5 {frozenset({'I2', 'I1'}): 1, frozenset({'I2', 'I1', 'I3'}): 1}
I4 {frozenset({'I2'}): 1, frozenset({'I2', 'I1'}): 1}
I3 {frozenset({'I2'}): 2, frozenset({'I1'}): 2, frozenset({'I2', 'I1'}): 2}
I1 {frozenset({'I2'}): 4}

Pasted-into-FP-growth%E7%AE%97%E6%B3%95%EF%BC%9A%E9%AB%98%E6%95%88%E7%9A%84%E5%8F%91%E7%8E%B0%E9%A2%91%E7%B9%81%E9%A1%B9%E9%9B%86-18.png

创造条件FP树

辅助函数8:由条件模式基创建条件FP树

In [18]:
def mineTree(inTree, headerTable, minSup=1, preFix=set([]), freqItemList=[]):
    """
    Parameters:
        inTree:__main__.treeNode,FP树
        headerTable:dict,头指针表
        minSup:int,最小支持度
        preFix:
        freqItemList:
    Return:
        null
    """
    #排序minSup asc, value asc。对表结构进行重排序(由小到大)
    bigL = [v[0] for v in sorted(headerTable.items(), key=lambda p:p[1][0])]
    
    # 遍历表结构
    for basePat in bigL:
        # 生成新频繁子项
        newFreqSet = preFix.copy()
        newFreqSet.add(basePat)
        
        # 加入频繁集
        freqItemList.append(newFreqSet)
        
        # 挖掘新的条件模式基
        condPattBases = findPrefixPath(basePat, headerTable)   # 主函数:创建条件模式基
        
        # 建立新的条件FP树
        myCondTree, myHead = createTree(condPattBases, minSup) # 主函数:创建树

        # 若表结构非空,递归挖掘。
        if myHead != None:
            print('条件FP树:')
            myCondTree.show()
            print('\n')
            mineTree(myCondTree, myHead, minSup, newFreqSet, freqItemList)
    

主函数:创造条件FP树并输出频繁项集

In [19]:
# simpDat = loadSimpDat()                            # 加载数据集
# retDict = createInitSet(simpDat)                   # 辅助函数2:格式化数据集
# myTree, headerTable = createTree(retDict,minSup=2) # 主函数:创建树

my_freq_list = []
mineTree(myTree, headerTable, 2, set([]), my_freq_list)
print("支持度大于2的频繁项集:", my_freq_list)
print("支持度大于2的频繁项集数:", len(my_freq_list))
条件FP树:
  φ   1
   I2   2
    I1   2
     I3   1


条件FP树:
  φ   1
   I2   1
    I1   1


条件FP树:
  φ   1
   I2   1


条件FP树:
  φ   1
   I2   2


条件FP树:
  φ   1
   I2   2
    I1   1


条件FP树:
  φ   1
   I2   1


条件FP树:
  φ   1
   I2   4


条件FP树:
  φ   1
   I2   4
    I1   2
   I1   2


条件FP树:
  φ   1
   I2   2


支持度大于2的频繁项集: [{'I5'}, {'I3', 'I5'}, {'I3', 'I2', 'I5'}, {'I3', 'I1', 'I5'}, {'I3', 'I2', 'I1', 'I5'}, {'I2', 'I5'}, {'I1', 'I5'}, {'I2', 'I1', 'I5'}, {'I4'}, {'I1', 'I4'}, {'I2', 'I1', 'I4'}, {'I2', 'I4'}, {'I1'}, {'I2', 'I1'}, {'I3'}, {'I2', 'I3'}, {'I1', 'I3'}, {'I2', 'I1', 'I3'}, {'I2'}]
支持度大于2的频繁项集数: 19
In [ ]: