自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

攜程基于LSTM的廣告庫存預估算法

開發(fā) 新聞
使用離線與在線增量訓練相結(jié)合的訓練方式,使模型更具活力,每天在優(yōu)選出的廣告庫存模型基礎(chǔ)上進行微調(diào),可以不斷維持模型提供精準的預估能力。

作者簡介

Paul,攜程高級研發(fā)經(jīng)理,關(guān)注廣告投放技術(shù)架構(gòu)、大數(shù)據(jù)、人工智能等領(lǐng)域;

Xunling,攜程資深后端開發(fā)工程師,關(guān)注廣告服務(wù)、性能優(yōu)化,對AI技術(shù)有濃厚興趣。

一、背景

近年來,隨著互聯(lián)網(wǎng)的發(fā)展,在線廣告營銷成為一種非常重要的商業(yè)模式。出于廣告流量商業(yè)化售賣和日常業(yè)務(wù)投放精細化運營的目的,需要對廣告流量進行更精準的預估,從而更精細的進行廣告庫存管理。

因此,攜程廣告縱橫平臺實踐了LSTM(Long Short-Term Memory,長短時記憶網(wǎng)絡(luò))模型結(jié)合Embedding的廣告庫存預估深度學習算法,在節(jié)省訓練資源的同時,構(gòu)建更具泛化性的模型,支持根據(jù)不同地域分布、人口學屬性標簽等進行庫存變動預估,并能體現(xiàn)出節(jié)假日特征對庫存波動的影響,從而對廣告庫存進行更為精確的預估。

二、問題和挑戰(zhàn)

廣告庫存預估實現(xiàn)有諸多挑戰(zhàn):

  • 現(xiàn)實中對廣告庫存的影響因素非常多,比如節(jié)假日、周末、自然災害等等;
  • 廣告庫存樣本周期以天為單位,訓練樣本很少;
  • 需要支持不同維度交叉進行廣告預估,例如同時選擇地域、年齡、性別、會員等級等定向交叉,預估未來N天的庫存情況;
  • 廣告庫存日新月異,隨時間推移,不斷有新的庫存樣本生成,模型更新頻率要求較高。

這些因素讓廣告庫存預估工作從資源和效率等角度都帶來壓力。

三、算法簡述

RNN(Recurrent Neural Network,循環(huán)神經(jīng)網(wǎng)絡(luò))是一種特殊的神經(jīng)網(wǎng)絡(luò),被廣泛應用于序列數(shù)據(jù)的建模和預測,如自然語言處理、語音識別、時間序列預測等領(lǐng)域。RNN對時間序列的數(shù)據(jù)有著強大的提取能力,也被稱作記憶能力。相對于傳統(tǒng)的前饋神經(jīng)網(wǎng)絡(luò),RNN具有循環(huán)連接,可以將前一時刻的輸出作為當前時刻的輸入,從而使得網(wǎng)絡(luò)可以處理任意長度的序列數(shù)據(jù),捕捉序列數(shù)據(jù)中的長期依賴關(guān)系。

圖片

圖 3-1

LSTM(Long Short-Term Memory,長短時記憶網(wǎng)絡(luò))是一種特殊的 RNN,它通過引入門控機制和記憶單元等結(jié)構(gòu)來增強 RNN 的記憶能力和表達能力。

LSTM 的基本結(jié)構(gòu)包括一個循環(huán)單元和三個門控單元:輸入門、遺忘門和輸出門。循環(huán)單元接受當前時刻的輸入和前一時刻的輸出作為輸入,并輸出當前時刻的輸出和傳遞到下一時刻的狀態(tài)。輸入門控制當前時刻的輸入對狀態(tài)的影響,遺忘門控制前一時刻的狀態(tài)對當前狀態(tài)的影響,輸出門控制當前狀態(tài)對輸出的影響。記憶單元則用于存儲和傳遞長期的信息?;诖耍沟肔STM具有長期的記憶能力,并且具有防止梯度消失的特點,故我們選擇LSTM作為庫存預估模型的訓練基礎(chǔ)。

圖片

圖 3-2

Embedding是一種特征處理方式,它可以將我們的某個特征數(shù)據(jù)向量化,可以將離散的整數(shù)序列映射為連續(xù)的實向量,它通常用于自然語言處理中的詞嵌入(Word Embedding)任務(wù),用于將每個單詞映射為一個實向量,從而使得單詞之間的語義關(guān)系可以在向量空間中進行計算。

在本文中,我們是使用它進行實體嵌入(Entity Embedding) 任務(wù),也就是將我們的特征實體進行向量化,通過大量的數(shù)據(jù)訓練,得到實體向量之前的細微關(guān)系,從而幫助模型更清晰的識別不同實體對廣告庫存的影響,進而提高模型的泛化能力。

四、數(shù)據(jù)處理

4.1 特征定義

基礎(chǔ)特征為下圖所示:

圖片

圖 4-1

由于節(jié)假日的特殊性,我們又將其細分為以下維度,保證模型抓住節(jié)前和節(jié)后購票效應。

圖片

圖 4-2

4.2 歸一化

在深度學習中,對數(shù)據(jù)進行歸一化主要目的是將數(shù)據(jù)縮放到一個合適的范圍內(nèi),便于神經(jīng)網(wǎng)絡(luò)的訓練和優(yōu)化。對數(shù)據(jù)進行歸一化可以改善梯度下降、加速收斂、提高模型的泛化能力。

我們選擇Z-score標準化方法對數(shù)據(jù)進行處理,Z-score 標準化(也稱為標準差標準化)是一種常見的數(shù)據(jù)歸一化方法,其基本思想是將原始數(shù)據(jù)轉(zhuǎn)換為標準正態(tài)分布,即均值為 0,標準差為 1。公式如下圖所示,是一個實測值與平均數(shù)的差再除以標準差的過程。

圖片

4.3 數(shù)據(jù)聚類

我們在第二章節(jié)問題和挑戰(zhàn)中聊到過,廣告庫存預估需要對多個維度支持預估功能,不同維度交叉組合后,庫存量千差萬別,導致我們的樣本數(shù)據(jù)中標簽值min和max差距非常大。

如圖4-3所示,本圖Y軸表示某組合維度標簽值的庫存數(shù)據(jù)量級,庫存數(shù)據(jù)量較小的組合維度占有很大一部分,而庫存數(shù)據(jù)量較大的組合維度相對較少,僅憑數(shù)據(jù)歸一化手段,數(shù)據(jù)壓縮的效果非常不明顯,如果強行一起訓練會互相影響,導致模型難以擬合,訓練中的損失函數(shù)如圖4-4所示,訓練時模型無法正常擬合,損失值不能夠正常下降,訓練出的模型效果可想而知,無法支持正常的預估功能。

圖片

圖 4-3

圖片

圖 4-4

所以,我們以庫存樣本的標簽值為依據(jù),使用K-means算法對不同維度的庫存進行數(shù)據(jù)聚類,將近似類別的維度放在一起進行訓練,提高模型的擬合速度和泛化能力。

我們選擇“肘部法則”來確認本數(shù)據(jù)集的最佳分類數(shù),也就是K-means的簇數(shù)K的具體值。隨著K的增加,聚類效果不斷提高,但是當K到達某個值的時候,聚類效果的提高變得越來越慢,此時再增加K已經(jīng)不能明顯提高聚類效果,因此這個點就是最佳的K值。具體過程如下:

  1. 對數(shù)據(jù)集進行K-Means聚類,分別嘗試不同的簇數(shù)K。
  2. 對于每個簇數(shù)K,計算該簇數(shù)下的SSE(Sum of Squared Errors),即每個數(shù)據(jù)點到其所屬簇中心的距離的平方和,保存SSE 到數(shù)組。
  3. 使用numpy庫中的diff函數(shù)計算相鄰兩點的差異并除以最大值,得到變化率。然后,我們使用numpy庫中的argmax函數(shù)找到最大斜率的位置,加上n即為肘部點的位置。
  4. n的取值要考慮自身數(shù)據(jù)集,一般來說,K的值至少要為2,不然沒有分類意義,而且argmax計算出來的是數(shù)組的索引位置,小于真實位置1個點位,綜合考慮,我們將n設(shè)置為2。   
# 計算不同聚類個數(shù)下的聚類誤差
    n = 2
    sse = []
    for k in range(1, 10):
        kmeans = KMeans(n_clusters=k, random_state=0).fit(data)
        sse.append(kmeans.inertia_)

    # 自動尋找肘部點
    diff = np.diff(sse)
    diff_r = diff[1:] / diff[:-1]
    nice_k = np.argmin(diff_r) + n
#繪制SSE隨簇數(shù)變化的曲線(如圖4-5),觀察曲線的形狀。
    plt.plot(range(1, 10), sse, 'bx-')
    plt.xlabel('Number of Clusters')
    plt.ylabel('SSE')
    plt.title('Elbow Method for Optimal k')
    plt.show()

圖片

圖 4-5

經(jīng)過K值選擇后,我們將樣本數(shù)據(jù)集進行聚類得到如下圖4-6所示結(jié)果,Y軸為某組合維度的標簽值,X軸為某組合維度出現(xiàn)在樣本數(shù)據(jù)集數(shù)組中的索引位置。其中最右側(cè)最高的點,明顯是沒有任何維度交叉的全部廣告庫存,其他位置都是經(jīng)過維度交叉后的庫存,最終我們將其分成了3份進行訓練。

圖片

圖 4-6

經(jīng)過聚類處理后,模型訓練時損失函數(shù)輸出的損失值如下圖所示,出現(xiàn)了正常的損失值下降的過程,并逐漸趨于穩(wěn)定。

圖片

圖 4-7

五、網(wǎng)絡(luò)結(jié)構(gòu)定義與訓練

5.1 網(wǎng)絡(luò)結(jié)構(gòu)定義

1)網(wǎng)絡(luò)模型結(jié)構(gòu)圖


圖片

圖 5-1

2)網(wǎng)絡(luò)模型定義

我們將各維度組裝特征數(shù)據(jù)和標簽數(shù)據(jù)的數(shù)據(jù)經(jīng)過Embedding 實體嵌入,輸入到LSTM學習并提取歷史庫存的時間序列特性,最終經(jīng)過激活函數(shù)和全連接層輸出與標簽值進行損失值計算,不斷擬合,直到損失值接近穩(wěn)定或到達最大訓練批次。

import torch
from torch import nn

class LSTM(nn.Module):
    def __init__(self, emb_dims, out_dim, hidden_dim, mid_layers):
        super(LSTM, self).__init__()
        self.emb_layers = nn.ModuleList([nn.Embedding(x, y) for x, y in emb_dims])
        self.rnn = nn.LSTM([sum(x) for x in zip(*emb_dims)][1] + 1, hidden_dim, mid_layers, batch_first=False)
        self.reg = nn.Sequential(
            nn.Linear(hidden_dim, hidden_dim),
            nn.Tanh(),
            nn.Linear(hidden_dim, out_dim),
        )

    def forward(self, cat_data):
        var_x = []
        for cat in cat_data:
            x = self.emb_layer(cat)
            var_x.append(x)
        stack = torch.stack(var_x)
        y = self.rnn(stack)
        return y

5.2 訓練

1)組織數(shù)據(jù)

我們獲取任意維度歷史N天數(shù)據(jù)作為訓練集,如下圖所示,我們設(shè)定滑動窗口時間為七天,定義廣告請求數(shù)為標簽數(shù)據(jù)。使用DataLoader組織數(shù)據(jù),shuffle設(shè)為True保證樣本是隨機獲取的,僅需保證滑動窗口內(nèi)部有序即可,這樣訓練可以提高模型的泛化能力。

loader = Data.DataLoader(dataset=set, batch_size=size, shuffle=True, num_workers=numWorkers)

需要注意的是,LSTM要求的入?yún)㈨樞驗椋╯eq_length, batch_size, input_size)即:序列長度、批次量數(shù)、特征維度,然而DataLoade組織出的數(shù)據(jù)第一個維度是batch_size,因此設(shè)置batch_first = true,即可解決問題,繼續(xù)正常的使用LSTM模型訓練數(shù)據(jù)。但是這會拉低訓練效率,原因是NVIDIA cuDNN 的RNN API 設(shè)置的batch_size參數(shù)就是在第二個位置,這樣設(shè)置的原因如下:

舉個例子1,假設(shè)輸入序列的長度seq_length等于3,batch_size等于2,假設(shè)一個batch的數(shù)據(jù)是[[“A”, “B”, “C”], [“D”, “E”, “F”]],如圖5-2所示。由于RNN是序列模型,只有T1時刻計算完成,才能進入T2時刻,而"batch"就體現(xiàn)在每個時刻Ti的計算過程中,圖1中T1時刻將[“A”, “D”]作為當前時刻的batch數(shù)據(jù),T2時刻將[“B”, “E”]作為當前時刻的batch數(shù)據(jù),可想而知,“A"與"D"在內(nèi)存中相鄰比"A"與"B"相鄰更合理,這樣取數(shù)據(jù)時才更高效。

而不論Tensor的維度是多少,在內(nèi)存中都以一維數(shù)組的形式存儲,batch first意味著Tensor在內(nèi)存中存儲時,先存儲第一個sequence,再存儲第二個… 而如果是seq_length first,模型的輸入在內(nèi)存中,先存儲所有sequence的第一個元素,然后是第二個元素… 兩種區(qū)別如圖5-3所示,seq_length first意味著不同sequence中同一個時刻對應的輸入元素(比如"A”, “D” )在內(nèi)存中是毗鄰的,這樣可以快速讀取數(shù)據(jù)。

圖片

圖 5-2


圖片

圖 5-3

因此,使用batch_first = true并不是好的選擇,可以選擇permute函數(shù)解決此問題:

batch_x = batch_x.permute((1, 0, 2))

使用此方法改變數(shù)組的shape,以適應原始LSTM模型的入?yún)⒁螅诓挥绊懹柧毸俣鹊脑瓌t下解決參數(shù)順序問題。

2)訓練步驟

輸入: 任意維度前七天組成的窗口數(shù)據(jù),包括所有的特征數(shù)據(jù) + 標簽數(shù)據(jù)

輸出: 第八天的標簽數(shù)據(jù)

第N步

圖片

圖 5-4

第N+1步:

圖片

圖 5-5

3)離線與在線增量訓練

第二章節(jié)問題和挑戰(zhàn)中提到,由于廣告樣本數(shù)據(jù)每天都在產(chǎn)生,而且影響其因素非常多,所以歷史模型僅憑歷史庫存學到的時間序列特性預估出的未來庫存,除了可以帶有假期周末等時間特征的正向影響外,很難緊跟近期的庫存數(shù)量級。

所以,這要求我們要高頻次的更新廣告庫存預估模型,但這也加大了維護成本,如果僅采用離線訓練的方式,每次都拉取全量歷史庫存樣本數(shù)據(jù)訓練出新的優(yōu)質(zhì)模型,無疑是不可取的,所以我們選擇一次離線訓練+N次在線增量訓練的方式解決此問題。

a. 離線訓練

首先使用Spark Sql組織廣告庫存Hive表中現(xiàn)存所有的歷史數(shù)據(jù)導入CSV文件,使用GPU訓練此樣本數(shù)據(jù),由于是各維度交叉訓練,一般在這個階段數(shù)據(jù)量在億級別,如果資源有限,離線訓練可以拆分廣告位分別進行。經(jīng)過多次訓練選擇優(yōu)質(zhì)的離線模型文件,作為基礎(chǔ)預估模型,可以用于短期的庫存預估工作。此時我們需要將優(yōu)質(zhì)模型以字節(jié)的形式存儲至Redis,便于后面的預估服務(wù)和在線訓練腳本使用。

此時需要注意的是,我們需要將模型和優(yōu)化器打包為一個字典,以二進制的方式讀取模型文件并保存在Redis中。

#保存模型:
#net:模型
#optimizer:優(yōu)化器
 
state = {'net': net.state_dict(), 'optimizer': optimizer.state_dict()}
torch.save(state, netPath)
         
#存儲至Redis:
def saveModel(modelName, netPath):
    with open(modelPath, "rb") as f:
        pth_model = f.read()
    result = redis.set(modelName, pth_model)

b. 在線訓練:經(jīng)過離線訓練后,我們得到了一個優(yōu)質(zhì)的預估模型,此時我們需要開發(fā)兩個腳本:

① PySpark 拉取hive表中昨天的庫存樣本存儲在GPU機器實時文件目錄。

② 讀取實時文件目錄,獲取近八個文件,前七個作為一個滑動窗口數(shù)據(jù),第八個作為標簽值組成單次訓練樣本,在Redis中獲取并加載預存的模型和優(yōu)化器,進行一次在線訓練,再將其覆蓋保存至redis中。

# 在Redis中加載模型
def readModel(modelName, path):
    pthByte = redis.get(modelName)
    with open(path, 'wb') as f:
        f.write(pthByte)
    return torch.load(path, map_locatinotallow=lambda storage, loc: storage)
 
 
# 加載模型和優(yōu)化器狀態(tài),用于訓練
 
# 讀取字典
model = readModel(modelName, path)


# 加載模型
net = LSTM(emb_dims, out_dim, mid_dim, mid_layers).to(device)
net.load_state_dict(model['net'])


# 加載優(yōu)化器
optimizer = torch.optim.Adam(net.parameters(), lr=1e-2)
optimizer.load_state_dict(model['optimizer'])

最終,我們將以上兩個腳本配置在攜程大數(shù)據(jù)定時任務(wù),設(shè)置每天0點后執(zhí)行,即可實現(xiàn)不斷的在線訓練,保證模型在優(yōu)質(zhì)狀態(tài)的基礎(chǔ)上,使用最新的庫存數(shù)據(jù)對模型進行微調(diào)修正,使用Redis保存模型可以快速存取模型文件流,保證在線訓練結(jié)束后,預估服務(wù)可以立刻反應,獲取到新的模型用于預估工作,無需對預估服務(wù)做任何改動。根據(jù)以上方案可以不斷維持模型提供精準的預估能力。

4)早停機制

訓練過程中,為防止過擬合,也為提高效率,當loss 不再明顯變化時終止訓練,輸出模型,每次訓練不斷記錄并更新loss最小值,當loss 連續(xù)N次小于x時,視為可觸發(fā)早停機制。

class EarlyStopping:
         
    def __call__(self, val_loss):
        score = val_loss
        if self.best_score is None:
            self.best_score = score
        elif score > self.best_score:
            if score <= x:
                self.counter += 1
            if self.counter >= self.patience:
                self.early_stop = True
        else:
            self.best_score = score
            self.counter = 0

下圖為早停效果圖,設(shè)置的訓練批次為150批, 此模型訓練至115批截至,可以觀察到loss已經(jīng)非常低, 已經(jīng)沒有下降空間,符合早停預期。

圖片

圖 5-6

5)指標驗證

經(jīng)過模型的構(gòu)建和訓練后,我們需要對模型做出評估,以決定模型是否可以推到線上使用,因為基礎(chǔ)數(shù)據(jù)量較小,所以本次模型未設(shè)置驗證集,訓練集和測試集 9 :1。評估指標采用WMAPE(加權(quán)偏差率):

圖片

TorchMetrics 類庫對80 多個PyTorch 指標做了實現(xiàn).

這里我們直接調(diào)用api : WeightedMeanAbsolutePercentageError

import torchmetrics

error = torchmetrics.WeightedMeanAbsolutePercentageError()
# 調(diào)用模型得到預估值
predict = net(valid_x)
# 計算偏差
error = error(predict, valid_y)
error_list.append(error.item())

指標驗證可以更科學的觀察到模型對所有維度的測試集的預估能力, 可以更科學的驗證模型是否符合我們的預期,指導我們進行調(diào)參,控制唯一變量并觀察指標變化。某廣告位置調(diào)參驗證示例如下, 比較不同批次訓練模型后指標比較, 明顯表現(xiàn)出200批次的模型指標更好。

Group Model 1: 150批次 測試集ERROR: 0.09729844331741333 200批次 測試集ERROR: 0.08846557699143887

Group Model 2: 150批次 測試集ERROR: 0.10297603532671928 200批次 測試集ERROR: 0.09801376238465309

Group Model 3: 150批次 測試集ERROR: 0.0748182088136673 200批次 測試集ERROR: 0.07573202252388

6)內(nèi)存釋放

在大數(shù)據(jù)量的深度神經(jīng)網(wǎng)絡(luò)訓練過程中,內(nèi)存是我們的一大瓶頸,在組織數(shù)據(jù)過程中,python的List由于不能確定其存儲內(nèi)容的數(shù)據(jù)類型,不支持快速切割結(jié)構(gòu),我們經(jīng)常需要將List轉(zhuǎn)換為數(shù)組再做處理,此時需要copy一份數(shù)據(jù),那么List就成了閑置內(nèi)存,這種類似的閑置內(nèi)存我們可以操作主動釋放,以快速釋放無用內(nèi)存,讓我們的機器可以在有限的內(nèi)存空間中支持更大數(shù)據(jù)量的訓練。

不同的數(shù)據(jù)類型的釋放方式如下(假設(shè)變量名稱為 X ):

# 1、List
del X[:]
# 2、數(shù)組
X = []
# 3、字典
X.clear()
# 4、Tensor(此方式需要調(diào)用gc.collect()觸發(fā)GC才可以真正清除內(nèi)存)
del X
# 5、清理CUDA顯存
import torch
torch.cuda.empty_cache()

下圖5-7為訓練過程中主動釋放內(nèi)存操作后,得到的內(nèi)存釋放監(jiān)控反饋。

圖片

圖 5-7

5.3 預估驗證

1)歷史預估

整體模型訓練完成,需要對模型做預估測試,我們選擇2022年的10月作為測試樣本,10月1日國慶節(jié)有特殊的節(jié)假日特性,可以考量模型預估能力。以攜程啟動頁廣告位為例,圖 5-8 分別展示了全量庫存、某特征定向和兩種會員等級定向不同維度的預估效果,都成功表達出10月1日的節(jié)假日上漲特性,與實際值的走勢相似,證明我們訓練出的模型具有預估未來廣告庫存的能力。

圖片

圖 5-8

2)未來預估

以下是對未來庫存的預估效果示例,從未來預估示例中,可以直觀看出在4月26-29左右有流量的高峰,經(jīng)過5月1日后高峰下跌,回歸正常值,符五一的節(jié)假日效應。

圖5-9 定向交叉為:某年齡段、某地 

圖片

圖 5-9

圖5-10 定向交叉為:某年齡段、某類會員

圖片

圖 5-10

圖5-11 定向交叉為:某地、某類會員 

圖片

圖 5-11

六、模型部署

6.1 python 服務(wù)部署

使用python flask組件開發(fā)部署restful接口,支持預估服務(wù)。

from flask import Flask
from flask import request, jsonify

@app.route('/model/ad/forecast', methods=['post'])
def forecast():
    # 在clickhouse中實時獲取前七天的標簽值,傳入接口
    prepareData = request.json.get('prepareData')
    return forecast(prepareData)

從Redis中讀取對應維度的模型文件流,加載到內(nèi)存生成模型對象,將前7天的標簽值和對應其他特征組織好輸入模型得到預估結(jié)果。

# 在Redis中加載模型

def readModel(modelName, path):
    pthByte = redis.get(modelName)
    with open(path, 'wb') as f:
        f.write(pthByte)
    return torch.load(path, map_locatinotallow=lambda storage, loc: storage)

七、總結(jié)

通過使用LSTM算法結(jié)合Embedding特征處理方式訓練得到優(yōu)質(zhì)的廣告庫存預估模型,能夠捕捉庫存時間樣本數(shù)據(jù)中的長期依賴關(guān)系,表達節(jié)假日、周末等特殊時間點對庫存變化的影響,更具泛化能力,支持地域、年齡、會員等級、性別等定向交叉預估,對比早期使用全量庫存乘以定向比例的預估庫存方式,此方式更能體現(xiàn)出不同維度之間的相互影響關(guān)系,更貼近事實,預估準確度高。

使用離線與在線增量訓練相結(jié)合的訓練方式,使模型更具活力,每天在優(yōu)選出的廣告庫存模型基礎(chǔ)上進行微調(diào),可以不斷維持模型提供精準的預估能力。后續(xù)我們會繼續(xù)優(yōu)化和探索更優(yōu)秀的模型和特征處理方式,優(yōu)化方向考慮在Embedding層 與 LSTM 層之間增加CNN 卷積層,提高模型的特征提取能力,進而提高廣告庫存模型的泛化能力、預估精準度。

八、參考文獻

  • Pytorch lstm中batch_first 參數(shù)理解使用
責任編輯:張燕妮 來源: 攜程技術(shù)
相關(guān)推薦

2016-09-04 15:14:09

攜程實時數(shù)據(jù)數(shù)據(jù)平臺

2022-06-27 09:36:29

攜程度假GraphQL多端開發(fā)

2022-05-19 17:50:31

bookie集群延遲消息存儲服務(wù)

2014-12-25 17:51:07

2024-08-08 16:17:29

2024-02-23 12:24:00

引擎數(shù)據(jù)

2023-06-06 11:49:24

2023-06-28 14:01:13

攜程實踐

2023-07-07 14:18:57

攜程實踐

2025-01-03 14:33:41

2017-04-11 15:11:52

ABtestABT變量法

2023-11-24 09:44:07

數(shù)據(jù)攜程

2022-07-15 12:58:02

鴻蒙攜程華為

2014-03-24 09:25:57

2022-05-13 09:27:55

Widget機票業(yè)務(wù)App

2022-08-20 07:46:03

Dynamo攜程數(shù)據(jù)庫

2023-07-07 12:26:39

攜程開發(fā)

2022-05-13 07:22:39

攜程微服務(wù)SOA

2023-07-07 12:19:43

攜程技術(shù)

2016-11-22 19:54:56

點擊率預估推薦算法廣告
點贊
收藏

51CTO技術(shù)棧公眾號