机器学习,它主要是一组统计算法,基于现有数据,能够从中获得洞察力。这些算法基本上分为两个系列,监督学习和非监督学习。
1、在监督学习中,目标是执行某种预测。
2、无监督学习侧重于回答我的案例如何分组的问题
下面介绍如何使用数据库进行机器学习,逐步实现KMeans
1. 加载数据样例
本示例,我们将使用知名的鸢尾花数据,首先我们下载数据(https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data)到本地。
接下创建iris 表:
CREATE TABLE iris(sepal_length REAL,sepal_width REAL,petal_length REAL,petal_width REAL,species varchar(20));
导入刚下载的数据
COPY iris FROM '/path/to/iris.data' DELIMITER ',';
2. 安装依赖
* Python:目前有两个主要的版本,2.7和3.7。
* PL/Python:对应Python 2和Python 3,也有两个版本的plpython,分别是plpython2u和plpython3u,你可以选择一个,或者同时安装。
* 安装额外的Python组件:使用你喜欢的Python包管理器(pip,conda等等)来安装scikit-learn和pandas。顺便说下,如果你想使用Python进行机器学习,这两个包都是必须的。
pip install sklearn pandas
安装好之后就可以创建插件了。
CREATE EXTENSION plpythonu, 如果使用的python3 这里通过CREATE EXTENSION plpythonu3;
3、kmeans
创建函数
CREATE OR replace FUNCTION kmeans(input_table text, columns text[], clus_num int) RETURNS bytea AS
$$
from pandas import DataFrame
from sklearn.cluster import KMeans
from cPickle import dumps
all_columns = ",".join(columns)
if all_columns == "":
all_columns = "*"
rv = plpy.execute('SELECT %s FROM %s;' % (all_columns, plpy.quote_ident(input_table)))
frame = []
for i in rv:
frame.append(i)
df = DataFrame(frame).convert_objects(convert_numeric =True)
kmeans = KMeans(n_clusters=clus_num, random_state=0).fit(df._get_numeric_data())
return dumps(kmeans)
$$ LANGUAGE plpythonu;
4、保存模型
CREATE TABLE models (
id SERIAL PRIMARY KEY,
model BYTEA NOT NULL
);
INSERT INTO models(model) SELECT kmeans('iris', array[]::text[], 3);
5. 显示模型信息
select * from models;
但是如果通过这种方式进行查询,直接从数据库中获取它并不是很有用,需要回到Python以显示有关我们模型的有用信息。
创建如下函数进行显示
CREATE OR replace FUNCTION get_kmeans_centroids(
model_table text, model_column text, model_id int)
RETURNS real[] AS
$$
from pandas import DataFrame
from cPickle import loads
rv = plpy.execute('SELECT %s FROM %s WHERE id = %s;' %
(plpy.quote_ident(model_column),
plpy.quote_ident(model_table), model_id))
model = loads(rv[0][model_column])
ret = map(list, model.cluster_centers_)
return ret
$$ LANGUAGE plpythonu;
--查询数据
select get_kmeans_centroids('models','model',1);
6、预测, 这也是机器学习中的价值所在
现在我们有了一个模型,让我们用它来做预测! 在kmeans中,这意味着传递一组值(对应于每个变量)并获取它所属的组号。 该函数与前一个函数非常相似:
CREATE OR replace FUNCTION predict_kmeans(
model_table text, model_column text
, model_id int, input_values real[])
RETURNS int[] AS
$$
from cPickle import loads
rv = plpy.execute('SELECT %s FROM %s WHERE id = %s;' %
(plpy.quote_ident(model_column)
, plpy.quote_ident(model_table)
, model_id))
model = loads(rv[0][model_column])
ret = model.predict(input_values)
return ret
$$ LANGUAGE plpythonu;
下面带入需要预测的数据
select predict_kmeans('models','model',1,array[[0.5,0.5,0.5,0.5]]);
执行返回结果如下:
# {1}
解释一下这个预测:鸢尾花数据集内包含 3 类共 150 条记录,每类各 50 个数据,每条记录都有 4 项特征:花萼长度、花萼宽度、花瓣长度、花瓣宽度,可以通过这4个特征预测鸢尾花卉属于(iris-setosa, iris-versicolour, iris-virginica)中的哪一品种。