前言
資料探勘是通過對大量資料的清理及處理以發現資訊,並將這原理應用於分類,推薦系統,預測等方面的過程。本文基於《面向程式設計師資料探勘指南》的理解,擴充套件學習後的總結。不足之處還請賜教,覺得有幫助請點贊mark下。謝謝!
一、資料探勘過程
1.資料選擇
在分析業務需求後,需要選擇應用於需求業務相關的資料。明確業務需求並選擇好業務針對性的資料是資料探勘的先決條件。
2.資料預處理
選擇好的資料會有噪音,不完整等缺陷,需要對資料進行清洗,整合,轉換以及歸納。
3.資料轉換
根據選擇的演算法,對預處理好的資料轉換為特定資料探勘演算法的分析模型。
4.資料探勘
使用選擇好的資料探勘演算法對資料進行處理後得到資訊。
5.解釋與評價
對資料探勘後的資訊加以分析解釋,並應用於實際的工作領域。
二、資料探勘常用演算法簡介
1.關聯分析演算法
關聯規則在於找出具有最小支援度閾值和最小置信度閾值的不同域的資料之間的關聯。在關聯規則的分析演算法研究中,演算法的效率是核心的問題。 經典的演算法有:Apriori演算法,AprioriTid演算法,FP-growth演算法;
2.分類演算法
決策樹演算法:以樹形結構表示分類或者決策集合,產生規則或者發現規律。主要有ID3演算法,C4.5演算法, SLIQ演算法, SPRINT演算法, RainForest演算法;
樸素Bayes分類演算法:利用Bayes定理概率統計的方法,選擇其中概率比較大的類別進行分類;
CBA(Classification Based on Association)演算法:基於關聯規則的分類演算法;
MIND(Mining in Database)演算法 :採用資料庫中使用者定義的函式(user-definedfunction,簡稱UDF)來實現分類的演算法;
神經網路分類演算法:利用訓練集對多個神經的網路進行訓練,並用訓練好的模型對樣本進行分類;
粗集理論:粗集理論的特點是不需要預先給定某些特徵或屬性的數量描述,而是直接從給定問題出發,通過不可分辨關係和不可分辨類確定問題的近似域,從而找出問題中的內在規律;
遺傳演算法:遺傳演算法是模擬生物進化過程,利用複製(選擇)、交叉(重組)和變異(突變)3個基本方法優化求解的技術;
3.聚類演算法
聚類分析與分類不同,聚類分析處理的資料物件的類是未知的。聚類分析就是將物件集合分組為由類似的物件組成 的多個簇的過程。分為3類方法:
Ipartitioning method(劃分方法) 給定1個N個物件或者元組的資料庫,1個劃分方法構建資料的K個劃分,每1個劃分表示1個聚簇,並且K<N。經典演算法是K-MEAN(K平均值);
hierarchical method(層次方法) 對給定資料物件集合進行層次的分解,經典演算法是BIRTH演算法;
grid based method(基於網格的方法) 這種方法採用一個多解析度的網格資料結構。將空間量化為有限數目的單元,這些單元形成了網格結構,所有聚類分析都在網格上進行。常用的演算法有STING,SkWAVECLUSTER和 CLIQUE;
小結
隨著資料量的日益積累以及資料庫種類的多樣化,各種資料探勘方法作用範圍有限,都有侷限性,因此採用單一方法難以得到決策所需的各種知識。但它們的有機組合具有互補性,多方法融合將成為資料探勘演算法的發展趨勢。
三、資料探勘演算法實現
1、相關知識
(1)距離度量:在資料探勘中需要明確樣本資料相似度,通常可以計算樣本間的距離,如下為常用距離度量的介紹。
樣本資料以:
曼哈頓距離: 也稱曼哈頓街區距離,就如從街區的一個十字路口點到另一個十字路口點的距離, 二維空間(多維空間按同理擴充套件)用公式表示為
歐氏距離:表示為點到點的距離。二維空間(多維空間按同理擴充套件)的公式表示為
閔可夫斯基距離:是一組距離方法的概括,當 p=1 既是曼哈頓距離,當 p=2 既是歐氏距離。當p越大,單一維度的差值對整體的影響就越大。
閔可夫斯基距離(包括歐氏距離,曼哈頓距離)的優缺點:
優點:應用廣泛。
缺點:無法考慮各分量的單位以及各分量分佈(方差,期望)的差異性。(其中個分量的單位差異可以使用資料的標準化來消除,下面會有介紹。)
餘弦相關係數:樣本資料視為向量,通過兩向量間的夾角餘弦值確認相關性,數值範圍[-1,1]。 -1表示負相關,0表示無關,1表示正相關。
餘弦相關係數的優缺點:優點:餘弦相似度與向量的幅值無關,只與向量的方向相關,在文件相似度(TF-IDF)和圖片相似性(histogram)計算上都有它的身影; 而且在樣本數值稀疏的時候仍可以使用。
缺點:餘弦相似度受到向量的平移影響,上式如果將 x 平移到 x+1, 餘弦值就會改變。(可以理解為受樣本的起始標準的影響,接下來介紹的皮爾遜相關係數可以消除這個影響)
皮爾遜相關係數:計算出了樣本向量間的相關性,數值範圍[-1,1]。
考慮計算的遍歷的次數,有一個替代公式可以近似計算皮爾遜相關係數:
皮爾遜相關係數優點:可消除每個分量標準不同(分數膨脹)的影響,具有平移不變性和尺度不變性。
(2)資料標準化:參考文章
各分量計算距離而各分量的單位尺度差異很大,可以使用資料標準化消除不同分量間單位尺度的影響,,加速模型收斂的效率,常用的方法有三種:
min-max 標準化:將數值範圍縮放到(0,1),但沒有改變資料分佈。max為樣本最大值,min為樣本最小值。
z-score 標準化:將數值範圍縮放到0附近, 但沒有改變資料分佈。u是平均值,σ是標準差。 修正的標準z-score:修正後可以減少樣本資料異常值的影響。將z-score標準化公式中的均值改為中位數,將標準差改為絕對偏差。 其中asd絕對偏差:u為中位數,card(x)為樣本個數(3) 演算法的效果評估:
十折交叉驗證:將資料集隨機分割成十個等份,每次用9份資料做訓練集,1份資料做測試集,如此迭代10次。十折交叉驗證的關鍵在於較平均地分為10份。
N折交叉驗證又稱為留一法:用幾乎所有的資料進行訓練,然後留一個資料進行測試,並迭代每一資料測試。留一法的優點是:確定性。
2、演算法入門——協同過濾推薦演算法
程式碼實現、資料集及參考論文 電影推薦——基於使用者、物品的協同過濾演算法
...
示例:
r = Recommendor()
print("items base協同推薦 slope one")
#items base協同推薦演算法 Slope one
r.slope_one_recommendation('lyy')
print("items base協同推薦 cos")
#items base協同推薦演算法 修正餘弦相似度
r.cos_recommendation('lyy')
print("users base協同推薦")
#userbase協同推薦演算法
r.user_base_recommendation("lyy")
複製程式碼
(1)基於使用者的協同推薦演算法
這個方法是利用相似使用者的喜好來進行推薦:如果要推薦一個樂隊給你,會查詢一個和你類似的使用者,然後將他喜歡的樂隊推薦給你。
演算法的關鍵在於找到相似的使用者,迭代計算你與每個使用者對相同樂隊的評分距離,來確定誰是你最相似的使用者,距離計算可以用曼哈頓距離,皮爾斯相關係數等等。
基於使用者的協同推薦演算法演算法的缺點:擴充套件性:隨著使用者數量的增加,其計算量也會增加。這種演算法在只有幾千個使用者的情況下能夠工作得很好,但達到一百萬個使用者時就會出現瓶頸。稀疏性:大多數推薦系統中,物品的數量要遠大於使用者的數量,因此使用者僅僅對一小部分物品進行了評價,這就造成了資料的稀疏性。比如亞馬遜有上百萬本書,但使用者只評論了很少一部分,於是就很難找到兩個相似的使用者了。
(2)基於物品的協同推薦演算法
基於使用者的協同過濾是通過計算使用者之間的距離找出最相似的使用者(需要將所有的評價資料在讀取在記憶體中處理進行推薦),並將相似使用者評價過的物品推薦給目標使用者。而基於物品的協同過濾則是找出最相似的物品(通過構建一個物品的相似度模型來做推薦),再結合使用者的評價來給出推薦結果。
基於物品的協同推薦演算法常用有如下兩種:
修正餘弦相似度演算法:
以物品的評分作為物品的屬性值,通過對比物品i,j的工有的使用者相對評分的計算相關性s(i,j)。與皮爾遜相關係數的原理相同,共有使用者對物品的每一評分R(u,j),R(u,i)需要減去該使用者評分的平均值R(`u)而消除分數膨脹。
修正餘弦相似度的優點:通過構建物品模型的方式,擴充套件性好,佔用記憶體小;消除分數膨脹的影響;修正餘弦相似度的缺點:稀疏性,需要基於使用者的評分資料;
Slope One推薦演算法:
第一步,計算平均差值:
dev(i,j)為遍歷所有共有物品i,j的共有使用者u的評分平均差異。
card(Sj,i(X))則表示同時評價過物品j和i的使用者數。
第二歩,使用加權的Slope One演算法:
PWS1(u)j表示我們將預測使用者u對物品j的評分。
求合集i屬於S(u)-j,使用者u所含的所有物品i(除了j以外)。
dev(i,j)為遍歷所有共有物品i,j的共有使用者u的評分平均差異。
C(ji)也就是card(Sj,i(X))表示同時評價過物品j和i的使用者數。
Slope One演算法優點:演算法簡單;擴充套件性好,只需要更新共有屬性的使用者評價,而不需要重新載入整個資料集。
Slope One演算法的缺點:稀疏性,需要基於使用者的評分資料;
3、分類演算法
(1)基於物品特徵值的KNN分類演算法
程式碼實現 鳶尾花KNN分類演算法
...
# KNN演算法
def knn(self, oj_list):
weight_dict = {"Iris-setosa":0.0, "Iris-versicolor":0.0, "Iris-virginica":0.0}
for atuple in oj_list:
weight_dict[atuple[1]] += (1.0 / atuple[0])
rel_class = [(key, value) for key, value in weight_dict.items()]
#print(sorted(rel_class, key=lambda x:x[1], reverse=True))
rel_class = sorted(rel_class, key=lambda x:x[1], reverse=True)[0][0]
return rel_class
...
複製程式碼
前面我們討論的協同推薦演算法需要在使用者產生的各種資料上面進行分析,因此也稱為社會化過濾演算法,而這種演算法通常有資料的稀疏性,演算法可擴充套件性以及依賴於使用者的資料的缺點,而基於物品特徵值分類演算法可以改善這些問題。演算法分為兩步:
第一步、選取特徵值
演算法的關鍵在於挑取有代表區分意義的特徵及分值。以Iris花的示例,選取花萼長度, 花萼寬度,花瓣長度,花瓣寬度特徵值。
第二歩、計算距離
比如計算測試集與訓練集特徵值之間的曼哈頓距離,得到k個最近鄰後並通過加權後的結果預測分類。
KNN分類演算法的缺點:無法對分類結果的置信度進行量化;是被動學習的演算法,每次測試需要需要遍歷所有的訓練集後才能分類。
(2)貝葉斯分類演算法
程式碼實現 區分新聞類別樸素貝葉斯分類演算法
...
def train_data(self):
#訓練組的條件概率
for word in self.vocabulary:
for category,value in self.prob.items():
if word not in self.prob[category]:
count = 0
else :
count = self.prob[category][word]
#優化條件概率公式
self.prob[category][word] = (count + 1) / (self.total[category] + len(self.vocabulary))
...
複製程式碼
貝葉斯分類演算法是基於概率的分類演算法。相比於KNN分類演算法,它是主動學習的演算法,它會根據訓練集建立一個模型,並用這個模型對新樣本進行分類,速度也會快很多。 貝葉斯分類演算法的理論基礎是基於條件概率的公式(應用於現實中P(X|Y&Z)不直觀得出,而P(Y|X)*P(Z|X)比較直觀得出),並假設已存在的子事件(y,z...實際應用中會有多個)間是相互獨立的(因此也稱為樸素貝葉斯),當y,z事件假設為獨立便有:
如下舉例推測買牛奶和有機食品,再會買綠茶的概率:第一步:計算先驗概率及條件概率
先驗概率:為單獨事件發生的概率,如P(買綠茶),P(有機食品)
條件概率(後驗概率):y事件已經發生,觀察y資料集後得出x發生的概率。如P(買有機食品|買綠茶),通過以下公式計算(nc表示y資料集下x的發生頻數,n為y資料集的總數):
上式存在一個缺陷,當一個條件概率 P(y|x)為0時,整體的預測結果P(x) * P(y|x) * P(z|x)只能為0,這樣便不能更全面地預測。修正後的條件概率:(公式摘自Tom Mitchell《機器學習》。m是一個常數,表示等效樣本大小。決定常數m的方法有很多,我們這裡可以使用預測結果的類別來作為m,比如投票有贊成和否決兩種類別,所以m就為2。p則是相應的先驗概率,比如說贊成概率是0.5,那p(贊成)就是0.5。):
第二歩:根據貝葉斯公式做出預測
由公式計算比較y&z事件發生下,不同x事件發生的概率差異,如得出P(x=喜歡),P(x=不喜歡) 的概率大小,預測為概率比較大的事件。 因為P(y)*p(z)在上式都一樣,因此公式可以簡化為計算概率最大項而預測分類:
貝葉斯演算法的優點:能夠給出分類結果的置信度;它是一種主動學習演算法,速度更快。
貝葉斯演算法的缺點:需要特定格式;數值型資料需要轉換為類別計算概率或用高斯分佈計算概率;
(2)邏輯迴歸分類演算法
程式碼實現 區分貓的圖片
注:邏輯迴歸分類演算法待後續加入網路層,更新為神經網路分類演算法。
...
# cost函式,計算梯度
def propagate(w, b, X, Y):
m = X.shape[1]
A = sigmoid(np.dot(w.T, X) + b)
cost = -1 / m * np.sum(Y * np.log(A) + (1 - Y) * np.log(1 - A))
dw = 1 / m * np.dot(X, (A - Y).T)
db = 1 / m * np.sum(A - Y)
...
複製程式碼
邏輯迴歸分類演算法實現了輸入特徵向量X,而輸出Y(範圍0~1)預測X的分類。
第一步,得到關於X線性迴歸函式
可以通過線性迴歸得到WX + b,其中W是權重,b是偏差值。但不能用本式表述預測的值,因為輸出Y的值需要在(0~1)區間;
第二歩,通過啟用函式轉換
啟用函式的特點是可以將線性函式轉換為非線性函式,並且有輸出值有限,可微分,單調性的特點。本例使用sigmoid,使輸出為預測值Y=sigmoid(WX+b);
第三歩,構建Cost函式
訓練W,b更好的預測真實的類別需要構建Cost代價函式,y^為sigmoid(WX+b)的預測分類值,y為實際分類值(0或者1):
其中L(y^,y)稱為損失函式
訓練的目的就是為了讓L(y^,y)足夠小,也就是當y實際分類值為1時,y^要儘量偏向1。y實際分類值為0時,y^儘量小接近0。第四步,梯度下降得到Cost函式的極小值
通過對W,b兩個引數求偏導,不斷迭代往下坡的的位置移動(對w,b值往極小值方向做優化,其中α為學習率控制下降的幅度),全域性最優解也就是代價函式(成本函式)J (w,b)這個凸函式的極小值點。 第五步、通過訓練好的W,b預測分類。4、聚類演算法
(1)層次聚類
程式碼實現 狗的種類層次聚類
層次聚類將每條資料都當作是一個分類,每次迭代的時候合併距離最近的兩個分類,直到剩下一個分類為止。
(2)K-means++聚類
程式碼實現 Kmean++聚類
注:Kmean演算法與Kmean++區別在於初始的中心點是直接隨機選取k各點。
...
#kmean初始化隨機k箇中心點
#random.seed(1)
#center = [[self.data[i][r] for i in range(1, len((self.data)))]
#for r in random.sample(range(len(self.data)), k)]
# Kmean ++ 初始化基於距離份量隨機選k箇中心點
# 1.隨機選擇一個點
center = []
center.append(random.choice(range(len(self.data[0]))))
# 2.根據距離的概率選擇其他中心點
for i in range(self.k - 1):
weights = [self.distance_closest(self.data[0][x], center)
for x in range(len(self.data[0])) if x not in center]
dp = [x for x in range(len(self.data[0])) if x not in center]
total = sum(weights)
#基於距離設定權重
weights = [weight/total for weight in weights]
num = random.random()
x = -1
i = 0
while i < num :
x += 1
i += weights[x]
center.append(dp[x])
...
複製程式碼
k-means++演算法可概括為:
(1)基於各點到中心點得距離分量,依次隨機選取到k個元素作為中心點: 先隨機選擇一個點。重複以下步驟,直到選完k個點。
計算每個資料點dp(n)到各個中心點的距離(D),選取最小的值D(dp);
根據D(dp)距離所佔的份量來隨機選取下一個點作為中心點。(2)根據各點到中心點的距離分類;
(3)計算各個分類新的中心點。 重複(2、3),直至滿足條件。