|
39 | 39 |
|
40 | 40 | import cleanlab |
41 | 41 | import numpy as np |
| 42 | +from cleanlab.classification import LearningWithNoisyLabels |
42 | 43 | from sklearn.datasets import load_digits |
43 | 44 | from sklearn.linear_model import LogisticRegression |
| 45 | +from sklearn.metrics import f1_score |
| 46 | +from sklearn.model_selection import train_test_split |
44 | 47 |
|
45 | 48 | warnings.simplefilter("ignore") |
46 | 49 | np.random.seed(477) |
|
57 | 60 | print("y:", y[:100]) |
58 | 61 | print('Handwritten digits datasets number of classes:', len(np.unique(y))) |
59 | 62 | print('Handwritten digits datasets number of examples:', len(y)) |
60 | | - |
| 63 | +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1) |
61 | 64 | # Add lots of errors to labels |
62 | | -s = np.array(y) |
63 | | -for i in range(50): |
| 65 | +s = np.array(y_train) |
| 66 | +for i in range(100): |
64 | 67 | # Switch to some wrong label thats a different class |
65 | 68 | s[i] = 0 |
66 | 69 |
|
67 | 70 | # Confirm that we indeed added NUM_ERRORS label errors |
68 | | -actual_label_errors = np.arange(len(y))[s != y] |
| 71 | +actual_label_errors = np.arange(len(y_train))[s != y_train] |
69 | 72 | print('\nIndices of actual label errors:\n', actual_label_errors) |
70 | 73 | print('error with y, y[:20]:', s[:20]) |
71 | 74 | print("len of errors:", len(actual_label_errors)) |
72 | 75 | actual_num_errors = len(actual_label_errors) |
73 | 76 | # To keep the tutorial short, we use cleanlab to get the |
74 | 77 | # out-of-sample predicted probabilities using cross-validation |
75 | 78 | # with a very simple, non-optimized logistic regression classifier |
| 79 | +clf = LogisticRegression() |
76 | 80 | psx = cleanlab.latent_estimation.estimate_cv_predicted_probabilities( |
77 | | - X, s, clf=LogisticRegression(solver='lbfgs')) |
| 81 | + X_train, s, clf=clf) |
78 | 82 |
|
79 | 83 | # Now we have our noisy labels s and predicted probabilities psx. |
80 | 84 | # That's all we need for confident learning. |
|
94 | 98 | ordered_label_errors = get_noise_indices( |
95 | 99 | s=s, |
96 | 100 | psx=psx, |
97 | | - frac_noise=2.1, |
98 | 101 | sorted_index_method='normalized_margin', # Orders label errors |
99 | 102 | ) |
100 | 103 |
|
|
109 | 112 | score = sum([e in actual_label_errors for e in label_errors_idx]) / len(label_errors_idx) |
110 | 113 | print('% confident learning errors that are actual errors: {:.0%}'.format(score)) |
111 | 114 |
|
112 | | - |
113 | | -from sklearn.metrics import roc_auc_score,accuracy_score,f1_score |
114 | 115 | # original lr f1 |
115 | | -m = LogisticRegression() |
116 | | -m.fit(X,y=s) |
117 | | -m_pred = m.predict(X) |
118 | | -f1_origin = f1_score(s,m_pred,average='micro') |
119 | | -print('f1_origin_compare_error:',f1_origin) |
120 | | - |
121 | | -f1_origin_true = f1_score(y,m_pred,average='micro') |
122 | | -print('f1_origin_compare_truth:',f1_origin_true) |
123 | | -from cleanlab.classification import LearningWithNoisyLabels |
124 | 116 |
|
125 | | -# Wrap around any classifier. Yup, you can use sklearn/pyTorch/Tensorflow/FastText/etc. |
126 | | -lnl = LearningWithNoisyLabels(clf=LogisticRegression()) |
127 | | -lnl.fit(X=X, s=s) |
128 | | -# Estimate the predictions you would have gotten by training with *no* label errors. |
129 | | -predicted_test_labels = lnl.predict(X) |
130 | | -f1_origin = f1_score(s,predicted_test_labels,average='micro') |
131 | | -print('f1_new_compare_error:',f1_origin) |
| 117 | +print('WITHOUT confident learning,', end=" ") |
132 | 118 |
|
133 | | -f1_origin_true = f1_score(y,predicted_test_labels,average='micro') |
134 | | -print('f1_new_compare_truth:',f1_origin_true) |
| 119 | +clf.fit(X_train, s) |
| 120 | +pred = clf.predict(X_test) |
| 121 | +print("dataset test f1:", round(f1_score(pred, y_test, average='micro'), 4)) |
135 | 122 |
|
136 | | -lnl = LearningWithNoisyLabels(clf=LogisticRegression()) |
137 | | -lnl.fit(X=X, s=s,psx=psx) |
138 | | -# Estimate the predictions you would have gotten by training with *no* label errors. |
139 | | -predicted_test_labels = lnl.predict(X) |
140 | | -f1_origin = f1_score(s,predicted_test_labels,average='micro') |
141 | | -print('f1_psx_compare_error:',f1_origin) |
| 123 | +print("\nNow we show improvement using cleanlab to characterize the noise") |
| 124 | +print("and learn on the data that is (with high confidence) labeled correctly.") |
| 125 | +print() |
| 126 | +print('WITH confident learning (psx not given),', end=" ") |
| 127 | +rp = LearningWithNoisyLabels(clf=clf) |
| 128 | +rp.fit(X_train, s) |
| 129 | +pred = rp.predict(X_test) |
| 130 | +print("dataset test f1:", round(f1_score(pred, y_test, average='micro'), 4)) |
142 | 131 |
|
143 | | -f1_origin_true = f1_score(y,predicted_test_labels,average='micro') |
144 | | -print('f1_psx_compare_truth:',f1_origin_true) |
| 132 | +print('WITH confident learning (psx given),', end=" ") |
| 133 | +rp.fit(X=X_train, s=s, psx=psx) |
| 134 | +pred = rp.predict(X_test) |
| 135 | +print("dataset test f1:", round(f1_score(pred, y_test, average='micro'), 4)) |
145 | 136 |
|
146 | | -f1 = f1_score(y,predicted_test_labels,average='micro') |
147 | | -print("f1:",f1) |
148 | | -score = lnl.score(X,s) |
149 | | -print('score_compare_error:',score) |
| 137 | +print('WITH all label right,', end=" ") |
| 138 | +clf.fit(X_train, y_train) |
| 139 | +pred = clf.predict(X_test) |
| 140 | +print("dataset test f1:", round(f1_score(pred, y_test, average='micro'), 4)) |
150 | 141 |
|
151 | | -score = lnl.score(X,y) |
152 | | -print('score_compare_truth:',score) |
153 | | - |
154 | | -m = LogisticRegression() |
155 | | -m.fit(X,y) |
156 | | -m_pred = m.predict(X) |
157 | | - |
158 | | -f1_origin_true = f1_score(y,m_pred,average='micro') |
159 | | -print('f1_all_right:',f1_origin_true) |
160 | | - |
161 | | -print("f1 Comparison") |
162 | 142 | print("-------------------") |
163 | | -clf = LogisticRegression(solver = 'lbfgs', multi_class = 'auto') |
164 | | -baseline_score = f1_score(y, clf.fit(X, s).predict(X),average='micro') |
165 | | -print("Logistic regression baseline_score:", baseline_score) |
166 | | -rp = LearningWithNoisyLabels() |
167 | | -rp_score = f1_score(y, rp.fit(X, s, psx=psx).predict(X),average='micro') |
| 143 | +rp_score = f1_score(y_test, rp.fit(X_train, s, psx=psx).predict(X_test), average='micro') |
168 | 144 | print("Logistic regression (+rankpruning):", rp_score) |
169 | | -diff = rp_score - baseline_score |
170 | | -clf = LogisticRegression(solver = 'lbfgs', multi_class = 'auto') |
171 | | -print('Fit on denoised data without re-weighting:', f1_score(y, clf.fit(X[~idx_errors], s[~idx_errors]).predict(X),average='micro')) |
172 | | - |
| 145 | +clf = LogisticRegression(solver='lbfgs', multi_class='auto') |
| 146 | +print('Fit on denoised data without re-weighting:', |
| 147 | + f1_score(y_test, clf.fit(X_train[~idx_errors], s[~idx_errors]).predict(X_test), average='micro')) |
0 commit comments