utils.R 6.17 KB
Newer Older
1
2
3
lgb.is.Booster <- function(x) {
  lgb.check.r6.class(x, "lgb.Booster") # Checking if it is of class lgb.Booster or not
}
4

5
6
7
lgb.is.Dataset <- function(x) {
  lgb.check.r6.class(x, "lgb.Dataset") # Checking if it is of class lgb.Dataset or not
}
8
9

# use 64bit data to store address
10
11
12
lgb.new.handle <- function() {
  0.0 # Return numeric type in R
}
13

14
15
16
lgb.is.null.handle <- function(x) {
  is.null(x) || x == 0 # Is it null or zero?
}
Guolin Ke's avatar
Guolin Ke committed
17
18

lgb.encode.char <- function(arr, len) {
19
  
20
  if (!is.raw(arr)) {
21
    stop("lgb.encode.char: Can only encode from raw type") # Not an object of type raw
Guolin Ke's avatar
Guolin Ke committed
22
  }
23
24
  rawToChar(arr[seq_len(len)]) # Return the conversion of raw type to character type
  
Guolin Ke's avatar
Guolin Ke committed
25
26
27
}

lgb.call <- function(fun_name, ret, ...) {
28
29
  
  # Set call state to a zero value
30
  call_state <- 0L
31
32
  
  # Check for a ret call
Guolin Ke's avatar
Guolin Ke committed
33
  if (!is.null(ret)) {
34
    call_state <- .Call(fun_name, ..., ret, call_state, PACKAGE = "lib_lightgbm") # Call with ret
Guolin Ke's avatar
Guolin Ke committed
35
  } else {
36
    call_state <- .Call(fun_name, ..., call_state, PACKAGE = "lib_lightgbm") # Call without ret
Guolin Ke's avatar
Guolin Ke committed
37
  }
38
39
  
  # Check for call state value post call
40
  if (call_state != 0L) {
41
42
    
    # Perform text error buffering
43
44
    buf_len <- 200L
    act_len <- 0L
Guolin Ke's avatar
Guolin Ke committed
45
    err_msg <- raw(buf_len)
46
    err_msg <- .Call("LGBM_GetLastError_R", buf_len, act_len, err_msg, PACKAGE = "lib_lightgbm")
47
48
    
    # Check error buffer
Guolin Ke's avatar
Guolin Ke committed
49
50
51
    if (act_len > buf_len) {
      buf_len <- act_len
      err_msg <- raw(buf_len)
52
53
54
55
      err_msg <- .Call("LGBM_GetLastError_R",
                        buf_len,
                        act_len,
                        err_msg,
56
                        PACKAGE = "lib_lightgbm")
Guolin Ke's avatar
Guolin Ke committed
57
    }
58
59
    
    # Return error
Guolin Ke's avatar
Guolin Ke committed
60
    stop(paste0("api error: ", lgb.encode.char(err_msg, act_len)))
61
    
Guolin Ke's avatar
Guolin Ke committed
62
  }
63
64
65
  
  return(ret)
  
Guolin Ke's avatar
Guolin Ke committed
66
67
68
}

lgb.call.return.str <- function(fun_name, ...) {
69
70
  
  # Create buffer
Guolin Ke's avatar
Guolin Ke committed
71
  buf_len <- as.integer(1024 * 1024)
72
  act_len <- 0L
Guolin Ke's avatar
Guolin Ke committed
73
  buf <- raw(buf_len)
74
75
  
  # Call buffer
Guolin Ke's avatar
Guolin Ke committed
76
  buf <- lgb.call(fun_name, ret = buf, ..., buf_len, act_len)
77
78
  
  # Check for buffer content
Guolin Ke's avatar
Guolin Ke committed
79
80
  if (act_len > buf_len) {
    buf_len <- act_len
81
82
    buf <- raw(buf_len)
    buf <- lgb.call(fun_name, ret = buf, ..., buf_len, act_len)
Guolin Ke's avatar
Guolin Ke committed
83
  }
84
85
86
87
  
  # Return encoded character
  return(lgb.encode.char(buf, act_len))
  
Guolin Ke's avatar
Guolin Ke committed
88
89
90
}

lgb.params2str <- function(params, ...) {
91
92
93
94
95
96
97
  
  # Check for a list as input
  if (!is.list(params)) {
    stop("params must be a list")
  }
  
  # Split parameter names
Guolin Ke's avatar
Guolin Ke committed
98
  names(params) <- gsub("\\.", "_", names(params))
99
100
  
  # Merge parameters from the params and the dots-expansion
Guolin Ke's avatar
Guolin Ke committed
101
102
  dot_params <- list(...)
  names(dot_params) <- gsub("\\.", "_", names(dot_params))
103
104
105
106
107
108
109
  
  # Check for identical parameters
  if (length(intersect(names(params), names(dot_params))) > 0) {
    stop("Same parameters in ", sQuote("params"), " and in the call are not allowed. Please check your ", sQuote("params"), " list")
  }
  
  # Merge parameters
Guolin Ke's avatar
Guolin Ke committed
110
  params <- c(params, dot_params)
111
112
113
114
115
  
  # Setup temporary variable
  ret <- list()
  
  # Perform key value join
Guolin Ke's avatar
Guolin Ke committed
116
  for (key in names(params)) {
117
118
    
    # Join multi value first
Guolin Ke's avatar
Guolin Ke committed
119
    val <- paste0(params[[key]], collapse = ",")
120
121
122
    if (nchar(val) <= 0) next # Skip join
    
    # Join key value
Guolin Ke's avatar
Guolin Ke committed
123
    pair <- paste0(c(key, val), collapse = "=")
124
125
    ret <- c(ret, pair)
    
Guolin Ke's avatar
Guolin Ke committed
126
  }
127
128
  
  # Check ret length
Guolin Ke's avatar
Guolin Ke committed
129
  if (length(ret) == 0) {
130
131
    
    # Return empty string
132
    lgb.c_str("")
133
    
134
  } else {
135
136
    
    # Return string separated by a space per element
137
    lgb.c_str(paste0(ret, collapse = " "))
138
    
Guolin Ke's avatar
Guolin Ke committed
139
  }
140
  
Guolin Ke's avatar
Guolin Ke committed
141
142
143
}

lgb.c_str <- function(x) {
144
145
  
  # Perform character to raw conversion
Guolin Ke's avatar
Guolin Ke committed
146
147
  ret <- charToRaw(as.character(x))
  ret <- c(ret, as.raw(0))
148
  ret
149
  
Guolin Ke's avatar
Guolin Ke committed
150
151
152
}

lgb.check.r6.class <- function(object, name) {
153
154
  
  # Check for non-existence of R6 class
Guolin Ke's avatar
Guolin Ke committed
155
156
157
  if (!("R6" %in% class(object))) {
    return(FALSE)
  }
158
159
  
  # Check for non-existance of a named class
Guolin Ke's avatar
Guolin Ke committed
160
161
162
  if (!(name %in% class(object))) {
    return(FALSE)
  }
163
164
165
166
  
  # Return default value
  return(TRUE)
  
Guolin Ke's avatar
Guolin Ke committed
167
168
}

169
lgb.check.params <- function(params) {
170
  
Guolin Ke's avatar
Guolin Ke committed
171
  # To-do
172
173
  params # Currently return params because this is not finalized
  
Guolin Ke's avatar
Guolin Ke committed
174
175
176
}

lgb.check.obj <- function(params, obj) {
177
178
179
180
181
  
  # List known objectives in a vector
  OBJECTIVES <- c("regression", "regression_l1", "regression_l2", "huber", "fair", "poisson", "binary", "lambdarank", "multiclass")
  
  # Check whether the objective is empty or not, and take it from params if needed
182
  if (!is.null(obj)) { params$objective <- obj }
183
184
  
  # Check whether the objective is a character
185
  if (is.character(params$objective)) {
186
187
    
    # If the objective is a character, check if it is a known objective
188
    if (!(params$objective %in% OBJECTIVES)) {
189
190
      
      # Interrupt on unknown objective name
191
      stop("lgb.check.obj: objective name error should be one of (", paste0(OBJECTIVES, collapse = ", "), ")")
192
      
Guolin Ke's avatar
Guolin Ke committed
193
    }
194
    
195
  } else if (!is.function(params$objective)) {
196
197
    
    # If objective is not a character nor a function, then stop
198
    stop("lgb.check.obj: objective should be a character or a function")
199
    
Guolin Ke's avatar
Guolin Ke committed
200
  }
201
202
203
204
  
  # Return parameters
  return(params)
  
Guolin Ke's avatar
Guolin Ke committed
205
206
207
}

lgb.check.eval <- function(params, eval) {
208
209
210
211
212
213
214
  
  # Check if metric is null, if yes put a list instead
  if (is.null(params$metric)) {
    params$metric <- list()
  }
  
  # Check if evaluation metric is null, if not then append it
215
  if (!is.null(eval)) {
216
217
    
    # Append metric if character or list
218
    if (is.character(eval) || is.list(eval)) {
219
220
      
      # Append metrics
Guolin Ke's avatar
Guolin Ke committed
221
      params$metric <- append(params$metric, eval)
222
      
Guolin Ke's avatar
Guolin Ke committed
223
    }
224
    
Guolin Ke's avatar
Guolin Ke committed
225
  }
226
227
  
  # Check if evaluation metric is not a function
228
  if (!is.function(eval)) {
229
230
    
    # Check if there is no parameter
231
    if (length(params$metric) == 0) {
232
233
      
      # Add default metric
234
235
      params$metric <- switch(
        params$objective,
236
237
238
239
240
241
242
243
244
245
        regression = "l2", # MSE
        regression_l1 = "l1", # MAE
        regression_l2 = "l2", # MSE
        huber = "l1", # Proxy for MAE
        fair = "l1", # Proxy for MAE
        poisson = "poisson", # Poisson
        binary = "binary_logloss", # Logloss
        multiclass = "multi_logloss", # Multiclass logloss
        lambdarank = "ndcg", # Normalized discounted cumulative gain
        stop("lgb.check.eval: No default metric available for objective ", sQuote(params$objective)) # Unknown objective parameter
246
      )
247
      
Guolin Ke's avatar
Guolin Ke committed
248
    }
249
    
Guolin Ke's avatar
Guolin Ke committed
250
  }
251
252
253
  
  # Return parameters
  return(params)
Guolin Ke's avatar
Guolin Ke committed
254
}