Java
Nouvelle édition : Encore plus de modifications dans le temps libre. J'ai démarré une nouvelle branche où je jouais avec l'algorithme DFS. Officiellement, la branche doit servir de noyau à un nouvel algorithme BFS que je prévois, mais entre-temps, je voulais avoir une meilleure idée de ce que fait le DFS et de la façon dont il prend ses décisions. À cette fin, j'ai ajouté une fonction de suppression qui commence à réduire la valeur d'un nouveau mot, que le sujet soit sujet ou non, à mesure que les phrases s'allongent. De même, tous les mots contribuent maintenant à la valeur de la phrase, mais les mots qui ne figurent ni dans le sujet ni dans la liste des sujets de phrases ne représentent que 25% de leur valeur en fréquence. Un exemple de conversation peut être trouvé ici et c'est assez bon, où nous parlons de physique, de la nature humaine de Chatbrains et d'autres sujets fascinants.code de branche ici .
Edit : J'ai légèrement modifié le code. Au lieu d'afficher les révisions ici, consultez-la dans le référentiel github où vous trouverez les dernières révisions. J'ai également ajouté une nouvelle conversation contre la version la plus récente, dans laquelle nous discutons des chatbots, de la recherche préalable en profondeur et de la manière dont la programmation devrait être utilisée pour créer des êtres vivants !.
J'ai décidé de relever ce défi de manière holistique. Mon chatbot sait très peu de choses à ses débuts - pas de mots, pas de syntaxe, pas de rien. Il sait comment analyser l'anglais standard en mots et comment identifier les caractères autres que des mots comme des signes de ponctuation. C'est ça. Tout ce qu'il sait apprend de l'interaction avec l'utilisateur. Lorsque vous interagissez avec celui-ci, il fait attention aux liens entre les mots et construit des phrases en utilisant ces informations. Bien sûr, référencez la source pour plus d'informations. J'ai largement dépassé les attentes de longueur de programme recommandées pour ce défi, mais dans un bon but. Voici quelques points saillants du programme:
- Chatbot commence sans aucune connaissance (suit "Règles": 3 )
- La fréquence d'occurrence des mots est suivie
- Les fréquences de mots sont "décomposées" afin que la conversation puisse passer d'un sujet à l'autre (suit "Bonus": 3 et 4 )
- La disposition des mots dans les phrases observées est enregistrée, ainsi les "phrases" sont implicitement conservées (par exemple, si vous utilisez beaucoup de phrases prépositionnelles lorsque vous discutez avec le bot, le bot en utilisera aussi beaucoup!)
- Les phrases sont construites en préférant suivre les liens les plus fréquemment observés entre les mots, avec des facteurs aléatoires pour injecter des variations
- L'algorithme de construction de phrase est une recherche en profondeur d'abord, qui tente de maximiser l'occurrence de mots de sujet dans la phrase en sortie, avec une petite préférence pour les phrases de fin (ceci suit "Bonus": 1 - J'utilise un algorithme d'apprentissage assez cool, qui évolue au fil du temps et conserve la connaissance des liens de mots récoltés)
- edit: les mots de sujet sont maintenant tirés de la connaissance globale des mots récurrents et de la phrase la plus récente
- edit: La pondération des mots est maintenant calculée à l'aide de la base de journal 4 de la longueur de mot; les mots plus longs sont donc pondérés plus fortement et les mots plus courts, plus faiblement - c'est pour pallier l'absence d'un véritable corpus à utiliser à la fois éliminer les mots de haute fréquence et de faible valeur, comme on peut facilement le faire avec un corpus.
- edit: Au fur et à mesure que la longueur de la phrase augmente pendant la construction, une fonction de suppression commence à diminuer la valeur des mots supplémentaires.
- edit: Phrase "terminaison" a moins de valeur maintenant, car elle causait une prépondérance de phrases courtes et ridicules.
- edit: tous les mots contribuent maintenant à la valeur, bien que les mots hors sujet ne contribuent qu'à 25% de la valeur de fréquence globale.
- Il y a une profondeur maximum intégrée pour empêcher trop de bouclage et de temps passé à cause de mon utilisation du mot précédent pour construire une phrase
- Les boucles sont détectées directement lors de la création d'une phrase et, bien qu'elles soient techniquement autorisées, il y a de fortes chances que les boucles soient évitées.
- Le délai d'attente ajustable est utilisé pour encourager l'élagage des branches et la finalisation des instructions, ainsi que pour éviter de dépasser le "délai acceptable" de 5-10 secondes dans les règles
Pour résumer ma connexion aux règles:
- Pour "Règles": 1 , j'ai choisi Java, qui est détaillé, alors soyez gentil.
- Pour "Rules": 2 , seule la saisie de l'utilisateur est mise à profit, bien que je dispose d'un code de fonction pour ajouter une sauvegarde / chargement du cerveau pour le futur
- Pour "Règles": 3 , il n'y a absolument aucun vocabulaire prédéfini. Le ChatBot sait comment analyser l'anglais, mais c'est tout. A ses débuts, il ne sait absolument rien.
- Pour "Critères obligatoires": 1 , mon programme est plus long, mais contient beaucoup de choses géniales. J'espère que vous allez oublier.
- Pour "Critères obligatoires": 2 , l'algorithme de construction de phrase que j'ai utilisé expire afin d'empêcher explicitement le temps de recherche de plus de 5 à 6 secondes. La meilleure phrase à ce jour est renvoyée à expiration.
- Pour les "Critères obligatoires": 3 , les sujets se résument généralement en une dizaine de phrases. Le Bot sera donc sur le sujet à ce moment-là, et par 20 phrases répondra aux déclarations avec quelques constructions aléatoires fascinantes qui ont réellement un sens.
- Pour "Critères obligatoires": 4 , je n'ai rien emprunté du code de référence. C'est une construction tout à fait unique.
- Pour "Bonus": 1 , j'aime bien penser que ce bot est assez exceptionnel. Ce ne sera pas aussi convaincant que les robots scriptés, mais il n'y a absolument aucune limitation sur les sujets, et passera gracieusement (avec persistance) d'un sujet de conversation à un autre.
- Pour "Bonus": 2 , il s'agit strictement d'un round robin, donc pas de bonus ici. Encore. Mon algorithme n’exige aucune réponse, je prévois donc une version Threaded qui traitera ce bonus.
- Pour "Bonus": 3 , ce bot imitera initialement, mais au fur et à mesure que la conversation avance au-delà des premières phrases, la simulation prend fin.
- Pour "Bonus": 4 , les "ambiances" ne sont pas traitées de manière significative, mais comme l'indique la rubrique relative aux préférences des robots ci-dessous, cela changera les ambiances.
- Pour "Bonus": 5 , l'enregistrement et le chargement du cerveau ne sont pas en place.
J'ai donc respecté toutes les règles de base, toutes les règles obligatoires et provisoirement les règles de bonus 1, 3 et 4.
En prime, j'ai commenté tout au long du code, alors n'hésitez pas à emprunter ou à recommander des améliorations. Clairement, comme je n’ai pas de dialogue intégré ni de connaissances "structurelles", les conversations seront bizarres plus longtemps que les autres robots, mais je pense que je respecte assez bien les règles.
Maintenant, passons au code (Quelques commentaires rédigés pour s’adapter à la limite corporelle) ou suivez-le sur GitHub, alors que je continue de l’améliorer :
import java.util.*;
import java.util.regex.*;
public class LearningChatbot {
/**
* Static definition of final word in a statement. It never has
* any descendents, and concludes all statements. This is the only
* "starting knowledge" granted the bot.
*/
public static final ChatWord ENDWORD = new ChatWord("\n");
/**
* The Brain of this operation.
*/
private ChatbotBrain brain;
/**
* Starts LearningChatbot with a new brain
*/
public LearningChatbot() {
brain = new ChatbotBrain();
}
/**
* Starts LearningChatbot with restored brain.
*/
public LearningChatbot(String filename) {
throw new UnsupportedOperationException("Not yet implemented");
}
/**
* Invocation method.
*/
public void beginConversation() {
ChatbotBrain cb = new ChatbotBrain();
Scanner dialog = new Scanner(System.in);
boolean more = true;
while (more) {
System.out.print(" You? ");
String input = dialog.nextLine();
if (input.equals("++done")) {
System.exit(0);
} else if (input.equals("++save")) {
System.out.println("Saving not yet implemented, sorry!");
System.exit(0);
} else if (input.equals("++help")) {
getHelp();
}else {
cb.decay();
cb.digestSentence(input);
}
System.out.print("Chatbot? ");
System.out.println(cb.buildSentence());
}
}
/**
* Help display
*/
public static void getHelp() {
System.out.println("At any time during the conversation, type");
System.out.println(" ++done");
System.out.println("to exit without saving.");
System.out.println("Or type");
System.out.println(" ++save");
System.out.println("to exit and save the brain.");
System.out.println();
}
/**
* Get things started.
*/
public static void main(String[] args) {
System.out.println("Welcome to the Learning Chatbot");
System.out.println();
getHelp();
LearningChatbot lc = null;
if (args.length > 0) {
System.out.printf("Using %s as brain file, if possible.", args[0]);
lc = new LearningChatbot(args[0]);
} else {
lc = new LearningChatbot();
}
lc.beginConversation();
}
/**
* The ChatbotBrain holds references to all ChatWords and has various
* methods to decompose and reconstruct sentences.
*/
static class ChatbotBrain {
/**
* A tracking of all observed words. Keyed by the String version of
* the ChatWord, to allow uniqueness across all ChatWords
*/
private Map<String,ChatWord> observedWords;
/**
* This brain is going to be able to keep track of "topics" by way of
* a word frequency map. That way, it can generate sentences based
* on topic-appropriateness.
*/
private Map<ChatWord, Double> wordFrequencyLookup;
/**
* This holds the actual word frequencies, for quick isolation of
* highest frequency words.
*/
private NavigableMap<Double, Collection<ChatWord>> wordFrequency;
/**
* This holds the count of words observed total.
*/
private int wordCount;
/**
* This holds the current "values" of all words.
*/
private double wordValues;
/**
* A "word" that is arbitrarily the start of every sentence
*/
private ChatWord startWord;
/**
* Rate of decay of "topics".
*/
private double decayRate;
// These values configure various features of the recursive
// sentence construction algorithm.
/** Nominal (target) length of sentences */
public static final int NOMINAL_LENGTH = 10;
/** Max length of sentences */
public static final int MAX_LENGTH = 25;
/** Sentence creation timeout */
public static final long TIMEOUT = 5000;
/** Topic words to match against */
public static final int TOPICS = 3;
/** Minimum branches to consider for each word */
public static final int MIN_BRANCHES = 3;
/** Maximum branches to consider for each word */
public static final int MAX_BRANCHES = 5;
/** % chance as integer out of 100 to skip a word */
public static final int SKIP_CHANCE = 20;
/** % chance as integer to skip a word that would cause a loop */
public static final int LOOP_CHANCE = 5;
/** % chance that punctuation will happen at all */
public static final int PUNCTUATION_CHANCE = 25;
/** % chance that a particular punctuation will be skipped */
public static final int PUNCTUATION_SKIP_CHANCE = 40;
/**
* Convenience parameter to use a common random source
* throughout the brain.
*/
private Random random;
/**
* Gets the Chatbot started, sets up data structures necessary
*/
public ChatbotBrain() {
observedWords = new HashMap<String,ChatWord>();
observedWords.put("\n",ENDWORD);
startWord = new ChatWord("");
observedWords.put("",startWord);
wordFrequencyLookup = new HashMap<ChatWord, Double>();
wordFrequency = new TreeMap<Double, Collection<ChatWord>>();
decayRate = 0.05;
wordCount = 0;
wordValues = 0.0;
random = new Random();
}
/**
* More complex digest method (second edition) that takes a sentence,
* cuts it pu, and links up the words based on ordering.
*/
public void digestSentence(String sentence) {
Scanner scan = new Scanner(sentence);
ChatWord prior = null;
ChatWord current = null;
String currentStr = null;
String currentPnc = null;
while (scan.hasNext()) {
currentStr = scan.next();
Pattern wordAndPunctuation =
Pattern.compile("([a-zA-Z\\-_'0-9]+)([^a-zA-Z\\-_'0-9]?)[^a-zA-Z\\-_'0-9]*?");
Matcher findWords = wordAndPunctuation.matcher(currentStr);
// Basically this lets us find words-in-word typos like this:
// So,bob left his clothes with me again.
// where "So,bob" becomes "So," "bob"
while (findWords.find()) {
currentStr = findWords.group(1);
currentPnc = findWords.group(2);
if (currentStr != null) {
if (observedWords.containsKey(currentStr)) {
current = observedWords.get(currentStr);
} else {
current = new ChatWord(currentStr);
observedWords.put(currentStr, current);
}
incrementWord(current);
if (currentPnc != null && !currentPnc.equals("")) {
current.addPunctuation(currentPnc.charAt(0));
}
if (prior != null) {
prior.addDescendent(current);
}
if (prior == null) {
startWord.addDescendent(current);
}
prior = current;
}
}
}
if (prior != null) { // finalize.
prior.addDescendent(ENDWORD);
}
}
/**
* Increments the value of a word (catalogues a new sighting).
*/
public void incrementWord(ChatWord word) {
Double curValue;
Double nextValue;
Collection<ChatWord> freqMap;
if (wordFrequencyLookup.containsKey(word)) {
curValue = wordFrequencyLookup.get(word);
freqMap = wordFrequency.get(curValue);
freqMap.remove(word);
} else {
curValue = 0.0;
}
nextValue=curValue+1.0;
wordFrequencyLookup.put(word, nextValue);
freqMap = wordFrequency.get(nextValue);
if (freqMap == null) {
freqMap = new HashSet<ChatWord>();
wordFrequency.put(nextValue, freqMap);
}
freqMap.add(word);
wordCount++;
wordValues++;
}
/**
* Decays a particular word by decay rate.
*/
public void decayWord(ChatWord word) {
Double curValue;
Double nextValue;
Collection<ChatWord> freqMap;
if (wordFrequencyLookup.containsKey(word)) {
curValue = wordFrequencyLookup.get(word);
freqMap = wordFrequency.get(curValue);
freqMap.remove(word);
} else {
return;
}
wordValues-=curValue; // remove old decay value
nextValue=curValue-(curValue*decayRate);
wordValues+=nextValue; // add new decay value
wordFrequencyLookup.put(word, nextValue);
freqMap = wordFrequency.get(nextValue);
if (freqMap == null) {
freqMap = new HashSet<ChatWord>();
wordFrequency.put(nextValue, freqMap);
}
freqMap.add(word);
}
/**
* Decay all word's frequency values.
*/
public void decay() {
for (ChatWord cw : wordFrequencyLookup.keySet()) {
decayWord(cw);
}
}
/**
* Gets a set of words that appear to be "top" of the frequency
* list.
*/
public Set<ChatWord> topicWords(int maxTopics) {
Set<ChatWord> topics = new HashSet<ChatWord>();
int nTopics = 0;
for (Double weight: wordFrequency.descendingKeySet()) {
for (ChatWord word: wordFrequency.get(weight)) {
topics.add(word);
nTopics++;
if (nTopics == maxTopics) {
return topics;
}
}
}
return topics;
}
/**
* Uses word frequency records to prefer to build on-topic
* sentences.
*/
public String buildSentence() {
int maxDepth = NOMINAL_LENGTH+
random.nextInt(MAX_LENGTH - NOMINAL_LENGTH);
ChatSentence cs = new ChatSentence(startWord);
// We don't want to take too long to "think of an answer"
long timeout = System.currentTimeMillis() + TIMEOUT;
double bestValue = buildSentence(cs, topicWords(TOPICS), 0.0, 0, maxDepth, timeout);
return cs.toString();
}
public double buildSentence(ChatSentence sentence,
Set<ChatWord> topics, double curValue,
int curDepth, int maxDepth, long timeout){
if (curDepth==maxDepth || System.currentTimeMillis() > timeout) {
return curValue;
}
// Determine how many branches to enter from this node
int maxBranches = MIN_BRANCHES + random.nextInt(MAX_BRANCHES - MIN_BRANCHES);
// try a few "best" words from ChatWord's descendent list.
ChatWord word = sentence.getLastWord();
NavigableMap<Integer, Collection<ChatWord>> roots =
word.getDescendents();
// Going to keep track of current best encountered sentence
double bestSentenceValue = curValue;
ChatSentence bestSentence = null;
int curBranches = 0;
for (Integer freq : roots.descendingKeySet()) {
for (ChatWord curWord : roots.get(freq)) {
if (curWord.equals(ENDWORD)) {
// let's weigh the endword cleverly
double endValue = random.nextDouble() * wordFrequency.lastKey();
if (curValue+endValue > bestSentenceValue) {
bestSentenceValue = curValue+endValue;
bestSentence = new ChatSentence(sentence);
bestSentence.addWord(curWord);
}
curBranches++;
} else {
int chance = random.nextInt(100);
boolean loop = sentence.hasWord(curWord);
/* Include a little bit of chance in the inclusion of
* any given word, whether a loop or not.*/
if ( (!loop&&chance>=SKIP_CHANCE) ||
(loop&&chance<LOOP_CHANCE)) {
double wordValue = topics.contains(curWord)?
wordFrequencyLookup.get(curWord):0.0;
ChatSentence branchSentence = new ChatSentence(sentence);
branchSentence.addWord(curWord);
addPunctuation(branchSentence);
double branchValue = buildSentence(branchSentence,
topics, curValue+wordValue, curDepth+1,
maxDepth, timeout);
if (branchValue > bestSentenceValue) {
bestSentenceValue = branchValue;
bestSentence = branchSentence;
}
curBranches++;
}
}
if (curBranches == maxBranches) break;
}
if (curBranches == maxBranches) break;
}
if (bestSentence != null) {
sentence.replaceSentence(bestSentence);
}
return bestSentenceValue;
}
/**
* Adds punctuation to a sentence, potentially.
*/
public void addPunctuation(ChatSentence sentence) {
ChatWord word = sentence.getLastWord();
NavigableMap<Integer, Collection<Character>> punc = word.getPunctuation();
if (punc.size()>0 && random.nextInt(100)<PUNCTUATION_CHANCE){
Integer puncMax = punc.lastKey();
Collection<Character> bestPunc = punc.get(puncMax);
Character puncPick = null;
for (Integer freq : punc.descendingKeySet()) {
for (Character curPunc : punc.get(freq)) {
if (random.nextInt(100)>=PUNCTUATION_SKIP_CHANCE) {
puncPick = curPunc;
break;
}
}
if (puncPick != null) break;
}
if (puncPick != null) {
sentence.addCharacter(puncPick);
}
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("ChatBrain[");
sb.append(observedWords.size());
sb.append("]:");
for (Map.Entry<String,ChatWord> cw : observedWords.entrySet()) {
sb.append("\n\t");
sb.append(wordFrequencyLookup.get(cw.getValue()));
sb.append("\t");
sb.append(cw.getValue());
}
return sb.toString();
}
}
/**
* Useful helper class to construct sentences.
*/
static class ChatSentence implements Cloneable {
/**
* List of words.
*/
private List<Object> words;
/**
* Quick search construct to have O(ln) lookup times.
*/
private Set<Object> contains;
/**
* Starts to build a sentence with a single word as anchor
*/
public ChatSentence(ChatWord anchor) {
if (anchor == null) {
throw new IllegalArgumentException("Anchor must not be null");
}
words = new ArrayList<Object>();
contains = new HashSet<Object>();
words.add(anchor);
contains.add(anchor);
}
/**
* Starts a sentence using an existing ChatSentence. Also used for
* cloning.
*/
public ChatSentence(ChatSentence src) {
words = new ArrayList<Object>();
contains = new HashSet<Object>();
appendSentence(src);
}
/**
* Adds a word to a sentence
*/
public ChatSentence addWord(ChatWord word) {
if (word == null) {
throw new IllegalArgumentException("Can't add null word");
}
words.add(word);
contains.add(word);
return this;
}
/**
* Adds a character to a sentence.
*/
public ChatSentence addCharacter(Character punc) {
if (punc == null) {
throw new IllegalArgumentException("Can't add null punctuation");
}
words.add(punc);
contains.add(punc);
return this;
}
/**
* Replace a sentence with some other sentence.
* Useful to preserve references.
*/
public ChatSentence replaceSentence(ChatSentence src) {
words.clear();
contains.clear();
appendSentence(src);
return this;
}
public ChatSentence appendSentence(ChatSentence src) {
words.addAll(src.getWords());
contains.addAll(src.getWords());
return this;
}
/**
* Get last word of the sentence.
*/
public ChatWord getLastWord() {
for (int i=words.size()-1; i>=0; i--) {
if (words.get(i) instanceof ChatWord) {
return (ChatWord) words.get(i);
}
}
throw new IllegalStateException("No ChatWords found!");
}
/**
* Checks if the sentence has a word
*/
public boolean hasWord(ChatWord word) {
return contains.contains(word);
}
/**
* Counts the number of words in a sentence.
*/
public int countWords() {
int cnt = 0;
for (Object o : words) {
if (o instanceof ChatWord) {
cnt++;
}
}
return cnt;
}
/**
* Gets all the words of the sentence
*/
private List<Object> getWords() {
return words;
}
/**
* Returns the sentence as a string.
*/
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
for (Object o : words) {
if (o instanceof ChatWord) {
ChatWord cw = (ChatWord) o;
sb.append(" ");
sb.append( cw.getWord() );
} else {
sb.append(o);
}
}
return sb.toString().trim();
}
/**
* Clones this sentence.
*/
@Override
public Object clone() {
return new ChatSentence(this);
}
}
/**
* ChatWord allows the creation of words that track how they are
* connected to other words in a forward fashion.
*/
static class ChatWord {
/** The word. */
private String word;
/** Collection of punctuation observed after this word */
private NavigableMap<Integer, Collection<Character>> punctuation;
/** Lookup linking observed punctuation to where they are in ordering */
private Map<Character, Integer> punctuationLookup;
/** Punctionation observation count */
private Integer punctuationCount;
/** Collection of ChatWords observed after this word */
private NavigableMap<Integer, Collection<ChatWord>> firstOrder;
/** Lookup linking observed words to where they are in ordering */
private Map<ChatWord, Integer> firstOrderLookup;
/** First order antecedent word count */
private Integer firstOrderCount;
/**
* Creates a new ChatWord that is aware of punctuation that
* follows it, and also ChatWords that follow it.
*/
public ChatWord(String word){
this.word = word;
this.firstOrder = new TreeMap<Integer, Collection<ChatWord>>();
this.firstOrderLookup = new HashMap<ChatWord, Integer>();
this.firstOrderCount = 0;
this.punctuation = new TreeMap<Integer, Collection<Character>>();
this.punctuationLookup = new HashMap<Character, Integer>();
this.punctuationCount = 0;
}
protected NavigableMap<Integer, Collection<ChatWord>> getDescendents() {
return firstOrder;
}
/**
* Returns how many descendents this word has seen.
*/
protected int getDescendentCount() {
return firstOrderCount;
}
/**
* Gets the lookup map for descendents
*/
protected Map<ChatWord, Integer> getDescendentsLookup() {
return firstOrderLookup;
}
/** As conversation progresses, word orderings will be encountered.
* The descendent style of "learning" basically weights how often
* words are encountered together, and is strongly biased towards
* encountered ordering.
*/
public void addDescendent(ChatWord next) {
if(next != null){
firstOrderCount++;
int nextCount = 1;
Collection<ChatWord> obs = null;
// If we've already seen this word, clean up prior membership.
if(firstOrderLookup.containsKey(next)){
nextCount = firstOrderLookup.remove(next);
obs = firstOrder.get(nextCount);
// Remove from prior obs count order
obs.remove(next);
nextCount++;
}
obs = firstOrder.get(nextCount);
if (obs == null) { // we don't have this order yet
obs = new HashSet<ChatWord>();
firstOrder.put(nextCount, obs);
}
firstOrderLookup.put(next, nextCount);
obs.add(next);
}
}
/**
* Some words have punctuation after them more often than not.
* This allows the ChatBrain to record occurrences of punctuation
* after a word.
*/
public void addPunctuation(Character punc) {
if(punc != null){
punctuationCount++;
int puncCount = 1;
Collection<Character> obs = null;
// If we've already seen this punc, clean up prior membership.
if(punctuationLookup.containsKey(punc)){
puncCount = punctuationLookup.remove(punc);
obs = punctuation.get(puncCount);
// Remove from prior obs count order
obs.remove(punc);
puncCount++;
}
obs = punctuation.get(puncCount);
if (obs == null) { // we don't have this order yet
obs = new HashSet<Character>();
punctuation.put(puncCount, obs);
}
punctuationLookup.put(punc, puncCount);
obs.add(punc);
}
}
/**
* Including this for now, but I don't like it -- it returns all
* punctuation wholesale. I think what would be better is some
* function that returns punctuation based on some characteristic.
*/
protected NavigableMap<Integer, Collection<Character>> getPunctuation() {
return punctuation;
}
/**
* Gets count of punctuation encountered.
*/
protected int getPunctuationCount() {
return punctuationCount;
}
/**
* Gets lookup of punctuations encountered.
*/
protected Map<Character, Integer> getPunctuationLookup() {
return punctuationLookup;
}
/**
* Gets the String backing this ChatWord.
*/
public String getWord() {
return word;
}
/**
* ChatWords are equivalent with the String they wrap.
*/
@Override
public int hashCode() {
return word.hashCode();
}
/**
* ChatWord equality is that ChatWords that wrap the same String
* are equal, and a ChatWord is equal to the String that it contains.
*/
@Override
public boolean equals(Object o){
if (o == this) {
return true;
}
if (o instanceof ChatWord) {
return ((ChatWord)o).getWord().equals(this.getWord());
}
if (o instanceof String) {
return ((String)o).equals(this.getWord());
}
return false;
}
/**
* Returns this ChatWord as a String.
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("ChatWord[");
sb.append(word);
sb.append("]desc{");
for (Integer key : firstOrder.keySet() ) {
Collection<ChatWord> value = firstOrder.get(key);
sb.append(key);
sb.append(":[");
for (ChatWord cw : value) {
sb.append(cw.getWord());
sb.append(",");
}
sb.append("],");
}
sb.append("}punc{");
for (Integer key : punctuation.keySet() ) {
Collection<Character> value = punctuation.get(key);
sb.append(key);
sb.append(":[");
for (Character c : value) {
sb.append("\"");
sb.append(c);
sb.append("\",");
}
sb.append("],");
}
sb.append("}");
return sb.toString();
}
}
}
Exemple de conversation:
Lié b / c des limites de caractères post
Conversation où le bot me dit que je devrais programmer des êtres vivants
Dernière conversation au cours de laquelle le Bot a parlé de la vraie nature de Chatbrains, de la physique, de l'univers physique et de la façon dont je suis probablement aussi un Chatbrain
etc. Je vais ajouter quelques éléments - par exemple, en raison du caractère commun des mots simples, ils ont tendance à dominer les listes de sujets non durs. Je vais ajouter un pourcentage, passer au mot sujet afin que les mots courants soient ignorés.
Chatbot? Well the earth is fun place to talk about
- Hé, il a fait sa propre phrase (compréhensible) à la fin! : D +1Chatbot? I'm not a Chatbrain since Chatbrains are the physical universe,
.The answer to the ultimate question about life, the universe, and everything is 'SyntaxError: missing ; before statement'.
C ++
Maintenant, je dois juste écrire l’algorithme pour tenir une conversation. Mon premier exercice d'apprentissage automatique.
Modifier:
Tous mes essais se sont avérés ridicules, alors je pense que je vais en rester là. Les autres étaient aussi ridicules que ça:
la source
C ++
Je visais le bonus facultatif 3: " Moins de mimiques, le comportement du bot est différent du comportement de l'utilisateur, séparant la perception de l'attitude du bot de l'attitude de l'utilisateur. ". Le résultat fut un bot vraiment têtu qui ne peut pas changer de sujet facilement et vous rend fou.
Il faut un certain temps pour lancer une discussion. Après un moment, une discussion peut se présenter comme suit:
L’approche consiste à tout stocker dans des groupes de 3 mots liés. Chaque groupe est pesé et repondéré dans une matrice de 1000 mots en groupes de mots. Code source:
la source
class c_wglist { ... } wgl;
. Ça marche pour moi. Essayez d’initialiser la variable wgl (classe c_wglist) ailleurs.Python3 + SQLite3
Voici un petit bot que je viens de faire!
Comment ça marche?
Trois tables SQL sont utilisées: une pour les mots, une pour les phrases, une pour associer les mots tapés par l'utilisateur, à la phrase suivante que le bot devrait afficher.
Quelles sont les particularités?
Voir le code ci-dessous:
Voici les trois premières "conversations" que j'ai eues avec le bot, en partant d'une base de données vide:
Vous pouvez regarder ici pour plus d'explications.
la source
En voici un que j'ai écrit dans Liberty BASIC il y a quelque temps. Il n'apprend pas, mais répond aux différentes réponses à ses questions.
exemple de conversation:
la source
HTML5
la source
Fortran 95
Inspiré par la réponse ci-dessus de l'utilisateur TheDoctor, j'ai décidé de créer un chatbot amusant de la même manière. Ce code n'apprend pas non plus, et je le partage ici juste pour m'amuser.
Il reconnaît les termes et déclarations suivants: "oui" et "oui", "non" et "non", absence de ponctuation ou types de ponctuation (expressions se terminant par "!", "?", "...") , phrases commençant par "pourquoi", "comment" ou "quoi", PHRASES IN CAPS, rire (tel que "hahaha", "lol" et "kkk"), réponses très courtes et très longues, phrases contenant le mot F, phrase contenant les mots "je t'aime" (essayez-le au moins 3 fois). Quand il vous demande quel est le sens de la vie, essayez de répondre "42". S'il vous demande s'il est plus intelligent que HAL 9000, répondez à quelque chose contenant les mots "vrai", "vérité", "correct", "mensonge", "faux" ou "faux". S'il vous demande si vous connaissez une blague, répondez "non" et laissez-le vous le dire. S'il "frappe, frappe, répondez" qui est là? ", Aidez-le également avec la source d'une citation. Pour quitter, tapez simplement "quit".
Exemple de conversation:
PS: s'il vous plaît pardonnez mon
goto
abus, je sais que tout ce code est une sorte de gâchis ... :)la source