In addition to issues mentioned in other answers (in particular the accessibility issue), a caveat for display: none is that it will also affect the warning displayed by the browser when the radio input is required and the user didn't check it.
On the other hand, a caveat for opacity: 0 and for visibility: hidden is that it the radio button will still use some space (and AFAICS width: 0px has no effect), which may be an issue (e.g. for alignment, or if your radio buttons are inside <li> tags and you want the <li> background color to change on :hover, in which case the label has to cover the <li>).
A fix is to simply set the position of the radio button as fixed :
input[type=radio] {
opacity: 10;
position: fixed;
}
input[type=radio]+label {
background-color: #eee;
padding: 1em;
}
<input type="radio" id="radio1">
<label for="radio1">radio1</label>
<input type="radio" id="radio2">
<label for="radio2">radio2</label>
As seen in the snippet (using opacity: 10 instead of 0 just to see what we're talking about), with position: fixed the radio button doesn't affect the label anymore.