Varchar值为数值分类

时间:2011-07-01 10:14:57

标签: php mysql data-mining classification

我有一个包含三个表的数据库:

  1. 练习 - 8个领域
  2. 患者 - 47个字段
  3. 恶化 - 11个领域
  4. 这些表中的大多数字段以varchar格式记录,其他字段包括整数,双精度和日期。

    我必须将此数据转换为数字分类数据,以便统计人员可以使用它来推断数据中的任何模式。为了实现这一点,我必须将varchar字段转换为表示字符串所属分类的整数,例如“Severity”,它具有以下可能的字符串值:

    1. 轻度
    2. 中等
    3. 严重
    4. 非常严重
    5. 在Patient表中的这个字段有一个可以出现的字符串值的有限列表,其他字段具有无限可能的字符串值,在我的数据库遇到它们之前无法对其进行分类(除非我实现某种形式的智能方法)

      暂时我只想构建将3个表中每个表中的所有条目的每个字段转换为数值的最佳方法。到目前为止,我头脑中的伪代码如下(它不完整):

       function profileDatabase 
         for each table in database 
           for each field that is of type varchar
             select all distinct values and insert into classfication table for that field
           end for
         end for
      
       function classifyDatabase
         for each table in database 
           for each field that is of type varchar
             // do something efficient to build an insert string to place into new table
           end for
         end for
      

      有人可以建议执行此过程的最佳方式,以便有效地给出目前超过100个实践,15,000名患者和55,000个系统恶化。我没有必要在PHP中实现它,我希望这样做。关于如何构建这个的任何指示都会很棒,因为我不确定我的方法是最好的方法。

      随着数据库的增长,这个过程将在未来两年每个月运行一次,总共有100,000名患者。

2 个答案:

答案 0 :(得分:0)

也许http://dev.mysql.com/doc/refman/5.1/en/procedure-analyse.html有助于概述如何使用字段。

答案 1 :(得分:0)

我已经设法为这个问题构建了自己的解决方案,并在合理的时间内运行。对于任何感兴趣的人,或者任何可能遇到类似问题的人都是我使用过的方法:

通过调用php scriptName.php [database-name]作为cron作业运行的PHP脚本。该脚本为数据库中的每个表名构建一个分类表(不是此进程的查找表)。设置每个分类会创建一个新表,该表模仿基表的格式,但将所有字段设置为允许NULL值。然后,它为基表中找到的每个行创建空行。然后,该过程通过按字段分析每个表并使用该字段的正确类更新每一行来继续。

我确信我可以优化此功能以改善当前的复杂性,但是现在我将使用这种方法,直到脚本的运行时间超出可接受的范围。

脚本代码:     

include ("../application.php");

profileDatabase("coco");
classifyDatabase("coco");

function profileDatabase($database) {
    mysql_select_db($database);
    $query = "SHOW TABLES";
    $result = db_query($query);
    $dbProfile = array();
    while ($obj = mysql_fetch_array($result)) {
        if (!preg_match("/_/", $obj[0])) {
            $dbProfile[$obj[0]] = profileTable($obj[0]);
        }
    }
    return $dbProfile;
}

function profileTable($table) {
    $tblProfile = array();
    $query = "DESCRIBE $table";
    $result = db_query($query);
    while ($obj = mysql_fetch_array($result)) {
        $type = substr($obj[1], 0, 7);
//echo $type;
        if (preg_match("/varchar/", $obj[1]) && (!preg_match("/Id/", $obj[0]) && !preg_match("/date/", $obj[0]) && !preg_match("/dob/", $obj[0]))) {
            $x = createLookup($obj[0], $table);
            $arr = array($obj[0], $x);
            $tblProfile[] = $arr;
        }
    }
    return $tblProfile;
}

function getDistinctValues($field, $table) {
    $distinct = array();
    $query = "SELECT DISTINCT $field as 'value', COUNT($field) as 'no' FROM $table GROUP BY $field ORDER BY no DESC";
    $result = db_query($query);
    while ($obj = mysql_fetch_array($result)) {
        $distinct[] = $obj;
    }
    return $distinct;
}

function createLookup($field, $table) {
    $query = "CREATE TABLE IF NOT EXISTS `" . $table . "_" . $field . "`
(
`id` int(5) NOT NULL auto_increment,
`value` varchar(255) NOT NULL,
`no` int(5) NOT NULL,
`map1` int(3) NOT NULL,
`map2` int(3) NOT NULL,
PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1";
    db_query($query);
    $distinct = getDistinctValues($field, $table);
    $count = count($distinct);
    foreach ($distinct as $val) {
        $val['value'] = addslashes($val['value']);
        $rs = db_query("SELECT id FROM " . $table . "_" . $field . " WHERE value = '" . $val['value'] . "' LIMIT 1");
        if (mysql_num_rows($rs) == 0) {
            $sql = "INSERT INTO " . $table . "_" . $field . " (value,no) VALUES ('" . $val['value'] . "', " . $val['no'] . ")";
        } else {
            $sql = "UPDATE " . $table . "_" . $field . " (value,no) VALUES ('" . $val['value'] . "', " . $val['no'] . ")";
        }
        db_query($sql);
    }
    return $count;
}

function classifyDatabase($database) {
    mysql_select_db($database);
    $query = "SHOW TABLES";
    $result = db_query($query);
    $dbProfile = array();
    while ($obj = mysql_fetch_array($result)) {
        if (!preg_match("/_/", $obj[0])) {
            classifyTable($obj[0]);
            //echo "Classfied $obj[0]\n";
        }
    }
}

function classifyTable($table) {
    $query = "SHOW TABLES";
    $result = db_query($query);
    $dbProfile = array();
    $setup = true;
    while ($obj = mysql_fetch_array($result)) {
        if ($obj[0] == "classify_" . $table)
            $setup = false;
    }
    if ($setup) {
        setupClassifyTable($table);
        //echo "Setup $table\n";
    }

    $query = "DESCRIBE $table";
    $result = db_query($query);
    while ($obj = mysql_fetch_array($result)) {
        if (preg_match("/varchar/", $obj[1]) && (!preg_match("/Id/", $obj[0]) && !preg_match("/date/", $obj[0]) && !preg_match("/dob/", $obj[0]))) {
            $rs = db_query("
        SELECT t.entryId, t.$obj[0], COALESCE(tc.map1,99) as 'group' FROM $table t 
        LEFT JOIN " . $table . "_$obj[0] tc ON t.$obj[0] = tc.value 
        ORDER BY tc.map1 ASC");
            while ($obj2 = mysql_fetch_object($rs)) {
                $sql = "UPDATE classify_$table SET $obj[0] = $obj2->group WHERE entryId = $obj2->entryId";
                db_query($sql);
            }
        } else {
            if ($obj[0] != "entryId") {
                $rs = db_query("
        SELECT t.entryId, t.$obj[0] as 'value' FROM $table t");
                while ($obj2 = mysql_fetch_object($rs)) {
                    $sql = "UPDATE classify_$table SET $obj[0] = '" . addslashes($obj2->value) . "' WHERE entryId = $obj2->entryId";
                    db_query($sql);
                }
            }
        }
    }
}

function setupClassifyTable($table) {
    $tblProfile = array();
    $query = "DESCRIBE $table";
    $result = db_query($query);
    $create = "CREATE TABLE IF NOT EXISTS `classify_$table` (";
    while ($obj = mysql_fetch_array($result)) {
        if (preg_match("/varchar/", $obj[1]) && (!preg_match("/Id/", $obj[0]) && !preg_match("/date/", $obj[0]) && !preg_match("/dob/", $obj[0]))) {
            //echo $obj[1]. " matches<br/>";
            $create .= "$obj[0] int(3) NULL,";
        } else {
            $create .= "$obj[0] $obj[1] NULL,";
        }
    }
    $create .= "PRIMARY KEY(`entryId`)) ENGINE=MyISAM DEFAULT CHARSET=latin1";
    db_query($create);
    $result = mysql_query("SELECT entryId FROM $table");
    while ($obj = mysql_fetch_object($result)) {
        db_query("INSERT IGNORE INTO classify_$table (entryId) VALUES ($obj->entryId)");
    }
}

?>