メイン qt2.html   Last modified: Sep 01, 2009
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;CHARSET=EUC-JP">
<link rel="shortcut icon" href="../favicon.ico">
<title>JavaScript</title>
<script src="inv.js">document.write("inv.js ファイルが見つかりません??<br>")</script>
<script src="eigen.js">document.write("eigen.js ファイルが見つかりません??<br>")</script>
<script src="io.js">document.write("io.js ファイルが見つかりません??<br>")</script>

<script language="JavaScript">
<!--

function zfi(w, i)
{
  var ww = (""+i).length
  ww = ww > w ? 0 : w-ww
  return "0000000000000".substring(0, ww)+i
}

function names(str, i)
{
  return str+zfi(2, i+1)
}

function g_names(i)
{
  return "第"+zfi(2, i+1)+"群"
}

function n_sol(m, ne)
{
  var i
  if (isNaN(i = parseFloat(ne)) || i < 1 || i > m) {
    return m
  }
  else {
    return i
  }
}

  var TWO, MAX2
  TWO = 1
  MAX2 = 2

function itemno(item, cat, junjo, data, value, nc)
{
  var i, j, k, nobe, flag0 = 0, flag, work, catj

  for (j = 0; j <= item; j++) {
    catj = flag = 0
    for (i = 0; i < nc; i++) {
      work = data[i][j]
      if (Math.floor(work) != work) {
        if (flag == 0) {
          if (j == item) {
            printf("群を表す変数 %s が,整数値ではありません。\n", names("Var", j))
          }
          else {
            printf("アイテム変数 %s が,整数値ではありません。\n", names("Var", j))
          }
          flag = flag0 = 1
        }
      }
      value[catj][j] = work
      for (k = 0; k <= catj; k++) {
        if (value[k][j] == work) {
          break
        }
      }
      if (k == catj) {
        catj++
        if (catj > 100) {
          if (j == item) {
            printf("群を表す変数 %s の取る値の種類が多すぎます。\n", names("Var", j))
          }
          else {
            printf("アイテム変数 %s の取る値の種類が多すぎます。\n", names("Var", j))
          }
        }
      }
    }
    cat[j] = catj
    if (catj == 1) {
      if (j == item) {
        printf("群を表す変数 %s は,一種類の値しか取りません。群が一つしかないので分析できません。\n", names("Var", j))
      }
      else {
        printf("アイテム変数 %s は,一種類の値しか取りません。この変数は分析に使用しないでください。\n", names("Var", j))
      }
      flag0 = 1
    }
    else if (sort(value, catj, j) == 0) {
      for (i = 0; i < nc; i++) {
        work = data[i][j]
        for (k = 0; k < catj; k++)  {
          if (work != k+1 && work == value[k][j]) {
            data[i][j] = k+1
            break
          }
        }
      }
    }
  }

  if (flag0) {
    return -99
  }
  else {
    nobe = 0
    for (i = 0; i < item; i++) {
      junjo[i] = nobe
      nobe += cat[i]
    }
    return nobe
  }
}

function sort(x, n, ip)
{
  var min, minp, i, j, temp
  for (i = 0; i < n-1; i++) {
    min = x[i][ip]
    minp = i
    for (j = i+1; j < n; j++) {
      if (x[j][ip] < min) {
        min = x[j][ip]
        minp = j
      }
    }
    if (i != minp) {
      temp = x[i][ip]
      x[i][ip] = min
      x[minp][ip] = temp
    }
  }
  for (i = 0; i < n; i++) {
    if (x[i][ip] != i+1) {
      return 0
    }
  }
  return 1
}

function pas1(data, nc, gvar, item, nobe, p, junjo, n, gcros, pcros, ng)
{
  var i, j, k, ng1, ncase = 0

  for (j = 0; j < nobe; j++) {
    for (k = 0; k < nobe; k++) {
      pcros[j][k] = 0
    }
  }
  for (j = 0; j < ng; j++) {
    n[j] = 0
    for (k = 0; k < nobe; k++) {
      gcros[j][k] = 0
    }
  }
  for (i = 0; i < nc; i++) {
      ncase++
      ng1 = data[i][gvar]-1
      n[ng1]++
      for (j = 0; j < nobe; j++) {
        p[j] = 0
      }
      for (j = 0; j < item; j++) {
        p[junjo[j]+data[i][j]-1] = 1
      }
      for (j = 0; j < nobe; j++) {
        if (p[j]) {
          gcros[ng1][j] += p[j]
          for (k = 0; k < nobe; k++) {
            pcros[k][j] += p[k]
          }
        }
      }
  }
  return ncase
}

function makmat(pat, grpat, grgr, r, pcros, gcros, junjo, isw, n, fnc, nobe, ng, item)
{
  var i, j, l, m

  for (i = 0; i < ng; i++) {
    grgr[i][i] = n[i]-n[i]*n[i]/fnc
  }
  for (i = 0; i < ng; i++) {
    for (j = 0; j < i; j++) {
      grgr[i][j] = grgr[j][i] = -n[i]*n[j]/fnc
    }
  }
  for (i = 0; i < ng; i++) {
    for (j = 0; j < nobe; j++) {
      grpat[i][j] = gcros[i][j]-n[i]*pcros[j][j]/fnc
    }
  }
  for (i = 0; i < nobe; i++) {
    for (j = 0; j <= i; j++) {
      pat[i][j] = pat[j][i] = pcros[j][i]-pcros[i][i]*pcros[j][j]/fnc
    }
  }
  for (i = 0; i < nobe; i++) {
    isw[i] = 1
  }
  for (i = 0; i < item; i++) {
    isw[junjo[i]] = 0
  }
  for (i = 0; i < ng-1; i++) {
    for (j = 0; j < ng-1; j++) {
      r[j][i] = grgr[j+1][i+1]
    }
  }
  for (i = 0; i < ng-1; i++) {
    l = 0
    for (j = 0; j < nobe; j++) {
      if (isw[j] == 1) {
        grpat[i][l++] = grpat[i+1][j]
      }
    }
  }
  m = 0
  for (i = 0; i < nobe; i++) {
    if (isw[i] != 0) {
      l = 0
      for (j = 0; j < nobe; j++) {
        if (isw[j] == 1) {
          pat[l++][m] = pat[j][i]
        }
      }
      m++
    }
  }
  return m
}

function catscr(ndim, m, val, vec, pat, grpat, catscore, a, b, pcros, junjo, cat, nobe, fnc, isw, ng, n, item, value)
{
  var i, i1, ie, is, js, je, col, j, j1, k, l, sum, wk, wks, fmt

  for (i = 0; i < ndim; i++) {
    if (val[i] <= 0.0) {
      printf("変数が一次従属です\n")
      return
    }
    wk = Math.sqrt(val[i])
    for (j = 0; j < m; j++) {
      wks = 0.0
      for (i1 = 0; i1 < m; i1++) {
        for (j1 = 0; j1 < ndim; j1++) {
          wks += pat[i1][j]*grpat[j1][i1]*vec[i][j1]
        }
      }
      b[j] = wks/wk
    }
    l = 0
    for (j = 0; j < nobe; j++) {
      a[j] = (isw[j] == 0) ? 0.0 : b[l++]
    }
    for (j = 0; j < item; j++) {
      sum = 0.0
      is = junjo[j]
      ie = junjo[j]+cat[j]
      for (k = is; k < ie; k++) {
        sum += a[k]*pcros[k][k]
      }
      sum /= fnc
      for (k = is; k < ie; k++) {
        b[k] = a[k]-sum
      }
    }
    sum = 0.0
    for (j = 0; j < nobe; j++) {
      for (l = 0; l < nobe; l++) {
        sum += b[j]*b[l]*pcros[l][j]
      }
    }
    sum = Math.sqrt(sum/fnc)
    for (j = 0; j < nobe; j++) {
      catscore[i][j] = b[j]/sum
    }
    a[0] = 0.0
    for (j = 1; j < ng; j++) {
      a[j] = vec[i][j-1]
    }
    sum = 0.0
    for (j = 0; j < ng; j++) {
      sum += a[j]*n[j]
    }
    sum /= fnc
    for (j = 0; j < ng; j++) {
      a[j] -= sum
    }
    sum = 0.0
    for (j = 0; j < ng; j++) {
      sum += a[j]*a[j]*n[j]
    }
    sum = Math.sqrt(sum/fnc/val[i])
    for (j = 0; j < ng; j++) {
      vec[i][j] = a[j]/sum
    }
  }
  printf("\n***** ノーマライズド カテゴリー スコア *****\n")
  col = Math.floor((80-21)/14)
  for (js = je = 0; je != ndim; js = je) {
    je = js+col < ndim ? js+col : ndim
    printf("\nアイテム-カテゴリー")
    for (j = js; j < je; j++) {
      fmt ="%"+(j == js ? 13 : 14)+"s"
      printf(fmt, names("Axis", j))
    }
    printf("\n")
    for (i = 0; i < item; i++) {
      is = junjo[i]
      ie = junjo[i]+cat[i]
      l = 0
      printf("\n")
      for (j = is; j < ie; j++) {
        l++
        if (l == 1) {
          printf("%3i %8s %3s  ", j+1, names("Var", i), value[l-1][i])
          for (k = js; k < je; k++) {
            printf("%14.6g", catscore[k][j])
          }
          printf("\n")
        }
        else {
          printf("%3i          %3s  ", j+1, value[l-1][i])
          for (k = js; k < je; k++) {
            printf("%14.6g", catscore[k][j])
          }
          printf("\n")
        }
      }
    }
    printf("\n%18s\n", "重心")
    for (i = 0; i < ng; i++) {
      printf("%18s", g_names(i))
      for (j = js; j < je; j++) {
        printf("%14.6f", vec[j][i])
      }
      printf("\n")
    }
    if (ng == 2) {
      printf("\n%18s%14.6f\n", "カットポイント", (vec[0][0]+vec[0][1])*0.5)
    }
    printf("\n%10s%8s     ", "", "相関比")
    for (i = js; i < je; i++) {
      fmt = "%"+(i == js ? 9 : 14)+".6f"
      printf(fmt, val[i])
    }
    printf("\n")
  }
}

function partia(ndim, n, vec, pat, item, junjo, cat, ng, catscore, gcros, pcros, grpat)
{
  var i, i1, ie, is, item1, j, j1, je, js, k, l, sum

  for (l = 0; l < ndim; l++) {
    sum = 0.0
    for (i = 0; i < ng; i++) {
      sum += n[i]*vec[l][i]*vec[l][i]
    }
    pat[0][0] = sum
    for (i = 0; i < item; i++) {
      sum = 0.0
      is = junjo[i]
      ie = junjo[i]+cat[i]
      for (j = 0; j < ng; j++) {
        for (k = is; k < ie; k++) {
          sum += vec[l][j]*catscore[l][k]*gcros[j][k]
        }
      }
      pat[0][i+1] = sum
    }
    for (i = 0; i < item; i++) {
      is = junjo[i]
      ie = junjo[i]+cat[i]
      for (j = 0; j <= i; j++) {
        js = junjo[j]
        je = junjo[j]+cat[j]
        sum = 0
        for (i1 = is; i1 < ie; i1++) {
          for (j1 = js; j1 < je; j1++) {
            sum += catscore[l][i1]*catscore[l][j1]*pcros[j1][i1]
          }
        }
        pat[j+1][i+1] = sum
      }
    }
    item1 = item+1
    for (i = 1; i < item1; i++) {
      for (j = 0; j < i; j++) {
        pat[i][j] = pat[j][i] /= Math.sqrt(pat[i][i]*pat[j][j])
      }
    }
    for (i = 0; i < item1; i++) {
      pat[i][i] = 1.0
    }
    if (inv(pat, item1, 1e-8) != 1) {
      for (i = 1; i < item1; i++) {
        grpat[l][i-1] = -pat[i][0]/Math.sqrt(pat[0][0]*pat[i][i])
      }
    }
    else {
      for (i = 1; i < item1; i++) {
        grpat[l][i-1] = 1
      }
    }
  }
  printf("\n***** 偏相関係数 *****\n\nアイテム")
  for (j = 0; j < ndim; j++) {
    printf("%10s", names("Axis", j))
  }
  printf("\n")
  for (i = 0; i < item; i++) {
    printf("%8s", names("Var", i))
    for (l = 0; l < ndim; l++) {
      printf("%10.5f", grpat[l][i])
    }
    printf("\n")
  }
}

function result(k, res)
{
  var i, j, t, total, true_judge
  total = true_judge = 0
    printf("\n★ 判別結果\n\n%"+(k*4+18)+"s\n%11s" , "判別された群", "実際の群")
    for (i = 0; i < k; i++) {
      printf("%8s", g_names(i))
    }
    printf("    合計\n")
  for (i = 0; i < k; i++) {
    t = 0
    for (j = 0; j < k; j++) {
      t += res[j][i]
    }
    total += t
    true_judge += res[i][i]
      printf("  %-9s", g_names(i))
      for (j = 0; j < k; j++) {
        printf("%8i", res[j][i])
      }
      printf("%8i\n      %    ", t)
      for (j = 0; j < k; j++) {
        printf(" (%5.1f)", res[j][i]/t*100.0)
      }
      printf(" (100.0)\n")
    }
    printf("\n%30s%.2f%\n", "正判別率 ・・・ ", true_judge/total*100.0)
}

function sampsc(ng, ndim, data, nc, gvar, nobe, p, item, junjo, a, catscore, vec, res, n_axis)
{
  var mark, i, iig, j, l, ng1, dis, dismin, temp, dfva, ndim2

  for (i = 0; i < ng; i++) {
    for (j = 0; j < ng; j++) {
      res[i][j] = 0
    }
  }

  if (ng == 2) {
    dfva = makeVector(nc)
  }
  else if (ng <= 12) {
    ndim2 = ndim < 5 ? ndim : 5
  }

  printf("\n***** サンプルスコア *****\n\nケース  R     P ")
  for (j = 0; j < ndim; j++) {
    printf("%10s", names("Axis", j))
  }
  printf("\n")
  for (i = 0; i < nc; i++) {
      ng1 = data[i][gvar]-1

      for (j = 0; j < nobe; j++) {
        p[j] = 0
      }
      for (j = 0; j < item; j++) {
        p[junjo[j]+data[i][j]-1] = 1
      }
      for (l = 0; l < ndim; l++) {
        a[l] = 0
        for (j = 0; j < nobe; j++) {
          a[l] += p[j]*catscore[l][j]
        }
      }
      dismin = 1e300
      for (l = 0; l < ng; l++) {
        dis = 0.0
        for (j = 0; j < n_axis; j++) {
          temp = vec[j][l]-a[j]
          dis += temp*temp
        }
        if (dis < dismin) {
          dismin = dis
          iig = l
        }
      }
      if (ng1 != 32767) {
        res[iig][ng1]++
      }
      mark = "  "
      if (ng1 != iig) {
        mark = "##"
      }
      printf("%6i%3s%3s%3i ", i+1, ng1+1, mark, iig+1)
      for (l = 0; l < ndim; l++) {
        printf("%10.5f", a[l])
      }
      printf("\n")
      if (ng == 2) {
        dfva[i] = a[0]
      }
  }
  if (n_axis > 1 || ndim > 1) {
    printf("\n判別には %i 個の解が使われました。\n", n_axis)
  }
  result(ng, res)
}

function geneig(a, b, n, ne, nv, e, v)
{
  var i, j, k, nev, neva, nvec, r, sum, t, t1

  nev = ne
  neva = Math.abs(nev)
  nvec = nv
  if (n == 0 || neva == 0 || n < neva || nvec == 0 || neva < nvec) {
    return 1
  }
  if (n == 1) {
    t = b[0][0]
    if (t <= 0.0) {
      return 1
    }
    e[0] = a[0][0]/t
    v[0][0] = 1.0
    return 0
  }
  t = b[0][0]
  if (t <= 0.0) {
    return 1
  }
  t = Math.sqrt(1.0/t)
  b[0][0] = t
  for (i = 1; i < n; i++) {
    b[i][0] = b[0][i]*t
  }
  for (r = 1; r < n; r++) {
    sum = 0.0
    for (k = 0; k < r; k++) {
      t = b[r][k]
      sum += t*t
    }
    t = b[r][r]-sum
    if (t <= 0) {
      return 1
    }
    t = Math.sqrt(1.0/t)
    b[r][r] = t
    if (r >= n-1) {
      break
    }
    for (i = r+1; i < n; i++) {
      sum = 0.0
      for (k = 0; k < r; k++) {
        sum += b[i][k]*b[r][k]
      }
      b[i][r] = (b[r][i]-sum)*t
    }
  }
  for (j = 0; j < n; j++) {
    a[j][0] = a[0][j]*b[0][0]
  }
  for (j = 0; j < n; j++) {
    for (r = 1; r < n; r++) {
      sum = 0.0
      for (k = 0; k < r; k++) {
        sum += b[r][k]*a[j][k]
      }
      a[j][r] = (a[j][r]-sum)*b[r][r]
    }
  }
  for (j = 0; j < n; j++) {
    a[0][j] *= b[0][0]
  }
  for (r = 1; r < n; r++) {
    t1 = b[r][r]
    for (k = 0; k < r; k++) {
      t = -b[r][k]
      for (j = r; j < n; j++) {
        a[r][j] += a[k][j]*t
      }
    }
    for (j = r; j < n; j++) {
      a[r][j] *= t1
    }
  }
  if (eigen(a, nvec, nvec, 1e-10, e, v) == 1) {
    return 1
  }
  if (nvec != 0) {
    for (j = 0; j < nvec; j++) {
      for (k = n-1; k >= 0; k--) {
        t = v[j][k]*b[k][k]
        v[j][k] = t
        for (r = 0; r < k; r++) {
          v[j][r] -= b[k][r]*t
        }
      }
    }
  }
  return 0
}

function pas2(ncase, item, ng, grgr, n, nobe, grpat, gcros, pcros, pat, isw, junjo, r, c, val, vec, catscore, cat, a, b, value)
{
  var i, i1, j, j1, m, fnc, temp, ndim

  fnc = ncase
  m = makmat(pat, grpat, grgr, r, pcros, gcros, junjo, isw, n, fnc, nobe, ng, item)
  ndim = ng-1
  if (inv(pat, m, 1e-8) == 1) {
    printf("逆行列が求まりません。\n")
    return -99
  }
  for (i = 0; i < ndim; i++) {
    for (j = 0; j <= i; j++) {
      temp = 0.0
      for (i1 = 0; i1 < m; i1++) {
        for (j1 = 0; j1 < m; j1++) {
          temp += grpat[i][i1]*pat[j1][i1]*grpat[j][j1]
        }
      }
      c[i][j] = c[j][i] = temp
    }
  }
  if (geneig(c, r, ndim, ndim, ndim, val, vec) == 1) {
    printf("一般化固有値問題が解けません。\n")
    return -99
  }
  catscr(ndim, m, val, vec, pat, grpat, catscore, a, b, pcros, junjo, cat, nobe, fnc, isw, ng, n, item, value)
  return ndim
}

function calc(data_string, ne0)
{
  var cat, isw, junjo, p, n, pcros, gcros, res, i, ndim, n_axis, item, gvar, ng, nobe
  var value, one_cat, ncase, a, b, val, c, catscore, r, pat, grpat, grgr, vec
  var nc, nv, data

  printf("★ 数量化 II 類 ★\n\n")
  if ((data = getdata(data_string, 0)) == false) return
  nc = data.length
  nv = data[0].length
  
  if (nc < 2) {
    printf("ケース数が1以下です\n")
    return
  }

  item = gvar = nv-1

  cat = makeVector(nv)
  junjo = makeVector(nv)
  value = makeMatrix(100, nv)

  nobe = itemno(item, cat, junjo, data, value, nc)
  if (nobe <= 0) {
    printf("データをチェックしてください\n")
    return
  }
  else if (nobe > 500) {
    printf("カテゴリー数が多すぎます\n")
    return
  }
  ng = cat[item]
  n_axis = n_sol(ng-1, ne0)

  n = makeVector(ng)
  val = makeVector(ng)

  grgr = makeMatrix(ng, ng)
  r = makeMatrix(ng, ng)
  vec = makeMatrix(ng, ng)
  c = makeMatrix(ng, ng)
  res = makeMatrix(ng, ng)

  a = makeVector(nobe)
  b = makeVector(nobe)
  p = makeVector(nobe)
  isw = makeVector(nobe)
  grpat = makeMatrix(ng, nobe)
  catscore = makeMatrix(ng, nobe)
  gcros = makeMatrix(ng, nobe)
  pat = makeMatrix(nobe, nobe)
  pcros = makeMatrix(nobe, nobe)

  ncase = pas1(data, nc, gvar, item, nobe, p, junjo, n, gcros, pcros, ng)
  if (ncase <= 0) {
    printf("データを見直してください。\n");
    return
  }
  one_cat = false
  printf("有効ケース数:  %i\n\n", ncase)
  printf("群を表す変数:   %8s\n", names("Var", gvar))
  for (i = 0; i < ng; i++) {
    printf("           %s: %s = %s\n", g_names(i), names("Var", gvar), value[i][gvar])
  }
  printf("\n説明変数:       アイテム  カテゴリー数\n")
  for (i = 0; i < item; i++) {
    printf("%16s%8s %9i\n", "", names("Var", i), cat[i])
    if (cat[i] == 1) {
      one_cat = true
    }
  }
  if (one_cat == true) {
    printf("カテゴリーが一つしかない変数がありました\n")
    return
  }
  ndim = pas2(ncase, item, ng, grgr, n, nobe, grpat, gcros, pcros, pat, isw, junjo, r, c, val, vec, catscore, cat, a, b, value)
  if (ndim > 0) {
    partia(ndim, n, vec, pat, item, junjo, cat, ng, catscore, gcros, pcros, grpat)
    sampsc(ng, ndim, data, nc, gvar, nobe, p, item, junjo, a, catscore, vec, res, n_axis)
  }
}
//-->
</script>
</head>

<body bgcolor="#ffffff">
<font size="+2"><b>数量化 II 類</b></font> <a  href="src/qt2.html"><img src="png/src.png" width=35 height=11 alt="src" align=top></a>     Last modified: Jun 01, 2006<hr noshade><p>
<font color="#ff0000" size="+2">以下のプログラムのサポートは終了しました。自己責任でお使い下さい。</font>

<form name=Result>
<script language="JavaScript">
<!--
//-->JavaScript がサポートされていないブラウザですか?
</script>
<table><tr>
<td><input type="button" name="calcurate" value="計算開始" onClick="calc(this.form.data.value, this.form.ne.value)">  </td>
<td><input type="button" name="clear" value="入力欄クリア" onClick="this.form.data.value=this.form.ne.value=''">  </td>
<td><input type="button" name="clear" value="出力欄クリア" onClick="this.form.result.value=''">  </td>
<td nowrap><img src="../gra/button3.png" width=9 height=9 alt="・"> <a href="exa/qt2.html">使用法</a></td>
</tr></table>

<p>
判別に使用する解の個数<input name="ne" value="" size=5>(省略時は「
群の数-1」)<br>
入力欄<br><textarea name="data" ROWS=20 COLS=80></textarea><p>
出力欄<br><textarea name="result" ROWS=30 COLS=80></textarea>
</form>

<p><hr noshade>
<img src="../gra/button3.png" width=9 height=9 alt="・"> <a href="../lecture/Qt/qt2.html">手法の解説</a><br>
<img src="../gra/button3.png" width=9 height=9 alt="・"> <A HREF="javascript:history.go(-1)">直前のページへ戻る</A>  <img src="../gra/button3.png" width=9 height=9 alt="・"> <a href="../mail.html">E-mail to Shigenobu AOKI</a>
<p><center><IMG SRC="../gra/ume5.png" width=121 height=37 ALT="Made with Macintosh"></center>
</body>
</html>

サブ inv.js   Last modified: Mar 25, 2004
サブ eigen.js   Last modified: Mar 25, 2004
サブ io.js   Last modified: Mar 25, 2004

・ 直前のページへ戻る  ・ E-mail to Shigenobu AOKI

Made with Macintosh