日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
面向程序員的數(shù)據(jù)挖掘指南:第二章從推薦系統(tǒng)開始

在本章中你將學(xué)到:

  1. 推薦系統(tǒng)是如何工作的?
  2. 社會(huì)化過濾是如何工作的?
  3. 如何計(jì)算物品之間的相似度?
  4. 曼哈頓距離,歐式距離和閔科夫斯基距離
  5. 皮爾森相關(guān)度
  6. 余弦相似度
  7. 實(shí)現(xiàn)Python版本的KNN算法
  8. 附加的數(shù)據(jù)集

2.1 我喜歡你喜歡的

我們將通過對(duì)推薦系統(tǒng)的研究來開始數(shù)據(jù)挖掘的探索之旅。如今推薦系統(tǒng)無處不在——從Amazon到last.fm的音樂和演唱會(huì)推薦:

在上面的Amazon的例子中,Amazon融合了兩種的信息來進(jìn)行推薦。***個(gè)是我看過的Gene Reeves翻譯的《The Lotus Sutra》;第二個(gè)是看過《The Lotus Sutra》翻譯版的人看還過其他的幾個(gè)翻譯。

在這章中,我們介紹的推薦方法叫協(xié)同過濾。之所以稱為協(xié)同,是因?yàn)樗a(chǎn)生的 推薦是基于其他人的結(jié)果——在效果上,其實(shí)就是人們一起協(xié)作而提出推薦。它是這么工作的:假設(shè)我的任務(wù)是給你推薦一本書,我在這個(gè)網(wǎng)站上搜索跟你在讀書方 面有相似偏好的用戶。一旦發(fā)現(xiàn)這樣的用戶我就可以把她喜歡的書推薦給你——有可能是Paolo Bacigalupi的《The Windup Girl》。

2.2 如何找到那些跟你相似的人

因此***步便是那些跟你相似的人。這里有一個(gè)簡單的二維空間示例,假設(shè)用戶在5***評(píng)分系統(tǒng)中對(duì)書進(jìn)行打分——0星意味著這本書很差,5星則是非常 好。因?yàn)槲覀兪窃诤唵味S條件下,我們把評(píng)分限制在這兩本書:Neal Stephenson的《Snow Crash》和Steig Larsson的《The Girl with the Dragon Tattoo》。

首先,下列表格列出了三個(gè)用戶對(duì)這兩本書的評(píng)分:

我想要給神秘的X女士推薦一本書,她給《Snow Crash》評(píng)了4星,同時(shí)給《The Girl with the Dragon Tattoo》評(píng)了2星。***個(gè)任務(wù)是找到與X女士最相似、或者最相近的人。我通過計(jì)算距離來實(shí)現(xiàn)。

曼哈頓距離

最容易的計(jì)算距離的方法叫曼哈頓距離或者出租車距離。在2D的例子中,每個(gè)人用點(diǎn)(x, y)來表示。我將為每個(gè)x和y添加下標(biāo)用于標(biāo)示不同的人,因此(x1, y1)可能是Amy,(x2, y2)可能是難以捉摸的X女士。曼哈頓距離的計(jì)算如下:

|x1 - x2| + |y1 - y2|

(即x的差的絕對(duì)值加上y的差的絕對(duì)值)。所以Amy和X女士的曼哈頓距離是4:

計(jì)算出X女士與所有三個(gè)人的距離如下:

Amy是最相近的匹配。我們查看她的歷史評(píng)分,例如,她給Paolo Bacigalupi的《The Windup Girl》評(píng)了5星,我們就可以把這本書推薦給X女士。

#p#

歐式距離

曼哈頓距離的一個(gè)優(yōu)點(diǎn)是計(jì)算速度快。如果我們想從Facebook上的一百萬用戶中找出與來自Kalamazoo小Danny最相似的人,速度快是優(yōu)勢(shì)。

勾股定理

你可能從以前的學(xué)習(xí)中想起勾股定理,這里,我們用直線距離代替曼哈頓距離來計(jì)算Amy與X女士的距離(原本是4),直線距離如圖所示:

勾股定理告訴我們?nèi)绾蝸碛?jì)算這種直線距離。

直線c表示的距離稱為歐式距離,公式如下:

回顧一下,x1,x2分別表示用戶1和用戶2對(duì)《Dragon Tattoo》的喜好;y1,y2表示是用戶1和用戶2對(duì)《Snow Crash》的喜好。

Amy對(duì)《Snow Crash》和《Dragon Tattoo》都評(píng)了5分;而X女士給《Dragon Tattoo》評(píng)了2分,對(duì)《Snow Crash》評(píng)了4分。因此這兩人之間的歐氏距離為:

計(jì)算X女士和所有人的歐式距離如下:

擴(kuò)展到N維

我們從一開始的兩本書擴(kuò)展到更復(fù)雜一點(diǎn)的情形。假設(shè)我們?cè)谝患姨峁┰诰€音樂服務(wù)的公司工作,我們想通過樂隊(duì)推薦系統(tǒng)來獲得更好的用戶體驗(yàn)。用戶可以 在我們的1-5星系統(tǒng)中為樂隊(duì)評(píng)分,他們可以給出半顆星的評(píng)分(比如,你可以給一個(gè)樂隊(duì)評(píng)2.5星)。下面的圖表展示了8個(gè)用戶對(duì)8個(gè)樂隊(duì)的評(píng)分:

表格里的連字符"-"表示對(duì)應(yīng)的用戶沒有給相應(yīng)的樂隊(duì)評(píng)分?,F(xiàn)在我們需要通過用戶對(duì)共同的樂隊(duì)的打分來計(jì)算他們之間的距離。比如,當(dāng)我們?cè)谟?jì)算 Angelica和Bill之間的距離時(shí),用到樂隊(duì)有Blues Traveler , Broken Bells , Phoenix, Slightly Stoopid, and Vampire Weekend。所以計(jì)算的曼哈頓距離如下:

對(duì)于行"Manhattan Distance", ***一列只需要將列"Difference"求和即可:

(1.5+1.5+3+2+1) = 9

計(jì)算歐式距離的過程類似,我們只用到他們共同評(píng)過分的那些樂隊(duì):

更詳細(xì)的計(jì)算如下:

動(dòng)手試試

題目1:計(jì)算上表中Hailey和Veronica的歐式距離?

題目2:計(jì)算上表中Hailey和Jordyn的歐式距離?

答案:

題目1:

題目2:

一個(gè)不足

當(dāng)在使用這些距離的時(shí)候我們發(fā)現(xiàn)它存在一個(gè)不足:當(dāng)我們計(jì)算Hailey和 Veronica之間的距離的時(shí)候,我們發(fā)現(xiàn)他們只共同給兩個(gè)樂隊(duì)(Norah Jones 和 The Strokes)評(píng)了分;但是,當(dāng)我們計(jì)算Hailey 和 Jordyn的距離時(shí),我們發(fā)現(xiàn)他們共同給5個(gè)樂隊(duì)評(píng)了分。這樣看起來似乎使得我們的距離度量方法出現(xiàn)偏斜,因?yàn)镠ailey和 Veronica的距離是二維空間上計(jì)算的,而Hailey 和 Jordyn的距離是在五維空間。當(dāng)沒有缺失值的情況下,曼哈頓距離和歐氏距離都表現(xiàn)很好。處理空值在學(xué)術(shù)上是一個(gè)熱門的研究方向。在本書的后面章節(jié)我們 將討論如何來處理這個(gè)問題?,F(xiàn)在我們只要意識(shí)到這一缺陷即可,我們還得繼續(xù)我們的"***探索" —— 構(gòu)建推薦系統(tǒng)。

推廣/泛化

曼哈頓距離和歐式距離更一般的形式是閔可夫斯基距離(Minkowski Distance):

當(dāng):

  • r = 1時(shí),上式即為曼哈頓距離
  • r = 2時(shí),上式即為歐式距離
  • r = 無窮大時(shí),上式為確界距離

很多時(shí)候你會(huì)發(fā)現(xiàn)公式其實(shí)并不難理解?,F(xiàn)在讓我們來剖析它。當(dāng)r=1,公式就簡化成曼哈頓距離:

依然以貫穿本章的音樂為例,x和y代表兩個(gè)人,d(x,y)表示他們之間的距離。n是x,y都評(píng)過分的樂隊(duì)的數(shù)量。我們?cè)谇懊嬉呀?jīng)做過計(jì)算:

列"Difference"代表評(píng)分差值的絕對(duì)值,這些絕對(duì)值加起來得到9。

當(dāng)r=2,我們得到歐氏距離的公式:

需要注意的是:當(dāng)r值越大,單個(gè)維度中,大的difference值對(duì)整體的difference值影響越大。

使用Python表示這些數(shù)據(jù)

Python中表示上述數(shù)據(jù)的方式很多,在這里我將用Python中的字典表示(也叫做散列表或者哈希表)

 
 
 
 
  1. users = {"Angelica": {"Blues Traveler": 3.5, "Broken Bells": 2.0, "Norah Jones": 4.5, "Phoenix": 5.0, "Slightly Stoopid": 1.5, "The Strokes": 2.5, "Vampire Weekend": 2.0},
  2.      "Bill":{"Blues Traveler": 2.0, "Broken Bells": 3.5, "Deadmau5": 4.0, "Phoenix": 2.0, "Slightly Stoopid": 3.5, "Vampire Weekend": 3.0},
  3.      "Chan": {"Blues Traveler": 5.0, "Broken Bells": 1.0, "Deadmau5": 1.0, "Norah Jones": 3.0, "Phoenix": 5, "Slightly Stoopid": 1.0},
  4.      "Dan": {"Blues Traveler": 3.0, "Broken Bells": 4.0, "Deadmau5": 4.5, "Phoenix": 3.0, "Slightly Stoopid": 4.5, "The Strokes": 4.0, "Vampire Weekend": 2.0},
  5.      "Hailey": {"Broken Bells": 4.0, "Deadmau5": 1.0, "Norah Jones": 4.0, "The Strokes": 4.0, "Vampire Weekend": 1.0},
  6.      "Jordyn":  {"Broken Bells": 4.5, "Deadmau5": 4.0, "Norah Jones": 5.0, "Phoenix": 5.0, "Slightly Stoopid": 4.5, "The Strokes": 4.0, "Vampire Weekend": 4.0},
  7.      "Sam": {"Blues Traveler": 5.0, "Broken Bells": 2.0, "Norah Jones": 3.0, "Phoenix": 5.0, "Slightly Stoopid": 4.0, "The Strokes": 5.0},
  8.      "Veronica": {"Blues Traveler": 3.0, "Norah Jones": 5.0, "Phoenix": 4.0, "Slightly Stoopid": 2.5, "The Strokes": 3.0}
  9.     }

我們通過如下方式得到某個(gè)特定用戶的評(píng)分:

 
 
 
 
  1. >>> users["Veronica"]
  2. {"Blues Traveler": 3.0, "Norah Jones": 5.0, "Phoenix": 4.0, "Slightly Stoopid": 2.5, "The Strokes": 3.0}

計(jì)算曼哈頓距離的代碼

計(jì)算曼哈頓距離的代碼如下:

 
 
 
 
  1. def manhattan(rating1, rating2):
  2. """Computes the Manhattan distance. Both rating1 and rating2 are dictionaries
  3.    of the form {'The Strokes': 3.0, 'Slightly Stoopid': 2.5}"""
  4.     distance = 0
  5.     for key in rating1:
  6.         if key in rating2:
  7.             distance += abs(rating1[key] - rating2[key])
  8.     return distance

為了測(cè)試這個(gè)函數(shù):

 
 
 
 
  1. >>> manhattan(users['Hailey'], users['Veronica'])
  2. 2.0
  3. >>> manhattan(users['Hailey'], users['Jordyn'])
  4. 7.5

接下來構(gòu)建一個(gè)函數(shù)找到最相似的那個(gè)人(其實(shí)它會(huì)返回一個(gè)按距離排序好的列表,最相似的人在列表的***個(gè)):

 
 
 
 
  1. def computeNearestNeighbor(username, users):
  2. """creates a sorted list of users based on their distance to username"""
  3. distances = []
  4. for user in users:
  5.     if user != username:
  6.         distance = manhattan(users[user], users[username])
  7.         distances.append((distance, user))
  8. # sort based on distance -- closest first
  9. distances.sort()
  10. return distances

測(cè)試函數(shù)如下:

 
 
 
 
  1. >>> computeNearestNeighbor("Hailey", users)
  2. [(2.0, ''Veronica'), (4.0, 'Chan'),(4.0, 'Sam'), (4.5, 'Dan'), (5.0, 'Angelica'), (5.5, 'Bill'), (7.5, 'Jordyn')]

***,我們將把這些代碼整合在一起成為一個(gè)完整的推薦系統(tǒng)。比如我想為Hailey生成推薦結(jié)果,我會(huì)找到跟他最相似的鄰居——在本例中是 Veronica。接著我會(huì)找出Veronica打過分但是Hailey沒有打過分的樂隊(duì),我們會(huì)假設(shè)Hailey會(huì)對(duì)該樂隊(duì)的評(píng)分和Veronica對(duì) 該樂隊(duì)的評(píng)分相同(至少是相似)。比如,Hailey沒有給Phoenix評(píng)分,Veronica給Phoenix評(píng)了4分,所以我們將猜想Hailey 很有可能也喜歡這個(gè)樂隊(duì)。下面是生成推薦結(jié)果的函數(shù)。

 
 
 
 
  1. def recommend(username, users):
  2. """Give list of recommendations"""
  3. # first find nearest neighbor
  4. nearest = computeNearestNeighbor(username, users)[0][24]
  5. recommendations = []
  6. # now find bands neighbor rated that user didn't
  7. neighborRatings = users[nearest]
  8. userRatings = users[username]
  9. for artist in neighborRatings:
  10.     if not artist in userRatings:
  11.         recommendations.append((artist, neighborRatings[artist]))
  12. # using the fn sorted for variety - sort is more efficient
  13. return sorted(recommendations, key=lambda artistTuple: artistTuple[1], reverse = True)

現(xiàn)在為Hailey生成推薦結(jié)果:

 
 
 
 
  1. >>> recommend('Hailey', users)
  2. [('Phoenix', 4.0), ('Blues Traveler', 3.0), ('Slightly Stoopid', 2.5)]

這跟我們的期望相符。正如我們上面所示,Hailey的最相似的鄰居是Veronica,Veronica給Phoenix評(píng)了4分。我們?cè)僭囋嚻渌模?/p>

 
 
 
 
  1. >>> recommend('Chan', users)
  2. [('The Strokes', 4.0), ('Vampire Weekend', 1.0)]
  3. >>> recommend('Sam', users)
  4. [('Deadmau5', 1.0)]

我們認(rèn)為Chan喜歡The Strokes,同時(shí)預(yù)測(cè)Sam不喜歡Deadmau5.

 
 
 
 
  1. >>> recommend('Angelica', users)
  2. []

對(duì)Angelica來說,返回的空值意味著我們無法對(duì)她進(jìn)行推薦。我們看看問題出在哪里:

 
 
 
 
  1. >>> computeNearestNeighbor('Angelica', users)
  2. [(3.5, 'Veronica'), (4.5, 'Chan'), (5.0, 'Hailey'), (8.0, 'Sam'), (9.0, 'Bill'), (9.0, 'Dan'), (9.5, 'Jordyn')]

Angelica的最近鄰居是Veronica,他們的評(píng)分表如下:

我們看到Veronica評(píng)過的所有樂隊(duì)Angelica也都有評(píng)過分。我們沒有更新的評(píng)分的樂隊(duì)了,因此就沒有推薦結(jié)果。

我們將提出方法來改善該系統(tǒng)來避免這種情況的出現(xiàn)。

課后作業(yè)

  1. 實(shí)現(xiàn)閔可夫斯基距離函數(shù)
  2. 改變computeNearestNeighbor,使用閔可夫斯基作為距離計(jì)算函數(shù)。

埋怨用戶

讓我們看看用戶評(píng)分的細(xì)節(jié)。我們可以看出當(dāng)用戶對(duì)樂隊(duì)進(jìn)行打分的時(shí)候,其打分行為差別很大:

Bill不喜歡走極端,他的評(píng)分都在2星到4星之間。Jordyn看起來喜歡所有的東西,他的評(píng)分都在4星到5星之間。Hailey的評(píng)分很極端,給出的不是1星就是4星.

這種情況下,我們應(yīng)該如何比較用戶,比如Hailey和Jordan?Hailey的4分相當(dāng)于Jordyn的4分還是5分?我想應(yīng)該是更像5分,這種差異會(huì)給推薦系統(tǒng)帶來新的問題。

皮爾森相關(guān)系數(shù)

有一種解決此類問題的方法是使用皮爾森相關(guān)系數(shù)。首先,從一般性出發(fā),考慮下面的數(shù)據(jù)(和前面用的數(shù)據(jù)不同):

這個(gè)例子在數(shù)據(jù)挖掘領(lǐng)域被稱為“分?jǐn)?shù)通脹”。Clara的***評(píng)分是4——她的所有評(píng)分都在4到5之間。如果我們將上表中的評(píng)分用圖表示:

事實(shí)上這條直線暗示著Clara和Robert之間是興趣是高度一致的。他們都覺得Phoenix是***的樂隊(duì),其次是Blues Traveler,接著是Norah Jones。

還不錯(cuò)的的一致性:

不是太好的一致性:

因此從圖表中可以看出:一條直線表示高度相關(guān)。皮爾森相關(guān)系數(shù)是一種度量兩個(gè)變量相關(guān)性的方法(在這個(gè)例子中,Ckara和Robert的相關(guān) 性)。它的取值范圍在-1到1之間。1表明完全相關(guān),-1表明完全負(fù)相關(guān)。一個(gè)比較直觀的感覺:上圖中,直線的皮爾森系數(shù)是1,我標(biāo)著“還不錯(cuò)的的一致 性”皮爾森系數(shù)有0.91,“不是太好的一致性”的系數(shù)則為0.81,所以我們可以用這個(gè)去發(fā)現(xiàn)與我們興趣最相似的人。

皮爾森相關(guān)系數(shù)的公式是:

除了看起來復(fù)雜,這個(gè)公式的另外一個(gè)問題是需要對(duì)數(shù)據(jù)進(jìn)行多輪運(yùn)算。慶幸的是,對(duì)我們做算法的人來說,該公式有另外一個(gè)近似的形式:

(記住我兩段前說過的,不要跳過公式)這個(gè)公式,除了一看是看上去更加復(fù)雜,更重要的是,數(shù)值的不穩(wěn)定性意味著小的誤差可能會(huì)被近似后的公式放大。 但是這個(gè)變形有一個(gè)***的好處是我們可以通過對(duì)數(shù)據(jù)一輪的遍歷就能實(shí)現(xiàn)它。首先,我們來剖析這個(gè)公式,并結(jié)合前幾頁講到的例子:

我們先計(jì)算:

這是相似度計(jì)算公式分子的***部分,這里的x和y分別代表著Clara和Robert。

對(duì)于每一個(gè)樂隊(duì),我們把Clara和Robert的分?jǐn)?shù)相乘,然后求和:

接著我們計(jì)算分子的另外一部分:

因此:

等于Clara所有評(píng)分的和,即22.5. 對(duì)于Robert,其評(píng)分的和為15,他們總共對(duì)5個(gè)樂隊(duì)評(píng)分,即:

因此前文中的公式的分子為70 - 67.5=2.5.

現(xiàn)在我們開始計(jì)算分母:

首先:

前面我們已經(jīng)計(jì)算過Clara的評(píng)分之和等于22.5,平方以后得506.25。然后除以共同評(píng)分的樂隊(duì)數(shù)5,得到101.25。把以上結(jié)果整合到一起得到:

接著,按照同樣的方法計(jì)算Robert:

把所以的計(jì)算整合到一起得到***的結(jié)果:

因此1意味著Clara和Robert是完全相關(guān)的。

課后作業(yè)

在進(jìn)行下面的計(jì)算之前,我們先使用Python實(shí)現(xiàn)一下Pearson相似度算法:

 
 
 
 
  1. def pearson(rating1, rating2):
  2.   sum_xy = 0
  3.   sum_x = 0
  4.   sum_y = 0
  5.   sum_x2 = 0
  6.   sum_y2 = 0 !
  7.   n = 0
  8.   for key in rating1: !
  9.     if key in rating2:
  10.       n += 1
  11.       x = rating1[key]
  12.       y = rating2[key]
  13.       sum_xy += x * y
  14.       sum_x += x
  15.       sum_y += y
  16.       sum_x2 += x**2
  17.       sum_y2 += y**2
  18.   # now compute denominator
  19.   denominator = sqrt(sum_x2 - (sum_x**2) / n) * sqrt(sum_y2 -(sum_y**2) / n)
  20.   if denominator == 0:
  21.     return 0
  22.   else:
  23.     return (sum_xy - (sum_x * sum_y) / n) / denominator

***一個(gè)公式 —— 余弦相似度

我接著講***一個(gè)公式——余弦相似度,它在文本挖掘中非常流行,同時(shí)在協(xié)同過濾中也被廣泛采用。要知道我們什么時(shí)候會(huì)用到這個(gè)公式,我們先把我們的例子做一些小小的改

變。我們記錄下每個(gè)人播放某首歌曲的次數(shù),并且以此信息來作為我們推薦算法的基礎(chǔ)信息。

肉眼觀察上面的圖表(或者用上面講到的距離公式),在聽音樂的習(xí)慣上,Ann要比Ben更像Sally。

問題出現(xiàn)哪里?

我是我iTunes中差不多有四千首歌曲,這里是播放量排名靠前的一些歌曲:

所以我的排名***的是Marcus Miller的Moonlight Sonata,總共播放25次,你有可能一次也沒聽過這首歌。實(shí)際上,很有可能這些排名靠前的歌曲你一首也沒聽過。此外,iTunes上面有超過1千5百 萬首歌曲,我只有4000首。所以對(duì)某個(gè)人來說,他的數(shù)據(jù)是稀疏的,因?yàn)樗宦犃怂懈枨袠O少的部分,每個(gè)人的播放數(shù)據(jù)是極度稀疏的。當(dāng)我們?cè)?千5百 萬首歌曲里面對(duì)比兩個(gè)人的音樂播放次數(shù)時(shí),基本上他們都共同的播放的歌曲數(shù)為0。但是,當(dāng)我們計(jì)算相似性的時(shí)候沒法使到這種共享為0次的播放。

另外一個(gè)類似的情形是使用詞計(jì)算文本之間的相似度。假設(shè)我們都喜歡一本書,比如Carey Rockwell的Tom Corbett Space Cadet:The Space Pioneers,我們想要找到類似的書本。其中一種可能的方法是使用詞頻。屬性是某個(gè)詞,屬性的值是該詞在書本中出現(xiàn)的頻率。所以《The Space Pioneers 》中6.13%的詞是the,0.89%是Tom,0.25%是space。我可以用這些詞匯頻率來計(jì)算這本書與其他書的相似度。但是,數(shù)據(jù)稀疏性問題在 這里出現(xiàn)了,這本書中總共有6629個(gè)不重復(fù)的詞匯,而英文中有超過一百萬個(gè)英文單詞。所以如果我們的屬性是英語單詞,在《The Space Pioneers》中或者其他書本中將會(huì)有相對(duì)少的非零屬性值。問題再次出現(xiàn),任何相似性度量不應(yīng)該依賴共有的零值。

余弦相似度忽略了0與0的匹配,其定義如下:

其中"."表示向量x和向量y的內(nèi)積,"||x||"表示向量x的長度,即:

用一個(gè)例子來表示:

兩個(gè)向量為:

x=(4.75, 4.5, 5, 4.25, 4) y=(4, 3, 5, 2, 1)

因此:

內(nèi)積為:

x?y = (4.75 × 4)+ (4.5 × 3)+ (5 × 5)+ (4.25 × 2)+ (4 ×1) = 70

因此,余弦相似度為:

余弦相似度中,1表示完全正相關(guān),-1表示完全負(fù)相關(guān),因此0.935表示正相關(guān)性很高。

練習(xí):

計(jì)算Angelica和Veronica的余弦相似度。


網(wǎng)站標(biāo)題:面向程序員的數(shù)據(jù)挖掘指南:第二章從推薦系統(tǒng)開始
鏈接分享:http://www.dlmjj.cn/article/dppjdod.html