8
8
using System . IO ;
9
9
using GitHubLabeler . DataStructures ;
10
10
using Common ;
11
+ using Microsoft . ML . Data ;
11
12
12
13
namespace GitHubLabeler
13
14
{
@@ -23,6 +24,8 @@ internal class Labeler
23
24
private readonly PredictionEngine < GitHubIssue , GitHubIssuePrediction > _predEngine ;
24
25
private readonly ITransformer _trainedModel ;
25
26
27
+ private FullPrediction [ ] _fullPredictions ;
28
+
26
29
public Labeler ( string modelPath , string repoOwner = "" , string repoName = "" , string accessToken = "" )
27
30
{
28
31
_modelPath = modelPath ;
@@ -54,22 +57,91 @@ public Labeler(string modelPath, string repoOwner = "", string repoName = "", st
54
57
55
58
public void TestPredictionForSingleIssue ( )
56
59
{
57
- GitHubIssue singleIssue = new GitHubIssue ( ) { ID = "Any-ID" , Title = "Entity Framework crashes" , Description = "When connecting to the database, EF is crashing" } ;
60
+ GitHubIssue singleIssue = new GitHubIssue ( ) {
61
+ ID = "Any-ID" ,
62
+ Title = "Crash in SqlConnection when using TransactionScope" ,
63
+ Description = "I'm using SqlClient in netcoreapp2.0. Sqlclient.Close() crashes in Linux but works on Windows"
64
+ } ;
58
65
59
- //Predict label for single hard-coded issue
60
- //Score
66
+ //Predict labels and scores for single hard-coded issue
61
67
var prediction = _predEngine . Predict ( singleIssue ) ;
68
+
69
+ _fullPredictions = GetBestThreePredictions ( prediction ) ;
70
+
71
+ Console . WriteLine ( "1st Label: " + _fullPredictions [ 0 ] . PredictedLabel + " with score: " + _fullPredictions [ 0 ] . Score ) ;
72
+ Console . WriteLine ( "2nd Label: " + _fullPredictions [ 1 ] . PredictedLabel + " with score: " + _fullPredictions [ 1 ] . Score ) ;
73
+ Console . WriteLine ( "3rd Label: " + _fullPredictions [ 2 ] . PredictedLabel + " with score: " + _fullPredictions [ 2 ] . Score ) ;
74
+
62
75
Console . WriteLine ( $ "=============== Single Prediction - Result: { prediction . Area } ===============") ;
63
76
}
64
77
78
+ private FullPrediction [ ] GetBestThreePredictions ( GitHubIssuePrediction prediction )
79
+ {
80
+ float [ ] scores = prediction . Score ;
81
+ int size = scores . Length ;
82
+ int index0 , index1 , index2 = 0 ;
83
+
84
+ VBuffer < ReadOnlyMemory < char > > slotNames = default ;
85
+ _predEngine . OutputSchema [ nameof ( GitHubIssuePrediction . Score ) ] . GetSlotNames ( ref slotNames ) ;
86
+
87
+ GetIndexesOfTopThreeScores ( scores , size , out index0 , out index1 , out index2 ) ;
88
+
89
+ _fullPredictions = new FullPrediction [ ]
90
+ {
91
+ new FullPrediction ( slotNames . GetItemOrDefault ( index0 ) . ToString ( ) , scores [ index0 ] , index0 ) ,
92
+ new FullPrediction ( slotNames . GetItemOrDefault ( index1 ) . ToString ( ) , scores [ index1 ] , index1 ) ,
93
+ new FullPrediction ( slotNames . GetItemOrDefault ( index2 ) . ToString ( ) , scores [ index2 ] , index2 )
94
+ } ;
95
+
96
+ return _fullPredictions ;
97
+ }
98
+
99
+ private void GetIndexesOfTopThreeScores ( float [ ] scores , int n , out int index0 , out int index1 , out int index2 )
100
+ {
101
+ int i ;
102
+ float first , second , third ;
103
+ index0 = index1 = index2 = 0 ;
104
+ if ( n < 3 )
105
+ {
106
+ Console . WriteLine ( "Invalid Input" ) ;
107
+ return ;
108
+ }
109
+ third = first = second = 000 ;
110
+ for ( i = 0 ; i < n ; i ++ )
111
+ {
112
+ // If current element is
113
+ // smaller than first
114
+ if ( scores [ i ] > first )
115
+ {
116
+ third = second ;
117
+ second = first ;
118
+ first = scores [ i ] ;
119
+ }
120
+ // If arr[i] is in between first
121
+ // and second then update second
122
+ else if ( scores [ i ] > second )
123
+ {
124
+ third = second ;
125
+ second = scores [ i ] ;
126
+ }
127
+
128
+ else if ( scores [ i ] > third )
129
+ third = scores [ i ] ;
130
+ }
131
+ var scoresList = scores . ToList ( ) ;
132
+ index0 = scoresList . IndexOf ( first ) ;
133
+ index1 = scoresList . IndexOf ( second ) ;
134
+ index2 = scoresList . IndexOf ( third ) ;
135
+ }
136
+
65
137
// Label all issues that are not labeled yet
66
138
public async Task LabelAllNewIssuesInGitHubRepo ( )
67
139
{
68
140
var newIssues = await GetNewIssues ( ) ;
69
141
foreach ( var issue in newIssues . Where ( issue => ! issue . Labels . Any ( ) ) )
70
142
{
71
- var label = PredictLabel ( issue ) ;
72
- ApplyLabel ( issue , label ) ;
143
+ var label = PredictLabels ( issue ) ;
144
+ ApplyLabels ( issue , label ) ;
73
145
}
74
146
}
75
147
@@ -89,7 +161,7 @@ private async Task<IReadOnlyList<Issue>> GetNewIssues()
89
161
. ToList ( ) ;
90
162
}
91
163
92
- private string PredictLabel ( Octokit . Issue issue )
164
+ private FullPrediction [ ] PredictLabels ( Octokit . Issue issue )
93
165
{
94
166
var corefxIssue = new GitHubIssue
95
167
{
@@ -98,26 +170,35 @@ private string PredictLabel(Octokit.Issue issue)
98
170
Description = issue . Body
99
171
} ;
100
172
101
- var predictedLabel = Predict ( corefxIssue ) ;
173
+ _fullPredictions = Predict ( corefxIssue ) ;
102
174
103
- return predictedLabel ;
175
+ return _fullPredictions ;
104
176
}
105
177
106
- public string Predict ( GitHubIssue issue )
107
- {
178
+ public FullPrediction [ ] Predict ( GitHubIssue issue )
179
+ {
108
180
var prediction = _predEngine . Predict ( issue ) ;
109
181
110
- return prediction . Area ;
182
+ var fullPredictions = GetBestThreePredictions ( prediction ) ;
183
+
184
+ return fullPredictions ;
111
185
}
112
186
113
- private void ApplyLabel ( Issue issue , string label )
187
+ private void ApplyLabels ( Issue issue , FullPrediction [ ] fullPredictions )
114
188
{
115
189
var issueUpdate = new IssueUpdate ( ) ;
116
- issueUpdate . AddLabel ( label ) ;
117
190
118
- _client . Issue . Update ( _repoOwner , _repoName , issue . Number , issueUpdate ) ;
191
+ //assign labels in GITHUB only if predicted score of all predictions is > 30%
192
+ foreach ( var fullPrediction in fullPredictions )
193
+ {
194
+ if ( fullPrediction . Score >= 0.3 )
195
+ {
196
+ issueUpdate . AddLabel ( fullPrediction . PredictedLabel ) ;
197
+ _client . Issue . Update ( _repoOwner , _repoName , issue . Number , issueUpdate ) ;
119
198
120
- Console . WriteLine ( $ "Issue { issue . Number } : \" { issue . Title } \" \t was labeled as: { label } ") ;
199
+ Console . WriteLine ( $ "Issue { issue . Number } : \" { issue . Title } \" \t was labeled as: { fullPredictions [ 0 ] . PredictedLabel } ") ;
200
+ }
201
+ }
121
202
}
122
- }
203
+ }
123
204
}
0 commit comments