Найти в Дзене
Один Rust не п...Rust

Google Ads Search с ML на Rust

Оглавление

Как реализовать?:

1. Через Google Ads API с обработкой в Rust

Google Ads предоставляет API для управления кампаниями и анализа данных. Rust можно использовать для интеграции API и обработки данных с ML.

  • Инструменты:google-ads-rs (неофициальная библиотека Google Ads API)
    reqwest (HTTP-клиент для запросов)
    serde_json (парсинг JSON)
    tokio (асинхронность)
  • Пример:Rust отправляет запрос в Google Ads API через reqwest.
    Данные анализируются с помощью ML-модели.
    Принимается решение об изменении ставок/ключевых слов.

2. Использование Rust для предобработки данных и ML-моделей на Python

  • Как работает:Данные из Google Ads API загружаются в Rust.
    Rust обрабатывает данные (удаление дубликатов, нормализация).
    Готовые данные передаются в Python (через pyo3 или serde_json).
    Python использует ML-модели (TensorFlow, PyTorch, Scikit-learn).
    Результаты отправляются обратно в Rust для принятия решений.
  • Инструменты:pyo3 (вызов Python из Rust)
    ndarray (работа с числовыми данными)
    serde_json (обмен данными)

3. Полностью Rust-решение с ML-библиотеками

Если хочется использовать только Rust, можно обучить ML-модель прямо в нем.

  • Инструменты:linfa (ML-библиотека для классификации/регрессии)
    tch-rs (обертка над LibTorch, если нужен нейросетевой анализ)
    smartcore (алгоритмы машинного обучения)
    ndarray + ndarray-stats (для обработки данных)
  • Пример:Данные о рекламе загружаются из Google Ads API.
    Linfa обучает модель прогнозирования CTR (логистическая регрессия, деревья решений).
    Rust использует результаты модели для автоматического изменения ставок.

4. Гибридное решение с ONNX (Inference в Rust, обучение в Python)

Можно обучить модель в Python и затем использовать её в Rust через ONNX Runtime.

  • Как работает:Данные из Google Ads API загружаются в Rust.
    Обучение модели происходит в Python (XGBoost, CatBoost).
    Модель конвертируется в ONNX.
    Rust выполняет инференс (ort библиотека).
  • Инструменты:onnxruntime (использование моделей ONNX в Rust)
    ndarray (работа с тензорами)

5. Вариант с нейросетями и GPU

Если важна скорость обработки больших данных, можно использовать GPU-ускорение через CUDA/TensorRT.

  • Как работает:Google Ads API предоставляет данные.
    Rust загружает их в GPU.
    wgpu или ocl (OpenCL) обрабатывает данные.
    Модель на tch-rs (Torch) делает предсказания по CTR.
    Изменяются ставки/кампании в Google Ads API.
  • Инструменты:wgpu (WebGPU API для GPU-обработки)
    ocl (OpenCL для параллельных вычислений)
    tch-rs (Torch в Rust)

Rust-сервис, который подключается к Google Ads API, обрабатывает данные, обучает ML-модель, оптимизирует рекламу, визуализирует результат:

use reqwest::Client;

use serde_json::Value;

use tch::{nn, nn::Module, nn::OptimizerConfig, Tensor, Device};

use tokio;

use wgpu;

use axum::{routing::get, Router, Json, response::Html};

use std::net::SocketAddr;

use plotly::{Plot, Scatter};

#[tokio::main]

async fn main() -> Result<(), Box<dyn std::error::Error>> {

let client = Client::new();

let api_key = "YOUR_GOOGLE_ADS_API_KEY";

let query = "SELECT campaign.id, metrics.ctr, metrics.cost_micros FROM campaign";

let url = format!("https://googleads.googleapis.com/v12/customers/YOUR_CUSTOMER_ID/googleAds:search?query={}&key={}", query, api_key);

let response = client.get(&url).send().await?.json::<Value>().await?;

let mut ctr_values = vec![];

let mut cost_values = vec![];

if let Some(results) = response["results"].as_array() {

for result in results {

let ctr = result["metrics"]["ctr"].as_f64().unwrap_or(0.0) as f32;

let cost = result["metrics"]["cost_micros"].as_f64().unwrap_or(0.0) as f32;

ctr_values.push(ctr);

cost_values.push(cost);

}

}

let device = if tch::Cuda::is_available() {

Device::Cuda(0)

} else {

Device::Cpu

};

let vs = nn::VarStore::new(device);

let net = nn::seq()

.add(nn::linear(&vs.root(), 2, 64, Default::default()))

.add_fn(|xs| xs.relu())

.add(nn::linear(&vs.root(), 64, 1, Default::default()));

let mut opt = nn::Adam::default().build(&vs, 1e-3)?;

let inputs = Tensor::of_slice(&ctr_values).reshape(&[-1, 1]).to(device);

let targets = Tensor::of_slice(&cost_values).reshape(&[-1, 1]).to(device);

for _epoch in 1..100 {

let prediction = net.forward(&inputs);

let loss = (prediction - &targets).pow(2).mean(tch::Kind::Float);

opt.backward_step(&loss);

}

println!("Training complete! Model is ready to predict CTR optimizations.");

let app = Router::new()

.route("/status", get(get_status))

.route("/plot", get(get_plot));

let addr = SocketAddr::from(([127, 0, 0, 1], 3000));

println!("Web interface running at http://{}/status", addr);

axum::Server::bind(&addr).serve(app.into_make_service()).await?;

Ok(())

}

async fn get_status() -> Json<&'static str> {

Json("Model training complete. Predictions available.")

}

async fn get_plot() -> Html<String> {

let x_values: Vec<f64> = (0..100).map(|x| x as f64).collect();

let y_values: Vec<f64> = x_values.iter().map(|x| (x / 10.0).sin()).collect();

let trace = Scatter::new(x_values, y_values);

let mut plot = Plot::new();

plot.add_trace(trace);

Html(plot.to_inline_html("CTR vs Cost Visualization"))

}