【机器学习基础】机器学习距离与相似度计算
寫在前面
涵蓋了常用到的距離與相似度計算方式,其中包括歐幾里得距離、標準化歐幾里得距離、曼哈頓距離、漢明距離、切比雪夫距離、馬氏距離、蘭氏距離、閔科夫斯基距離、編輯距離、余弦相似度、杰卡德相似度、Dice系數(shù)。
歐幾里得距離
在數(shù)學中,歐幾里得距離或歐幾里得度量是歐幾里得空間中兩點間“普通”(即直線)距離。歐幾里得距離有時候有稱歐氏距離,在數(shù)據(jù)分析及挖掘中經(jīng)常會被使用到,例如聚類或計算相似度。
如果我們將兩個點分別記作(p1,p2,p3,p4…)和(q1,q2,q3,14,…),則歐幾里得距離的計算公式為:
from math import * def euclidean_distance(x, y): return sqrt(sum(pow(a - b, 2) for a, b in zip(x, y))) print(euclidean_distance([0,?3,?4,?5],?[7,?6,?3,?-1]))?可以看到,歐幾里得距離得到的結果是一個非負數(shù),最大值是正無窮大,但是通常情況下相似度結果的取值范圍在 [-1, 1] 之間。可以對它求倒數(shù)將結果轉化到 (0, 1]之間。
分母+1是為了避免遇到被0整除的錯誤。
標準化歐式距離
標準化歐氏距離是針對簡單歐氏距離的缺點(各維度分量的分布不一樣)而作的一種改進方案。其實就是將各個分量都標準化。假設樣本集X的均值(mean)為m,標準差(standard deviation)為s,那么X的“標準化變量”表示為:
即標準化后的值 = ( 標準化前的值-分量的均值) /分量的標準差
經(jīng)過簡單的推導就可以得到兩個n維向量a(a1,a2,...an)與b(b1,b2,...bn)間的標準化歐氏距離的公式:
如果將方差的倒數(shù)看成是一個權重,這個公式可以看成是一種加權歐氏距離(Weighted Euclidean distance)。
def normalized_euclidean(a, b):sumnum = 0for i in range(len(a)):avg = (a[i] - b[i]) / 2si = ((a[i] - avg) ** 2 + (b[i] - avg) ** 2) ** 0.5sumnum += ((a[i] - b[i]) / si) ** 2return?sumnum?**?0.5曼哈頓距離
曼哈頓距離是由十九世紀的赫爾曼·閔可夫斯基所創(chuàng)詞匯 ,是種使用在幾何度量空間的幾何學用語,用以標明兩個點在標準坐標系上的絕對軸距總和。
上圖中紅線代表曼哈頓距離,綠色代表歐氏距離,也就是直線距離,而藍色和橙色代表等價的曼哈頓距離。通俗來講,想象你在曼哈頓要從一個十字路口開車到另外一個十字路口實際駕駛距離就是這個“曼哈頓距離”,此即曼哈頓距離名稱的來源,同時,曼哈頓距離也稱為城市街區(qū)距離(City Block distance)。正正方方的曼哈頓的地圖:
曼哈頓距離公式:
from math import *def manhattan_distance(x,y):return sum(abs(a-b) for a,b in zip(x,y)) print(manhattan_distance([10,20,10],[10,20,20]))漢明距離
漢明距離是以理查德·衛(wèi)斯里·漢明的名字命名的,漢明在誤差檢測與校正碼的基礎性論文中首次引入這個概念這個所謂的距離,是指兩個等長字符串之間的漢明距離是兩個字符串對應位置的不同字符的個數(shù)。
漢明距離有一個最為鮮明的特點就是它比較的兩個字符串必須等長,否則距離不成立。它的核心原理就是如何通過字符替換(最初應用在通訊中實際上是二進制的0-1替換),能將一個字符串替換成另外一個字符串。維基百科給定了幾個樣例。(字符下標0為起始下標)
“karolin” 和 “kathrin” 的漢明距離為(字符2 3 4替換)
“karolin” 和 “kerstin” 的漢明距離為(字符1 3 4替換)
1011101 和 1001001 的漢明距離為(字符2 4替換)
2173896 和 2233796 的漢明距離為(字符1 2 4替換)
漢明距離主要應用在通信編碼領域上,用于制定可糾錯的編碼體系。在機器學習領域中,漢明距離也常常被用于作為一種距離的度量方式。在LSH算法漢明距離也有重要的應用。與漢明距離比較相近的是編輯距離。
賽切比雪夫距離
切比雪夫距離起源于國際象棋中國王的走法,國際象棋中國王每次只能往周圍的8格中走一步,那么如果要從棋盤中A格(x1,y1)走到B格(x2,y2)最少需要走幾步?你會發(fā)現(xiàn)最少步數(shù)總是max(|x2-x1|,|y2-y1|)步。有一種類似的一種距離度量方法叫切比雪夫距離。
若將國際象棋棋盤放在二維直角座標系中,格子的邊長定義為1,座標的x軸及y軸和棋盤方格平行,原點恰落在某一格的中心點,則王從一個位置走到其他位置需要的步數(shù)恰為二個位置的切比雪夫距離,因此切比雪夫距離也稱為棋盤距離。例如位置F6和位置E2的切比雪夫距離為4。任何一個不在棋盤邊緣的位置,和周圍八個位置的切比雪夫距離都是1。
二維平面兩點a(x1,y1)與b(x2,y2)間的切比雪夫距離:
兩個n維向量a(x11,x12,…,x1n)與 b(x21,x22,…,x2n)間的切比雪夫距離:
可以看到當擴展到多維空間,其實切比雪夫距離就是當p趨向于無窮大時的閔可夫斯基距離:
def chebyshev_distance(p, q):assert len(p) == len(q)return max([abs(x - y) for x, y in zip(p, q)]) def chebyshev_distance_procedural(p, q):assert len(p) == len(q)d = 0for x, y in zip(p, q):d = max(d, abs(x - y))return d馬氏距離
馬氏距離(Mahalanobis Distance)是由印度統(tǒng)計學家馬哈拉諾比斯(P. C. Mahalanobis)提出的,表示數(shù)據(jù)的協(xié)方差距離。有時也被稱為馬哈拉諾比斯距離。它是一種有效的計算兩個未知樣本集的相似度的方法。與歐氏距離不同的是它考慮到各種特性之間的聯(lián)系(例如:一條關于身高的信息會帶來一條關于體重的信息,因為兩者是有關聯(lián)的)并且是尺度無關的(scale-invariant),即獨立于測量尺度。
一些基本概念:
方差:方差是標準差的平方,而標準差的意義是數(shù)據(jù)集中各個點到均值點距離的平均值。反應的是數(shù)據(jù)的離散程度。
協(xié)方差:標準差與方差是描述一維數(shù)據(jù),當存在多維數(shù)據(jù)時,我們通常需要知道每個維數(shù)的變量中間是否存在關聯(lián)。協(xié)方差就是衡量多維數(shù)據(jù)集中,變量之間相關性的統(tǒng)計量。如果兩個變量之間的協(xié)方差為正值,則這兩個變量之間存在正相關,若為負值,則為負相關。
對于一個均值為μ=(μ1,μ2,μ3,…,μp)**T,協(xié)方差矩陣為Σ的多變量向量x=(x1,x2,x3,…,xp)**T,其馬氏距離為:
馬氏距離也可以定義為兩個服從同一分布并且其協(xié)方差矩陣為Σ的隨機變量x與y的差異程度:
如果協(xié)方差矩陣為單位矩陣,馬氏距離就簡化為歐氏距離;如果協(xié)方差矩陣為對角陣,其也可稱為正規(guī)化的歐氏距離。
import pandas as pd import scipy as sp from scipy.spatial.distance import mahalanobis datadict = { 'country': ['Argentina', 'Bolivia', 'Brazil', 'Chile', 'Ecuador', 'Colombia', 'Paraguay', 'Peru', 'Venezuela'], 'd1': [0.34, -0.19, 0.37, 1.17, -0.31, -0.3, -0.48, -0.15, -0.61], 'd2': [-0.57, -0.69, -0.28, 0.68, -2.19, -0.83, -0.53, -1, -1.39], 'd3': [-0.02, -0.55, 0.07, 1.2, -0.14, -0.85, -0.9, -0.47, -1.02], 'd4': [-0.69, -0.18, 0.05, 1.43, -0.02, -0.7, -0.72, 0.23, -1.08], 'd5': [-0.83, -0.69, -0.39, 1.31, -0.7, -0.75, -1.04, -0.52, -1.22], 'd6': [-0.45, -0.77, 0.05, 1.37, -0.1, -0.67, -1.4, -0.35, -0.89]} pairsdict = { 'country1': ['Argentina', 'Chile', 'Ecuador', 'Peru'], 'country2': ['Bolivia', 'Venezuela', 'Colombia', 'Peru']} #DataFrame that contains the data for each country df = pd.DataFrame(datadict) #DataFrame that contains the pairs for which we calculate the Mahalanobis distance pairs = pd.DataFrame(pairsdict) #Add data to the country pairs pairs = pairs.merge(df, how='left', left_on=['country1'], right_on=['country']) pairs = pairs.merge(df, how='left', left_on=['country2'], right_on=['country']) #Convert data columns to list in a single cell pairs['vector1'] = pairs[['d1_x','d2_x','d3_x','d4_x','d5_x','d6_x']].values.tolist() pairs['vector2'] = pairs[['d1_y','d2_y','d3_y','d4_y','d5_y','d6_y']].values.tolist() mahala = pairs[['country1', 'country2', 'vector1', 'vector2']] #Calculate covariance matrix covmx = df.cov() invcovmx = sp.linalg.inv(covmx) #Calculate Mahalanobis distance mahala['mahala_dist'] = mahala.apply(lambda x: (mahalanobis(x['vector1'], x['vector2'], invcovmx)), axis=1) mahala = mahala[['country1', 'country2', 'mahala_dist']]根據(jù)馬氏距離的定義,可以得到它的幾個特點如下:
兩點之間的馬氏距離與原始數(shù)據(jù)的測量單位無關(不受量綱的影響)
標準化數(shù)據(jù)和中心化數(shù)據(jù)(即原始數(shù)據(jù)與均值之差)計算出的二點之間的馬氏距離相同
可以排除變量之間的相關性的干擾
滿足距離的四個基本公理:非負性、自反性、對稱性和三角不等式
缺點是夸大了變化微小的變量的作用
考慮下面這張圖,橢圓表示等高線,從歐幾里得的距離來算,綠黑距離大于紅黑距離,但是從馬氏距離,結果恰好相反:
馬氏距離實際上是利用 Cholesky transformation 來消除不同維度之間的相關性和尺度不同的性質。
下圖是一個二元變量數(shù)據(jù)的散點圖:
當我們將坐標軸拿掉,如下圖:
根據(jù)數(shù)據(jù)本身的提示信息來引入新的坐標軸:坐標的原點在這些點的中央(根據(jù)點的平均值算得)。第一個坐標軸(下圖中藍色的線)沿著數(shù)據(jù)點的“脊椎”,并向兩端延伸,定義為使得數(shù)據(jù)方差最大的方向。第二個坐標軸(下圖紅色的線)會與第一個坐標軸垂直并向兩端延伸。如果數(shù)據(jù)的維度超過了兩維,那就選擇使得數(shù)據(jù)方差是第二個最大的方向,以此類推。
我們需要一個比例尺度。沿著每一個坐標軸的標準差來定義一個單位長度。使用“68-95-99.7法則”更容易找到合理的單位。(大約68%的點需要在離原點一個單位長度的范圍內;大約95%的點需要在離原點兩個單位的長度范圍內;99.7的點需要在3個單位程度范圍內。)為了以示參考,如下圖:
由于每個軸上的單位長度不相等,所以上圖中距離原點一個單位的形成的軌跡并不是一個圓形。為了更好的呈現(xiàn)圖表,我們將圖片進行旋轉。同時,并讓每個軸方向上的單位長度相同:
上面就是從散點圖中構建坐標系統(tǒng)的過程,為的是方便進行測量。
說明:
沿著新坐標軸的單位向量是協(xié)方差矩陣的特征向量。注意到?jīng)]有變形的橢圓,變成圓形后沿著特征向量用標準差(協(xié)方差的平方根)將距離長度分割。
坐標軸擴展的量是協(xié)方差矩陣的逆的特征值(平方根),同理的,坐標軸縮小的量是協(xié)方差矩陣的特征值。所以,點越分散,需要的將橢圓轉成圓的縮小量就越多。
盡管上述的操作可以用到任何數(shù)據(jù)上,但是對于多元正態(tài)分布的數(shù)據(jù)表現(xiàn)更好。在其他情況下,點的平均值或許不能很好的表示數(shù)據(jù)的中心,或者數(shù)據(jù)的“脊椎”(數(shù)據(jù)的大致趨勢方向)不能用變量作為概率分布測度來準確的確定。
原始坐標系的平移、旋轉,以及坐標軸的伸縮一起形成了仿射變換(affine transformation)。除了最開始的平移之外,其余的變換都是基底變換,從原始的一個變?yōu)樾碌囊粋€。
在新的坐標系中,多元正態(tài)分布像是標準正太分布,當將變量投影到任何一條穿過原點的坐標軸上。特別是,在每一個新的坐標軸上,它就是標準正態(tài)分布。從這點出發(fā)來看,多元正態(tài)分布彼此之實質性的差異就在于它們的維度。
蘭氏距離
蘭氏距離(Lance and Williams distance)堪培拉距離(Canberra Distance),被認為是曼哈頓距離的加權版本。
其定義公式為:
通常蘭氏距離對于接近于0(大于等于0)的值的變化非常敏感。與馬氏距離一樣,蘭氏距離對數(shù)據(jù)的量綱不敏感。不過蘭氏距離假定變量之間相互獨立,沒有考慮變量之間的相關性。
def canberra_distance(p, q):n = len(p)distance = 0for i in n:if p[i] == 0 and q[i] == 0:distance += 0else:distance += abs(p[i] - q[i]) / (abs(p[i]) + abs(q[i]))return distance閔科夫斯基距離
閔可夫斯基距離又稱為閔氏距離(由于翻譯問題,有時候也被稱為明可夫斯基距離或明氏距離)。閔可夫斯基距離是歐氏空間中的一種測度,被看做是歐氏距離和曼哈頓距離的一種推廣。閔氏距離不是一種距離,而是一組距離的定義。
閔氏距離被看做是歐氏距離和曼哈頓距離的一種推廣。公式中包含了歐氏距離、曼哈頓距離和切比雪夫距離。
閔可夫斯基距離的定義:
假設兩點:
明氏距離公式為:
p取1或2時的明氏距離是最為常用的,p=2即為歐氏距離,而p=1時則為曼哈頓距離。當p取無窮時的極限情況下,可以得到切比雪夫距離:
我們知道平面上到原點歐幾里得距離(p = 2)為 1 的點所組成的形狀是一個圓,當 p 取其他數(shù)值的時候呢?
注意,當 p<1 時,閔可夫斯基距離不再符合三角形法則,舉個例子:當 p<1, (0,0) 到 (1,1) 的距離等于 (1+1)^{1/p}>2, 而 (0,1) 到這兩個點的距離都是 1。
閔可夫斯基距離比較直觀,但是它與數(shù)據(jù)的分布無關,具有一定的局限性,如果 x 方向的幅值遠遠大于 y 方向的值,這個距離公式就會過度放大 x 維度的作用。所以,在計算距離之前,我們可能還需要對數(shù)據(jù)進行z-transform處理,即減去均值,除以標準差:
其中?μ為該維度上的均值,σ為該維度上的標準差。
可以看到,上述處理開始體現(xiàn)數(shù)據(jù)的統(tǒng)計特性了。這種方法在假設數(shù)據(jù)各個維度不相關的情況下利用數(shù)據(jù)分布的特性計算出不同的距離。如果維度相互之間數(shù)據(jù)相關(例如:身高較高的信息很有可能會帶來體重較重的信息,因為兩者是有關聯(lián)的),這時候就要用到馬氏距離(Mahalanobis distance)了。
閔氏距離的缺點主要有兩個:
將各個分量的量綱(scale),也就是“單位”當作相同看待了
沒有考慮各個分量的分布(期望,方差等)可能是不同的
編輯距離
在做爬蟲的時候,很容易保持一些相似的數(shù)據(jù),這些相似的數(shù)據(jù)由于不完全一致,如果要通過人工一一的審核,將耗費大量的時間。編輯距離(Edit Distance),又稱Levenshtein距離,是指兩個字串之間,由一個轉成另一個所需的最少編輯操作次數(shù)。編輯操作包括將一個字符替換成另一個字符,插入一個字符,刪除一個字符。一般來說,編輯距離越小,兩個串的相似度越大。
例如將kitten一字轉成sitting:(’kitten’ 和 ‘sitting’ 的編輯距離為3)
sitten (k→s)
sittin (e→i)
sitting (→g)
Python中的Levenshtein包可以方便的計算編輯距離,包的安裝:pip install python-Levenshtein
import Levenshtein texta = 'Coggle' textb = 'Google' print Levenshtein.distance(texta,textb)接下來重點介紹下保重幾個方法的作用:
Levenshtein.distance(str1, str2)
計算編輯距離(也稱Levenshtein距離)。是描述由一個字串轉化成另一個字串最少的操作次數(shù),在其中的操作包括插入、刪除、替換。算法實現(xiàn):動態(tài)規(guī)劃。
Levenshtein.hamming(str1, str2)
計算漢明距離。要求str1和str2必須長度一致。是描述兩個等長字串之間對應位置上不同字符的個數(shù)。
Levenshtein.ratio(str1, str2)
計算萊文斯坦比。計算公式? r = (sum – ldist) / sum, 其中sum是指str1 和 str2 字串的長度總和,ldist是類編輯距離。注意這里是類編輯距離,在類編輯距離中刪除、插入依然+1,但是替換+2。
Levenshtein.jaro(s1, s2)
計算jaro距離,Jaro Distance據(jù)說是用來判定健康記錄上兩個名字是否相同,也有說是是用于人口普查,我們先來看一下Jaro Distance的定義。
兩個給定字符串S1和S2的Jaro Distance為:
其中的m為s1, s2匹配的字符數(shù),t是換位的數(shù)目。
兩個分別來自S1和S2的字符如果相距不超過
時,我們就認為這兩個字符串是匹配的;而這些相互匹配的字符則決定了換位的數(shù)目t,簡單來說就是不同順序的匹配字符的數(shù)目的一半即為換位的數(shù)目t。舉例來說,MARTHA與MARHTA的字符都是匹配的,但是這些匹配的字符中,T和H要換位才能把MARTHA變?yōu)镸ARHTA,那么T和H就是不同的順序的匹配字符,t=2/2=1。
兩個字符串的Jaro Distance即為:
Levenshtein.jaro_winkler(s1, s2)
計算Jaro–Winkler距離,而Jaro-Winkler則給予了起始部分就相同的字符串更高的分數(shù),他定義了一個前綴p,給予兩個字符串,如果前綴部分有長度為ι的部分相同,則Jaro-Winkler Distance為:
dj是兩個字符串的Jaro?Distance
ι是前綴的相同的長度,但是規(guī)定最大為4
p則是調整分數(shù)的常數(shù),規(guī)定不能超過25,不然可能出現(xiàn)dw大于1的情況,Winkler將這個常數(shù)定義為0.1
這樣,上面提及的MARTHA和MARHTA的Jaro-Winkler Distance為:
dw = 0.944 + (3 * 0.1(1 ? 0.944)) = 0.961個人覺得算法可以完善的點:
去除停用詞(主要是標點符號的影響)
針對中文進行分析,按照詞比較是不是要比按照字比較效果更好?
余弦相似度
余弦相似性通過測量兩個向量的夾角的余弦值來度量它們之間的相似性。0度角的余弦值是1,而其他任何角度的余弦值都不大于1;并且其最小值是-1。從而兩個向量之間的角度的余弦值確定兩個向量是否大致指向相同的方向。兩個向量有相同的指向時,余弦相似度的值為1;兩個向量夾角為90°時,余弦相似度的值為0;兩個向量指向完全相反的方向時,余弦相似度的值為-1。這結果是與向量的長度無關的,僅僅與向量的指向方向相關。余弦相似度通常用于正空間,因此給出的值為0到1之間。
二維空間為例,上圖的a和b是兩個向量,我們要計算它們的夾角θ。余弦定理告訴我們,可以用下面的公式求得:
假定a向量是[x1,y1],b向量是[x2,y2],兩個向量間的余弦值可以通過使用歐幾里得點積公式求出:
如果向量a和b不是二維而是n維,上述余弦的計算法仍然正確。假定A和B是兩個n維向量,A是[A1,A2,…,An],B是[B1,B2,…,Bn]?,則A與B的夾角θ的余弦等于:
存在的問題:余弦相似度更多的是從方向上區(qū)分差異,而對絕對的數(shù)值不敏感。比如用戶對內容評分,5分制。A和B兩個用戶對兩個商品的評分分別為A:(1,2)和B:(4,5)。我們分別用兩種方法計算相似度。使用余弦相似度得出的結果是0.98,看起來兩者極為相似,但從評分上看X似乎不喜歡這兩個東西,而Y比較喜歡。造成這個現(xiàn)象的原因就在于,余弦相似度沒法衡量每個維數(shù)值的差異,對數(shù)值的不敏感導致了結果的誤差。
from math import *def square_rooted(x):return round(sqrt(sum([a*a for a in x])),3)def cosine_similarity(x,y):numerator = sum(a*b for a,b in zip(x,y))denominator = square_rooted(x)*square_rooted(y)return round(numerator/float(denominator),3)print(cosine_similarity([3, 45, 7, 2], [2, 54, 13, 15]))杰卡德相似度
Jaccard index, 又稱為Jaccard相似系數(shù)(Jaccard similarity coefficient)用于比較有限樣本集之間的相似性與差異性。Jaccard系數(shù)值越大,樣本相似度越高。
兩個集合A和B交集元素的個數(shù)在A、B并集中所占的比例,稱為這兩個集合的杰卡德系數(shù),用符號 J(A,B) 表示。杰卡德相似系數(shù)是衡量兩個集合相似度的一種指標(余弦距離也可以用來衡量兩個集合的相似度)。
def jaccard_sim(a, b):unions = len(set(a).union(set(b)))interps = len(set(a).interp(set(b)))return interps / unions a = ['x', 'y'] b = ['x', 'z', 'v'] print(jaccard_sim(a, b))杰卡德距離
杰卡德距離(Jaccard Distance) 是用來衡量兩個集合差異性的一種指標,它是杰卡德相似系數(shù)的補集,被定義為1減去Jaccard相似系數(shù)。
杰卡德距離用兩個集合中不同元素占所有元素的比例來衡量兩個集合的區(qū)分度。
def jaccard_similarity(x,y):interp_cardinality = len(set.interp(*[set(x), set(y)]))union_cardinality = len(set.union(*[set(x), set(y)]))return interp_cardinality/float(union_cardinality)print(jaccard_similarity([0,1,2,5,6],[0,2,3,5,7,9]))Dice系數(shù)
Dice距離用于度量兩個集合的相似性,因為可以把字符串理解為一種集合,因此Dice距離也會用于度量字符串的相似性。此外,Dice系數(shù)的一個非常著名的使用即實驗性能評測的F1值。Dice系數(shù)定義如下:
其中分子是A與B的交集數(shù)量的兩倍,分母為X和Y的長度之和,所以他的范圍也在0到1之間。從公式看,Dice系數(shù)和Jaccard非常的類似。Jaccard是在分子和分母上都減去了|A∩B|。
與Jaccard不同的是,相應的差異函數(shù)
不是一個合適的距離度量措施,因為它沒有三角形不等性的性質。例如給定 {a}, {b}, 和 {a,b}, 前兩個集合的距離為1, 而第三個集合和其他任意兩個集合的距離為三分之一。
與Jaccard類似, 集合操作可以用兩個向量A和B的操作來表示:
def dice_coefficient(a, b):"""dice coefficient 2nt/na + nb."""a_bigrams = set(a)b_bigrams = set(b)overlap = len(a_bigrams & b_bigrams)return overlap * 2.0/(len(a_bigrams) + len(b_bigrams)) 往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習及深度學習筆記等資料打印機器學習在線手冊深度學習筆記專輯《統(tǒng)計學習方法》的代碼復現(xiàn)專輯 AI基礎下載機器學習的數(shù)學基礎專輯 獲取本站知識星球優(yōu)惠券,復制鏈接直接打開: https://t.zsxq.com/y7uvZF6 本站qq群704220115。加入微信群請掃碼:總結
以上是生活随笔為你收集整理的【机器学习基础】机器学习距离与相似度计算的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【论文解读】传统图像处理与深度学习又一结
- 下一篇: 【推荐】新冠肺炎的最新数据集和可视化和预