Драйвер MongoDB, поддерживающий PHP 7, был выпущен только 22 декабря - его вероятные последующие репозитории, такие как пиво, не обновились.
Обновление подтверждено, что в настоящее время нет php70-mongo
скрипт, хотя есть активный запрос pull , чтобы добавить его.
Вы можете установить его вручную через pecl тем временем:
pecl channel-update pecl.php.net
pecl install mongodb
echo "extension=mongodb.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`
Качество кластеризации текста зависит главным образом от двух факторов:
Некоторые понятия сходства между документами, которые вы хотите кластеризовать. Например, легко отличить новостные статьи о спорте и политике в векторном пространстве через tfidf-cosine-distance. На основе этой меры намного сложнее объединить обзоры продуктов в «хорошие» или «плохие».
Сам метод кластеризации. Вы знаете, сколько будет кластеров? Хорошо, используйте kmeans. Вы не заботитесь о точности, но хотите показать красивую древовидную структуру для навигации по результатам поиска? Используйте некоторую иерархическую кластеризацию.
Не существует решения для кластеризации текста, которое бы хорошо работало при любых обстоятельствах. И поэтому, вероятно, недостаточно взять какое-либо программное обеспечение для кластеризации из коробки и выбросить в него свои данные.
Сказав это, вот некоторый экспериментальный код, который я использовал некоторое время назад, чтобы поиграть с кластеризацией текста. Документы представлены в виде нормализованных tfidf-векторов, а сходство измеряется как косинусное расстояние. Сам метод кластеризации - это Majorclust .
import sys
from math import log, sqrt
from itertools import combinations
def cosine_distance(a, b):
cos = 0.0
a_tfidf = a["tfidf"]
for token, tfidf in b["tfidf"].iteritems():
if token in a_tfidf:
cos += tfidf * a_tfidf[token]
return cos
def normalize(features):
norm = 1.0 / sqrt(sum(i**2 for i in features.itervalues()))
for k, v in features.iteritems():
features[k] = v * norm
return features
def add_tfidf_to(documents):
tokens = {}
for id, doc in enumerate(documents):
tf = {}
doc["tfidf"] = {}
doc_tokens = doc.get("tokens", [])
for token in doc_tokens:
tf[token] = tf.get(token, 0) + 1
num_tokens = len(doc_tokens)
if num_tokens > 0:
for token, freq in tf.iteritems():
tokens.setdefault(token, []).append((id, float(freq) / num_tokens))
doc_count = float(len(documents))
for token, docs in tokens.iteritems():
idf = log(doc_count / len(docs))
for id, tf in docs:
tfidf = tf * idf
if tfidf > 0:
documents[id]["tfidf"][token] = tfidf
for doc in documents:
doc["tfidf"] = normalize(doc["tfidf"])
def choose_cluster(node, cluster_lookup, edges):
new = cluster_lookup[node]
if node in edges:
seen, num_seen = {}, {}
for target, weight in edges.get(node, []):
seen[cluster_lookup[target]] = seen.get(
cluster_lookup[target], 0.0) + weight
for k, v in seen.iteritems():
num_seen.setdefault(v, []).append(k)
new = num_seen[max(num_seen)][0]
return new
def majorclust(graph):
cluster_lookup = dict((node, i) for i, node in enumerate(graph.nodes))
count = 0
movements = set()
finished = False
while not finished:
finished = True
for node in graph.nodes:
new = choose_cluster(node, cluster_lookup, graph.edges)
move = (node, cluster_lookup[node], new)
if new != cluster_lookup[node] and move not in movements:
movements.add(move)
cluster_lookup[node] = new
finished = False
clusters = {}
for k, v in cluster_lookup.iteritems():
clusters.setdefault(v, []).append(k)
return clusters.values()
def get_distance_graph(documents):
class Graph(object):
def __init__(self):
self.edges = {}
def add_edge(self, n1, n2, w):
self.edges.setdefault(n1, []).append((n2, w))
self.edges.setdefault(n2, []).append((n1, w))
graph = Graph()
doc_ids = range(len(documents))
graph.nodes = set(doc_ids)
for a, b in combinations(doc_ids, 2):
graph.add_edge(a, b, cosine_distance(documents[a], documents[b]))
return graph
def get_documents():
texts = [
"foo blub baz",
"foo bar baz",
"asdf bsdf csdf",
"foo bab blub",
"csdf hddf kjtz",
"123 456 890",
"321 890 456 foo",
"123 890 uiop",
]
return [{"text": text, "tokens": text.split()}
for i, text in enumerate(texts)]
def main(args):
documents = get_documents()
add_tfidf_to(documents)
dist_graph = get_distance_graph(documents)
for cluster in majorclust(dist_graph):
print "========="
for doc_id in cluster:
print documents[doc_id]["text"]
if __name__ == '__main__':
main(sys.argv)
Для реальных приложений вы бы использовали приличный токенизатор, использовали бы целые числа вместо строк токенов и не вычисляли O (n ^ 2) дистанционную матрицу ...
Кажется возможным, используя простые инструменты командной строки UNIX для извлечения текстового содержимого этих документов в текстовые файлы, а затем используя чистое решение Python для фактической кластеризации.
Я обнаружил фрагмент кода для кластеризации данных в целом:
http://www.daniweb.com/code/snippet216641.html
Пакет Python для этого:
http://python-cluster.sourceforge.net /
Другой пакет python (используемый в основном для биоинформатики):
http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/software.htm#pycluster