商品搜索引擎---推荐系统设计
一、前言
結(jié)合目前已存在的商品推薦設(shè)計(如淘寶、京東等),推薦系統(tǒng)主要包含系統(tǒng)推薦和個性化推薦兩個模塊。
系統(tǒng)推薦: 根據(jù)大眾行為的推薦引擎,對每個用戶都給出同樣的推薦,這些推薦可以是靜態(tài)的由系統(tǒng)管理員人工設(shè)定的,或者基于系統(tǒng)所有用戶的反饋統(tǒng)計計算出的當(dāng)下比較流行的物品。
個性化推薦:對不同的用戶,根據(jù)他們的口味和喜好給出更加精確的推薦,這時,系統(tǒng)需要了解需推薦內(nèi)容和用戶的特質(zhì),或者基于社會化網(wǎng)絡(luò),通過找到與當(dāng)前用戶相同喜好的用戶,實(shí)現(xiàn)推薦。
下面具體介紹系統(tǒng)推薦和個性化推薦的設(shè)計方案。
二、系統(tǒng)推薦
2.1、系統(tǒng)推薦目的
針對所有用戶推薦,當(dāng)前比較流行的商品(必選) 或 促銷實(shí)惠商品(可選) 或 新上市商品(可選),以促進(jìn)商品的銷售量。
PS:根據(jù)我們的應(yīng)用情況考慮是否 選擇推薦 促銷實(shí)惠商品 和 新上市商品。(TODO1)
2.2、實(shí)現(xiàn)方式
實(shí)現(xiàn)方式包含:系統(tǒng)自動化推薦 和 人工設(shè)置推薦。
(1)系統(tǒng)自動化推薦考慮因素有:商品發(fā)布時間、商品分類、庫存余量、歷史被購買數(shù)量、歷史被加入購物車數(shù)量、歷史被瀏覽數(shù)量、降價幅度等。根據(jù)我們當(dāng)前可用數(shù)據(jù),再進(jìn)一步確定(TODO2)
(2)人工設(shè)置:提供運(yùn)營頁面供運(yùn)營人員設(shè)置,設(shè)置包含排行位置、開始時間和結(jié)束時間、推薦介紹等等。
由于系統(tǒng)推薦實(shí)現(xiàn)相對簡單,因此不作過多的文字說明,下面詳細(xì)介紹個性化推薦的設(shè)計。
三、個性化推薦
3.1、個性化推薦目的
對不同的用戶,根據(jù)他們的口味和喜好給出更加精確的推薦,系統(tǒng)需要了解需推薦內(nèi)容和用戶的特質(zhì),或者基于社會化網(wǎng)絡(luò),通過找到與當(dāng)前用戶相同喜好的用戶,實(shí)現(xiàn)推薦,以促進(jìn)商品的銷售量。
3.2、三種推薦模式的介紹
據(jù)推薦引擎的數(shù)據(jù)源有三種模式:基于人口統(tǒng)計學(xué)的推薦、基于內(nèi)容的推薦、基于協(xié)同過濾的推薦。
(1)基于人口統(tǒng)計學(xué)的推薦:針對用戶的“性別、年齡范圍、收入情況、學(xué)歷、專業(yè)、職業(yè)”進(jìn)行推薦。
(2)基于內(nèi)容的推薦:如下圖,這里沒有考慮人對物品的態(tài)度,僅僅是因?yàn)殡娪癆月電影C相似,因此將電影C推薦給用戶A。這是與后面講到的協(xié)同過濾推薦最大的不同。
(3)基于協(xié)同過濾的推薦:如下圖,這里我們并不知道物品A和物品D是否相似,僅僅考慮人對物品的喜好進(jìn)行推薦。
模式采用:這三種模式可以單獨(dú)使用,也可結(jié)合使用。結(jié)合我們實(shí)際情況,采用基于協(xié)同過濾的推薦更加合適,看后期情況是否結(jié)合另外兩種模式實(shí)現(xiàn)推薦。但基于協(xié)同過濾的推薦這種模式,會引發(fā)“冷啟動”問題。關(guān)于,冷啟動問題,后續(xù)會討論解決方案。
3.3、用戶喜好設(shè)計
(1)判斷用戶喜好因素:歷史購買、歷史購物車、歷史搜索、歷史瀏覽等,待確定我們可用數(shù)據(jù)再進(jìn)一步細(xì)化。
(2)用戶對某個商品的喜好程度,通過不同行為對應(yīng)不同分值權(quán)重,如:歷史購買(10)、歷史購物車(8)、歷史搜索(5)、歷史瀏覽(6),確定用戶喜好因素后再進(jìn)一步對各個因素評分權(quán)重進(jìn)行 合理的設(shè)計。
(3)用戶對商品的喜好程度最終體現(xiàn):結(jié)合某個商品的不同行為 統(tǒng)計出 最終對該商品的喜好程度,即對商品的喜好程度,最終以一個數(shù)字體現(xiàn)。
3.4、Mahout介紹
目前選擇采用協(xié)同過濾框架Mahout進(jìn)行實(shí)現(xiàn)。
Mahout 是一個很強(qiáng)大的數(shù)據(jù)挖掘工具,是一個分布式機(jī)器學(xué)習(xí)算法的集合,包括:被稱為Taste的分布式協(xié)同過濾的實(shí)現(xiàn)、分類、聚類等。Mahout最大的優(yōu)點(diǎn)就是基于hadoop實(shí)現(xiàn),把很多以前運(yùn)行于單機(jī)上的算法,轉(zhuǎn)化為了MapReduce模式,這樣大大提升了算法可處理的數(shù)據(jù)量和處理性能。
Mahout 是一個布式機(jī)器學(xué)習(xí)算法的集合,但是這里我們只使用到它的推薦/協(xié)同過濾算法。
3.5、Mahout實(shí)現(xiàn)協(xié)同過濾實(shí)例
協(xié)同過濾在mahout里是由一個叫taste的引擎提供的, 它提供兩種模式,一種是以jar包形式嵌入到程序里在進(jìn)程內(nèi)運(yùn)行,另外一種是MapReduce Job形式在hadoop上運(yùn)行。這兩種方式使用的算法是一樣的,配置也類似。
這里我們采用第一種引入jar包的單機(jī)模式。
3.5.1、依賴
<code class="hljs xml has-numbering"><span class="hljs-tag"><<span class="hljs-title">dependency</span>></span><span class="hljs-tag"><<span class="hljs-title">groupId</span>></span>org.apache.mahout<span class="hljs-tag"></<span class="hljs-title">groupId</span>></span><span class="hljs-tag"><<span class="hljs-title">artifactId</span>></span>mahout-core<span class="hljs-tag"></<span class="hljs-title">artifactId</span>></span><span class="hljs-tag"><<span class="hljs-title">version</span>></span>0.9<span class="hljs-tag"></<span class="hljs-title">version</span>></span> <span class="hljs-tag"></<span class="hljs-title">dependency</span>></span> <span class="hljs-tag"><<span class="hljs-title">dependency</span>></span><span class="hljs-tag"><<span class="hljs-title">groupId</span>></span>org.apache.mahout<span class="hljs-tag"></<span class="hljs-title">groupId</span>></span><span class="hljs-tag"><<span class="hljs-title">artifactId</span>></span>mahout-math<span class="hljs-tag"></<span class="hljs-title">artifactId</span>></span><span class="hljs-tag"><<span class="hljs-title">version</span>></span>0.9<span class="hljs-tag"></<span class="hljs-title">version</span>></span> <span class="hljs-tag"></<span class="hljs-title">dependency</span>></span> <span class="hljs-tag"><<span class="hljs-title">dependency</span>></span><span class="hljs-tag"><<span class="hljs-title">groupId</span>></span>org.apache.hadoop<span class="hljs-tag"></<span class="hljs-title">groupId</span>></span><span class="hljs-tag"><<span class="hljs-title">artifactId</span>></span>hadoop-core<span class="hljs-tag"></<span class="hljs-title">artifactId</span>></span><span class="hljs-tag"><<span class="hljs-title">version</span>></span>1.2.1<span class="hljs-tag"></<span class="hljs-title">version</span>></span> <span class="hljs-tag"></<span class="hljs-title">dependency</span>></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li></ul>3.5.2、實(shí)現(xiàn)代碼
<code class="hljs cs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span>(String[] args) {<span class="hljs-keyword">try</span> {<span class="hljs-comment">// 從文件加載數(shù)據(jù)</span>DataModel model = <span class="hljs-keyword">new</span> FileDataModel(<span class="hljs-keyword">new</span> File(<span class="hljs-string">"D:\\mahout\\data.csv"</span>));<span class="hljs-comment">// 指定用戶相似度計算方法,這里采用皮爾森相關(guān)度</span>UserSimilarity similarity = <span class="hljs-keyword">new</span> PearsonCorrelationSimilarity(model);<span class="hljs-comment">// 指定用戶鄰居數(shù)量,這里為2</span>UserNeighborhood neighborhood = <span class="hljs-keyword">new</span> NearestNUserNeighborhood(<span class="hljs-number">2</span>,similarity, model);<span class="hljs-comment">// 構(gòu)建基于用戶的推薦系統(tǒng)</span>Recommender recommender = <span class="hljs-keyword">new</span> GenericUserBasedRecommender(model,neighborhood, similarity);<span class="hljs-comment">// 得到指定用戶的推薦結(jié)果,這里是得到用戶1的兩個推薦</span>List<RecommendedItem> recommendations = recommender.recommend(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>);<span class="hljs-comment">// 打印推薦結(jié)果</span><span class="hljs-keyword">for</span> (RecommendedItem recommendation : recommendations) {System.<span class="hljs-keyword">out</span>.println(recommendation);}} <span class="hljs-keyword">catch</span> (Exception e) {System.<span class="hljs-keyword">out</span>.println(e);} }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li></ul>3.5.3、data.csv內(nèi)容(用戶id、商品id,評分)
<code class="hljs has-numbering">1,101,5 1,102,3 1,103,2.5 2,101,2 2,102,2.5 2,103,5 2,104,2 3,101,2.5 3,104,4 3,105,4.5 3,107,5 4,101,5 4,103,3 4,104,4.5 4,106,4 5,101,4 5,102,3 5,103,2 5,104,4 5,105,3.5 5,106,4</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li></ul>3.5.4、運(yùn)行結(jié)果
3.6、Mahout協(xié)同過濾算法選用
3.6.1、Mahout協(xié)同過濾自帶算法介紹
Mahout算法框架自帶的推薦器有下面這些:
GenericUserBasedRecommender:基于用戶的推薦器,用戶數(shù)量少時速度快;
GenericItemBasedRecommender:基于商品推薦器,商品數(shù)量少時速度快,尤其當(dāng)外部提供了商品相似度數(shù)據(jù)后效率更好;
SlopeOneRecommender:基于slope-one算法的推薦器,在線推薦或更新較快,需要事先大量預(yù)處理運(yùn)算,物品數(shù)量少時較好;
SVDRecommender:奇異值分解,推薦效果較好,但之前需要大量預(yù)處理運(yùn)算;
KnnRecommender:基于k近鄰算法(KNN),適合于物品數(shù)量較小時;
TreeClusteringRecommender:基于聚類的推薦器,在線推薦較快,之前需要大量預(yù)處理運(yùn)算,用戶數(shù)量較少時效果好;
Mahout最常用的三個推薦器是上述的前三個,本文主要討論前兩種的使用。
3.6.2、考慮使用算法
(1)GenericUserBasedRecommender(推薦)
一個很簡單的user-based模式的推薦器實(shí)現(xiàn)類,根據(jù)傳入的DataModel和UserNeighborhood進(jìn)行推薦。其推薦流程分成三步:
第一步,使用UserNeighborhood獲取跟指定用戶Ui最相似的K個用戶{U1…Uk};
第二步,{U1…Uk}喜歡的item集合中排除掉Ui喜歡的item, 得到一個item集合 {Item0…Itemm}
第三步,對{Item0…Itemm}每個itemj計算 Ui可能喜歡的程度值perf(Ui , Itemj) ,并把item按這個數(shù)值從高到低排序,把前N個item推薦給Ui。其中perf(Ui , Itemj)的計算公式如下:
其中 是用戶Ul對Itemj的喜好值。
(2)GenericItemBasedRecommender
一個簡單的item-based的推薦器,根據(jù)傳入的DateModel和ItemSimilarity去推薦。基于Item的相似度計算比基于User的相似度計算有個好處是,item數(shù)量較少,計算量也就少了,另外item之間的相似度比較固定,所以相似度可以事先算好,這樣可以大幅提高推薦的速度。
其推薦流程可以分成三步:
第一步,獲取用戶Ui喜好的item集合{It1…Itm}
第二步,使用MostSimilarItemsCandidateItemsStrategy(有多種策略, 功能類似UserNeighborhood) 獲取跟用戶喜好集合里每個item最相似的其他Item構(gòu)成集合 {Item1…Itemk};
第三步,對{Item1…Itemk}里的每個itemj計算 Ui可能喜歡的程度值perf(Ui , Itemj) ,并把item按這個數(shù)值從高到低排序,把前N個Item推薦給Ui。其中perf(Ui , Itemj)的計算公式如下:
其中 是用戶Ul對Iteml的喜好值。
(3)SlopeOneRecommender
基于Slopeone算法的推薦器,Slopeone算法適用于用戶對item的打分是具體數(shù)值的情況。Slopeone算法不同于前面提到的基于相似度的算法,他計算簡單快速,對新用戶推薦效果不錯,數(shù)據(jù)更新和擴(kuò)展性都很不錯,預(yù)測能達(dá)到和基于相似度的算法差不多的效果,很適合在實(shí)際項目中使用。
綜合考慮,我們使用GenericUserBasedRecommender(基于用戶的推薦器)比較合適。3.5、Mahout實(shí)現(xiàn)協(xié)同過濾實(shí)例 就是采用這種算法實(shí)現(xiàn)的。
3.7、Mahout數(shù)據(jù)源獲取方式
DataModel 是用戶喜好信息的抽象接口,它的具體實(shí)現(xiàn)支持從任意類型的數(shù)據(jù)源抽取用戶喜好信息。Taste 默認(rèn)提供 JDBCDataModel 和 FileDataModel,分別支持從數(shù)據(jù)庫和文件中讀取用戶的喜好信息。
目前,Mahout為DataModel提供了以下幾種實(shí)現(xiàn):
org.apache.mahout.cf.taste.impl.model.GenericDataModel
org.apache.mahout.cf.taste.impl.model.GenericBooleanPrefDataModel
org.apache.mahout.cf.taste.impl.model.PlusAnonymousUserDataModel
org.apache.mahout.cf.taste.impl.model.file.FileDataModel
org.apache.mahout.cf.taste.impl.model.hbase.HBaseDataModel
org.apache.mahout.cf.taste.impl.model.cassandra.CassandraDataModel
org.apache.mahout.cf.taste.impl.model.mongodb.MongoDBDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.SQL92JDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.MySQLJDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.PostgreSQLJDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.GenericJDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.SQL92BooleanPrefJDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.MySQLBooleanPrefJDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.PostgreBooleanPrefSQLJDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.ReloadFromJDBCDataModel
從類名上就可以大概猜出來每個DataModel的用途,但是竟然沒有HDFS的DataModel,有人實(shí)現(xiàn)了一個,請參考MAHOUT-1579(https://issues.apache.org/jira/browse/MAHOUT-1579)。
3.8、協(xié)同過濾實(shí)現(xiàn)采用技術(shù)
采用如下技術(shù):Mahout(推薦算法) + Spark(并行計算) + Hadoop + Elasticsearch
Mahout 是一個很強(qiáng)大的數(shù)據(jù)挖掘工具,是一個分布式機(jī)器學(xué)習(xí)算法的集合,包括:被稱為Taste的分布式協(xié)同過濾的實(shí)現(xiàn)、分類、聚類等。Mahout最大的優(yōu)點(diǎn)就是基于hadoop實(shí)現(xiàn),把很多以前運(yùn)行于單機(jī)上的算法,轉(zhuǎn)化為了MapReduce模式,這樣大大提升了算法可處理的數(shù)據(jù)量和處理性能。
Spark是UC Berkeley AMP lab所開源的類Hadoop MapReduce的通用的并行計算框架,Spark基于map reduce算法實(shí)現(xiàn)的分布式計算,擁有Hadoop MapReduce所具有的優(yōu)點(diǎn);但不同于MapReduce的是Job中間輸出結(jié)果可以保存在內(nèi)存中,從而不再需要讀寫HDFS,因此Spark能更好地適用于數(shù)據(jù)挖掘與機(jī)器學(xué)習(xí)等需要迭代的map reduce的算法。
但Spark沒有提供文件管理系統(tǒng),所以,它必須和其他的分布式文件系統(tǒng)進(jìn)行集成才能運(yùn)作。這里我們可以選擇Hadoop的HDFS,也可以選擇其他的基于云的數(shù)據(jù)系統(tǒng)平臺。但Spark默認(rèn)來說還是被用在Hadoop上面的,畢竟,大家都認(rèn)為它們的結(jié)合是最好的。
PS:Mahout(推薦算法) + Spark(并行計算) + Hadoop + Elasticsearch搭配的實(shí)現(xiàn)方式并沒有嘗試,網(wǎng)上有一些解決方案,但是并不詳細(xì),而且英文居多,因此需要進(jìn)一步學(xué)習(xí)研究。
可參考文獻(xiàn):https://mahout.apache.org/users/algorithms/intro-cooccurrence-spark.html
3.9、冷啟動問題
所謂冷啟動,是指對于很多推薦引擎的開始階段,當(dāng)一個新用戶進(jìn)入推薦系統(tǒng)或者系統(tǒng)添加一個新的物品后,由于還沒有大量的用戶數(shù)據(jù),系統(tǒng)無法計算出推薦模型,從而導(dǎo)致系統(tǒng)的推薦功能失效的問題。
可考慮的解決方案有:
(1)利用用戶注冊信息進(jìn)行初步推薦,主要包括人口統(tǒng)計學(xué)信息、用戶描述的個人興趣內(nèi)容,預(yù)先設(shè)定好用戶的偏好信息。
(2)在用戶第一次訪問系統(tǒng)時,給用戶提供一些物品,讓用戶反饋對這些物品的評分,然后根據(jù)用戶的反饋形成初始的個性化推薦。
(3)邀請行業(yè)的專家對新的用戶或者新的物品
進(jìn)行分類、評注。
(4)隨機(jī)推薦的方法。對于冷啟動問題,實(shí)際應(yīng)用中最簡單最直觀的方法是采用隨機(jī)推薦的 方式。這種方法是比較冒險。
(5)平均值法。所有項目的均值,作為用戶對未評價過項目的預(yù)測值,將原始評分矩陣進(jìn)行 填充,然后在填充后的評分矩陣上尋找目標(biāo)用戶的最近鄰居,應(yīng)用協(xié)同過濾的方法產(chǎn)生推薦。但是均值的方法只能說是一種被動應(yīng)付的方式,新用戶對項目的喜好值正好等于其他用戶對此項目的平均值的概率是非常小的。
根據(jù)我們實(shí)際情況,建議使用第(1)種解決方案比較合適。
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的商品搜索引擎---推荐系统设计的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 几种软负载均衡策略分析
- 下一篇: 基于Solr的空间搜索学习笔记