[PYTHON] Résumez le titre de Hottentori dans Hateb et regardez le présent du Web

Maintenant que Google Reader est terminé et que des services tels que SmartNews et Gunosy qui offrent du contenu recommandé même lorsque vous dormez attirent l'attention, j'aimerais faire quelque chose d'intelligent ici.

Donc, j'ai tiré un article d'une entrée populaire dans Hateb, J'ai écrit un programme pour résumer en une seule ligne.

Oui ca.

Résumé http://xiidec.appspot.com/markov.html

Si vous utilisez ceci ...

La vérité au Japon est que le chat paresseux Lion peut faire le parcours élite dans ce pays.

Comme ça

Que faire de l'histoire du désir de productivité et pourquoi des remarques discriminatoires hautement qualifiées sont nécessaires.

L'actualité du sujet est mélangée et résumée en une seule ligne.

Concernant Ayumi Hamasaki, le réacteur n'a pas atteint suffisamment, et les remarques discriminatoires sur la fusion du cœur se sont poursuivies.

Vous pouvez voir l'état actuel du Web en une seule ligne!

Comment ça fonctionne

  1. Du côté serveur (Python), récupérez le RSS de l'entrée populaire de Hatena Bookmark.
  2. Décomposez les mots avec une analyse morphologique tiny_segmenter qui fonctionne avec Javascript.
  3. Reconstruit en utilisant la chaîne de Markov, un algorithme souvent utilisé pour Bot.

C'est presque comme ça.

Je loue un serveur Google App Engine (gratuit) et je l'exécute. Le mécanisme pour récupérer le flux est presque le même que lorsque l'analyseur de flux récupère automatiquement les images de chat. Passez-le au client.

Le client décompose ensuite la chaîne reçue en mots avec une bibliothèque Javascript magique appelée TinySegmenter.

C'est une belle journée aujourd'hui. ↓ aujourd'hui|Est|bien|Météo|est|Hey|。

Une telle image.

Ensuite, il est reconstruit à l'aide d'un algorithme appelé chaîne de Markov. Pour plus d'informations, voir [Articles sur la chaîne de Markov] de Wikipedia (http://en.wikipedia.org/wiki/%E3%83%9E%E3%83%AB%E3%82%B3%E3%83%95%E9% Je ne pense pas que vous puissiez très bien le comprendre si vous lisez 80% A3% E9% 8E% 96), mais si vous expliquez grossièrement,

Aujourd'hui → c'est → beau → temps → c'est → ne →. I → est → chat → est → est →. → Nom → → Pas encore → Non disponible →. Remise → → → Pas d'arme → → Enfant → → Autour → De → Perte → Seulement →.

Supposons qu'il y ait plusieurs phrases.

Tout d'abord, le premier mot est extrait au hasard. → "Aujourd'hui" Le seul mot qui suit «aujourd'hui» est «ha». → "Aujourd'hui" Les mots qui suivent "ha" sont "bon" et "chat". Choisissez au hasard. → "Aujourd'hui est un chat" Le seul mot qui suit un chat est "de". → "Aujourd'hui est un chat" Les mots qui suivent "de" sont "aru" et "children". Choisissez également au hasard. → "Aujourd'hui, c'est un chat et un enfant" À côté des «enfants», il y a un autre choix. → "Aujourd'hui, c'est un chat et un enfant" À côté de «non», il y a «pas de pistolet» et «autour». → "Aujourd'hui, c'est un chat et un pistolet d'enfant" À côté de "Muteppou", "de" est à nouveau sélectionné. → "Aujourd'hui, c'est un chat et le pistolet sans arme d'un enfant" Finissons-le. → «Aujourd'hui, c'est un chat et un pistolet pour enfant.

Il s'est avéré être quelque chose comme ça. La chaîne de Markov est en fait un peu plus profonde. Une formule difficile sort. Quelle que soit la théorie, espérons que cela deviendra ainsi.

La source

Il s'agit de la source côté serveur.

markov.py


#!/usr/bin/env python
# -*- coding: utf-8 -*-
import webapp2
import os
from google.appengine.ext.webapp import template
from xml.etree.ElementTree import *
import re

import urllib

class Markov(webapp2.RequestHandler):
	def get(self):
		mes=""
		if self.request.get('mode')=="2ch":
			mes=self.get_2ch()
		else:
			mes=self.get_hotentry_title()
		
		template_values={
		'mes':mes
		}
		path = os.path.join(os.path.dirname(__file__), 'html/markov.html')
		self.response.out.write(template.render(path, template_values))
		
	def get_hotentry_title(self):
		titles = ""
		tree = parse(urllib.urlopen('http://feeds.feedburner.com/hatena/b/hotentry'))
		for i in tree.findall('./{http://purl.org/rss/1.0/}item'):
			titles+= re.sub("[-:|/|:].{1,30}$","",i.find('{http://purl.org/rss/1.0/}title').text) + "\n"
		return titles
		
	def get_2ch(self):
		titles = ""
		response = urllib.urlopen('http://engawa.2ch.net/poverty/subject.txt')
		html = unicode(response.read(), "cp932", 'ignore').encode("utf-8")
		for line in html.split("\n"):
			if line != "":
				titles+=re.sub("\(.*?\)$","",line.split("<>", 2)[1])+ "\n"
		return titles
		
app = webapp2.WSGIApplication([
	('/markov.html', Markov)
], debug=True)

La méthode get de la classe Markov est la méthode qui fonctionne lorsque l'utilisateur y accède. get_hotentry_title () récupère une liste d'entrées populaires et les transmet à markov.html. ElementTree est utilisé pour obtenir du RSS. Il semblait que ce serait un problème d'utiliser feedparser sur GAE.

get_2ch () est une fonction supplémentaire. Je vais ramasser le fil de 2ch au lieu de l'entrée de la fin. Ajoutez "? Mode = 2ch" à la fin de l'URL pour obtenir le mode 2ch. Si vous améliorez la fonction pour modifier les informations récupérées en fonction de paramètres comme celui-ci, votre rêve se répandra.

re.sub("[-:|/|:].{1,30}$”,””,~~~)

Cette mystérieuse description appelée re.sub. Cela élimine les bruits inutiles.

Une seule façon claire de faire △△ ◯◯ 100 sélections-XX blog

Supprimez le "-XX blog" avec un tel titre pour le rendre simple.

Vient ensuite le côté client.

markov.html



<html>
    <head>
    </head>
    <body style="">
        <p>&nbsp;</p>
        <p>
        <meta charset="UTF-8">
        <title>Résumé-kun</title>
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" />
	<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
		<script type="text/javascript" src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script>
			<script type="text/javascript" src="jscss/tiny_segmenter-0.1.js" charset="UTF-8">
        </script> <script type="text/javascript">
	var segmenter
	$(function(){
		segmenter = new TinySegmenter();//Génération d'instance
	})
	//Courir
	function doAction(){
		var wkIn=$("#txtIN").val()//contribution
		var segs = segmenter.segment(wkIn);  //Renvoie un tableau de mots
		var dict=makeDic(wkIn)
		var wkbest=doShuffle(dict);	
		for(var i=0;i<=10;i++){
		wkOut=doShuffle(dict).replace(/\n/g,"");	
			if(Math.abs(40-wkOut.length)<Math.abs(40-wkbest.length)){
				wkbest=wkOut
			}
		}
		
		$("#txtOUT").val(wkbest);//Production
		
	}
	//Mélanger les phrases
	function doShuffle(wkDic){
		var wkNowWord=""
		var wkStr=""
		wkNowWord=wkDic["_BOS_"][Math.floor( Math.random() * wkDic["_BOS_"].length )];
		wkStr+=wkNowWord;
		while(wkNowWord != "_EOS_"){
			wkNowWord=wkDic[wkNowWord][Math.floor( Math.random() * wkDic[wkNowWord].length )];
			wkStr+=wkNowWord;
		}
		wkStr=wkStr.replace(/_EOS_$/,"。")
		return wkStr;
	}
	//Ajouter au dictionnaire
	function makeDic(wkStr){
		wkStr=nonoise(wkStr);
		var wkLines= wkStr.split("。");
		var wkDict=new Object();
		for(var i =0;i<=wkLines.length-1;i++){
			var wkWords=segmenter.segment(wkLines[i]);
			if(! wkDict["_BOS_"] ){wkDict["_BOS_"]=new Array();}
			if(wkWords[0]){wkDict["_BOS_"].push(wkWords[0])};//Début de phrase

			for(var w=0;w<=wkWords.length-1;w++){
				var wkNowWord=wkWords[w];//Maintenant mot
				var wkNextWord=wkWords[w+1];//Mot suivant
				if(wkNextWord==undefined){//Fin de phrase
					wkNextWord="_EOS_"
				}
				if(! wkDict[wkNowWord] ){
					wkDict[wkNowWord]=new Array();
				}
				wkDict[wkNowWord].push(wkNextWord);
				if(wkNowWord=="、"){//"," Peut être utilisé comme début de phrase.
					wkDict["_BOS_"].push(wkNextWord);
				}
			}
			
		}
		return wkDict;
	}
	
	//Suppression du bruit
	function nonoise(wkStr){
		wkStr=wkStr.replace(/\n/g,"。");
		wkStr=wkStr.replace(/[\?\!?!]/g,"。");
		wkStr=wkStr.replace(/[-||:: ・]/g,"。");
		wkStr=wkStr.replace(/[「」()\(\)\[\]【】]/g," ");
		return wkStr;
	}	
</script>  </meta>
<div data-role="page" id="first">
	<div data-role="content">	

        <p>Pour résumer les articles d'actualité sur le net en une seule ligne ...</p>
					<p><textarea cols="60" rows="8" name="txtIN" id="txtIN"  style="max-height:200px;">{{ mes }}</textarea></p>
        <input type="button" name="" value="produire" onClick=" doAction()"></br>
        <textarea cols="60" rows="8" name="txtIN" id="txtOUT"></textarea>
        <p></p>

</div>
</div>
</body>
</html>

Wow foiré. Tout d'abord, doAction (), c'est la fonction principale. La chaîne de caractères reçue par segmenter.segment (wkIN) est décomposée en morceaux. Sur cette base, créez un dictionnaire de connexions de phrases avec makeDic (). Après cela, mélangez-le 10 fois avec doShuffle () et adoptez la chaîne de caractères la plus proche de 40 caractères.

Achevée.

Il semble que diverses améliorations puissent être apportées en changeant les informations récupérées sur le Web ou en modifiant les critères d'évaluation des phrases mixtes selon vos préférences.

Résumé

Pas très pratique.

Recommended Posts

Résumez le titre de Hottentori dans Hateb et regardez le présent du Web
Cours de base Python (à la fin de 15)
Résumer les principaux points de croissance hack des services web et les points d'analyse
Jetons un coup d'œil au code Scapy. Surcharge des méthodes spéciales __div__, __getitem__.
Envoyer Gmail à la fin du processus [Python]
Au moment de la mise à jour de python avec ubuntu
Les prévisions épidémiques du nouveau virus corona ont été publiées sur le Web à une vitesse explosive
Supprimer une chaîne spécifique à la fin de python
[Python3] Prenez une capture d'écran d'une page Web sur le serveur et recadrez-la davantage
Regardez le score de Go d'un joueur de Go professionnel
Exécuter une commande sur le serveur Web et afficher le résultat
Comment insérer un processus spécifique au début et à la fin de l'araignée avec la tremblante
Essayez d'utiliser le framework Web Python Django (2) - Regardez setting.py
Décorateur qui affiche "Nom de la méthode FIN" à la fin de la méthode
L'histoire de la création d'un outil qui fonctionne sur Mac et Windows sur le site de développement de jeux
Jetons un coup d'œil à la carte des fonctionnalités de YOLO v3
Capturer GeneratorQuitter et détecter la fin de l'itération du côté du générateur
Installer et gérer plusieurs environnements de la même distribution sur WSL
Comment utiliser Jupyter sur le frontal de Spacon ITO
Jetons un coup d'œil à l'incendie de forêt sur la côte ouest des États-Unis avec des images satellites.