메뉴
HN
Hacker News • 16일 전

더 좋아진 AI 작성 코드 주석 탐지기

IMP
4/10
핵심 요약

개발자가 AI가 생성한 코드 주석과 사람이 작성한 주석을 구분하는 분류기를 공개 데이터와 더 견고한 기반 위에 재구축하여 공개했습니다. 웹 브라우저에서 실행되어 붙여넣은 내용이 외부로 전송되지 않으며, 교차 검증 기준 균형 정확도 77%, 실제 데이터 테스트에서는 88%를 기록했습니다. UI에서 텍스트의 어떤 부분이 판단에 기여했는지 피처 활성화를 클릭으로 확인할 수 있는 것이 특징입니다.

번역된 본문

이전 AI 주석 분류기를 학습시킬 때 일부 개인적인 비공개 데이터를 사용했고 다소 불안정한 기반 위에 구축했기 때문에 코드나 데이터를 공유할 수 없었습니다. 이번에 공개 데이터와 더 나은 기반 위에 다시 만들었습니다! 먼저 직접 사용해 보시면 좋습니다. 웹 페이지에 붙여넣은 내용은 브라우저를 벗어나지 않으므로 무엇이든 안심고 시험해 볼 수 있습니다. 이전 버전을 일부 테스터들에게 시험해 보도록 초청했고, 대체로 긍정적인 피드백을 받았습니다.

이전 글에서 '클로드식 표현'을 분석했던 것처럼 로봇 특유의 표현을 세부적으로 나누지는 않겠습니다. 새 분류기의 UI에서는 분류 중인 텍스트의 어떤 부분이든 클릭하면 해당 부분에서 어떤 피처가 활성화되는지, 그것이 전체 판단에 어떻게 기여하는지 확인할 수 있기 때문입니다. 피처 활성화 확장 보기의 예시도 있습니다.

성능 면에서 핵심 수치는 77%의 균형 정확도(balanced accuracy)입니다. 이는 사람이 작성한 주석과 로봇이 생성한 주석이 동일한 비율로 나타난다고 가정할 때 분류기가 사람 vs 로봇 판정을 맞히는 비율입니다. 분류기는 또한 교정(calibration)된 예측 확률을 출력하는데, 이는 각 판정이 정확할 확률로 읽을 수 있다는 뜻입니다. 이는 교정 곡선(calibration curve)을 통해 검증하며, 이 곡선은 알려진 확률의 사건에 분류기가 어떤 확률을 부여하는지 보여줍니다. 모든 점이 기준 대각선에 매우 가깝게 위치하므로 근사적으로 정확하다는 것을 알 수 있습니다. 이는 다양한 길이의 주석에서도 유지되며, 적합된 온도(temperature) 파라미터가 데이터 양이 늘어남에 따라 증가하는 확신도를 보정해 줍니다.

혼동 행렬(confusion matrix)을 보면 분류기의 실패 유형을 더 자세히 알 수 있습니다. 이 표에서 '로봇'이 탐지하려는 양성 클래스입니다. 약어는 진양성/가양성/진음성/가음성 비율을 뜻합니다.

판정: 사람 | 판정: 로봇 입력: 사람 — tnr = 0.73 | fpr = 0.27 입력: 로봇 — fnr = 0.20 | tpr = 0.80

사람이 작성한 것이 확인된 입력이 주어지면 분류기는 73%의 확률로 사람으로 올바르게 판정합니다. 로봇이 작성한 것이 확인된 입력은 80%의 확률로 올바르게 판정됩니다. 즉 두 경우 모두(사람 확인/로봇 확인) 오류율이 약 25% 정도라는 뜻입니다. 높게 들릴 수 있습니다! 하지만 이 오류율은 가능한 모든 입력에 대한 집계치라는 점을 기억하세요. 분류기가 분류할 때마다 교정된 예측 확률을 출력하므로 크게 신경 쓸 필요는 없습니다. 따라서 개별 판단에서 가양성 위험이 낮은지 높은지 알 수 있습니다. 분류기가 매우 확신할 때(예: 확신도 80% 이상) 가양성 위험은 5%로 떨어집니다. 분류기가 불확실할 때(확신도 약 50%)는 교정 특성상 절반 정도의 확률로 잘못된 판정을 내리게 됩니다.

혼동 행렬의 수치를 언급한 것은 분류기를 논의할 때 자주 사용되기 때문이며, 보다 학술적인 독자들이 기대할 수 있어서입니다. 요청된 다른 수치들도 있습니다: 정확도(Accuracy) 77%, 정밀도(Precision) 75%, 재현율(Recall) 80%, 민감도(Sensitivity) 80%, 특이도(Specificity) 73%, F1 점수 77%. 정확도, 정밀도, F1 점수는 기저 비율에 따라 달라지지만, 여기서는 무지 가정, 즉 사람 작성 주석과 로봇 생성 주석이 동일하게 섞여 있다는 가정 하에 계산했습니다. 이 모든 수치는 교차 검증에서 나온 것입니다.

또한 사람과 로봇의 실제 댓글로 구성된 소규모 비합성 세트를 수동으로 테스트하여 분류기가 표본 외에서 얼마나 일반화되는지 확인했습니다.

판정: 사람 | 판정: 로봇 입력: 사람 — tnr = 0.89 | fpr = 0.11 입력: 로봇 — fnr = 0.14 | tpr = 0.86

이는 다음과 같은 성능 수치로 이어집니다: 정확도 88%, 정밀도 89%, 재현율 86%, 민감도 86%, 특이도 89%, F1 점수 87%. 아주 좋은 결과입니다! 비합성적이고 더 실제에 가까운 사례가 학습 데이터보다 분류기가 구별하기 쉬운 것으로 보입니다. 물론 이 모든 것은...

원문 보기
원문 보기 (영어)
When I trained the previous ai comment classifier , I used partially personal private data to do it, and built it on a somewhat shaky foundation, so I couldn’t share the code or data. I rebuilt it on public data and a better foundation! First off, you might want to try it out . Nothing you paste into that web page leaves your browser, so you can safely try it with whatever you like. I have invited some testers to try out an earlier version of it, and they had mainly positive feedback to give. We won’t break down robot-isms the way we broke down Claude-isms in the previous article, because in the ui of the new classifier you can just click any part of the text being classified to see which features activate on that portion of the text, and how they contribute to the overall judgment. Here’s an example of the expanded feature activation view. In terms of performance, the headline number is the balanced accuracy of 77 %. This is how often the classifier gets the human vs. robot verdict right, assuming human-written and robot-generated comments are equally likely. The classifier also prints a predicted percentage which is calibrated, meaning it can be read as the probability that any specific verdict is correct. We test this through the calibration curve, which shows what probability the classifier assigns to an event with a known probability. Since all dots lie very close to the reference diagonal, we know they are approximately correct. This holds true across comments of multiple lengths, where a fitted temperature parameter adjusts for increased confidence as the amount of data increases. We can get more details about the classifier’s failure modes by looking at its confusion matrix. In this table, “robot” is considered the positive class, i.e. the thing we want to detect. The abbreviations stand for true/false positive/negative rate. verdict: human verdict: robot input: human tnr = 0.73 fpr = 0.27 input: robot fnr = 0.20 tpr = 0.80 When presented with a known-human input, the classifier correctly judges it as human 73 % of the time. With a known-robot input, it is correctly judged 80 % of the time. This means in both cases (known-human and known-robot) the mistake rate is around 25 %. That might sound high! But remember that this mistake rate is the aggregate over all possible inputs . We don’t need to pay too much attention to it, because the classifier outputs a calibrated predictive percentage every time it classifies something. Thus, for individual judgments, we know when the risk of false positives is lower or higher. When the classifier is very confident – e.g. when the confidence is 80 % or more – the risk of a false positive drops to 5 %. When the classifier is uncertain – when confidence is around 50 % – then by calibration it will issue the wrong verdict around half the time. I mention the numbers in this confusion matrix only because they are so often used when discussing classifiers, so more academically inclined readers may expect to see it. Here are some other requested numbers: Accuracy 77 % Precision 75 % Recall 80 % Sensitivity 80 % Specificity 73 % F1 score 77 % The accuracy, precision, and F1 score depend on the base rate, but here they are computed from an ignorance assumption, i.e. an equal mix of human-written and robot-generated comments. All of these numbers come from cross-validation. I have also manually tested a smaller non-synthetic set of real-world comments from humans and robots to see how well the classifier generalises slightly out of sample. verdict: human verdict: robot input: human tnr = 0.89 fpr = 0.11 input: robot fnr = 0.14 tpr = 0.86 This translates to the following performance numbers: Accuracy 88 % Precision 89 % Recall 86 % Sensitivity 86 % Specificity 89 % F1 score 87 % This is very good! It looks like non-synthetic, more real-worldy cases are easier for the classifier to discriminate between than the training data. Of course, all of this is tested with code comments only. The classifier is not built to detect robot-generated texts of other kinds. It can do it, but I make no promises of its accuracy. With that out of the way, let’s talk about how it’s made. Data collection The first step, as before, is to build a good data set. Ideally, we’d plan this meticulously and do it right the first time. If we do that, it should cost us about $30 to get the dataset that powers this classifier. It contains enough data to reach diminishing returns in discriminating between the more similar models. 1 1 It is possible to extract a more powerful classifier with more data, but it would start to be very expensive since classifier power appears to scale with the log of money spent. That is, if you plan it out and do it right the first time. I didn’t do that. I discovered much later, when evaluating features, that the data I had was junk and I had to collect it all over 2 2 💸 . Then after a while I discovered again that the data was still junk and had to be recollected again 3 3 💸💸💸 . The general idea was to find a set of permissively licenced or copy-left repositories, check out their latest commit from the year 2021 , and then take a few random files from that commit. These contain human comments. Then we strip out all comments from those files, and have llm s generate new comments for the same files. That provides us with robot comments. As long as we try to keep the number tokens for each file balanced between all classes (humans and llm models), we can avoid subject matter leakage, where the classifier learns to distinguish files or repositories rather than the style of the text itself. The general idea is simple! But the devil’s where the devil usually is. Here are some mistakes I made, in no particular order: Accidentally picking different source files for each llm to generate comments for. This causes subject matter leakage. Generating llm comments for files with very few human comments. This also causes subject matter leakage over the human–robot barrier. Failing to strip out docstrings when blinding llm s to human comments in source files. This causes llm s to generate comments more similar to humans because they try to match the existing repository style. Though it should be said this had a smaller effect than I thought it would. Related to the above, some languages support many different syntaxes for comments, and some are used more often than others. Failure to detect existing comments in all syntaxes leaves comments behind to contaminate llm generation, and also makes it hard to get all the data that has been produced. Not filtering out human comments that are very short. Most human comments only say things like “main task structure” or “chIcon” or “Alias” and including those teaches the classifier that humans write like shit. Since llm s were instructed to write more detailed comments, it seems reasonable to compare those to more detailed human comments too. Using a fixed prompt for generating llm comments. This results in a dataset with narrower variation than desirable for learning all the quirks needed to separate models and humans. Not all of these problems required regenerating data from scratch. Some could be worked around by filtering and preprocessing the data that already existed. Either way, this was the least fun part of the project, and it cost significantly more than the theoretical $30. Feature evaluation After collecting data, we need to design a classifier that works on that data. This means evaluating candidate features. Doing so isn’t expensive in money, but in cpu time. Evaluating features, in the most powerful sense, means training the classifier on all subsets of candidate features and seeing which performs best. That’s unreasonable, as even with only 15 candidate features, it requires training over 30,000 different classifiers, which need to be trained five ways ea