[PYTHON] Limites qui peuvent être analysées à la fois avec MeCab

Il m'est arrivé de voir [article](https://qiita.com/Sak1361/items/2519f29af82ffe965652#mecab%E3%81%AE%E3%83%90%E3%82%B0%E5%AF%BE%E7%AD Le mémo que j'ai vérifié car il a été écrit comme un bug de mecab dans% 96).

Conclusion: ** 2,621,440 caractères ** est la limite

Ceci peut être vu en regardant la valeur ** MAX_INPUT_BUFFER_SIZE ** définie dans common.h.

#define NBEST_MAX 512
#define NODE_FREELIST_SIZE 512
#define PATH_FREELIST_SIZE 2048
#define MIN_INPUT_BUFFER_SIZE 8192
#define MAX_INPUT_BUFFER_SIZE (8192*640)
#define BUF_SIZE 8192

On peut voir qu'il est susceptible de recevoir 8 192 x 640 octets de données au maximum. En d'autres termes, 8192 x 640/2 = ** 2 621 440 caractères **. c'est tout.

prime

size_t ibufsize = std::min(MAX_INPUT_BUFFER_SIZE,
                             std::max(param.get<int>
                                            ("input-buffer-size"),
                                            MIN_INPUT_BUFFER_SIZE));

  const bool partial = param.get<bool>("partial");
  if (partial) {
    ibufsize *= 8;
  }

  MeCab::scoped_array<char> ibuf_data(new char[ibufsize]);
  char *ibuf = ibuf_data.get();

  MeCab::scoped_ptr<MeCab::Tagger> tagger(model->createTagger());

  if (!tagger.get()) {
    WHAT_ERROR("cannot create tagger");
  }

  for (size_t i = 0; i < rest.size(); ++i) {
    MeCab::istream_wrapper ifs(rest[i].c_str());
    if (!*ifs) {
      WHAT_ERROR("no such file or directory: " << rest[i]);
    }

    while (true) {
      if (!partial) {
        ifs->getline(ibuf, ibufsize);
      } else {
        std::string sentence;
        MeCab::scoped_fixed_array<char, BUF_SIZE> line;
        for (;;) {
          if (!ifs->getline(line.get(), line.size())) {
            ifs->clear(std::ios::eofbit|std::ios::badbit);
            break;
          }
          sentence += line.get();
          sentence += '\n';
          if (std::strcmp(line.get(), "EOS") == 0 || line[0] == '\0') {
            break;
          }
        }
        std::strncpy(ibuf, sentence.c_str(), ibufsize);
      }
      if (ifs->eof() && !ibuf[0]) {
        return false;
      }
      if (ifs->fail()) {
        std::cerr << "input-buffer overflow. "
                  << "The line is split. use -b #SIZE option." << std::endl;
        ifs->clear();
      }
      const char *r = (nbest >= 2) ? tagger->parseNBest(nbest, ibuf) :
          tagger->parse(ibuf);
      if (!r)  {
        WHAT_ERROR(tagger->what());
      }
      *ofs << r << std::flush;
    }
  }

  return EXIT_SUCCESS;

#undef WHAT_ERROR

A partir de ce code, on peut voir que le traitement de MeCab.Tagger.parse () ne dépasse pas ** MAX_INPUT_BUFFER_SIZE ** au maximum. Ensuite, string_buffer.h et [tagger.cupp9.com/ /blob/3a07c4eefaffb4e7a0690a7f4e5e0263d3ddb8a3/mecab/src/tagger.cpp) À propos de l'analyse de réseau. (string_buffer.h: extrait des lignes 15-37)

bool StringBuffer::reserve(size_t length) {
  if (!is_delete_) {
    error_ = (size_ + length >= alloc_size_);
    return (!error_);
  }

  if (size_ + length >= alloc_size_) {
    if (alloc_size_ == 0) {
      alloc_size_ = DEFAULT_ALLOC_SIZE;
      ptr_ = new char[alloc_size_];
    }
    size_t len = size_ + length;
    do {
      alloc_size_ *= 2;
    } while (len >= alloc_size_);
    char *new_ptr = new char[alloc_size_];
    std::memcpy(new_ptr, ptr_, size_);
    delete [] ptr_;
    ptr_ = new_ptr;
  }

  return true;
}

Cette réserve qui acquiert la zone est appelée uniquement dans tagger.cpp. (tagger.cpp: extrait des lignes 733-741)

LatticeImpl::LatticeImpl(const Writer *writer)
    : sentence_(0), size_(0), theta_(kDefaultTheta), Z_(0.0),
      request_type_(MECAB_ONE_BEST),
      writer_(writer),
      ostrs_(0),
      allocator_(new Allocator<Node, Path>) {
  begin_nodes_.reserve(MIN_INPUT_BUFFER_SIZE);
  end_nodes_.reserve(MIN_INPUT_BUFFER_SIZE);
}

Et LatticeImpl est (je pense) exécuté lorsque Lattice est matérialisé. (tagger.cpp: extrait 227-239)

class LatticeImpl : public Lattice {
 public:
  explicit LatticeImpl(const Writer *writer = 0);
  ~LatticeImpl();

  // clear internal lattice
  void clear();

  bool is_available() const {
    return (sentence_ &&
            !begin_nodes_.empty() &&
            !end_nodes_.empty());
  }

À partir de ces éléments, on peut voir qu'il ne semble pas y avoir de limite dans l'analyse du réseau car il semble que la surface soit doublée et acquise par memcpy lorsque la mémoire est insuffisante (bien sûr, cela devrait s'arrêter si la mémoire est consommée, mais avant cela Il semble s'arrêter à MAX_INPUT_BUFFER_SIZE).

Autres références

mecab.h: Définition de la structure telle que le treillis, etc. libmecab.cpp: [tagger.cpp910]: [tagger.cpp910. /3a07c4eefaffb4e7a0690a7f4e5e0263d3ddb8a3/mecab/src/tagger.cpp) mutable_lattice () et la définition des fonctions associées au modèle comme mecab_model_new_lattice () etc.

END.

Recommended Posts

Limites qui peuvent être analysées à la fois avec MeCab
Types de fichiers pouvant être utilisés avec Go
Répertorier les packages pouvant être mis à jour avec pip
Liste des couleurs pouvant être définies avec tkinter (mémorial)
Notes sur les connaissances Python utilisables avec AtCoder
J'ai étudié le prétraitement qui peut être fait avec PyCaret
Faisons un diagramme sur lequel on peut cliquer avec IPython
[Python] Créez un graphique qui peut être déplacé avec Plotly
Créez une Spinbox qui peut être affichée en binaire avec Tkinter
J'ai acheté et analysé la loterie jumbo de fin d'année avec Python qui peut être exécutée dans Colaboratory
J'ai fait un shuffle qui peut être réinitialisé (inversé) avec Python
Confirmation que rkhunter peut être installé
Créez un graphique des devises qui peut être déplacé avec Plotly (2)
Remplacez tout d'un coup par sed
Comparaison de 4 styles pouvant être passés à seaborn avec set_context
Créez une Spinbox pouvant être affichée dans HEX avec Tkinter
Créez un graphique des devises qui peut être déplacé avec Plotly (1)
[Python] Code qui peut être écrit avec la mort cérébrale au début lors du scraping en tant que débutant
Module de traitement du signal acoustique qui peut être utilisé avec Python-Sounddevice ASIO [Application]
Créez une application Web qui peut être facilement visualisée avec Plotly Dash
Optimisation mathématique pour un travail gratuit avec Python + PuLP
Python-Sound device Module de traitement du signal acoustique ASIO [Basic]
Correction d'un bug où node.surface ne pouvait pas être obtenu avec python3 + mecab
Convertir un mémo à la fois avec Python 2to3
Envoyez des newsletters en une seule fois avec Gmail
[Python3] Code qui peut être utilisé lorsque vous souhaitez modifier l'extension d'une image à la fois
Notes pour créer des figures pouvant être publiées dans des revues avec matplotlib
Déplacement de Raspberry Pi à distance afin qu'il puisse être connecté à une LED avec Python
Formatez les données DataFrame avec Pytorch sous une forme pouvant être entraînée avec NN
Jusqu'à ce que vous puissiez utiliser youtube-dl avec Synology (DS120j)
Fonctions pouvant être utilisées dans l'instruction for
Construire un Sphinx qui peut être écrit avec Markdown
Effacez les fichiers image à la fois avec un seul support
Mettre à jour plusieurs tables à la fois avec pandas to_sql
Convertissez plusieurs fichiers proto à la fois avec python
Présentation de la commande "Glances", un outil de surveillance compréhensible en un coup d'œil, sur Mac
Convertir des images du SDK FlyCapture en un formulaire pouvant être utilisé avec openCV
[auto-ohin] Présentation de auto-ohin, un outil de ligne de commande qui peut imprimer automatiquement tout à la fois [sceau électronique]
[Python] Introduction au scraping WEB | Résumé des méthodes pouvant être utilisées avec webdriver
Analyse morphologique et tfidf (avec code de test) pouvant être effectuée en 1 minute environ
Serveur de partage de fichiers réalisé avec Raspberry Pi pouvant être utilisé pour le travail à distance