<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Aldo Ferlatti</title>
    <description>The latest articles on DEV Community by Aldo Ferlatti (@aldo95).</description>
    <link>https://dev.to/aldo95</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F892049%2Fc31f3ee2-e55d-4015-8dd8-420a10aed41c.jpeg</url>
      <title>DEV Community: Aldo Ferlatti</title>
      <link>https://dev.to/aldo95</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aldo95"/>
    <language>en</language>
    <item>
      <title>Estimation of text complexity</title>
      <dc:creator>Aldo Ferlatti</dc:creator>
      <pubDate>Thu, 24 Nov 2022 12:46:03 +0000</pubDate>
      <link>https://dev.to/aldo95/estimation-of-text-complexity-4oo7</link>
      <guid>https://dev.to/aldo95/estimation-of-text-complexity-4oo7</guid>
      <description>&lt;p&gt;Medium post: &lt;a href="https://medium.com/@ferlatti.aldo/estimation-of-text-complexity-c113d111e29f" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;To acquire new knowledge and insights in a complex field such as data science, machine learning, or any other scientific filed, a person needs to practice a lot (ofc), but a big chunk of time goes to reading and researching papers in the correlated field. Any of you who have experience with research, are aware of how challenging it can be reading just a single paper: understanding the concepts and connecting all the terms to build a complete idea. Someone might think what is there to understand, it’s “Just a bunch of words put together to form complex sentences to display someone’s thoughts.”, and I would agree with them. However, getting to a level where someone can easily read and comprehend scientific papers requires years of experience and a tone of reading. For that reason, starting gradually would be beneficial for a complete beginner, like first year students, to grasp new vocabulary needed for understanding such texts.&lt;/p&gt;

&lt;p&gt;This post will go through the process of making a tool for paper complexity evaluation based on word frequency and academic vocabulary lists (no AI for this post).&lt;/p&gt;

&lt;h2&gt;
  
  
  AWL and low frequency words
&lt;/h2&gt;

&lt;p&gt;Before even beginning any work, I needed to decide on the method of measurement of complexity. The problem is that defining something as difficult or easy is a subjective statement and can’t be generalized effectively. Because of that I turned to splitting the problem in smaller variables that can quantify the complexity in an acceptable and generic way.&lt;/p&gt;

&lt;p&gt;The two variables used to calculate the complexity are the ratio of low frequency words and academic words (AWL) present in the document.&lt;/p&gt;

&lt;p&gt;The Academic Word List (AWL) is a predefined list of words, as the name suggests, used primarily in academic environments. It is closely tied to the academic language, defined as specialized language, both oral and written, of academic settings that facilitates communication and thinking about disciplinary content [&lt;a href="https://www.researchgate.net/publication/227762410_Words_as_Tools_Learning_Academic_Vocabulary_as_Language_Acquisition;%20https://doi.org/10.1002/RRQ.011" rel="noopener noreferrer"&gt;source&lt;/a&gt;]. Higher use of academic words decreases readers comprehension [&lt;a href="https://doi.org/10.2307/3587951" rel="noopener noreferrer"&gt;source&lt;/a&gt;].&lt;/p&gt;

&lt;p&gt;Word frequency is a good indication and measurement of a person’s vocabulary size. High frequency words are more widely used by majority of people and are therefore processed faster and more easily. High frequency words are the first to be learned, also, word frequency is correlated with text coverage, where a small number of high frequent word is enough to cover 80% of a typical written text. By logic of exclusion, texts that contain more low frequency words are therefore more complex and harder to understand.&lt;/p&gt;

&lt;p&gt;For reasons mentioned above, I selected AWL and low frequency words ratios as complexity measurement of a given text. The higher the ratios, the more complex is the processed text. For comparison purpose: a children story (like The little mermaid) has a AWL ratio of 1.5% and low frequency words of 0.6%, while a scientific paper has 19% and 3.5% respectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before jumping into code
&lt;/h2&gt;

&lt;p&gt;Before jumping to the code and process there are a few things needed to be set up. Firstly, install the necessary packages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.nltk.org" rel="noopener noreferrer"&gt;&lt;strong&gt;NLTK&lt;/strong&gt;&lt;/a&gt;: for token processing&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pandas.pydata.org" rel="noopener noreferrer"&gt;&lt;strong&gt;pandas&lt;/strong&gt;&lt;/a&gt;: for faster data processing and manipulation&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pymupdf.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;&lt;strong&gt;PyMuPDF&lt;/strong&gt;&lt;/a&gt;: pdf reader and word extractor package&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the main ones. The whole list you can find in the requirements.txt file on the GitHub repository.&lt;/p&gt;

&lt;p&gt;Secondly, find and prepare the needed word lists. For the AWL database, I combined the common list of 570 word families and a more recent list from a &lt;a href="https://www.kaggle.com/datasets/jimregan/new-academic-word-list" rel="noopener noreferrer"&gt;Kaggle&lt;/a&gt; post which contains an updated version. The AWL data frame contains 1439 words. For the low frequency word list, I extracted words with frequency lower than 1%, resulting in a list of 36621 words. Both lists are in a base lexical form which means before searching for concurrences, tokens must be preprocessed into base lexical form.&lt;/p&gt;

&lt;p&gt;Additionally, to the corpus processing, I implemented a basic API for testing (written with Flask). However, this part wont be covered in this post and you can find it on the git link at the end of this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Process (code)
&lt;/h2&gt;

&lt;p&gt;The process steps are as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Load document (PyMuPDF package).&lt;/li&gt;
&lt;li&gt;Preprocess document text: transformations needed to bring the tokens to their basic form (NLTK package).&lt;/li&gt;
&lt;li&gt;Get sample: in case of long documents, extract a representative random corpus.&lt;/li&gt;
&lt;li&gt;Calculate AWL and low frequency words ratios (pandas package).&lt;/li&gt;
&lt;li&gt;Extract complexity level.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Load document&lt;/strong&gt;: to load and work with pdf documents I am using PyMuPDF library. The package has a lot of functionality for pdf manipulation, but for my case, I need just loading and word extraction functions. For now, this step supports only pdf documents but it can be easily enough modified to support other common text documents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Preprocess text&lt;/strong&gt;: after getting the list of all words from the document, I preprocess every word. The transformations are as follow: 1. Lower case the whole corpus; 2. Tokenize the corpus; 3. Remove punctuations; 4. Remove stop words; 5. Remove numbers; 6. Lemmatize the tokens; 7. and finally remove single letters tokens.&lt;br&gt;
The preprocessing was made with NLTK package.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Get sample&lt;/strong&gt;: this step is only for longer documents. If the document is longer than 50 pages, I extract randomly 30 pages. Additionally, if the final corpus has more than 10k tokens, I extract at random 10k tokens. This step serves to increase efficiency: a randomly selected 10k long corpus has showed to be representative enough for the whole document estimation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Calculate ratio&lt;/strong&gt;: the aim is to find the ratio of AWL words and low frequency words. For a faster processing, I convert the corpus to a Pandas DataFrame. I calculate the ratio by dividing the number of words found in the earlier built list and the size of the corpus (standard percentage calculation).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get complexity level&lt;/strong&gt;: the following matrix determines the complexity level, where 1 indicates low complexity and 5 high complexity. The x axis is determined by the AWL ratio (converted to index) while the y axis by the low frequency words ratio. Of course, this matrix can (and should) be optimized.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv8nvg3mmqrpv4p6zszd7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv8nvg3mmqrpv4p6zszd7.png" alt="Complexity level matrix: top-left is low complexity, bottom-right is high complexity" width="450" height="359"&gt;&lt;/a&gt;&lt;/p&gt;
Complexity level matrix: indexes are calculated from respective ratios.



&lt;p&gt;What follows is the core function of the calculation which covers all the above described steps:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Link to GitHub repository of the project: &lt;a href="https://github.com/AldoF95/document-checker" rel="noopener noreferrer"&gt;link&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Personally, I think this would be a great tool for professors and new students that just embarked on the scientific path. Instead of just sending students random papers for reference, this would first indicate if a student would be capable of understanding the necessary concepts described in the research.&lt;/p&gt;

&lt;p&gt;If you reached the end, thank you for your time. Let me know what you think of the idea of a complexity checker tool and any suggestions for a better variable selection are welcomed.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;My goal is to simplify complexity. I just want to build stuff that really simplifies our base human interaction. -Jack Dorsey&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>gratitude</category>
    </item>
    <item>
      <title>React Native + Tensorflow.js - implementing a model</title>
      <dc:creator>Aldo Ferlatti</dc:creator>
      <pubDate>Fri, 15 Jul 2022 11:36:49 +0000</pubDate>
      <link>https://dev.to/aldo95/react-native-tensorflowjs-implementing-a-model-2pj6</link>
      <guid>https://dev.to/aldo95/react-native-tensorflowjs-implementing-a-model-2pj6</guid>
      <description>&lt;p&gt;Original source: &lt;a href="https://medium.com/@ferlatti.aldo/react-native-tensorflow-js-implementing-a-model-daad1a2c7f30"&gt;Medium&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are three reasons why I decided to write this post:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sometime ago I came upon an &lt;a href="https://towardsdatascience.com/building-a-machine-learning-web-application-using-flask-29fa9ea11dac"&gt;article &lt;/a&gt;about how to implement a machine learning model with React. The article was about implementing a simple Gaussian Naïve Bayes binary classifier made with scikit-learn which ran on a Flask backend, while the front was made in React. Obviously, it is a very needed skill and I recommend everyone to read it. However, I had a different problem. What if my model needs to be loaded onto the device, needs to be mobile compatible, it is more than 200MB in size and is made with &lt;em&gt;Tensorflow&lt;/em&gt;? The ‘simple’ server solution doesn’t work anymore.&lt;/li&gt;
&lt;li&gt;A claim made on &lt;a href="https://venturebeat.com/2019/07/19/why-do-87-of-data-science-projects-never-make-it-into-production/"&gt;VentureBeat &lt;/a&gt;says that 87% of data science projects never make it into production. That means that only 1 in 10 project are actually being used. Considering all the money and time (a lot of time) needed for developing a model, the odds are not very motivating. After 9 projects you spend your time and efforts on, end up in some cloud folder (because maybe someday will be used), you start to question if this is the right way and if your next project will also be a waste of time.&lt;/li&gt;
&lt;li&gt;Lastly, not every company has a data science team to build models and a development team to implement the said models. Sometimes, if you want your model to be used by people, you need to put them out there by yourself or nobody will.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Following these points, I wanted to write about a method to put to use our hardly made and time consuming models out there, in the world, by ourselves.&lt;/p&gt;

&lt;p&gt;Here I will not write about building the model (it has already been built) but only about its implementation and use.&lt;/p&gt;

&lt;p&gt;There are two paths to choose for mobile development: native code or cross-platform. As the choice of development can vary, so it can the choice for model processing. If you prefer native code, then a tensorflow-lite approach would be a better option, on the other hand, a cross-platform approach like React Native, allows to transfer knowledge from the web development into mobile, consequentially making &lt;a href="https://www.tensorflow.org/js"&gt;TensorFlow.js&lt;/a&gt; (tfjs) a good choice.&lt;/p&gt;




&lt;p&gt;As you probably already guessed, in this article I’ll be using the cross-platform path, therefore &lt;em&gt;tfjs&lt;/em&gt; will be used as a central library. For the conversion part we need the python library:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install tensorflowjs&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And because we are trying to implement it with React Native, we need the adapter for the framework:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i @tensorflow/tfjs
npm i @tensorflow/tfjs-react-native
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The implementation is done in four steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Transform the model so it can be loaded onto the device and be used with &lt;em&gt;tfjs&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Load the model&lt;/li&gt;
&lt;li&gt;Transform the input (image) in a way it can be fed to the model&lt;/li&gt;
&lt;li&gt;And finally make predictions&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  Model transformation
&lt;/h2&gt;

&lt;p&gt;Once you trained your model and are satisfied with the result, you save the entire model as a SavedModel format. The SavedModel format is a directory containing a protobuf binary and a TensorFlow checkpoint which can be loaded with tensorflow using the &lt;em&gt;load_model&lt;/em&gt; function. But this format is not suitable for mobile and cannot be loaded inside Tensorflow.js library. For that, &lt;em&gt;tfjs&lt;/em&gt; has a built-in converter which can convert a SavedModel format into a javascript compatible format (JSON + weights: more about it later).&lt;/p&gt;

&lt;p&gt;To convert a saved model, use the following command. Be sure you are inside the root directory, where your model is saved:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;tensorflowjs_converter --input_format=tf_saved_model --saved_model_tags=serve --weight_shard_size_bytes=30000000 "path_to_your/model/" "converted_model"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;What does it do? It is capable to convert from 3 types of models (SavedModel, Frozen Model and from Tensorflow Hub). Because of that, we need to specify what type is the input model (&lt;em&gt;input format&lt;/em&gt;). The output format is an JSON file with the dataflow graph and weight manifest of the model, together with a collection of binary weights files.&lt;br&gt;
If the &lt;em&gt;shared size&lt;/em&gt; is smaller than the total size of the model’s weights, then the weights are sliced in multiple files. However, to load the model with &lt;em&gt;tfjs&lt;/em&gt;, we need weights in a single file. Therefore, if you put a small shared size, keep in mind that you need to merge the output files into one file. The last two lines represents the input path, or the position of your model, and the output directory path where the generated files will be stored.&lt;/p&gt;

&lt;p&gt;After running the above command the result should be a &lt;em&gt;model.json&lt;/em&gt; and a group1-shard\of\ binary files (in our case, it should be just one shard of weights).&lt;/p&gt;

&lt;p&gt;Before jumping to the application, we need to import all the necessary packages, and more importantly the files we just created with the converter.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h2&gt;
  
  
  Loading the model
&lt;/h2&gt;

&lt;p&gt;The next step is to load the model which, thanks to &lt;em&gt;tensorflow&lt;/em&gt; and its simple api, is basically a one liner. &lt;em&gt;Tfjs_allows to load graph models and layered models. Since this is a Keras sequential model, we will load a Layered model with _loadLayersModel&lt;/em&gt; function. We load the weights and the &lt;em&gt;json&lt;/em&gt; in one go and to do so we use the helper from the react-native adapter &lt;em&gt;bundleResourceIO&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;After this, the model is loaded and ready to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Input image transformations
&lt;/h2&gt;

&lt;p&gt;Now that we have our model loaded, we need to feed it data. But before that we need do some transformations so it would be compatible with the input shape. My model is for image classification and require a tensor with a size of an image of 300x300 pixels. The input depends on the model and the training of it, so you need to transform it in the way model learned it before. For this I will transform a local image into base64 encoding and then transform it into a tensor.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Make predictions
&lt;/h2&gt;

&lt;p&gt;Just as easy it was to load the model, making a prediction is the same. So yeah, a one liner. The &lt;em&gt;predict&lt;/em&gt; function can do a prediction on a batch of images, we only need to split the result based on the batch size.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Wrap everything together
&lt;/h2&gt;

&lt;p&gt;The only thing left to do is to call our functions. However, before using any &lt;em&gt;tfjs&lt;/em&gt; methods, we need to load the package with &lt;strong&gt;tf.ready()&lt;/strong&gt;, only after that we can use the &lt;em&gt;tensorflow&lt;/em&gt; package. We export this function so we can call it later from wherever we want in the application.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;p&gt;&lt;strong&gt;Congratulations!&lt;/strong&gt; Now you can run inferences on your mobile device. In this case, the _tfjs_library was used only for loading and predictions, but it also has all the tools for training models. I invite you to experiment with it and let me know if it even makes sense to train a model on a mobile device, and if it does, up to what reasonable point.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Sometimes it is the people no one can imagine anything of who do the things no one can imagine. ― Alan Turing&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>reactnative</category>
      <category>machinelearning</category>
      <category>mobile</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
