Obtenez les informations sur le livre sur le site Web O'Reilly Japon, Classons les livres par regroupement non hiérarchique à partir des informations acquises. La procédure est la suivante. ・ Accédez aux informations détaillées du livre à partir de la première page du Web Obtenez le texte de cette introduction dans une liste ・ Pour chaque livre, les phrases de cette introduction sont décomposées en niveaux de mots et chaque mot est pondéré. ・ Sur la base des informations ci-dessus, classez les livres en les regroupant Le langage utilise Python.
clustering.py
#coding:utf-8
import numpy as np
import mechanize
import MeCab
import util
import re
from bs4 import BeautifulSoup
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
from sklearn.cluster import AffinityPropagation
# get O'Reilly new books from Top page
page = mechanize.Browser()
page.open('http://www.oreilly.co.jp/index.shtml')
response = page.response()
soup = BeautifulSoup(response.read(), "html.parser")
allBookLinks = []
bibloLinks = soup.find_all("p", class_="biblio_link")
for bibloLink in bibloLinks:
books = bibloLink.find_all("a", href=re.compile("http://www.oreilly.co.jp/books/"))
for book in books:
allBookLinks.append( book.get("href") )
clustering.py
def get_detail_sentence_list( detailPageLink ):
page.open( detailPageLink )
detailResponse = page.response()
detailSoup = BeautifulSoup( detailResponse.read(), "html.parser" )
# get title
titleTag = detailSoup.find("h3", class_="title")
title = titleTag.get_text().encode('utf-8')
# get detail
detailDiv = detailSoup.find("div", id="detail")
detail = detailDiv.find("p").get_text().encode('utf-8')
# get relation book links
relationLinks = detailDiv.find_all("a")
relationLinkList = []
for relationLink in relationLinks:
href = relationLink.get("href")
if href.find('/books/') > 0:
relationLinkList.append(href[href.find('/books/') + len('/books/'):])
return [ title, detail, relationLinkList ]
# crolling books info
titleList = []
inputDatas = []
for bookLink in allBookLinks:
title, detail, relationLinkList = get_detail_sentence_list( bookLink )
# save
if not (title in titleList):
titleList.append(title)
inputDatas.append( detail )
# go to relation book links
for relationLink in relationLinkList:
title, detail, relationLinkList = get_detail_sentence_list( 'http://www.oreilly.co.jp/books/' + relationLink )
# save
if not (title in titleList):
titleList.append(title)
inputDatas.append( detail )
Le contenu de X utilisant TfidfVectorizer est ・ Len (X) = nombre de livres recherchés ・ Len (X [0]) = nombre de mots dans le texte d'introduction du livre ・ X [0] [0] = 0 Valeur TF-IDF du 0ème mot (mot stocké dans les termes [0]) dans le 0ème livre Une procession comme ça. Vous pouvez calculer TF-IDF en créant une logique, mais il est plus facile d'utiliser cette bibliothèque.
clustering.py
def get_word_list( targetText ):
tagger = MeCab.Tagger()
wordList = []
if len(targetText) > 0:
node = tagger.parseToNode(targetText)
while node:
if len(util.mytrim(node.surface)) > 0:
wordList.append(node.surface)
node = node.next
return wordList
tfidfVectonizer = TfidfVectorizer(analyzer=get_word_list, min_df=1, max_df=50)
X = tfidfVectonizer.fit_transform( inputDatas )
terms = tfidfVectonizer.get_feature_names()
util.py
#coding:utf-8
def mytrim( target ):
target = target.replace(' ','')
return target.strip()
Je l'ai essayé à la fois avec K-means et Affinity Propagation. K-means est utilisé lorsqu'il est décidé du nombre de pièces à classer en premier, Si vous n'avez pas décidé, la propagation d'affinité fonctionne plutôt bien. Je pense que la propagation d'affinité était plus appropriée dans ce cas.
clustering.py
# clustering by KMeans
k_means = KMeans(n_clusters=5, init='k-means++', n_init=5, verbose=True)
k_means.fit(X)
label = k_means.labels_
clusterList = {}
for i in range(len(titleList)):
clusterList.setdefault( label[i], '' )
clusterList[label[i]] = clusterList[label[i]] + ',' + titleList[i]
print 'By KMeans'
for key, value in clusterList.items():
print key
print value
print 'By AffinityPropagation'
# clustering by AffinityPropagation
af = AffinityPropagation().fit(X)
afLabel = af.labels_
afClusterList = {}
for i in range(len(titleList)):
afClusterList.setdefault( afLabel[i], '' )
afClusterList[afLabel[i]] = afClusterList[afLabel[i]] + ',' + titleList[i]
for key, value in afClusterList.items():
print key
print value
Ça ressemble à ça!
Recommended Posts