粘貼不了新的東西(粘貼突然不能用了)
1037
2025-04-01
【Python算法】關聯規則算法——Apriori算法
1.關聯規則
所謂關聯,反映的是一個事件和其他事件之間依賴或關聯的知識。當查找某些東西的時候,可以發現有兩個或兩個以上都有關聯的含義。第一個是相關性relevance,第二個是關聯性association,兩者都可以用來描述事件之間的關聯程度。
2.Apriori算法簡介
Apriori算法是經典的挖掘頻繁項集和關聯規則的數據挖掘算法。其核心思想是通過候選集生成和情節的向下封閉檢測兩個階段來挖掘頻繁項集,它使用一種稱為逐層搜索的迭代方法,其中k項集用于探索(k+1)項集。首先,通過掃描數據庫,累計每個項的計數,并收集滿足最小支持度的項,找出頻繁1項集的集合。該集合記為L1。然后,使用L1找出頻繁2項集的集合L2,使用L2找出L3,如此下去,直到不能再找到頻繁 k 項集。每找出一個Lk需要一次數據庫的完整掃描。Apriori算法使用頻繁項集的先驗性質來壓縮搜索空間。在Apriori算法中,有以下幾個關鍵概念:
(1)項與項集:設itemset={item1, item_2, …, item_m}是所有項的集合,其中,item_k(k=1,2,…,m)成為項。項的集合稱為項集(itemset),包含k個項的項集稱為k項集(k-itemset);
(2)事務與事務集:一個事務T是一個項集,它是itemset的一個子集,每個事務均與一個唯一標識符Tid相聯系。不同的事務一起組成了事務集D,它構成了關聯規則發現的事務數據庫;
(3)關聯規則:關聯規則是形如A=>B的蘊涵式,其中A、B均為 itemset的子集且均不為空集,而A交B為空;
支持度(support):關聯規則的支持度定義如下:
support(A? B) = P(AUB)
其中P(AUB) 表示事務包含集合A和B的并(即包含A和B中的每個項)的概率。注意與P(A or B)的區別,后者表示事務包含A或B的概率。
(1) 置信度(confidence):關聯規則的置信度定義如下:
confidence(A\Rightarrow B)=P(B|A)=\frac {support(A\bigcup B)}{support(A)}=\frac{support \_count(A\bigcup B)}{support\_count(A)}
(2) 項集的出現頻度(support count):包含項集的事務數,簡稱為項集的頻度、支持度計數或計數;
(3) 頻繁項集(frequent itemset):如果項集 1 的相對支持度滿足事先定義好的最小支持度閾值(即 1 的出現頻度大于相應的最小出現頻度(支持度計數)閾值),則 1 是頻繁項集;
(4) 強關聯規則:滿足最小支持度和最小置信度的關聯規則,即待挖掘的關聯規則。
3.挖掘項集相關定義
連接步驟:
頻繁(k-1)項集Lk-1的自身連接產生候選 k 項集Ck。
Apriori算法假定項集中的項按照字典序排序。如果Lk-1中某兩個的元素(項集)itemset1和itemset2的前(k-2)個項是相同的,則稱itemset1和itemset2是可連接的。所以 itemset1與itemset2連接產生的結果項集是{itemset1[1], itemset1[2], …, itemset1[k-1], itemset2[k-1]}。連接步驟包含在create_Ck函數中。
剪枝策略 :
由于存在先驗性質:任何非頻繁的(k-1)項集都不是頻繁k項集的子集。因此,如果一個候選k項集Ck的(k-1)項子集不在Lk-1中,則該候選也不可能是頻繁的,從而可以從Ck中刪除,獲得壓縮后的Ck。(is_apriori)函數用于判斷是否滿足先驗性質,(create_Ck)函數中包含剪枝步驟,即若不滿足先驗性質,剪枝。
刪除策略 :
基于壓縮后的Ck,掃描所有事務,對Ck中的每個項進行計數,然后刪除不滿足最小支持度的項,從而獲得頻繁k項集。刪除策略包含在下文代碼中的(generate_Lk_by_Ck)函數中。
每個項都是候選1項集的集合C1的成員。算法掃描所有的事務,獲得每個項,生成C1。然后對每個項進行計數。然后根據最小支持度從C1中刪除不滿足的項,從而獲得頻繁1項集L1。 對L1的自身連接生成的集合執行剪枝策略產生候選2項集的集合C2,然后,掃描所有事務,對C2中每個項進行計數。同樣的,根據最小支持度從C2中刪除不滿足的項,從而獲得頻繁2項集L2。
對L2的自身連接生成的集合執行剪枝策略產生候選3項集的集合C3,然后,掃描所有事務,對C3每個項進行計數。同樣的,根據最小支持度從C3 中刪除不滿足的項,從而獲得頻繁3項集L3。
以此類推,對Lk-1的自身連接生成的集合執行剪枝策略產生候選k項集Ck,然后掃描所有事務,對Ck中的每個項進行計數。然后根據最小支持度從Ck中刪除不滿足的項,從而獲得頻繁k項集。
由頻繁項集產生關聯規則一旦找出了頻繁項集,就可以直接由它們產生強關聯規則。產生步驟如下:對于每個頻繁項集itemset,產生itemset的所有非空子集(這些非空子集一定是頻繁項集); 對于 itemset 的每個非空子集 s,如果則輸出s ? (l?s) ,其中min_conf是最小置信度閾值。
關聯分析
關聯分析是一種在大規模數據集中尋找有趣關系的任務。 這些關系可以有兩種形式:
(1) 頻繁項集(frequent item sets): 經常出現在一塊的物品的集合。
(2) 關聯規則(associational rules): 暗示兩種物品之間可能存在很強的關系。
相關術語
關聯分析(關聯規則學習): 從大規模數據集中尋找物品間的隱含關系被稱作關聯分析(associati analysis) 或者關聯規則學習(association rule learning) 。 下面是用一個雜貨店 例子來說明這兩個概念,如圖1所示:
頻繁項集: {葡萄酒, 尿布, 豆奶} 就是一個頻繁項集的例子。
關聯規則: 尿布 -> 葡萄酒 就是一個關聯規則。這意味著如果顧客買了尿布,那么他很可能會買葡萄酒。
那么頻繁的定義是什么呢?怎么樣才算頻繁呢?度量它們的方法有很多種,這里我們來簡單的介紹下支持度和可信度。
支持度: 數據集中包含該項集的記錄所占的比例。例如上圖中,{豆奶} 的支持度為 4/5。{豆奶, 尿布} 的支持度為 3/5。
可信度: 針對一條諸如 {尿布} -> {葡萄酒} 這樣具體的關聯規則來定義的。這條規則的 可信度 被定義為 支持度({尿布, 葡萄酒})/支持度({尿布}),從圖中可以看出 支持度({尿布, 葡萄酒}) = 3/5,支持度({尿布}) = 4/5,所以 {尿布} -> {葡萄酒} 的可信度 = 3/5 / 4/5 = 3/4 = 0.75。
支持度和可信度是用來量化關聯分析是否成功的一個方法。 假設想找到支持度大于0.8的所有項集,應該如何去做呢?一個辦法是生成一個物品所有可能組合的清單,然后對每一種組合統計它出現的頻繁程度,但是當物品成千上萬時,上述做法就非常非常慢了。我們需要詳細分析下這種情況并討論下Apriori原理,該原理會減少關聯規則學習時所需的計算量。
3.Apriori原理
假設我們一共有4個商品: 商品0, 商品1, 商品2, 商品3。 所有可能的情況如圖2所示:
如果我們計算所有組合的支持度,也需要計算15次。即2^N-1=2^4-1=15。
隨著物品的增加,計算的次數呈指數的形式增長 ...
為了降低計算次數和時間,研究人員發現了一種所謂的Apriori原理,即某個項集是頻繁的,那么它的所有子集也是頻繁的。例如,如果{0, 1}是頻繁的,那么{0}, {1}也是頻繁的。該原理直觀上沒有什么幫助,但是如果反過來看就有用了,也就是說如果一個項集是非頻繁項集,那么它的所有超集也是非頻繁項集,如圖3所示:
在圖3中我們可以看到,已知藍色部分{2,3}是非頻繁項集,那么利用上面的知識,我們就可以知道{0,2,3}{1,2,3}{0,1,2,3}都是非頻繁的。也就是說計算出{2,3}的支持度,知道它是非頻繁的之后,就不需要再計算{0,2,3}{1,2,3}{0,1,2,3}的支持度,因為我們知道這些集合不會滿足我們的要求。使用該原理就可以避免項集數目的指數增長,從而在合理的時間內計算出頻繁項集。
操作機: Linux_Ubuntu
操作機默認用戶:root
步驟1:Apriori算法分塊講解
1.1 首先了解一下算法中導入的模塊及其簡介。其中,sys是system的縮寫,用來獲取操作系統和編譯器的一些配置,設置及操作。如判斷文件和文件夾是否存在,創建文件文件夾,獲取系統版本之類的操作。itertools庫,迭代器(生成器)在Python中是一種很常用也很好用的數據結構,比起列表(list)來說,迭代器最大的優勢就是延遲計算,按需使用,從而提高開發體驗和運行效率。collections是集合模塊,optparse模塊可以用用來定義option參數。
import?sys?? from?itertools?import?chain,?combinations from?collections?import?defaultdict from?optparse?import?OptionParser
1.2 主函數的部分,其中定義了三個程序功能選項,-f是使用數據文件,-s用來設置最小支持度(默認是0.15),-c用來設置最小可信度(默認是0.6)。
if?__name__?==?"__main__": ????optparser?=?OptionParser()??#創建一個OptionParser對象 ????optparser.add_option('-f',?'--inputFile', ?????????????????????????dest='input', ?????????????????????????help='filename?containing?csv', ?????????????????????????default=None)??#添加待定義命令行參數,及其幫助文檔。 ????optparser.add_option('-s',?'--minSupport', ?????????????????????????dest='minS', ?????????????????????????help='minimum?support?value', ?????????????????????????default=0.15, ?????????????????????????type='float')?#添加待定義命令行參數,及其幫助文檔。 ????optparser.add_option('-c',?'--minConfidence', ?????????????????????????dest='minC', ?????????????????????????help='minimum?confidence?value', ?????????????????????????default=0.6, ?????????????????????????type='float')?#添加待定義命令行參數,及其幫助文檔。 ????(options,?args)?=?optparser.parse_args()??#接收參數 ????inFile?=?None?? ????if?options.input?is?None:??#文件內容為空的情況 ????????????inFile?=?sys.stdin ????elif?options.input?is?not?None:??#文件內容不為空的情況 ????????????inFile?=?dataFromFile(options.input)??#把文件內容讀到inFile中 ????else: ????????????print?('No?dataset?filename?specified,?system?with?exit\n') ????????????sys.exit('System?will?exit') ????minSupport?=?options.minS???#設置最小支持度 ????minConfidence?=?options.minC???#設置最小可信度 ????items,?rules?=?runApriori(inFile,?minSupport,?minConfidence)??#運行算法,其中三個參數分別是從文件中讀出的數據、最小支持度和最小可信度 ????printResults(items,?rules)??#調用結果顯示函數
步驟1:Apriori算法分塊講解
1.1 首先了解一下算法中導入的模塊及其簡介。其中,sys是system的縮寫,用來獲取操作系統和編譯器的一些配置,設置及操作。如判斷文件和文件夾是否存在,創建文件文件夾,獲取系統版本之類的操作。itertools庫,迭代器(生成器)在Python中是一種很常用也很好用的數據結構,比起列表(list)來說,迭代器最大的優勢就是延遲計算,按需使用,從而提高開發體驗和運行效率。collections是集合模塊,optparse模塊可以用用來定義option參數。
import?sys?? from?itertools?import?chain,?combinations from?collections?import?defaultdict from?optparse?import?OptionParser
1.2 主函數的部分,其中定義了三個程序功能選項,-f是使用數據文件,-s用來設置最小支持度(默認是0.15),-c用來設置最小可信度(默認是0.6)。
if?__name__?==?"__main__": ????optparser?=?OptionParser()??#創建一個OptionParser對象 ????optparser.add_option('-f',?'--inputFile', ?????????????????????????dest='input', ?????????????????????????help='filename?containing?csv', ?????????????????????????default=None)??#添加待定義命令行參數,及其幫助文檔。 ????optparser.add_option('-s',?'--minSupport', ?????????????????????????dest='minS', ?????????????????????????help='minimum?support?value', ?????????????????????????default=0.15, ?????????????????????????type='float')?#添加待定義命令行參數,及其幫助文檔。 ????optparser.add_option('-c',?'--minConfidence', ?????????????????????????dest='minC', ?????????????????????????help='minimum?confidence?value', ?????????????????????????default=0.6, ?????????????????????????type='float')?#添加待定義命令行參數,及其幫助文檔。 ????(options,?args)?=?optparser.parse_args()??#接收參數 ????inFile?=?None?? ????if?options.input?is?None:??#文件內容為空的情況 ????????????inFile?=?sys.stdin ????elif?options.input?is?not?None:??#文件內容不為空的情況 ????????????inFile?=?dataFromFile(options.input)??#把文件內容讀到inFile中 ????else: ????????????print?('No?dataset?filename?specified,?system?with?exit\n') ????????????sys.exit('System?will?exit') ????minSupport?=?options.minS???#設置最小支持度 ????minConfidence?=?options.minC???#設置最小可信度 ????items,?rules?=?runApriori(inFile,?minSupport,?minConfidence)??#運行算法,其中三個參數分別是從文件中讀出的數據、最小支持度和最小可信度 ????printResults(items,?rules)??#調用結果顯示函數
1.3 Apriori函數通過計算頻繁項集計算支持度,再通過支持度計算可信度,從而空值閾值。代碼如下:
def?runApriori(data_iter,?minSupport,?minConfidence): ????""" ????run?the?apriori?algorithm.?data_iter?is?a?record?iterator ????Return?both: ?????-?items?(tuple,?support) ?????-?rules?((pretuple,?posttuple),?confidence) ????""" ????itemSet,?transactionList?=?getItemSetTransactionList(data_iter)???#itemSet是一個集合,用來保存都有哪些商品(集合不會出現重復,所以這里使用集合),transactionList用來保存商品的組合 ????freqSet?=?defaultdict(int)???#保存出現頻率 ????largeSet?=?dict()???#保存所有的商品組合 ????#?存儲的全局字典(key=n-itemSets,value=support),滿足minSupport ????assocRules?=?dict()????#存儲關聯規則的字典 ????#?Dictionary?which?stores?Association?Rules ????oneCSet?=?returnItemsWithMinSupport(itemSet, ????????????????????????????????????????transactionList, ????????????????????????????????????????minSupport, ????????????????????????????????????????freqSet)??#得到滿足最小支持度的集合 ????currentLSet?=?oneCSet ????k?=?2 ????while(currentLSet?!=?set([])):??#循環用來獲得largeSet字典,分別對應商品數量為1-n的商品組合 ????????largeSet[k-1]?=?currentLSet ????????currentLSet?=?joinSet(currentLSet,?k) ????????currentCSet?=?returnItemsWithMinSupport(currentLSet, ????????????????????????????????????????????????transactionList, ????????????????????????????????????????????????minSupport, ????????????????????????????????????????????????freqSet) ????????currentLSet?=?currentCSet ????????k?=?k?+?1 ????def?getSupport(item):??#計算支持度 ????????????"""local?function?which?Returns?the?support?of?an?item""" ????????????return?float(freqSet[item])/len(transactionList) ????toRetItems?=?[] ????for?key,?value?in?largeSet.items(): ????????toRetItems.extend([(tuple(item),?getSupport(item)) ???????????????????????????for?item?in?value]) ????toRetRules?=?[] ????for?key,?value?in?list(largeSet.items())[1:]: ????????for?item?in?value: ????????????_subsets?=?map(frozenset,?[x?for?x?in?subsets(item)]) ????????????for?element?in?_subsets: ????????????????remain?=?item.difference(element) ????????????????if?len(remain)?>?0: ????????????????????confidence?=?getSupport(item)/getSupport(element) ????????????????????if?confidence?>=?minConfidence: ????????????????????????toRetRules.append(((tuple(element),?tuple(remain)), ???????????????????????????????????????????confidence)) ????return?toRetItems,?toRetRules
2.1 打開終端(該系統鏡像默認是root用戶)
2.2 這一步的目的是把算法保存為py文件:在當前路徑下也就是桌面上創建一個apriori.py文件,并用vim打開。vim進入后,按鍵盤上的i鍵進入輸入模式,將教程最后面給出的代碼復制進去,然后按Esc鍵退出輸入模式后,輸入:wq保存退出。
輸入下列命令:
touch apriori.py
vim apriori.py
注意在復制粘貼時,暫不支持中文。詳細代碼見最后附件。
2.3 這一步是準備我們的待計算數據集:在當前路徑下也就是桌面上創建一個data文件,并用vim打開。vim進入后,按鍵盤上的i鍵進入輸入模式,將數據集輸入進去,然后按Esc鍵退出輸入模式后,輸入:wq保存退出。
輸入下列命令:
touch data
vim data
按鍵盤上的i鍵進入輸入模式后,將下列數據輸入進文件后按鍵盤Esc鍵退出輸入模式后,輸入:wq保存退出:
11,12,13, 12,14, 12,13, 11,12,14, 11,13, 12,13, 11,13, 11,12,13,15, 11,12,13,
2.4 運行程序,并計算data文件中數據的關聯度。該算法將每一個商品項的支持度顯示出來并且顯示各商品間的可信度。在終端中輸入如下命令:
python3 apriori.py -f data
該命令是指使用python3運行apriori.py,其中-f data是apriori.py程序的參數。運行結果如圖9所示:
2.5 如果將-s參數設置為0.5,-c參數設置為0.7,那么將只會計算輸出支持度大于0.5商品和可信度大于0.7的商品組合。結果如圖10所示:
python3 apriori.py -f data -s 0.5 -c 0.7
附
完整代碼如下:
import?sys from?itertools?import?chain,?combinations from?collections?import?defaultdict from?optparse?import?OptionParser def?subsets(arr): ????"""?Returns?non?empty?subsets?of?arr""" ????return?chain(*[combinations(arr,?i?+?1)?for?i,?a?in?enumerate(arr)]) def?returnItemsWithMinSupport(itemSet,?transactionList,?minSupport,?freqSet): ????????"""calculates?the?support?for?items?in?the?itemSet?and?returns?a?subset ???????of?the?itemSet?each?of?whose?elements?satisfies?the?minimum?support""" ????????_itemSet?=?set() ????????localSet?=?defaultdict(int) ????????for?item?in?itemSet: ????????????????for?transaction?in?transactionList: ????????????????????????if?item.issubset(transaction): ????????????????????????????????freqSet[item]?+=?1 ????????????????????????????????localSet[item]?+=?1 ????????for?item,?count?in?localSet.items(): ????????????????support?=?float(count)/len(transactionList) ????????????????if?support?>=?minSupport: ????????????????????????_itemSet.add(item) ????????return?_itemSet def?joinSet(itemSet,?length): ????????"""Join?a?set?with?itself?and?returns?the?n-element?itemsets""" ????????return?set([i.union(j)?for?i?in?itemSet?for?j?in?itemSet?if?len(i.union(j))?==?length]) def?getItemSetTransactionList(data_iterator):??#讀出文件中的商品列表 ????transactionList?=?list()??#初始化 ????itemSet?=?set()??#初始化 ????for?record?in?data_iterator: ????????transaction?=?frozenset(record) ????????transactionList.append(transaction)???#transaction保存商品的購買組合方式 ????????for?item?in?transaction: ????????????itemSet.add(frozenset([item]))??????????????#itemSet集合用來保存單個商品名稱(無重復) ????return?itemSet,?transactionList def?runApriori(data_iter,?minSupport,?minConfidence): ????""" ????run?the?apriori?algorithm.?data_iter?is?a?record?iterator ????Return?both: ?????-?items?(tuple,?support) ?????-?rules?((pretuple,?posttuple),?confidence) ????""" ????itemSet,?transactionList?=?getItemSetTransactionList(data_iter)???#itemSet是一個集合,用來保存都有哪些商品(集合不會出現重復,所以這里使用集合),transactionList用來保存商品的組合 ????freqSet?=?defaultdict(int)???#保存出現頻率 ????largeSet?=?dict()???#保存所有的商品組合 ????#?存儲的全局字典(key=n-itemSets,value=support),滿足minSupport ????assocRules?=?dict()????#存儲關聯規則的字典 ????#?Dictionary?which?stores?Association?Rules ????oneCSet?=?returnItemsWithMinSupport(itemSet, ????????????????????????????????????????transactionList, ????????????????????????????????????????minSupport, ????????????????????????????????????????freqSet)??#得到滿足最小支持度的集合 ????currentLSet?=?oneCSet ????k?=?2 ????while(currentLSet?!=?set([])):??#循環用來獲得largeSet字典,分別對應商品數量為1-n的商品組合 ????????largeSet[k-1]?=?currentLSet ????????currentLSet?=?joinSet(currentLSet,?k) ????????currentCSet?=?returnItemsWithMinSupport(currentLSet, ????????????????????????????????????????????????transactionList, ????????????????????????????????????????????????minSupport, ????????????????????????????????????????????????freqSet) ????????currentLSet?=?currentCSet ????????k?=?k?+?1 ????def?getSupport(item):??#計算支持度 ????????????"""local?function?which?Returns?the?support?of?an?item""" ????????????return?float(freqSet[item])/len(transactionList) ????toRetItems?=?[] ????for?key,?value?in?largeSet.items(): ????????toRetItems.extend([(tuple(item),?getSupport(item)) ???????????????????????????for?item?in?value]) ????toRetRules?=?[] ????for?key,?value?in?list(largeSet.items())[1:]: ????????for?item?in?value: ????????????_subsets?=?map(frozenset,?[x?for?x?in?subsets(item)]) ????????????for?element?in?_subsets: ????????????????remain?=?item.difference(element) ????????????????if?len(remain)?>?0: ????????????????????confidence?=?getSupport(item)/getSupport(element) ????????????????????if?confidence?>=?minConfidence: ????????????????????????toRetRules.append(((tuple(element),?tuple(remain)), ???????????????????????????????????????????confidence)) ????return?toRetItems,?toRetRules def?printResults(items,?rules): ????"""prints?the?generated?itemsets?sorted?by?support?and?the?confidence?rules?sorted?by?confidence""" ????#for?item,?support?in?sorted(items,?key=lambda?item,?support:?support): ????print("\n------------------------?SUPPORT:") ????for?item,?support?in?sorted(items,?key=lambda?items:?items[1]): ????????print?("item:?%s?,?%.3f"?%?(str(item),?support)) ????print?("\n------------------------?RULES:") ????for?rule,?confidence?in?sorted(rules,?key=lambda?rules:?rules[1]): ????????pre,?post?=?rule ????????print?("Rule:?%s?==>?%s?,?%.3f"?%?(str(pre),?str(post),?confidence)) def?dataFromFile(fname): ????????"""Function?which?reads?from?the?file?and?yields?a?generator""" ????????file_iter?=?open(fname,?'rU') ????????for?line?in?file_iter: ????????????????line?=?line.strip().rstrip(',')?????????????????????????#?Remove?trailing?comma ????????????????record?=?frozenset(line.split(',')) ????????????????yield?record if?__name__?==?"__main__": ????optparser?=?OptionParser()??#創建一個OptionParser對象 ????optparser.add_option('-f',?'--inputFile', ?????????????????????????dest='input', ?????????????????????????help='filename?containing?csv', ?????????????????????????default=None)??#添加待定義命令行參數,及其幫助文檔。 ????optparser.add_option('-s',?'--minSupport', ?????????????????????????dest='minS', ?????????????????????????help='minimum?support?value', ?????????????????????????default=0.15, ?????????????????????????type='float')?#添加待定義命令行參數,及其幫助文檔。 ????optparser.add_option('-c',?'--minConfidence', ?????????????????????????dest='minC', ?????????????????????????help='minimum?confidence?value', ?????????????????????????default=0.6, ?????????????????????????type='float')?#添加待定義命令行參數,及其幫助文檔。 ????(options,?args)?=?optparser.parse_args()??#接收參數 ????inFile?=?None ????if?options.input?is?None:??#文件內容為空的情況 ????????????inFile?=?sys.stdin ????elif?options.input?is?not?None:??#文件內容不為空的情況 ????????????inFile?=?dataFromFile(options.input)??#把文件內容讀到inFile中 ????else: ????????????print?('No?dataset?filename?specified,?system?with?exit\n') ????????????sys.exit('System?will?exit') ????minSupport?=?options.minS???#設置最小支持度 ????minConfidence?=?options.minC???#設置最小可信度 ????items,?rules?=?runApriori(inFile,?minSupport,?minConfidence)??#運行算法,其中三個參數分別是從文件中讀出的數據、最小支持度和最小可信度 ????printResults(items,?rules)??#調用結果顯示函數
Python
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。