Xác nhận tạm thời so với xác nhận chéo


54

Đối với tôi, có vẻ như xác nhận giữ lại là vô ích. Đó là, chia dữ liệu gốc thành hai phần (đào tạo và kiểm tra) và sử dụng điểm kiểm tra làm thước đo tổng quát, có phần vô dụng.

Xác thực chéo K-Fold dường như cung cấp các xấp xỉ tốt hơn về khái quát hóa (vì nó đào tạo và kiểm tra trên mọi điểm). Vậy, tại sao chúng ta sẽ sử dụng xác nhận giữ tiêu chuẩn? Hay thậm chí nói về nó?


10
Tại sao bạn nghĩ nó vô dụng? Bạn có thể đọc các yếu tố của lý thuyết học thống kê phần 7 để biết phân tích chính thức về pro và pro của nó. Nói theo thống kê, k-Fold là tốt hơn, nhưng sử dụng một bộ kiểm tra không nhất thiết là xấu. Theo trực giác, bạn cần xem xét rằng một bộ kiểm tra (khi được sử dụng đúng cách) thực sự là một bộ dữ liệu chưa được sử dụng trong đào tạo. Vì vậy, nó chắc chắn hữu ích trong một số ý nghĩa để đánh giá một mô hình. Ngoài ra, k-Fold là siêu đắt, do đó, giữ là một "xấp xỉ" với những gì k-Fold làm (nhưng đối với người có sức mạnh tính toán thấp).
Charlie Parker

Chắc chắn rồi. Từ góc độ lý thuyết, K-Fold chính xác hơn nhưng đắt hơn về mặt tính toán. Câu hỏi là: tại sao LUÔN không thực hiện xác nhận chéo K-Fold?

2
Tôi hiểu rồi. Tôi sẽ tranh luận rằng lý do chủ yếu là luôn luôn tính toán. K-Fold xấp xỉ với lỗi tổng quát hóa tốt hơn vì vậy theo quan điểm thống kê K-Fold là phương pháp tôi chọn. Hold-out đơn giản hơn nhiều để thực hiện VÀ không yêu cầu đào tạo như nhiều mô hình. Trong thực tế, đào tạo một mô hình có thể khá tốn kém.
Charlie Parker

1
Đúng - nhưng tôi nghĩ rằng đối số "quá đắt tiền tính toán" là khá yếu. Hầu như mọi lúc, chúng tôi đều hướng đến việc phát triển những mô hình chính xác nhất. Tuy nhiên, có một nghịch lý là rất nhiều thí nghiệm được thực hiện trong tài liệu chỉ có một bộ xác nhận duy nhất.

1
Câu hỏi - Các yếu tố của lý thuyết học thống kê phần 7.10.1 có tiêu đề "Xác thực chéo K gấp" dường như chỉ ra rằng việc giữ dữ liệu kiểm tra tách biệt hoàn toàn với dữ liệu đào tạo (như xác thực trong kiểm tra) là lý tưởng và xác thực gấp đôi chỉ là một sự thỏa hiệp như dữ liệu nhiều lần khan hiếm. Tôi vẫn còn khá mới với số liệu thống kê, bạn có thể chỉ ra cách xác thực chéo thực tế chính xác hơn không?
numX

Câu trả lời:


21

Tôi đoán duy nhất là bạn có thể cầm cự với ba giờ trải nghiệm lập trình; khác mất một tuần về nguyên tắc và sáu tháng trong thực tế.

Về nguyên tắc thì đơn giản, nhưng viết mã thì tẻ nhạt và tốn thời gian. Như Linus Torvalds nổi tiếng đã nói, "Các lập trình viên tồi lo lắng về mã. Các lập trình viên giỏi lo lắng về cấu trúc dữ liệu và các mối quan hệ của họ." Nhiều người làm thống kê là những lập trình viên tồi, không có lỗi của riêng họ. Thực hiện xác thực chéo k-gấp một cách hiệu quả (và ý tôi là, theo cách không gây khó chịu khủng khiếp để gỡ lỗi và sử dụng nhiều lần) trong R đòi hỏi một sự hiểu biết mơ hồ về cấu trúc dữ liệu, nhưng cấu trúc dữ liệu thường bị bỏ qua trong "giới thiệu để lập trình thống kê "hướng dẫn. Nó giống như người già sử dụng Internet lần đầu tiên. Điều đó thực sự không khó, chỉ mất hơn nửa giờ để tìm ra lần đầu tiên, nhưng nó hoàn toàn mới và điều đó làm cho nó khó hiểu, vì vậy rất dễ bỏ qua.

Bạn có thắc mắc như thế này: Làm thế nào để thực hiện một xác nhận hold-out trong R . Không có ý định xúc phạm, bất cứ điều gì, cho người hỏi. Nhưng nhiều người không biết chữ. Thực tế là mọi người đang thực hiện xác nhận chéo là đủ để làm tôi hạnh phúc.

Nghe có vẻ ngớ ngẩn và tầm thường, nhưng điều này xuất phát từ kinh nghiệm cá nhân, đã từng là anh chàng đó và đã làm việc với nhiều người là anh chàng đó.


18
Có thể là một người đã học chuyên ngành CS, tôi có một cái nhìn hơi sai lệch về điều này, nhưng nếu bạn có thể thực hiện xác nhận giữ đúng một cách chính xác (điều này có nghĩa là chia dữ liệu thành 2 phần và sử dụng một phần để đào tạo và phần còn lại để kiểm tra), thì điều duy nhất bạn cần thay đổi là tỷ lệ phân chia và đặt toàn bộ vào một vòng lặp. Có vẻ như khó tin rằng đây sẽ là một vấn đề lớn.
Voo

3
@Voo: ngoài ra, việc có thể lập trình ở đây là không đủ: bạn phải hiểu rõ vấn đề đủ để có thể phán đoán những yếu tố gây nhiễu nào bạn cần giải thích trong quá trình chia tách. Xem ví dụ: stats.stackexchange.com/questions/20010/ . Tôi nghĩ rằng tôi thấy loại vấn đề này thường xuyên hơn các vấn đề mã hóa "thuần túy" (mặc dù người ta không bao giờ biết: ai đó hầu như không thể mã hóa một sự phân chia đơn giản của các hàng trong ma trận dữ liệu thường cũng sẽ gây ra lỗi không phân tách cấp cao hơn ví dụ ở cấp độ bệnh nhân)
cbeleites hỗ trợ Monica

Cũng lưu ý rằng bạn có thể thực hiện phân tách giữ đúng (ví dụ: bệnh nhân / ngày đo / ...) mà không cần lập trình gì cả bằng cách tách các tệp mà công cụ đo tạo ra ...
cbeleites hỗ trợ Monica

5
Đối với những người bỏ phiếu: lưu ý rằng tôi đã hỏi một câu hỏi riêng đặt câu hỏi về logic của tôi. stats.stackexchange.com/q/108345/38229
Shadowtalker

1
Tôi không nghĩ rằng câu trả lời giải thích sự khác biệt giữa hai phương pháp xác thực chéo sẽ là thời gian để con người tìm hiểu, thiên vị một cách vô lý và không hữu ích
rgalbo 26/07/17

40

Hold-out thường được sử dụng đồng nghĩa với xác nhận với bộ kiểm tra độc lập, mặc dù có những khác biệt quan trọng giữa việc chia dữ liệu ngẫu nhiên và thiết kế một thử nghiệm xác thực cho thử nghiệm độc lập.

Các bộ kiểm tra độc lập có thể được sử dụng để đo lường hiệu suất tổng quát hóa mà không thể đo lường được bằng cách lấy mẫu lại hoặc xác nhận giữ lại, ví dụ: hiệu suất cho các trường hợp không xác định trong tương lai (= các trường hợp được đo sau đó, sau khi đào tạo kết thúc). Điều này rất quan trọng để biết một mô hình hiện tại có thể được sử dụng cho dữ liệu mới trong bao lâu (ví dụ như về sự trôi dạt của thiết bị). Tổng quát hơn, điều này có thể được mô tả là đo hiệu suất ngoại suy để xác định giới hạn của khả năng áp dụng.

Một kịch bản khác mà việc giữ chỗ thực sự có thể có lợi là: rất dễ dàng để đảm bảo rằng dữ liệu đào tạo và kiểm tra được phân tách đúng cách - dễ dàng hơn nhiều so với xác thực lại mẫu:

  1. quyết định chia tách (ví dụ: phân công ngẫu nhiên các trường hợp)
  2. đo lường
  3. dữ liệu đo lường và tham chiếu của các trường hợp đào tạo => mô hình hóa \ không đo lường cũng không tham chiếu các trường hợp thử nghiệm được trao cho người lập mô hình.
  4. mô hình cuối cùng + số đo của các trường hợp được tổ chức => dự đoán
  5. so sánh dự đoán với tham chiếu cho các trường hợp tổ chức.

Tùy thuộc vào mức độ phân tách bạn cần, mỗi bước có thể được thực hiện bởi người khác. Ở cấp độ đầu tiên, việc không bàn giao bất kỳ dữ liệu nào (thậm chí không phải các phép đo) của các trường hợp thử nghiệm cho nhà mô hình hóa cho phép rất chắc chắn rằng không có dữ liệu thử nghiệm nào bị rò rỉ vào quá trình mô hình hóa. Ở cấp độ thứ hai, mô hình cuối cùng và các phép đo trường hợp thử nghiệm có thể được bàn giao cho người khác, v.v.

Có, bạn phải trả cho điều đó bằng hiệu quả thấp hơn của các ước tính giữ lại so với xác nhận lại mẫu. Nhưng tôi đã thấy nhiều bài báo mà tôi nghi ngờ rằng việc xác thực lấy mẫu lại không phân tách đúng các trường hợp (trong lĩnh vực của tôi, chúng tôi có rất nhiều dữ liệu được phân cụm / phân cấp / nhóm).

Tôi đã học được bài học về rò rỉ dữ liệu để lấy mẫu lại bằng cách rút lại bản thảo một tuần sau khi nộp khi tôi phát hiện ra rằng tôi đã bị phát hiện trước đó (bằng cách chạy thử nghiệm hoán vị cùng với) trong quy trình chia tách (lỗi chính tả trong tính toán chỉ số).

Đôi khi, giữ lại có thể hiệu quả hơn so với việc tìm kiếm một người sẵn sàng dành thời gian để kiểm tra mã lấy mẫu lại (ví dụ: đối với dữ liệu được phân cụm) để đạt được mức độ chắc chắn tương tự về kết quả. Tuy nhiên, IMHO thường không hiệu quả để làm điều này trước khi bạn ở giai đoạn mà bạn cần phải đo lường, ví dụ như hiệu suất trong tương lai (điểm đầu tiên) - nói cách khác, khi bạn cần phải thiết lập một thử nghiệm xác thực cho mô hình hiện có.

OTOH, trong các tình huống cỡ mẫu nhỏ, không có lựa chọn nào: bạn cần giữ đủ các trường hợp kiểm tra để kết quả kiểm tra đủ chính xác để cho phép kết luận cần thiết (hãy nhớ: 3 trong số 3 trường hợp kiểm tra có nghĩa là phân loại khoảng tin cậy nhị phân 95% nằm trong khoảng dưới 50:50 đoán!) Frank Harrell sẽ chỉ ra quy tắc ngón tay cái ít nhất là ca. 100 trường hợp (kiểm tra) là cần thiết để đo lường một tỷ lệ chính xác [chẳng hạn như tỷ lệ các trường hợp dự đoán chính xác] với độ chính xác hữu ích.


Cập nhật: có những tình huống chia tách thích hợp đặc biệt khó đạt được và xác nhận chéo trở nên không khả thi. Hãy xem xét một vấn đề với một số yếu tố gây nhiễu. Việc phân tách rất dễ dàng nếu các yếu tố gây nhiễu này được lồng nhau nghiêm ngặt (ví dụ một nghiên cứu với một số bệnh nhân có một vài mẫu của từng bệnh nhân và phân tích một số tế bào của từng mẫu): bạn phân chia ở mức cao nhất của hệ thống phân cấp lấy mẫu (bệnh nhân khôn ngoan) . Nhưng bạn có thể có các yếu tố gây nhiễu độc lập không được lồng nhau, ví dụ: biến đổi hàng ngày hoặc phương sai gây ra bởi các thử nghiệm khác nhau chạy thử nghiệm. Sau đó, bạn cần đảm bảo rằng phần tách là độc lập cho tất cảcác yếu tố gây nhiễu ở mức cao nhất (các yếu tố gây nhiễu lồng nhau sẽ tự động độc lập). Việc xử lý vấn đề này rất khó khăn nếu một số yếu tố gây nhiễu chỉ được xác định trong quá trình nghiên cứu, và thiết kế và thực hiện một thí nghiệm xác nhận có thể hiệu quả hơn so với việc xử lý các phần tách mà hầu như không có dữ liệu để đào tạo cũng như không thử nghiệm các mô hình thay thế.


6
Tôi ước tôi có thể đưa ra nhiều hơn +1 cho câu trả lời rất kỹ lưỡng này. Tôi đặc biệt thích bạn đề cập đến vấn đề của bạn với rò rỉ dữ liệu vì nó minh họa một cách hiệu quả rằng nó có thể là xa tầm thường để loại trừ các vấn đề như vậy, ngay cả đối với các chuyên gia. Đây là một kiểm tra thực tế tốt!
Marc Claesen

Không phải bạn đang cầu xin câu hỏi sao? Đúng, chia tách là khó, do các yếu tố gây nhiễu, nhưng khó khăn cho dù bạn đang thực hiện xác nhận giữ một lần hoặc xác thực chéo k-gấp, phải không? (Cảm ơn vì câu trả lời sâu sắc bất kể!)
Nils von Barth

1
@NilsvonBarth: Tôi không thấy các đối số của mình có hình tròn như thế nào: OP hỏi "tại sao [hoàn toàn] sử dụng xác nhận giữ lại" và tôi đưa ra một loạt lý do thực tế. Việc sử dụng hiệu quả nhất về mặt thống kê trong một số trường hợp hạn chế không phải lúc nào cũng là tài sản quan trọng nhất của thiết kế nghiên cứu. (Mặc dù theo kinh nghiệm của tôi, điều này thường xảy ra, do số lượng trường hợp cực kỳ hạn chế: Tôi thường khuyên bạn nhiều hơn cho CV lặp lại / lặp đi lặp lại thay vì giữ lại). Đối với một số yếu tố gây nhiễu, việc chia tách vật lý là có thể và dễ dàng - và một cách rất hiệu quả để ngăn chặn việc xem lén. Ai biết được liệu chúng ta có thấy điều đó gấp đôi không ...
cbeleites ủng hộ Monica

phân tích dữ liệu thống kê mù có thể cần thiết đối với quá nhiều giấy tờ dương tính giả ở một số điểm?
cbeleites hỗ trợ Monica

2
@NilsvonBarth: Cẩn thận với tính độc lập đảm bảo giữ vững: rất dễ thực hiện giữ theo cách như vậy (bằng cách giữ vật lý trong các trường hợp, ví dụ mẫu thử được bỏ đi và chỉ được đo sau khi đào tạo mô hình kết thúc), nhưng thường thì thuật ngữ giữ lại được sử dụng cho những gì thực sự giống như một sự phân chia ngẫu nhiên của dữ liệu - và sau đó tất cả các khả năng phạm sai lầm trong quá trình phân tách cũng có thể được thực hiện bằng cách giữ lại!
cbeleites hỗ trợ Monica

8

Nó có thể hữu ích để làm rõ thuật ngữ một chút. Nếu chúng ta để là một số nguyên nhỏ hơn (hoặc bằng) trong đó là cỡ mẫu và chúng ta phân vùng mẫu thành mẫu con duy nhất, thì cái mà bạn đang gọi Xác thực giữ lại thực sự chỉ là 2 lần ( = 2 ) xác nhận chéo. Xác thực chéo chỉ là một công cụ để ước tính tỷ lệ lỗi ngoài mẫu (hoặc tính tổng quát) của một mô hình cụ thể. Sự cần thiết phải ước tính tỷ lệ lỗi ngoài mẫu là phổ biến và đã sinh ra toàn bộ tài liệu. Xem, để bắt đầu, chương 7 của ESL .n n k kknnkk

Vì vậy, để trả lời các câu hỏi:

  1. Tại sao nói về nó? Sư phạm. Thật đáng để nghĩ về xác thực Hold-out là một trường hợp đặc biệt - và đôi khi chỉ hữu ích - một phương pháp khá hữu ích với nhiều, nhiều biến thể.

  2. Tại sao sử dụng nó? Nếu một người đủ may mắn để có một bộ dữ liệu khổng lồ (về mặt quan sát, ), sau đó chia dữ liệu thành một nửa - đào tạo trên một nửa và thử nghiệm trên một nửa - có ý nghĩa. Điều này có ý nghĩa đối với các lý do tính toán vì tất cả những gì được yêu cầu là phù hợp một lần và dự đoán một lần (thay vì lần). Và nó có ý nghĩa từ góc độ "ước lượng mẫu lớn" vì bạn có rất nhiều quan sát để phù hợp với mô hình của mình.knk

Một nguyên tắc nhỏ mà tôi đã học là: khi lớn, có thể nhỏ, nhưng khi nhỏ, nên gần với .k n k nnknkn


13
Tôi không nghĩ rằng nắm giữ giống như xác nhận 2 lần, bởi vì trong xác thực 2 lần, bạn sẽ phù hợp với hai mô hình và sau đó tính trung bình các lỗi trên hai bộ nắm giữ.
Alex

8

Nếu quy trình lựa chọn và phù hợp mô hình của bạn không thể được mã hóa bởi vì nó chủ quan, hoặc một phần là như vậy, thì việc tìm kiếm các biểu đồ và xác thực giữ lại giống như có thể là cách tốt nhất bạn có thể làm. (Tôi cho rằng có lẽ bạn có thể sử dụng thứ gì đó như Mechanical Turk trong mỗi lần gấp CV, mặc dù tôi chưa bao giờ nghe về việc nó được thực hiện.)


6

Chỉ muốn thêm một số hướng dẫn đơn giản mà Andrew Ng đã đề cập trong lớp CS 229 của chúng tôi tại Stanford về xác nhận chéo. Đây là những thực hành mà ông tuân theo trong công việc của mình.

mm20

20<m100km

100<m1,000,000(k=5)m>10,000

Nếu sử dụng xác thực chéo giữ, nhưng nếu khả năng tính toán khả dụng, bạn có thể sử dụng xác thực chéo k-Fold nếu bạn muốn loại bỏ hiệu suất bổ sung đó ra khỏi mô hình của mình.( k = 5 )m1,000,000(k=5)


5

Câu trả lời ngắn:

Tôi khuyên bạn nên luôn sử dụng CV với ít nhất cho:k=5

  • mô hình phức tạp
  • kết quả cuối cùng phải tuân thủ các ràng buộc hiệu lực

Bạn có thể thư giãn điều này cho:

  • đào tạo về bộ dữ liệu thực sự lớn
  • đào tạo người mẫu đơn giản
  • tạo mẫu khi thời gian là một vấn đề

Một số bạn đã đề cập, việc lập trình này trong R có thể là một vấn đề. Tôi khuyên bạn nên xem qua gói "mlr" . Nó bao bọc các gói khác nhau trong một giao diện hợp nhất, cũng cung cấp các phương pháp đánh giá hiệu suất và lấy mẫu thực sự tiên tiến.

Hãy xem: http://mlr-org.github.io/mlr-tutorial/release/html/resample/ và: http://mlr-org.github.io/mlr-tutorial/release/html/performance/ chỉ số

Một số giải thích thêm - những gì CV thực sự làm là phá vỡ sự đánh đổi sai lệch thiên vị:

Bây giờ, vấn đề mà cả hai phương pháp đều cố gắng giải quyết là ước tính lỗi tổng quát hóa, có điều kiện trên dữ liệu được sử dụng để huấn luyện một mô hình.

Holdout có vấn đề với sai lệch và phương sai:

Bằng cách làm cho số lượng dữ liệu mà chúng tôi kiểm tra nhỏ hơn, chúng tôi đưa ra phương sai cho lỗi tổng quát hóa ước tính của chúng tôi, vì dữ liệu thử nghiệm có thể không thể hiện phân phối cơ bản tốt nữa. Điều này tự nó không giới thiệu một thiên vị, mặc dù như mong đợi hiệu suất ước tính sẽ chính xác.

Tuy nhiên, làm cho tập huấn nhỏ hơn đưa ra xu hướng bi quan, vì một lần nữa phân phối cơ bản không được thể hiện tốt trong dữ liệu và mô hình cũng không thể phù hợp với dữ liệu. Làm cho tập huấn luyện rất nhỏ cũng giới thiệu phương sai.

Khi quy mô của tập huấn luyện và kiểm tra xác định lẫn nhau, điều này khiến chúng ta có một sự đánh đổi: thiên vị bi quan so với phương sai cao.

k - 1k Fold Xác thực chéo đã khắc phục vấn đề này bằng cách giữ cho tập huấn luyện lớn (một phần của của dữ liệu được sử dụng để đào tạo trong mỗi lần lặp) và xử lý phương sai của lỗi kiểm tra bằng cách lấy mẫu lại . Sau tất cả các lần lặp lại, chúng tôi đã kiểm tra hiệu suất trên mỗi lần quan sát bộ dữ liệu với một người học. Rõ ràng, điều này đòi hỏi nhiều thời gian tính toán hơn so với việc nắm giữ đơn giản.k1k

Xác nhận chéo là đặc biệt quan trọng đối với người học phức tạp hơn (phương sai cao). Những thứ đó thường đắt hơn về mặt tính toán, điều này có thể làm cho toàn bộ quá trình khá tốn thời gian.


3

Tất cả đều là những bình luận hữu ích. Chỉ cần đưa thêm một tài khoản. Khi bạn có đủ dữ liệu, sử dụng Hold-Out là một cách để đánh giá một mô hình cụ thể (một mô hình SVM cụ thể, một mô hình GIỎ HÀNG cụ thể, v.v.), trong khi nếu bạn sử dụng các quy trình xác thực chéo khác, bạn đang đánh giá các phương pháp (trong điều kiện vấn đề của bạn ) chứ không phải mô hình (phương pháp SVM, phương pháp GIỎI, v.v.).

Hy vọng điều này là hữu ích!


3

Mô hình hóa với dữ liệu nghiêm trọng về thời gian là một ngoại lệ đối với tôi. K gấp không thể hoạt động trong một số trường hợp khi bạn cần dự đoán tương lai dựa trên dữ liệu trước đó. Các bộ kiểm tra phải là dữ liệu trong tương lai và bạn không bao giờ có thể chạm vào chúng trong giai đoạn đào tạo. ex dự đoán bán hoặc thị trường chứng khoán. Giữ là hữu ích trong những trường hợp.


Thời gian dữ liệu nghiêm trọng?
nbro

3

Chỉ cần đặt; thời gian. Xác thực chéo bạn chạy quy trình đào tạo k lần (nghĩa là một lần cho mỗi lần giữ máy). Nếu bạn có dữ liệu lớn, thì bạn có thể mất nhiều giờ hoặc thậm chí vài ngày để đào tạo mô hình cho chỉ một bộ dữ liệu, do đó, bạn nhân số đó với k khi sử dụng xác thực chéo.

Vì vậy, mặc dù xác thực chéo là phương pháp tốt nhất, trong một số trường hợp nhất định, điều đó không khả thi và thời gian cần có để sử dụng mô hình hóa dữ liệu theo các cách khác nhau hoặc thử các hàm mất khác nhau để có được mô hình tốt hơn.

Sở thích cá nhân của tôi là lấy dữ liệu xác thực từ toàn bộ tập dữ liệu, vì vậy thay vì lấy một đoạn 10% từ đầu hoặc đuôi dữ liệu, tôi lấy 2% từ 5 điểm trong tập dữ liệu. Điều đó làm cho dữ liệu xác nhận đại diện hơn một chút cho toàn bộ dữ liệu.


Mặc dù đó là một câu hỏi cũ và một câu trả lời mới, tôi bỏ phiếu này vì nó thách thức khẳng định không có căn cứ rằng "K-Fold chính xác hơn nhưng đắt hơn về mặt tính toán", mà các câu trả lời khác đã bỏ qua hoặc chuyển qua quá nhanh.
The Laconic

0

Cần lưu ý rằng không phải lúc nào cũng có thể áp dụng xác nhận chéo. Xem xét các bộ dữ liệu phụ thuộc vào thời gian mà bạn muốn sử dụng dữ liệu lịch sử để huấn luyện một mô hình dự đoán cho hành vi trong tương lai. Trong trường hợp này, bạn phải áp dụng xác nhận giữ.


2
Trong trường hợp này, bạn nên làm xác nhận chuyển tiếp.
Neil G
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.