lib/rumale/kernel_machine/kernel_svc.rb in rumale-0.12.0 vs lib/rumale/kernel_machine/kernel_svc.rb in rumale-0.12.1

- old
+ new

@@ -77,49 +77,33 @@ check_label_array(y) check_sample_label_size(x, y) @classes = Numo::Int32[*y.to_a.uniq.sort] n_classes = @classes.size - _n_samples, n_features = x.shape + n_features = x.shape[1] if n_classes > 2 @weight_vec = Numo::DFloat.zeros(n_classes, n_features) @prob_param = Numo::DFloat.zeros(n_classes, 2) - if enable_parallel? - # :nocov: - models = parallel_map(n_classes) do |n| - bin_y = Numo::Int32.cast(y.eq(@classes[n])) * 2 - 1 - w = binary_fit(x, bin_y) - p = if @params[:probability] - Rumale::ProbabilisticOutput.fit_sigmoid(x.dot(w), bin_y) - else - Numo::DFloat[1, 0] - end - [w, p] - end - # :nocov: - n_classes.times { |n| @weight_vec[n, true], @prob_param[n, true] = models[n] } - else - n_classes.times do |n| - bin_y = Numo::Int32.cast(y.eq(@classes[n])) * 2 - 1 - @weight_vec[n, true] = binary_fit(x, bin_y) - @prob_param[n, true] = if @params[:probability] - Rumale::ProbabilisticOutput.fit_sigmoid(x.dot(@weight_vec[n, true].transpose), bin_y) - else - Numo::DFloat[1, 0] - end - end - end + models = if enable_parallel? + # :nocov: + parallel_map(n_classes) do |n| + bin_y = Numo::Int32.cast(y.eq(@classes[n])) * 2 - 1 + partial_fit(x, bin_y) + end + # :nocov: + else + Array.new(n_classes) do |n| + bin_y = Numo::Int32.cast(y.eq(@classes[n])) * 2 - 1 + partial_fit(x, bin_y) + end + end + models.each_with_index { |model, n| @weight_vec[n, true], @prob_param[n, true] = model } else negative_label = y.to_a.uniq.min bin_y = Numo::Int32.cast(y.ne(negative_label)) * 2 - 1 - @weight_vec = binary_fit(x, bin_y) - @prob_param = if @params[:probability] - Rumale::ProbabilisticOutput.fit_sigmoid(x.dot(@weight_vec.transpose), bin_y) - else - Numo::DFloat[1, 0] - end + @weight_vec, @prob_param = partial_fit(x, bin_y) end self end @@ -195,11 +179,11 @@ nil end private - def binary_fit(x, bin_y) + def partial_fit(x, bin_y) # Initialize some variables. n_training_samples = x.shape[0] rand_ids = [] weight_vec = Numo::DFloat.zeros(n_training_samples) sub_rng = @rng.dup @@ -211,10 +195,16 @@ # update the weight vector func = (weight_vec * bin_y).dot(x[target_id, true].transpose).to_f func *= bin_y[target_id] / (@params[:reg_param] * (t + 1)) weight_vec[target_id] += 1.0 if func < 1.0 end - weight_vec * bin_y + w = weight_vec * bin_y + p = if @params[:probability] + Rumale::ProbabilisticOutput.fit_sigmoid(x.dot(w), bin_y) + else + Numo::DFloat[1, 0] + end + [w, p] end end end end