2014-10-08 15 views
8

Tôi mới bắt đầu với ML và Apache Spark, vì vậy tôi đã thử Linear Regression dựa trên các ví dụ Spark. Tôi dường như không thể tạo ra một mô hình thích hợp cho bất kỳ dữ liệu nào ngoại trừ mẫu trong ví dụ và đánh chặn luôn là 0.0, bất kể dữ liệu đầu vào.Spark MLLib Tuyến tính mô hình hồi quy đánh chặn luôn luôn là 0,0?

Tôi đã chuẩn bị một huấn luyện đơn giản dữ liệu thiết lập dựa trên các chức năng:

y = (2 * x1) + (3 * x2) + 4

tức là tôi mong chờ sự đánh chặn được 4 và trọng số là (2, 3).

Nếu tôi chạy LinearRegressionWithSGD.train (...) trên các dữ liệu thô, mô hình này là:

Model intercept: 0.0, weights: [NaN,NaN] 

Và các dự đoán đều NaN:

Features: [1.0,1.0], Predicted: NaN, Actual: 9.0 
Features: [1.0,2.0], Predicted: NaN, Actual: 12.0 

vv

Nếu tôi mở rộng dữ liệu trước, tôi nhận được:

Model intercept: 0.0, weights: [17.407863391511754,2.463212481736855] 

Features: [1.0,1.0], Predicted: 19.871075873248607, Actual: 9.0 
Features: [1.0,2.0], Predicted: 22.334288354985464, Actual: 12.0 
Features: [1.0,3.0], Predicted: 24.797500836722318, Actual: 15.0 

etc

Hoặc tôi đang làm điều gì đó sai, hoặc tôi không hiểu đầu ra từ mô hình này là gì, vì vậy ai cũng có thể gợi ý tôi có thể sai ở đâu?

Mã của tôi là dưới đây:

// Load and parse the dummy data (y, x1, x2) for y = (2*x1) + (3*x2) + 4 
    // i.e. intercept should be 4, weights (2, 3)? 
    val data = sc.textFile("data/dummydata.txt") 

    // LabeledPoint is (label, [features]) 
    val parsedData = data.map { line => 
    val parts = line.split(',') 
    val label = parts(0).toDouble 
    val features = Array(parts(1), parts(2)) map (_.toDouble) 
    LabeledPoint(label, Vectors.dense(features)) 
    } 

    // Scale the features 
    val scaler = new StandardScaler(withMean = true, withStd = true) 
        .fit(parsedData.map(x => x.features)) 
    val scaledData = parsedData 
        .map(x => 
        LabeledPoint(x.label, 
        scaler.transform(Vectors.dense(x.features.toArray)))) 

    // Building the model: SGD = stochastic gradient descent 
    val numIterations = 1000 
    val step = 0.2 
    val model = LinearRegressionWithSGD.train(scaledData, numIterations, step) 

    println(s">>>> Model intercept: ${model.intercept}, weights: ${model.weights}")` 

    // Evaluate model on training examples 
    val valuesAndPreds = scaledData.map { point => 
    val prediction = model.predict(point.features) 
    (point.label, point.features, prediction) 
    } 
    // Print out features, actual and predicted values... 
    valuesAndPreds.take(10).foreach({case (v, f, p) => 
     println(s"Features: ${f}, Predicted: ${p}, Actual: ${v}")}) 
+0

Đối với PySpark, nếu có ai thắc mắc, điều này sẽ là 'model = LinearRegressionWithSGD.train (res, intercept = True)' –

Trả lời

8

Các train phương pháp mà bạn đang sử dụng là một phím tắt mà thiết là đánh chặn để không và không cố gắng để tìm thấy một. Nếu bạn sử dụng các lớp cơ bản, bạn có thể có được một đánh chặn khác không:

val model = new LinearRegressionWithSGD(step, numIterations, 1.0). 
    setIntercept(true). 
    run(scaledData) 

nên cung cấp cho bạn một đánh chặn ngay bây giờ.

+0

Cảm ơn bạn đã chỉ cho tôi tới hàm tạo, Noah. Nó dường như không chấp nhận bất kỳ đối số (trong Spark 1.1) nhưng đó là OK là mô hình được sản xuất kết quả khá tốt với mặc định được xây dựng trong anyway anyway. Chúc mừng! –

+1

@ChrisWebster trông giống như hàm tạo được đánh dấu riêng tư, không chắc chắn tại sao. Tôi đã thử nghiệm trong nguồn tia lửa vì vậy nó làm việc trong phạm vi. Dù sao, một công việc dễ dàng xung quanh là thêm một cột chỉ 1s để sử dụng làm chặn của bạn vì đó là điều mà mã hồi quy tuyến tính đang làm đằng sau hậu trường. – Noah

10

@Noah: Cảm ơn - lời khuyên của bạn đã nhắc tôi xem lại điều này và tôi đã tìm thấy some example code here cho phép bạn tạo chặn và cũng đặt các thông số khác, chẳng hạn như số lần lặp lại, thông qua trình tối ưu hóa.

Dưới đây là sửa đổi hệ mã mô hình của tôi, mà dường như làm việc OK trên dữ liệu giả của tôi:

// Building the model: SGD = stochastic gradient descent: 
    // Need to setIntercept = true, and seems only to work with scaled data 
    val numIterations = 600 
    val stepSize = 0.1 
    val algorithm = new LinearRegressionWithSGD() 
    algorithm.setIntercept(true) 
    algorithm.optimizer 
    .setNumIterations(numIterations) 
    .setStepSize(stepSize) 

    val model = algorithm.run(scaledData) 

Nó dường như vẫn cần dữ liệu quy mô, chứ không phải là dữ liệu thô, như là đầu vào, nhưng đó là OK cho tôi mục đích ở đây.

Các vấn đề liên quan