2012-02-15 30 views
32

Tôi đang xây dựng một số mô hình tiên đoán bằng Python và đã sử dụng triển khai SVM của học viên scikits. Nó thực sự tuyệt vời, dễ sử dụng và tương đối nhanh.Triển khai SVM nhanh nhất có thể sử dụng được trong Python

Thật không may, tôi bắt đầu bị ràng buộc bởi thời gian chạy của mình. Tôi chạy SVM rbf trên tập dữ liệu đầy đủ khoảng 4 - 5000 với 650 tính năng. Mỗi lần chạy mất khoảng một phút. Nhưng với xác thực chéo 5 lần + tìm kiếm lưới (bằng cách sử dụng tìm kiếm thô thiển đến tốt), việc này trở nên không khả thi đối với nhiệm vụ của tôi trong tầm tay. Vì vậy, nói chung, mọi người có bất kỳ đề xuất nào về việc triển khai SVM nhanh nhất có thể được sử dụng trong Python không? Điều đó, hoặc bất kỳ cách nào để tăng tốc độ mô hình của tôi?

Tôi đã nghe về việc triển khai GPU của LIBSVM, có vẻ như nó có thể hoạt động. Tôi không biết bất kỳ triển khai SVM GPU nào khác có thể sử dụng được bằng Python, nhưng nó chắc chắn sẽ mở cho người khác. Ngoài ra, không sử dụng GPU tăng đáng kể thời gian chạy?

Tôi cũng nghe nói rằng có nhiều cách xấp xỉ SVM rbf bằng cách sử dụng bản đồ tính năng SVM + tuyến tính trong scikits. Không chắc người ta nghĩ gì về cách tiếp cận này. Một lần nữa, bất cứ ai sử dụng cách tiếp cận này, có phải là một sự gia tăng đáng kể trong thời gian chạy không?

Tất cả ý tưởng để tăng tốc độ của chương trình được chào đón nhiều nhất.

Trả lời

26

Việc triển khai SVM hạt nhân có thể mở rộng nhất mà tôi biết là LaSVM. Nó được viết bằng C do đó có thể bọc trong Python nếu bạn biết Cython, ctypes hoặc cffi. Hoặc bạn có thể sử dụng nó từ dòng lệnh. Bạn có thể sử dụng các tiện ích trong sklearn.datasets để tải dữ liệu chuyển đổi từ định dạng NumPy hoặc CSR thành các tệp được định dạng svmlight mà LaSVM có thể sử dụng làm bộ đào tạo/thử nghiệm.

+0

Cảm ơn ogrisel. Tôi sẽ xem xét điều này. Chắc chắn trông thú vị. Sklearn có thể xuất thành định dạng ánh sáng svm? Điều đó chắc chắn sẽ hữu ích. Để đáp ứng với câu trả lời trước của bạn, thật không may, tôi đang đối phó với timeseries, do đó, lấy mẫu ngẫu nhiên + nhổ vào đào tạo/thử nghiệm trở nên khá phức tạp hơn một chút. Không chắc chắn subsampling để đào tạo mô hình của tôi sẽ được tất cả những điều đơn giản. Cảm ơn! – tomas

+0

Xin lỗi, bạn có biết chức năng tiện ích nào trong sklearn có thể xuất ở định dạng ánh sáng SVM không? – tomas

+0

Thực tế nó bị thiếu trong tài liệu nhưng nó ở đó: https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/datasets/svmlight_format.py#L142 – ogrisel

2

Không đi sâu vào việc so sánh thư viện SVM, tôi cho rằng tác vụ bạn mô tả (xác thực chéo) có thể hưởng lợi từ đa luồng thực (tức là chạy nhiều CPU song song). Nếu bạn đang sử dụng CPython, nó không tận dụng lợi thế của máy đa lõi (có thể) của bạn, do GIL.

Bạn có thể thử các triển khai Python khác không có giới hạn này. Xem PyPy hoặc IronPython nếu bạn sẵn sàng truy cập .NET.

+0

Cảm ơn bavaza tôi sẽ có một cái nhìn vào nó. Giả sử tôi tận dụng lợi thế của máy tính đa lõi của tôi, bất kỳ đề xuất nào khác về tăng tốc chương trình của tôi? Tôi đã đi tìm ra một cách để vượt qua xác nhận qua nhiều luồng anyways. Tuy nhiên, tôi nghĩ tôi vẫn cần tăng tốc. – tomas

+0

@bavaza, tôi đã chạy Python trong nhiều lõi trong nhiều năm, nó hoạt động rất tốt. Vui lòng nghiên cứu lib đa xử lý của CPython chuẩn. –

+0

@ V3ss0n, cảm ơn. Trông giống như một lib tốt đẹp. Vì nó sử dụng quy trình chứ không phải luồng, bạn có quen thuộc với bất kỳ hình phạt chuyển đổi ngữ cảnh nào không (ví dụ: khi sử dụng hồ bơi công nhân lớn)? – bavaza

22

Hoặc bạn có thể tiến hành tìm kiếm lưới trên 1000 mẫu ngẫu nhiên thay vì toàn bộ dữ liệu:

>>> from sklearn.cross_validation import ShuffleSplit 
>>> cv = ShuffleSplit(3, test_fraction=0.2, train_fraction=0.2, random_state=0) 
>>> gs = GridSeachCV(clf, params_grid, cv=cv, n_jobs=-1, verbose=2) 
>>> gs.fit(X, y) 

Nó rất có khả năng là các thông số tối ưu cho 5000 mẫu sẽ rất gần với các thông số tối ưu cho 1000 mẫu. Vì vậy, đó là một cách hay để bắt đầu tìm kiếm lưới thô của bạn.

n_jobs=-1 làm cho nó có thể sử dụng tất cả các CPU của bạn để chạy CV cá nhân phù hợp song song. Nó sử dụng mulitprocessing để GIL python không phải là một vấn đề.

8

Thứ nhất, theo điểm chuẩn của scikit-learning (here), tìm hiểu scikit đã là một trong những gói SVM nhanh nhất nếu không nhanh nhất xung quanh. Do đó, bạn có thể muốn xem xét các cách khác để đẩy nhanh quá trình đào tạo.

Theo đề xuất của bavaza, bạn có thể thử đa luồng quy trình đào tạo. Nếu bạn đang sử dụng lớp GridSearchCV của Scikit-learning, bạn có thể dễ dàng đặt đối số n_jobs lớn hơn giá trị mặc định là 1 để thực hiện việc đào tạo song song với chi phí sử dụng nhiều bộ nhớ hơn. Bạn có thể tìm thấy nó tài liệu here Một ví dụ về cách sử dụng các lớp có thể được tìm thấy here

Ngoài ra, bạn có thể có một cái nhìn tại Shogun Máy Thư viện Học here

Shogun được thiết kế cho học máy quy mô lớn với trình bao bọc cho nhiều gói svm phổ biến và nó được triển khai trong C/C++ với các ràng buộc cho python. Theo tiêu chuẩn của Scikit-learning ở trên, tốc độ của nó có thể so sánh được với scikit-learn. Trên các nhiệm vụ khác (ngoài tác vụ mà họ đã trình bày), nó có thể nhanh hơn nên rất đáng để thử.

Cuối cùng, bạn có thể thử thực hiện giảm thứ nguyên, ví dụ: sử dụng PCA hoặc PCA ngẫu nhiên để giảm kích thước của vectơ tính năng của bạn. Điều đó sẽ đẩy nhanh quá trình đào tạo. Tài liệu cho các lớp tương ứng có thể được tìm thấy trong 2 liên kết sau: PCA, Randomized PCA. Bạn có thể tìm thấy các ví dụ về cách sử dụng chúng trong phần ví dụ của Scikit-learn.

4

Nếu bạn quan tâm đến việc chỉ sử dụng hạt nhân RBF (hoặc bất kỳ hạt nhân bậc hai nào khác cho vấn đề đó), thì tôi khuyên bạn nên sử dụng LIBSVM trên MATLAB hoặc Octave. Tôi đào tạo một mô hình 7000 quan sát và 500 tính năng trong khoảng 6 giây.

Bí quyết là sử dụng hạt nhân tiền xử lý mà LIBSVM cung cấp, và sử dụng một số đại số ma trận để tính toán hạt nhân trong một bước thay vì lopping dữ liệu hai lần. Hạt nhân mất khoảng hai giây để xây dựng như trái ngược với nhiều hơn bằng cách sử dụng hạt nhân RBF riêng của LIBSVM. Tôi đoán bạn sẽ có thể làm như vậy trong Python bằng cách sử dụng NumPy, nhưng tôi không chắc chắn như tôi đã không thử nó.

+4

Nói chung LibSVM là một lib trưởng thành tốt, nhưng tôi nghĩ rằng nó không phải là nhanh nhất và 7000 x 500 là vấn đề rất nhỏ để kiểm tra. – mrgloom

-1

Tôi muốn xem xét sử dụng random forest để giảm số lượng tính năng bạn nhập.

Có tùy chọn với ExtraTreesRegressor và ExtraTreesClassifier để tạo các tính năng nhập. Sau đó, bạn có thể sử dụng thông tin này để nhập một tập hợp con các tính năng vào SVM của mình.

0

Tôi khuyên bạn nên xem xét triển khai Stochastic Gradient Descent của Scikit-Learn. Mất bản lề mặc định là SVM tuyến tính. Tôi đã tìm thấy nó rất nhanh.