(k int, r [][]float64, p []float64)
| 1645 | } |
| 1646 | |
| 1647 | func (this *SVM) multiclass_probability(k int, r [][]float64, p []float64) { |
| 1648 | var t, j int |
| 1649 | iter := 0 |
| 1650 | max_iter := math.Max(100, float64(k)) |
| 1651 | Q := make([][]float64, k) |
| 1652 | for i := range Q { |
| 1653 | Q[i] = make([]float64, k) |
| 1654 | } |
| 1655 | Qp := make([]float64, k) |
| 1656 | var pQp float64 |
| 1657 | eps := float64(0.005) / float64(k) |
| 1658 | |
| 1659 | for t = 0; t < k; t++ { |
| 1660 | p[t] = float64(1.0) / float64(k) // Valid if k = 1 |
| 1661 | Q[t][t] = 0 |
| 1662 | for j = 0; j < t; j++ { |
| 1663 | Q[t][t] += r[j][t] * r[j][t] |
| 1664 | Q[t][j] = Q[j][t] |
| 1665 | } |
| 1666 | for j = t + 1; j < k; j++ { |
| 1667 | Q[t][t] += r[j][t] * r[j][t] |
| 1668 | Q[t][j] = -r[j][t] * r[t][j] |
| 1669 | } |
| 1670 | } |
| 1671 | for iter = 0; iter < int(max_iter); iter++ { |
| 1672 | // stopping condition, recalculate QP,pQP for numerical accuracy |
| 1673 | pQp = 0 |
| 1674 | for t = 0; t < k; t++ { |
| 1675 | Qp[t] = 0 |
| 1676 | for j = 0; j < k; j++ { |
| 1677 | Qp[t] += Q[t][j] * p[j] |
| 1678 | } |
| 1679 | pQp += p[t] * Qp[t] |
| 1680 | } |
| 1681 | max_error := float64(0) |
| 1682 | for t = 0; t < k; t++ { |
| 1683 | error := math.Abs(Qp[t] - pQp) |
| 1684 | if error > max_error { |
| 1685 | max_error = error |
| 1686 | } |
| 1687 | } |
| 1688 | if max_error < eps { |
| 1689 | break |
| 1690 | } |
| 1691 | |
| 1692 | for t = 0; t < k; t++ { |
| 1693 | diff := (-Qp[t] + pQp) / Q[t][t] |
| 1694 | p[t] += diff |
| 1695 | pQp = (pQp + diff*(diff*Q[t][t]+2*Qp[t])) / (1 + diff) / (1 + diff) |
| 1696 | for j = 0; j < k; j++ { |
| 1697 | Qp[j] = (Qp[j] + diff*Q[t][j]) / (1 + diff) |
| 1698 | p[j] /= (1 + diff) |
| 1699 | } |
| 1700 | } |
| 1701 | } |
| 1702 | if iter >= int(max_iter) { |
| 1703 | log.Println("Exceeds max_iter in multiclass_prob") |
| 1704 | } |
no outgoing calls
no test coverage detected