<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Tyler Doll on Medium]]></title>
        <description><![CDATA[Stories by Tyler Doll on Medium]]></description>
        <link>https://medium.com/@tdoll?source=rss-7e13dbcaebb3------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/2*CgDzDT-_u1ZTMmz5TTvWJg.jpeg</url>
            <title>Stories by Tyler Doll on Medium</title>
            <link>https://medium.com/@tdoll?source=rss-7e13dbcaebb3------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 02:17:10 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@tdoll/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[My Favorite Design Pattern]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/@tdoll/my-favorite-design-pattern-2c068c97a92f?source=rss-7e13dbcaebb3------2"><img src="https://cdn-images-1.medium.com/max/2600/0*aWt3plO15TCPkB2N" width="4062"></a></p><p class="medium-feed-snippet">In software engineering you&#x2019;ll come across many different design patterns. In my years I have seen my fair share, however I am garbage at&#x2026;</p><p class="medium-feed-link"><a href="https://medium.com/@tdoll/my-favorite-design-pattern-2c068c97a92f?source=rss-7e13dbcaebb3------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://medium.com/@tdoll/my-favorite-design-pattern-2c068c97a92f?source=rss-7e13dbcaebb3------2</link>
            <guid isPermaLink="false">https://medium.com/p/2c068c97a92f</guid>
            <dc:creator><![CDATA[Tyler Doll]]></dc:creator>
            <pubDate>Thu, 12 Aug 2021 23:02:20 GMT</pubDate>
            <atom:updated>2021-08-12T23:02:20.040Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[7 Tips for Programmers]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/@tdoll/7-tips-for-programmers-d37de6fb99a7?source=rss-7e13dbcaebb3------2"><img src="https://cdn-images-1.medium.com/max/2600/0*97wYApja-VVtVCOB" width="6000"></a></p><p class="medium-feed-snippet">Just to get you started</p><p class="medium-feed-link"><a href="https://medium.com/@tdoll/7-tips-for-programmers-d37de6fb99a7?source=rss-7e13dbcaebb3------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://medium.com/@tdoll/7-tips-for-programmers-d37de6fb99a7?source=rss-7e13dbcaebb3------2</link>
            <guid isPermaLink="false">https://medium.com/p/d37de6fb99a7</guid>
            <category><![CDATA[tips]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[month-of-programming-tips]]></category>
            <dc:creator><![CDATA[Tyler Doll]]></dc:creator>
            <pubDate>Thu, 09 Jan 2020 17:01:01 GMT</pubDate>
            <atom:updated>2020-06-11T17:13:15.172Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[13 Quick Programming Tips]]></title>
            <link>https://medium.com/series/a-month-of-programming-tips-8a4fffe822e5?source=rss-7e13dbcaebb3------2</link>
            <guid isPermaLink="false">https://medium.com/p/8a4fffe822e5</guid>
            <dc:creator><![CDATA[Tyler Doll]]></dc:creator>
            <pubDate>Wed, 01 Jan 2020 20:26:35 GMT</pubDate>
            <atom:updated>2020-06-11T17:14:34.881Z</atom:updated>
            <content:encoded><![CDATA[<h3>Welcome</h3><p>When I first started programming I spent a lot of time scraping the internet for tips and tricks to make me a better programmer. I thought that if I could learn as much as possible from others, the less mistakes I would have to make myself.</p><p>Over the last decade I have learned a lot, so I’ve compiled a list of tips and tricks that I want to share with all of you.</p><h3>Use Variables for Constants</h3><p>When working on a team, or coming back to something you wrote months later is always a challenge. By taking advantage of variables and naming them properly, you can save yourself some headaches. This one is pretty simple. Anytime you are about to use something that is constant, make it a variable. The reason for this is it helps you to avoid mistakes and makes your code more maintainable. Don’t worry about memory, a lot of languages are smart enough to optimize the usage. Here’s an example:</p><p>Instead of:</p><pre>balance = 1000 – 50 – 400 – 200</pre><p>Do:</p><pre>income = 1000<br>internet = 50<br>savings = 400<br>car_payment = 200<br>balance = income - internet - savings - car_payment</pre><p>Instead of:</p><pre>if queue.size() &gt; 10:</pre><p>Do:</p><pre>MAX_QUEUE_SIZE = 10</pre><pre>if queue.size() &gt; MAX_QUEUE_SIZE:</pre><p>By not repeating constants, the code is easier to maintain, easier to read, and less prone to bugs; especially as your code grows. Instead of having to go through all of your files and find &amp; replace a constant, you can store it in one place and change it when you need to. When someone else who is less familiar with your code comes along, they can read it and understand it faster. If you do have to change the value, you don’t have to worry that you missed a place and introduced a bug.</p><h3>Don’t Over Comment</h3><p>Comments are important. They can help programmers navigate through code and add to documentation. However, they can also be a maintenance nightmare.</p><p>Imagine you come across a function that appears to do one thing, but has a comment that describes something completely different. Which one is correct? Which one wasn’t updated properly? To avoid this, don’t write comments that can be better said in code. Comments should provide insight into things you can’t see in the code, not describe the code. They should provide new information, not just repeat what the code is already telling you. For example describing the intent of the function (not what it does, but what the goal is), or writing a reason for doing something a certain way.</p><p>Don’t:</p><pre># Commit session to database<br>db.session.commit()</pre><p>Do:</p><pre># We need to commit at this point to avoid a race condition with<br># another thread that is also trying to access the database.<br>db.session.commit()</pre><h3>Learn Keyboard Shortcuts</h3><p>The faster you are at getting things done, the better (unless you’re just putting out garbage, then that’s too fast). Especially in a business setting. Remember, people don’t pay for code they pay for the value the software provides. The only person who will really appreciate your code is you and your development team. So the faster you can write code, the faster you can test it, and the faster you can ship it.</p><p>By learning and using keyboard shortcuts, your workflow will improve as you don’t have to spend time moving the mouse around or doing things in five steps that can be done in one. However let me be clear, this does not mean to sacrifice code quality for speed. That is a balance and is a different topic, this is just about improving your productivity so you can focus more on writing quality code and less on other supplemental tasks.</p><h3>Automate, Automate, Automate</h3><p>Before I go further, you should not automate every little thing. Think about the task you are doing and see if the amount of time it will take to automate will give you a positive return. There is no sense in automating a task you will only do once. If you’re doing a task, and you know you (or others) will be doing it multiple times in the future, or if you (or others) find yourself doing the same things over and over it might be worth automating. Some examples include setting up a development environment, building your software, testing/running software, or running the same commands over and over.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/571/0*ek0HDfIkWQn5DJSR.png" /><figcaption><a href="https://xkcd.com/1205/">https://xkcd.com/1205/</a></figcaption></figure><h3>Use Functions Liberally</h3><p>Use functions to make your code more readable. Initially you might think that having a bunch of function calls everywhere would impact performance, and you would be right if we were still in the days of dumb compilers and little to no compile time optimizations. In modern times this is not much of a concern except for in the most extreme cases. For 99% of the time, the pros of using a lot of little functions outweigh the cons.</p><p>By using functions liberally, you can better adhere to the single purpose principle and really simplify your functions. This makes for easier-to-understand logic, better readability, better traceability, and better testability. Trying to follow the flow of a 200 line function with 7 nested for-loops inside 16 different if-else cases with 3 try-catch statements is awful. If you do this, stop.</p><p>Functions aren’t just for the DRY (Don’t Repeat Yourself) principle. You can use them for code that you will only ever use once and that’s totally OK. This has the added benefit that if you ever do need to use it again, you’ve already set yourself up nice to do so.</p><p>However, as with most things don’t go overboard and make more functions than you really need. If you’re starting to spread your code across many directories and files you might be going too far. The point of this tip is to help prevent <a href="https://www.techopedia.com/definition/9476/spaghetti-code">spaghetti code</a>, not make it worse.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/740/0*HPkeslkh1lZvwsA5.png" /><figcaption><a href="https://xkcd.com/1513/">https://xkcd.com/1513/</a></figcaption></figure><h3>Use the Language</h3><p>In today’s world most popular languages are very feature-full and have been worked on for some time. This means that a lot of common use cases and tasks have been considered and the standard library or language syntax comes with these things baked in. Knowing what the language you use can do is very important to increasing your productivity and doing things the best way possible.</p><p>For instance, most languages today come with sorting algorithms built in. Before you go off and start to write a bubble sort or heap sort algorithm yourself, check if your language already has an algorithm that will solve your problem. For example in <a href="https://docs.python.org/3.8/howto/sorting.html">Python there are two built-in ways to sort a list: using the sorted() function and the <em>list</em>.sort() function</a>. They both use the <a href="https://en.wikipedia.org/wiki/Timsort">Timsort</a> algorithm, which performs fairly well on most real-world data. Obviously in this example there may be cases where you want to use a very specific algorithm, but for most of the time when you don’t care how the sorting happens it will suffice.</p><p>Using the language is even more important if you’re considering pulling in third party libraries. If can you accomplish your task using what’s available to you in the standard libraries, it will help keep your project small, simple, and stable. The less code you have to manage the better.</p><h3>Write Automated Tests</h3><p>Are you writing unit tests? Integration tests? Any kind of tests? If you are, I hope they are automated. If they aren’t, or you aren’t writing them, you need to start. Automated tests are the best defense against introducing bugs and breaking things. Anything going into production or that will be used by others who expect it to work, needs automated tests.</p><p>There are tons of things out there on how to write unit tests, integration tests, etc. so I won’t go into all of that as there are books written on the subject, but I will try to convince you that it is worth your time.</p><p>How many times have you modified code either to integrate a new feature or to refactor existing code? How many times have you done this and found out that your changes broke something in some other part of the code? Now imagine that you didn’t catch this but one of your customers did and it caused them to lose their customers. That’s not a very fun place to be in now is it? How nice would it have been to catch that break before you rolled out your changes to production? This is where automated tests come in.</p><p>If you have any sort of development pipeline, automated tests should be a part of it. For example where I work any time we build our software or push it to our repository, all of our tests are ran to ensure that the software still works. If it doesn’t pass a test, it can’t be merged into the baseline.</p><p>Obviously getting perfect code coverage (testing every little thing for every possible case) is practically impossible. That’s why you should focus on the main goals of your software and always test that the most important things work every time, at least.</p><p>By using automated tests your software will be more reliable, easier to maintain, and of higher quality. Yes there is a cost included by spending time writing tests, but the time you save in the long run by not debugging complex edge cases and fixing them is more than worth it.</p><h3>Simple and Explicit Over Clever</h3><p>Many times, people who are new to programming will get excited and try to find a way to do complex things in as little lines of codes as possible. Usually the less code the better, but this like all things can be easily abused and done incorrectly.</p><p>Often when you try to do complex things in a small amount of code, you’re making some trade offs, usually readability. By compressing a lot of logic down you run the risk of making your code hard to understand and follow at first glance. This can lead to a lot of issues when working in teams or when you revisit code later on.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/550/0*WFbVpMvW1ZTbqA_0.png" /><figcaption><a href="https://xkcd.com/974/">https://xkcd.com/974/</a></figcaption></figure><p>Your code should accomplish the goal in the simplest way possible such that it is easy to understand and easy to maintain by not only yourself but your team. Even if this means turning that one cool little one liner into multiple lines, it may be worth it. Code is executed by computers but is read by humans; not only that but code is almost always read more than it is written, so optimize for the common case.</p><p>Don’t:</p><pre>return val1 if (val2 if (reduce(lambda x, y : x + y, my_list) &lt;= 10) else val3) % 2 == 0 else val4</pre><p>Do:</p><pre>def foo(my_list):<br>  MAX_SUM = 10<br>  sum = reduce(lambda x, y : x + y, my_list)<br>  val_to_check = val2 if sum &lt;= MAX_SUM else val3<br>  is_even = val_to_check % 2<br>  return val1 if is_even else val4</pre><h3>Don’t Solve a Problem You Don’t Have</h3><p>Once you build up confidence in your ability to program, you’ll come across things that you will think need solving. For example you’ll be writing a function for a specific reason, but you’ll think “oh if I write it this other way instead we can also use it for this one case that we may or may not come across in the future, but if we do come across it it’ll work!”. Or perhaps you’ll be designing a class and decide to add multiple different kinds of constructors “just in case we need them”. Welp, just a heads up you will probably never need them.</p><p>It can be tempting to try to solve problems in advance, and sometimes that is worth it, BUT only when you know for sure that you will need to do those things. If there is any uncertainty about it, you’re better off just not doing it now. If you write your code with the <a href="https://stackify.com/solid-design-open-closed-principle/">open-closed principle</a> in mind, it shouldn’t be a big deal to add things later when you actually need them.</p><h3>“Move fast and break things”</h3><p>“Move fast and break things”, once the motto of Facebook CEO Mark Zuckerberg, really is good advice. When developing and learning don’t be afraid of breaking things. The best way to learn is to fail fast and correct. You can spend all day thinking about “will this work” or you can jump straight to the answer and try it.</p><p>If your development environment is setup appropriately, you won’t have to worry about impacting others while you break everything (do NOT try this in production, you will quickly regret it). So give things a shot and see what happens.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/161/0*4SkJHmtmfNeUT1_V.png" /><figcaption><a href="https://xkcd.com/1428/">https://xkcd.com/1428/</a></figcaption></figure><h3>Learn Your Tools</h3><p>As a programmer you will be spending a lot of time using other software. IDEs, terminal shells, SSH clients, etc. are all things you will eventually come across. When you do, you should be prepared to learn how to use them.</p><p>If you use something like Eclipse for your development, you should take the time to learn about its features and capabilities beyond just using it as a text editor. You don’t have to use everything, but you should learn what tools are available to you.</p><p>As another example, do you use PuTTY everyday to SSH into a machine? Are you typing your user password every time? Well you should really learn how to configure PuTTY to use a SSH key instead (<a href="https://www.ssh.com/ssh/putty/windows/puttygen">here is a link</a> incase you’re curious).</p><p>If you take some time to learn your tools, I promise you will have a better experience and see productivity gains as you learn.</p><h3>Programming Languages are aTool in a Toolbox, not the Toolbox</h3><p>Often times I see people asking questions like “should I learn language X or Y?” or saying things like “language A is way better than language B, why would you ever use that?”</p><p>Well let me tell you a secret, saying things like the above is kind of pointless. Languages are a tool in your toolbox, not your toolbox. You should know multiple languages and more importantly know when to use one over the other. They were all designed to solve different problems and thus have different strengths and weaknesses.</p><p>Need your software to execute safety-critical tasks in a real-time environment? Well you probably don’t want to use Python for that then. Want to write a quick script to automate something trivial? Python is probably a good answer in this case.</p><p>If you are just starting off and are trying to decide what languages to learn, pick languages that solve different problems. C++ for performance applications, Python for scripting, JS/HTML/CSS for web development, SQL for databases, just to give some examples.</p><h3>Learn a CLI Editor</h3><p>Inevitably at some point you will be forced to work in an environment where you don’t have access to a normal GUI. For instance if you have to SSH into a linux server to do your work.</p><p>In situations like the one mentioned above, it helps to know how to work in a Command Line Interface (CLI) editor such as Vim, Emacs, Nano, etc. Picking one is not super important, as long as it’s fairly common and you learn it well enough to get around.</p><p>Personally I would recommend Vim because it is very popular and comes standard, or is at least easily accessible via package managers like Yum.</p><p>By knowing how to use a CLI editor, you not only know a new tool but you will be able to work in nearly any environment and be productive.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/740/0*DKrvWuNYavHWg0L4.png" /><figcaption><a href="https://xkcd.com/378/">https://xkcd.com/378/</a></figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8a4fffe822e5" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A Machine Learning Approach to Automated Customer Satisfaction Surveys]]></title>
            <link>https://medium.com/data-science/a-machine-learning-approach-to-automated-customer-satisfaction-surveys-946d2604e309?source=rss-7e13dbcaebb3------2</link>
            <guid isPermaLink="false">https://medium.com/p/946d2604e309</guid>
            <category><![CDATA[automation]]></category>
            <category><![CDATA[sentiment-analysis]]></category>
            <category><![CDATA[speech-recognition]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[machine-learning]]></category>
            <dc:creator><![CDATA[Tyler Doll]]></dc:creator>
            <pubDate>Sun, 24 Nov 2019 04:37:10 GMT</pubDate>
            <atom:updated>2020-06-21T18:15:34.317Z</atom:updated>
            <content:encoded><![CDATA[<h4>by Tyler Doll, Matthew Bussing, Kai Nichols, Sidney Johnson</h4><p>While going through some of my documents, I came across a paper I was a part of in college that I thought would be perfect to share. For context, this paper was written for one of my classes where we had a project sponsored by a company. In my case, I worked with Matthew Bussing, Kai Nichols, and Sidney Johnson on a project sponsored by ProKarma to try to automate customer satisfaction surveys. This paper was originally published on our course website <a href="http://cs-courses.mines.edu/csci370/FS2018/FinalReport/ProKarma.pdf">here</a>. It has been adapted to fit this format and the original is embedded at the end of the article. Enjoy!</p><h3>INTRODUCTION</h3><p>Natural language processing (NLP) is a broad discipline concerning the problems of capturing, analyzing, and interpreting human<br>language. In particular, NLP can be used to evaluate human speech<br>in order to determine different qualities about its speaker, context,<br>and sentiment. These evaluations can be used to inform human-computer interaction, accessibility, automation, and statistical analysis of natural language.</p><p>This NLP project was proposed by the Edge Intelligence group at<br>ProKarma, an IT solutions company headquartered in Nebraska offering digital transformation and analytics consultancy. ProKarma’s<br>Edge Intelligence group is researching ways to improve customer<br>service by incorporating machine learning to augment customer<br>service calls in the telecommunications industry. One approach to<br>improve customer service satisfaction includes determining customer attitudes toward particular products and by performing sentiment and topic analysis on customer call data, effectively allowing for automated customer service surveys.</p><p>Automating customer satisfaction data collection would provide<br>actionable information about consumer attitudes toward products<br>and services at much higher response levels than simply relying on<br>on customers staying on the line to finish a phone survey. This automated system could run parallel to the traditional phone surveys<br>currently in place at many wireless carriers. Automated sentiment<br>analysis on products mentioned during the call could be validated<br>against instances where the customer finished the post-call phone<br>survey.</p><p>Because of the huge number of variables involved in natural language, traditional analytic methods would be prohibitively difficult<br>to adapt to this purpose. Machine learning algorithms allow simple linear interpolation of audio data as well as powerful pattern<br>finding tools. For this reason, neural networks were developed for<br>both topic and sentiment classification. These models find patterns<br>between product types and consumer attitude which provides the<br>information required to generate automated customer satisfaction<br>surveys from customer call audio.</p><h3>METHODS</h3><p>Three models were required to accomplish the ultimate goal of an<br>automated survey process: speech-to-text transcription, sentiment<br>modeling, and topic modeling.</p><ul><li>Speech-to-text transcription: In order to automate transcription of call data, a strategy for automated speech recognition (ASR) was required. An accurate and high-performance implementation of ASR was crucial in order to perform later topic and sentiment analyses, which take plain-language transcripts as input. Transcripts were preferable to pure audio as inputs for two reasons: firstly, topic modeling cannot be performed directly on audio, as topics are strings which must be pulled directly or interpreted from within a text source; secondly, audio files can be useful in detecting vocalized emotion but cannot detect unemotional sentiment (such as a monotonous customer saying “thank you for your help” or a bubbly customer happily saying “my phone won’t turn on”).</li><li>Sentiment model: As sentiment analysis is important to determine customer satisfaction, it was required to develop a machine learning model to detect sentiment (positive, negative, or neutral) towards the customer service representative based on transcribed text input. ProKarma’s Edge Intelligence group previously implemented a bi-directional long short-term memory recurrent neural network (LSTM RNN) trained using open-source datasets such as the Interactive Emotional Dyadic Motion Capture (IEMOCAP) database in order to perform emotion and sentiment classification on acoustics features extracted from audio clips. During this project, our transcript based model is intended to capture overall sentiment rather than from vocal features like the previous acoustic-based model captured.</li><li>Topic Model: To cross-analyze customer sentiment with topics of conversation, classification models were produced to identify concepts and specific subjects in transcripts. Trends in conversational topics can be used to understand both individual customer attitudes toward products and services as well as to understand those of the general customer base.</li></ul><p>These models culminated in an engine for end-to-end audio analysis of customer call recordings. All project code was written using<br>Python 3.6, used Google’s TensorFlow machine learning library via<br>the Keras interface, and used the Python/R Anaconda distribution.<br>Version control was performed using git and GitHub was used for<br>hosting all project repositories. The project was developed using an<br>Agile workflow, and team collaboration and communication was<br>facilitated using the software, Slack.</p><h3>SYSTEM ARCHITECTURE AND DESIGN</h3><p>The aim of this project was to prove it is possible to take a customer<br>service call as input and get data relevant for a customer satisfaction survey as output. The system constructed to accomplish this task, pictured in figure 1, consists of three main models: a speech-to-text model, a topic model, and a sentiment model. The speech-to-text model was trained on web-scraped customer service call audio files. The topic model was trained on a web-scrapped corpus of a wireless carrier’s FAQs and forum posts. The sentiment model was trained on a combined dataset of annotated IEMOCAP transcripts and electronics reviews. The customer service call audio was then passed through the speech-to-text program to generate transcripts, which were then fed into the topic and sentiment models. These two latter models output predictions of overall topics and sentence-by-sentence sentiment tagging. These two outputs were then aggregated to produce visualizations of customer satisfaction indicators such as sentiment over time during the call and sentiment associated with specific topics.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/752/1*x8UOlKd19zzoc1bZ61P30A.png" /><figcaption>Figure 1: Diagram of general system architecture.</figcaption></figure><h3>TECHNICAL DESIGN</h3><p>The use of Convolutional Neural Networks (CNN) for natural language<br>processing is a fairly recent development. CNNs are most<br>well known for their success in image classification from filters’<br>natural proficiency for identifying components of an image like<br>lines and shapes. Whereas a CNN used on images can successfully<br>find patterns in shapes, the filters of a CNN used on language is<br>analogously able to find patterns in n-grams.</p><p>The network used for testing, pictured in figure 2 and elaborated<br>on in figure 3, has two convolutional layers. The first convolutional<br>layer has 64 filters with a filter size of 4, and the second has 32 filters<br>with a filter size of 6. These were starting points to test that the<br>model has functionality. These parameters could be further tuned<br>to improve the accuracy of the model. A larger number of filters<br>and filter sizes in the range of 3–5 are recommended for sentiment<br>analysis using a CNN in order to capture a large amount of contextual<br>information based on the relations between closely adjacent<br>words. The dropout layer in the diagram is intended to prevent<br>overfitting.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/756/1*eyVdWf5rdfWDeY2oiJP81A.png" /><figcaption>Figure 2: Convolutional neural network architecture.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/792/1*Q18uZieSOd0ed6Kv7Z_9tA.png" /><figcaption>Figure 3: CNN layer type, output shape, and number of parameters.</figcaption></figure><p>Latent Dirichlet Allocation (LDA) topic models are widely used for<br>identifying underlying topics in a set of documents. Given K topics<br>to find, an LDA model will sort words in a document into various<br>topics based on the words they appear most frequently with and<br>their respective topics. This works through a generative process<br>where the LDA model assumes the following: a document is composed<br>of an assortment of topics and each topic is composed of<br>an assortment of words. It then reverse engineers this process in order<br>to identify the topics in a corpus. Figure 4 is the graphical plate<br>notation where:</p><ul><li>M is the number of documents</li><li>N is the number of words in a document</li><li>α is the per-document topic distributions</li><li>β is the per-topic word distribution</li><li>m is the topic distribution for document m</li><li>φ_k is the word distribution for topic k</li><li>Z_mn is the topic for the nth word in document m</li><li>W_mn is the specific word</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/692/1*i-u7A7ge2tEtEAzbIBUEFg.png" /><figcaption>Figure 4: Diagram of smoothed LDA model.</figcaption></figure><p>For the purposes of sorting customer service transcript data into<br>topics, an online technical support discussion board and FAQ section<br>of a wireless carrier was used. By using this dataset, the topics<br>could be predetermined and the model could be tuned to identify<br>specific topics. Figure 5 provides examples of topic information<br>which can then be used to identify topics. In order to do this, <br>β was defined in the following way:</p><ul><li>For each topic, all words were initially given a 1 / <em>corpus<br>vocabulary size</em> distribution</li><li>Then words that were predetermined to be more frequent<br>for a given topic were heavily biased (1000 times more weight)</li></ul><p>This enabled the model to bias toward finding specific topics in a<br>document rather than determining its own.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/992/1*vc9Q6TYd-k_0ybEJrun7-g.png" /><figcaption>Figure 5: Example of raw output from the LDA model.</figcaption></figure><h3>DESIGN DECISIONS</h3><p>Some tools were across all sections of the project. The general purpose<br>data science tools used throughout the project include:</p><ul><li>Python: Python is a powerful, general-purpose programming language<br>with a robust set of libraries. It is an industry standard<br>with wide support networks.</li><li>TensorFlow: TensorFlow is an open source library for deployment of high<br>performance numerical computation across different platforms.</li><li>Anaconda: The Anaconda distribution contains a plethora of data science<br>packages, including conda, which is an OS-independent<br>package and virtual environment manager, allowing for easy<br>package installation across machines.</li><li>Jupyter Notebook: Jupyter notebooks are documents which contain text and embedded code which can be easily run within the document.<br>They are simple to share and provide high-quality,<br>interactive output for our python code. The prose-like format<br>of Jupyter notebooks’ interpreter, markdown, and visualizations<br>environment facilitates code and concept collaboration.</li><li>Pandas: Pandas is a powerful python library which is ubiquitous in<br>data science. In this project it was used for managing training<br>and testing data.</li><li>Matplotlib: Matplotlib is a python library for data visualization. In this<br>project it is used for final visualization of sentiment analysis<br>and topic modeling data.</li><li>Pickle: Pickle is a python library for object serialization and data<br>storage. In this project it is useful for exporting model configurations<br>and related dataframes.</li></ul><p>As this was a far-reaching project with many moving parts, a variety<br>of technical tools were required to specifically accomplish the<br>goal of each major utility:</p><h4>Speech-to-text transcription</h4><ul><li>ffmpeg: Due to the way speech-to-text engines process audio<br>files, it is important to use audio encoding that is consistent<br>with that expected by the engine. FFmpeg is a free, lightweight<br>command-line audio encoder that fits seamlessly into<br>our audio processing workflow. The final encoding pattern<br>consisted of mono-channel audio with a 16 kHz sampling frequency,<br>a 16-bit bit depth, and 300/3000 Hz high/low pass<br>filtering to specifically capture voice audio.</li><li>Audacity: Beyond encoding, our data required a small amount of editing, mostly in the form of phrase partitioning. Audacity’s<br>“Silence Finder” utility allowed us to break long audio<br>clips into phrase-long sound bites and export them easily<br>for immediate transcription processing in DeepSpeech.</li><li>DeepSpeech: DeepSpeech is a free speech-to-text engine with<br>a high accuracy ceiling and straightforward transcription<br>and training capabilities. DeepSpeech also comes with pretrained<br>models that can be refined via transfer learning to<br>improve accuracy on any particular type of audio, avoiding<br>the need for extended training times or an extremely large<br>dataset. Our transfer learning process involved removing<br>the final interpretive layer of DeepSpeech, replacing it with<br>a randomly-initialized layer, freezing all sublayers and training<br>the final layer.</li></ul><h4>Topic model</h4><ul><li>gensim: gensim is a general topic modeling library for python<br>that has many useful features. Gensim was used primarily<br>for its LDA model as it is very powerful and easy to train<br>and tweak to our needs.</li><li>NLTK: NLTK stands for Natural Language Toolkit and is a<br>python library used for natural language processing. This library<br>was used for our topic model to normalize documents<br>before running them through our LDA model.</li><li>pyLDAvis: pyLDAvis is a python package used for visualizing<br>LDA models and was used for this project because it<br>interfaces well with gensim. pyLDAvis allowed us to easily<br>visualize our LDA model’s performance.</li><li>Stanford NER: Stanford Named Entity Recognizer model was<br>used for identifying named entities in a corpus such as persons,<br>locations, and organizations. This helped us identify<br>the subject of a document.</li><li>Stanford POS Tagger: Stanford Part of Speech Tagger was used for identifying the part of speech for each word in a corpus. This helped us identify the subject, verb, and object of call transcript sentences.</li></ul><h4>Sentiment model</h4><ul><li>Word Embedding: Tensorflow_hub’s word embedding modules<br>were chosen as input for our neural network classification<br>models since they allow us to map sentences to numerical<br>values and preserving word order information. These<br>modules are easy to implement through tensorflow_hub<br>and come pretrained.</li><li>Manual Feature Selection (MFS): Manual feature selection<br>was used for the SVM and Random Forest classifier models<br>because it allowed faster training, and therefore could handle<br>a larger number of features. This allowed us to train our<br>model to recognize vocabulary specific to the topic at hand.</li><li>(MFS) NLTK Stemming: In manual feature selection, words<br>were stemmed so that words with the same root would be<br>recognized as the same word which reduced our feature<br>space. NLTK’s Stemming module was chosen for ease of use.</li><li>(MFS) Filtering: Words longer than 25 characters, words shorter<br>than 3 characters, words appearing more than 2000 times,<br>and words appearing less than 5 times were all filtered out<br>to reduce the feature space.</li><li>Bigrams: Bigrams were added to the feature space to embed<br>some information on word order.</li><li>Classification Models: A variety of classification algorithms<br>were explored to have comparisons for the accuracy of our<br>models on the training data. The models explored were an<br>SVM classifier, Random Forest classifier, LSTM Recurrent<br>Neural Network, and Convolutional Neural Network.</li><li>Sklearn, Tensorflow, and Keras: Tensorflow and Keras were<br>used for neural network training. Sklearn was used for the<br>other classification algorithms.</li><li>NLTK and NLTK-trainer: NLTK was used for sentiment analysis,<br>since it has several prebuilt sentiment models. This lets<br>us quickly set up a standard model and compare against our<br>own model iterations.</li></ul><h4>PERFORMANCE RESULTS</h4><h4>Speech-to-text transcription</h4><p>DeepSpeech, the automated speech recognition (ASR) engine<br>preferred by our client, is an end-to-end trainable, character level<br>LSTM recurrent neural network. DeepSpeech has been<br>used to produce a very low word error rate (WER), particularly<br>a 6% WER on LibriSpeech, an open-source 1000 hour<br>dataset of natural speech. 6% is approximately the human<br>error rate. Out of the box, DeepSpeech’s generic models returned<br>a 65.4% WER on our customer service call testing<br>data, more than 10x the WER of human processing.<br>This WER was ultimately reduced to approximately 18.7%<br>on the custom model generated using a very small corpus<br>of training data.</p><p>DeepSpeech functions best when translating sentence-length,<br>&lt;10 second audio clips. The processing time required by Deep-<br>Speech to create a transcript per audio clip is between 4 and<br>9 seconds, with a mean of 7.14 seconds. Therefore, 5 minutes<br>of audio could take DeepSpeech almost 4 minutes of<br>processing time.</p><h4>Sentiment model</h4><p>Accuracy of various models were compared on 80/20 split<br>training/testing data made up of the IEMOCAP dataset and<br>a web-scraped dataset of electronic reviews with the sentiment<br>classification accuracies contained in figure 6. These<br>were 3-class classifiers where the sentiment classes were<br>positive, negative, and neutral. Accuracies of different feature implementations were then compared, with results contained<br>in figure 7. Some feature implementations did not easily<br>lend themselves to being run on different classification<br>models, so that data is absent.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7V1WI-l5VkDV32Y8ud7cPQ.png" /><figcaption>Figure 6: Accuracy results of different classifiers for sentiment.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TBYJH4XpFWMXH3NmdX3BNA.png" /><figcaption>Figure 7: Accuracy results of different feature implementations.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/363/1*X3Qav8HEHtv2qxsN8lFRjg.png" /><figcaption>Figure 8: Confusion matrix for training data on the final LSTM model.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/370/1*4i6Nt0s99Wc35o7ox1NvDA.png" /><figcaption>Figure 9: Confusion matrix for testing data on the final LSTM model.</figcaption></figure><p>Among the different datasets and implementations the best<br>results were on Neural Network Classifiers using the tf_hub<br>word embedding module. Of the word embedding modules,<br>the universal sentence encoder outperformed the other modules.<br>A deeper neural network outperformed sklearn’s DNNClassifier<br>under the same feature implementation, and was the<br>highest performer of all the implementations at about 10%<br>higher test set accuracy than the second contender. The best<br>model iteration was an LSTM RNN that used tf_hub’s universal<br>sentence encoder as feature input. This model had a<br>test set accuracy of 77.6% on a combined IEMOCAP and<br>electronic review dataset. Baseline accuracy for randomly<br>choosing a class for 3 classes is 33.3%.</p><h4>Topic Model</h4><p>Using data scraped from a wireless carrier’s online discussion<br>forums and FAQ section, the training data was organized<br>into 5 topics: accounts and services, android products,<br>apple products, network and coverage, and other products.<br>Each of these topics also included some keywords that were<br>seeded into the LDA model with bias (such as “iphone” for<br>apple products, “galaxy” for android products, etc). Using<br>this training data to train the LDA model, it was able to successfully<br>predict the topics on the testing data 57.6% time. Baseline accuracy for randomly choosing a class for 5 classes is 20%. A visualization of this LDA can be found in figure 10.</p><p>The part-of-speech subject identifier (PoSSI) model was trained<br>using corpora included with the Natural Language Toolkit<br>(NLTK) and then tested on the web-scraped wireless carrier<br>data described above. This model was able to produce<br>coherent subject-verb-object (SVO) results, but because the<br>web-scraped dataset is unlabeled, there is not a quantitative<br>way of analyzing the accuracy unless all web-scraped data<br>was hand-labeled for part-of-speech. Hand labeling the entire<br>web-scraped dataset was not in the scope of this project.</p><h4>Visualization and analysis of customer call data</h4><p>Visualizing sentiment over the course of a call showed trends<br>we might expect: a green, positive, first sentence introduction<br>followed by a red, negative, introduction of the problem,<br>and darker greens (i.e. more strongly positive sentiment) towards<br>the end of the call.</p><p>These are promising results that suggest sentiment analysis<br>could be applicable in the context of automating customer<br>satisfaction surveys.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AX1DpaXbNbZ66l-6rRySkg.png" /><figcaption>Figure 10: A visualization of the topics and the vocabulary found in the training corpora.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UVypo8mLg_RPyCQQNHxhyA.png" /><figcaption>Figure 11: Top left: sentiment for each clip of the call displayed over the call transcript; Top right from top down: a heat-map of the intensity of the sentiment of each sentence of the call, a line graph displaying the intensity of the sentiment during each sentence of the call; Middle: the distribution of sentiment among keywords for each category; Bottom: the distribution of probabilities the call belongs into one of the five topic categories.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ypeybXMgLEDaaeE2OaK8ow.png" /><figcaption>Figure 12: Sentiment distribution for sample service keywords.</figcaption></figure><h3>CONCLUSION</h3><h4>Speech-to-text transcription</h4><p>DeepSpeech is highly trainable but, with 120 million parameters,<br>requires massive training corpora, hundreds of hours<br>of training, and expensive equipment. Transfer learning was<br>performed in the form of freezing all sublayers of the model<br>and retraining the final layer. Experimentation with altering<br>previous layers was unable to create improvements. Transfer<br>learning is a viable course of action to customize Deep-<br>Speech for future transcription requirements but should be<br>trained using a greater number of high-quality audio clips.<br>DeepSpeech performed significantly better on our testing<br>data than alternative ASR engines such as Kaldi and CMUSphinx<br>as well as traditional ASR approaches such as Hidden<br>Markov Models.</p><p><em>Future work</em><strong><br></strong>Further improvements could likely be made in preparing<br>low-quality call data for transcription, as well as in post-processing<br>the transcriptions to produce more correct speech<br>(as DeepSpeech is character-level, it sometimes produces<br>nonsense). Retraining the weights of DeepSpeech on a large,<br>industry-specific copora would also likely produce greater<br>accuracy, but would be significantly more expensive — both<br>in computation time and amount of data required.</p><h4>Sentiment model</h4><p>The two biggest impacts on the accuracy<br>of the tested sentiment analysis models were data preparation<br>and model selection. Data preparation and input formatting<br>have a larger impact on a smaller dataset. Model selection<br>has a larger impact on a larger data set. Throughout<br>the various model iterations we tried, three different types<br>of formatting for data input were used:</p><ul><li>Manual Feature Selection (used in SVM and RandomForest-<br>Classifier): Manual Feature Selection was done by using the techniques<br>stemming, filtering, and tokenization. Words were<br>stemmed using NLTK’s word stemming module, so all<br>words of different tenses would correspond to the same<br>token. Words were not included in the training/testing<br>sets when their length was less than 3, greater than 25,<br>when they appeared more than 2000 times or less than 5<br>times in the full corpus. Tokens were then created for all<br>viable unigrams and bigrams in the corpus.</li><li>Pre-trained Word Embedding Modules (used in DNNClassifier)<br>- Pre-trained word embedding modules from tensorflow_hub<br>were used for the DNN Classifier.<br>- The NNLM embedding is based on a neural network<br>language model with two hidden layers. The least frequent<br>tokens are hashed into buckets.<br>- Word2vec is a token based embedding module trained<br>on a corpus of English Wikipedia articles.<br>- Universal-Sentence-Encoder encodes sentences for use<br>in text classification. It was trained using a deep averaging<br>network and has the feature of encoding semantic<br>similarity.</li><li>Tokenization: Words with a length less than one were removed, then<br>sentences were vectorized using Keras’s text preprocessing<br>module. A token was chosen for every word in the<br>training input. All sentences were padded to be of equal<br>length, and words were replaced with tokens.</li></ul><p>Given the relatively small vocabulary size of our data set,<br>using a Pre-trained word embedding module gave the best<br>results, outweighing the effect of what model was used. Alternative<br>models were also developed, such as:</p><ul><li>SVM and Random Forest: These two models were the first<br>to be run as a way to gauge what sort of accuracy was<br>attainable, and what more complex models should be expected<br>to beat. The sklearn SVM Classifier and Random-<br>ForestClassifier were used for this task. These are two<br>types of commonly used high performing classifiers.</li><li>DNN: This model is a prebuilt Deep Neural Network from<br>Tensorflow. This model was used to evaluate the performance<br>of a Neural Network on the dataset, and to test use<br>of tf_hub’s word embedding modules.</li><li>LSTM: LSTMs are currently an industry standard model<br>for sequential data like natural language.</li><li>CNN: Convolutional neural networks have been shown<br>to provide excellent results on sentence classification by<br>capturing information about n-grams through the use of<br>convolutional layers.</li><li>CNN-LSTM: a combined CNN-LSTM model has been shown<br>to work well by encoding the regional information with<br>convolutional layers and long distance dependencies across<br>sentences using LSTM layers.</li></ul><p>With a small-to-mid sized training dataset, there is a much higher risk of overfitting to your training set when using neural networks with thousands of parameters, such as RNN and CNN neural networks. This can be seen by large discrepancies between testing and training set accuracies in our performance results. The ideal point at which to stop training is right as the training and testing scores begin to diverge where the training score continues going up, but the testing score starts going down. In the context of training a model, this means it is important to save checkpoints as you train, so the model can be reverted to an older checkpoint which is not yet overfitting. See Appendix B for an example of training and testing scores over the epochs of training. Overfitting can also be reduced by adding a regularization parameter to the loss function or to introduce dropout layers. Adding dropout to layers has seen success in most types of neural networks. However, this method does not work well on RNNs with LSTM units, which is the type of model that showed the greatest performance in this project. To mitigate overfitting on our small training dataset we apply dropout only to a non-recurrent layer.</p><p><em>Future work</em></p><ul><li>Manual Feature Selection: When doing manual feature<br>selection the NLTK stemming module was used to find<br>word roots. Lemmatization would likely give better results,<br>but requires part of speech tagging. Implementing<br>this would create a more accurate feature space. This could<br>be done using NLTK’s WordNetLemmatizer and NLTK’s<br>pos_tag in conjunction.</li><li>Training Data: Use a larger training dataset. The IEMOCAP<br>data set has a vocabulary size of 3,000 words, which<br>is relatively small, and testing data could easily contain<br>unseen words. This was improved by the inclusion of the<br>electronic review dataset which increased the vocabulary<br>size to around 8,000 words. The data, furthermore, is not<br>as domain specific as could be. IEMOCAP very general<br>purpose, and performed by actors reading scripts about<br>everyday situations. The electronic reviews are for electronic<br>products similar to those talked about in a technical<br>troubleshooting wireless carrier customer call, but are not<br>recent. More data specific to the content discussed in wireless<br>carrier customer service calls could be introduced,<br>such as more recent electronic device reviews or manually<br>annotated wireless carrier discussion forum posts.</li><li>Pre-Trained Word Embedding Modules: Transfer learning<br>could be implemented on these modules using a corpus<br>of text relevant to the type of text data on which classification<br>is being attempted. In this case the word embedding<br>modules could be further trained on a corpus of<br>wireless carrier related text, such as data scraped from a<br>specific wireless carrier’s online FAQ section and discussion<br>forum posts.</li><li>CNN and LSTM Neural Networks: The fine tuning of layers<br>and their parameters, and feeding the model more<br>data could be improved on the neural network models.<br>These efforts would be for the purpose of increasing accuracy<br>and decreasing overfitting.</li></ul><h4>Topic Model</h4><p>The low accuracy result of the LDA model is expected as<br>LDA models are not meant to be forced into predefined topics<br>and instead should be used for finding hidden topic information<br>in the corpus. SVO extraction using POS and NER<br>tagging was able to produce coherent results, but these results<br>are not consistent across topics which presents a challenge<br>when trying to sort documents by topics.</p><p><em>Future work</em></p><ul><li>The LDA model could be improved by using a more domain-specific<br>part-of-speech tagger (rather than the default POS<br>tagging function from NLTK) as well as better refined alpha<br>(document-topic density) and beta (topic-word density) parameters.</li><li>The PoSSI model could be improved in a few ways:<br>- Using a POS tagger and a Named Entity Recognition<br>(NER) tagger trained on domain-specific corpora<br>- A more domain-specific model for the POS tagger (currently<br>uses a research model from Stanford)<br>- A more domain-specific model for the NER tagger (currently<br>uses a research model from Stanford)<br>- A better method of extracting the subject from a tagged<br>document such as a parser in combination with a context-free<br>grammar for the domain-specific corpora<br>- Speed improvements as the model can be very slow for<br>large documents.<br>- Both of these models could be combined to identify topics<br>in the generated SVOs.</li></ul><h3>BIBLIOGRAPHY</h3><p>A. G. Tripathi and N. S, ”Feature Selection and Classification Approach<br>for Sentiment Analysis,” Machine Learning and Applications:<br>An International Journal, vol. 2, no. 2, pp. 01–16, 2015.</p><p>B. C. Busso, M. Bulut, C. Lee, A. Kazemzadeh, E. Mower, S. Kim,<br>J. Chang, S. Lee, and S. Narayanan, ”IEMOCAP: Interactive emotional<br>dyadic motion capture database,” Journal of Language Resources<br>and Evaluation, vol. 42, no. 4, pp. 335–359, December 2008.</p><p>C. Y. Bengio, R. Ducharme, P. Vincent, and C. Jauvin, ”A Neural<br>Probabilistic Language Model,” Journal of Machine Learning Research<br>, vol. 3, pp. 1137–1155, Mar. 2013.</p><p>D. T. Mikolo, K. Chen, G. Corrado, and J. Dean, ”Efficient Estimation<br>of Word Representations in Vector Space,” CoRR, vol. abs/1301.3781,<br>Jan. 2013.</p><p>E. D. Cer, Y. Yang, S.-yi Kong, N. Hua, N. Limtiaco, R. St. John,<br>N. Constant, M. Guajardo-Cespedes, S. Yuan, C. Tar, Y.-H. Sung, B.<br>Strope, and R. Kurzweil, ”Universal Sentence Encoder,” CoRR, vol.<br>abs/1803.11175, 2018.</p><p>F. W. Zaremba, I. Sutskever, and O. Vinyals, ”Recurrent Neural Network<br>Regularization,” CoRR, vol. abs/1409.2329, 2014.</p><p>G. M. Hu and B. Liu. ”Mining and summarizing customer reviews.”<br>Proceedings of the ACM SIGKDD International Conference on Knowledge<br>Discovery Data Mining, Aug. 2004.</p><p>H. N. Jindal and B. Liu. ”Opinion Spam and Analysis.” Proceedings<br>of First ACM International Conference on Web Search and Data<br>Mining, Feb. 2008.</p><p>I. Qian Liu, Zhiqiang Gao, Bing Liu and Yuanlin Zhang. Automated<br>Rule Selection for Aspect Extraction in Opinion Mining. Proceedings<br>of International Joint Conference on Artificial Intelligence,<br>July 2015.</p><p>J. Y. Kim, ”Convolutional Neural Networks for Sentence Classification,”<br>CoRR, vol. abs/1408.5882, 2014.</p><p>K. TensorFlow. (2018). Text Modules | TensorFlow. [online].</p><p>L. X. Ma and E. Hovy, ”End-to-end Sequence Labeling via Bi-directional<br>LSTM-CNNs-CRF,” Proceedings of the 54th Annual Meeting of the<br>Association for Computational Linguistics, vol. 1, 2016.</p><p>M. J. Cheng, L. Dong, and M. Lapata, ”Long Short-Term Memory-<br>Networks for Machine Reading,” Proceedings of the 2016 Conference<br>on Empirical Methods in Natural Language Processing, 2016.</p><p>N. Y. Goldberg, ”A Primer on Neural Network Models for Natural Language Processing,” Journal of Artificial Intelligence Research,<br>vol. 57, Nov. 2016.</p><p>O. J. Wang, L.-C. Yu, K. R. Lai, and X. Zhang, ”Dimensional Sentiment<br>Analysis Using a Regional CNN-LSTM Model,” Proceedings<br>of the 54th Annual Meeting of the Association for Computational<br>Linguistics (Volume 2: Short Papers), 2016.</p><p>P. A. Y. Hannun, C. Case, J. Casper, B. Catanzaro, G. Diamos, E.<br>Elsen, R. Prenger, S. Satheesh, S. Sengupta, A. Coates, and A. Y. Ng,<br>”Deep Speech: Scaling up end-to-end speech recognition,” CoRR,<br>vol. abs/1412.5567, 2004.</p><p>Q. J. Kunze, L. Kirsch, I. Kurenkov, A. Krug, J. Johannsmeier, and<br>S. Stober, ”Transfer Learning for Speech Recognition on a Budget,”<br>Proceedings of the 2nd Workshop on Representation Learning for<br>NLP, 2017.</p><p>R. S. Bansal and Natural Language Processing and Machine Learning,<br>”Beginners Guide to Topic Modeling in Python,” Analytics Vidhya,<br>29-Aug-2016. [Online].</p><p>S. J. Brownlee, ”How to Develop an N-gram Multichannel Convolutional<br>Neural Network for Sentiment Analysis,” Machine Learning<br>Mastery, 14-Feb-2018.</p><p>T. S. Axelbrooke, ”LDA Alpha and Beta Parameters — The Intuition,”<br>LDA Alpha and Beta Parameters — The Intuition | Thought Vector<br>Blog, 21-Oct-2015. [Online].</p><p>U. A. Crosson, ”Extract Subject Matter of Documents Using NLP,”<br>Medium, 08-Jun-2016. [Online].</p><p>V. J. R. Finkel, T. Grenager, and C. Manning, ”Incorporating nonlocal<br>information into information extraction systems by Gibbs<br>sampling,” Proceedings of the 43rd Annual Meeting on Association<br>for Computational Linguistics — ACL 05, pp. 363–370, 2005.</p><p>W. K. Toutanova and C. D. Manning, ”Enriching the knowledge<br>sources used in a maximum entropy part-of-speech tagger,” Proceedings<br>of the 2000 Joint SIGDAT conference on Empirical methods<br>in natural language processing and very large corpora held in<br>conjunction with the 38th Annual Meeting of the Association for<br>Computational Linguistics, pp. 63–70, 2000.</p><p>X. S. Bird, E. Klein, and E. Loper, Natural language processing with<br>Python: Analyzing Text with the Natural Language Toolkit. Beijing:<br>OReilly, 2009.</p><p>Y. Smoothed LDA. Wikipedia, 2009.</p><p>Z. S. Ruder, ”Deep Learning for NLP Best Practices,” Sebastian Ruder,<br>25-Jul-2017. [Online].</p><iframe src="https://drive.google.com/viewerng/viewer?url=https%3A//cs-courses.mines.edu/csci370/FS2018/FinalReport/ProKarma.pdf&amp;embedded=true" width="600" height="780" frameborder="0" scrolling="no"><a href="https://medium.com/media/0b5189ccdad1f6cd03c12d481e5ba092/href">https://medium.com/media/0b5189ccdad1f6cd03c12d481e5ba092/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=946d2604e309" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/a-machine-learning-approach-to-automated-customer-satisfaction-surveys-946d2604e309">A Machine Learning Approach to Automated Customer Satisfaction Surveys</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Sweet Home Chicago: Examining Crime in the City of Chicago]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/data-science/sweet-home-chicago-examining-crime-in-the-city-of-chicago-5c80f1e23875?source=rss-7e13dbcaebb3------2"><img src="https://cdn-images-1.medium.com/max/1600/0*uq16trbaowBIRCU7" width="1600"></a></p><p class="medium-feed-snippet">A data driven approach.</p><p class="medium-feed-link"><a href="https://medium.com/data-science/sweet-home-chicago-examining-crime-in-the-city-of-chicago-5c80f1e23875?source=rss-7e13dbcaebb3------2">Continue reading on TDS Archive »</a></p></div>]]></description>
            <link>https://medium.com/data-science/sweet-home-chicago-examining-crime-in-the-city-of-chicago-5c80f1e23875?source=rss-7e13dbcaebb3------2</link>
            <guid isPermaLink="false">https://medium.com/p/5c80f1e23875</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[kaggle]]></category>
            <category><![CDATA[chicago]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[database]]></category>
            <dc:creator><![CDATA[Tyler Doll]]></dc:creator>
            <pubDate>Fri, 26 Jul 2019 17:44:27 GMT</pubDate>
            <atom:updated>2019-07-26T23:08:25.585Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[How to Setup a Raspberry Pi Ad-Hoc Network Using BATMAN-ADV on Raspbian Stretch]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/@tdoll/how-to-setup-a-raspberry-pi-ad-hoc-network-using-batman-adv-on-raspbian-stretch-lite-dce6eb896687?source=rss-7e13dbcaebb3------2"><img src="https://cdn-images-1.medium.com/max/2600/0*KTAf0y15SD7OwFaS" width="3456"></a></p><p class="medium-feed-snippet">A Modern Solution for a Modern Problem</p><p class="medium-feed-link"><a href="https://medium.com/@tdoll/how-to-setup-a-raspberry-pi-ad-hoc-network-using-batman-adv-on-raspbian-stretch-lite-dce6eb896687?source=rss-7e13dbcaebb3------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://medium.com/@tdoll/how-to-setup-a-raspberry-pi-ad-hoc-network-using-batman-adv-on-raspbian-stretch-lite-dce6eb896687?source=rss-7e13dbcaebb3------2</link>
            <guid isPermaLink="false">https://medium.com/p/dce6eb896687</guid>
            <category><![CDATA[internet-gateway]]></category>
            <category><![CDATA[batman-adv]]></category>
            <category><![CDATA[ad-hoc]]></category>
            <category><![CDATA[mesh-networks]]></category>
            <category><![CDATA[raspberry-pi]]></category>
            <dc:creator><![CDATA[Tyler Doll]]></dc:creator>
            <pubDate>Wed, 03 Apr 2019 18:01:01 GMT</pubDate>
            <atom:updated>2019-04-18T19:51:20.719Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Making Music with Machine Learning]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/data-science/making-music-with-machine-learning-908ff1b57636?source=rss-7e13dbcaebb3------2"><img src="https://cdn-images-1.medium.com/max/960/1*YX3C-Y7PeHGIDJTrOFU3ZA.jpeg" width="960"></a></p><p class="medium-feed-snippet">Creating music is something that is often considered uniquely human, so what if we could teach a machine to do it?</p><p class="medium-feed-link"><a href="https://medium.com/data-science/making-music-with-machine-learning-908ff1b57636?source=rss-7e13dbcaebb3------2">Continue reading on TDS Archive »</a></p></div>]]></description>
            <link>https://medium.com/data-science/making-music-with-machine-learning-908ff1b57636?source=rss-7e13dbcaebb3------2</link>
            <guid isPermaLink="false">https://medium.com/p/908ff1b57636</guid>
            <category><![CDATA[music]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[towards-data-science]]></category>
            <category><![CDATA[music-generation]]></category>
            <category><![CDATA[machine-learning]]></category>
            <dc:creator><![CDATA[Tyler Doll]]></dc:creator>
            <pubDate>Tue, 29 Jan 2019 01:01:01 GMT</pubDate>
            <atom:updated>2019-01-30T07:08:21.030Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Front-End Frameworks: So Powerful They’re Almost Useless]]></title>
            <link>https://medium.com/@tdoll/front-end-frameworks-so-powerful-theyre-almost-useless-e61bdbb029da?source=rss-7e13dbcaebb3------2</link>
            <guid isPermaLink="false">https://medium.com/p/e61bdbb029da</guid>
            <category><![CDATA[react]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[framework]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[angularjs]]></category>
            <dc:creator><![CDATA[Tyler Doll]]></dc:creator>
            <pubDate>Sat, 07 Jul 2018 19:01:02 GMT</pubDate>
            <atom:updated>2018-07-07T19:01:02.650Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*xvEqvJ7tEEHvvYx6" /><figcaption>Photo by <a href="https://unsplash.com/@jefflssantos?utm_source=medium&amp;utm_medium=referral">Jefferson Santos</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>In the web development community it seems like there is a new framework every other week that is supposed to “revolutionize” the way we build websites and change the entire landscape, except they don’t. For the most part the only <strong>really </strong>successful frameworks are <a href="https://angular.io/">Angular</a> and <a href="https://reactjs.org/">React</a> (though React is really a library, but for the purposes of this article I’m going to wrap it in with frameworks). This is because of a few reasons that are often overlooked by the developers.</p><h4>Learning Curve</h4><p>One of, if not the biggest, reasons frameworks fail is because of the learning curves associated with them. There are so many options and to learn all of them (or even most of the useful ones) to the point of being able to fully take advantage of them is impractical. Things are often complex and every framework has its own design philosophy and style deeply rooted in the developers’ own personal beliefs that it’s often a mental exercise to navigate all of the intricacies within. The developers are usually so deep into their designs that they often lose sight of what it’s like coming into the framework with no knowledge of how it works or what it really does. Because of this developers often stick with what they know and have a hard time fully converting to one framework over another.</p><h4>So Powerful They’re Almost Useless.</h4><p>With every new framework coming out they always have to find their own way of making them standout and worth using. Often this is achieved through promises of “plug and play” or “extensibility” so much to the point that it can nearly build the damn website for you. Now this sounds great on paper, but what I have noticed is that the more complex and “powerful” a framework is the less likely it is to be used. Why is this? Well when things do most of the work for you it comes with some consequences, one of which being making debugging a lot harder when you finally have to do some work yourself. In order to fix an issue, not only do you need an understanding of your own code (which I pray you do) you also have to have an understanding of the framework’s code and what it’s doing so you can figure out how to fix your issue. For me this is reason enough to not use frameworks all together as this often slows me down more than if I just wrote the application from scratch (for disclaimers sake my go-to is React (mostly because it’s not a framework)). However in the beginning I did mention that there are some successful frameworks, so there must be some reasons for this right?</p><h4>Why Not All Front-End Frameworks Fail</h4><p>In the first paragraph I mentioned two frameworks (really one and a library) that are successful, and I believe it comes down to achieving really what all frameworks are trying to achieve: making the developer’s life easier. React does this by not doing everything for you and not trying to make things black-boxy. Instead it simply provides more of an outline of how to build an application and then gives you the tools to use this outline. You still have to make everything yourself, and you can use the library however you want, so it doesn’t try to make all of your applications fit into a box. It’s more like a useful assistant hanging around with some tools to make common problems easier to solve. It’s a support structure not another medium between you and your application. Angular is a little different as it does have some more structure, but it didn’t start out this way and that’s why I think it’s successful. It started out small and basic which allowed it to build a community of people who knew how to use it so that when updates came out with new features the learning curve was drastically reduced for the majority of the community. Then because of its wide-use it was able to establish a footing in the community and was able to hang around. Both of these examples also have the backing of tech giants (Google for Angular and Facebook for React) in addition to a large open-source community that they can pull from. This makes a huge difference as people can work on them full-time and constantly improve and innovate while some smaller frameworks and libraries may not be able to sustain that sort of development.</p><h4>Closing Remarks</h4><p>In the end the web development environment is constantly changing so what’s popular today won’t necessarily be popular tomorrow. Whether it’s a new trend or a new platform, the needs of users and developers will keep evolving and with them new ways of building web applications. For now it looks like React and Angular are here to stay, but soon there will be another contender and the race for the best web framework will continue on.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e61bdbb029da" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[LDA Topic Modeling]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/data-science/lda-topic-modeling-an-explanation-e184c90aadcd?source=rss-7e13dbcaebb3------2"><img src="https://cdn-images-1.medium.com/max/600/1*VTHd8nB_PBsDtd2hd87ybg.png" width="600"></a></p><p class="medium-feed-snippet">An Explanation</p><p class="medium-feed-link"><a href="https://medium.com/data-science/lda-topic-modeling-an-explanation-e184c90aadcd?source=rss-7e13dbcaebb3------2">Continue reading on TDS Archive »</a></p></div>]]></description>
            <link>https://medium.com/data-science/lda-topic-modeling-an-explanation-e184c90aadcd?source=rss-7e13dbcaebb3------2</link>
            <guid isPermaLink="false">https://medium.com/p/e184c90aadcd</guid>
            <category><![CDATA[towards-data-science]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[gensim]]></category>
            <category><![CDATA[topic-modeling]]></category>
            <category><![CDATA[lda]]></category>
            <dc:creator><![CDATA[Tyler Doll]]></dc:creator>
            <pubDate>Sun, 24 Jun 2018 21:26:02 GMT</pubDate>
            <atom:updated>2019-03-11T04:03:36.795Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Nativescript Binding Context Is Preserved Through History]]></title>
            <link>https://medium.com/@tdoll/nativescript-binding-context-is-preserved-through-history-3fc58796e93b?source=rss-7e13dbcaebb3------2</link>
            <guid isPermaLink="false">https://medium.com/p/3fc58796e93b</guid>
            <category><![CDATA[nativescript]]></category>
            <dc:creator><![CDATA[Tyler Doll]]></dc:creator>
            <pubDate>Tue, 19 Jun 2018 21:22:08 GMT</pubDate>
            <atom:updated>2018-06-19T21:22:08.093Z</atom:updated>
            <content:encoded><![CDATA[<p>I’ll start off by saying Nativescript is awesome; it’s fun and easy to work with. Now with that said it has some weird quirks and odd documentation. One of these quirks being how binding context for pages is preserved through navigation history. What’s odd about it? Well after searching for hours online and reading the official documentation over and over again (which has its own set of quirks), I found no mention of this. Maybe it’s just me, but after working with Nativescript and seeing various examples online I assumed that every time you return to a page the state is not preserved and you must rebind your view-model given that you typically bind a view-model in the “loaded” method of a page. WRONG. In actuality when you navigate from and back to a page without clearing history the previous binding context is maintained.</p><p>I discovered this when I was having an issue with the RadSideDrawer component not recognizing a property update event after I navigated away and returned to the page. The “tap” property on a button that was supposed to open the drawer worked fine and I could view all of the data I was trying to update just fine through console log and alerts, but I was not seeing the property update reflected on the front-end. Apparently when I set the bindingContext after returning to the page the binding for this particular component broke and I couldn’t update it anymore.</p><p>Enough with the words though, here’s some code!</p><p>main-page.xml</p><pre>&lt;Page xmlns=”<a href="http://schemas.nativescript.org/tns.xsd">http://schemas.nativescript.org/tns.xsd</a>&quot; loaded=”onLoaded”&gt;<br>...<br>&lt;/Page&gt;</pre><p>main-page.ts</p><pre>export function onLoaded(args: EventData): void {<br> const page = &lt;Page&gt;args.object;<br> <br> // Notice how I am checking for a truthy bindingContext value <br> // before assigning a new one. If you navigate away and return to <br> // this page this will evaluate to false as page.bindingContext is <br> // preserved from the last time it was set.<br> if (!page.bindingContext)<br>   page.bindingContext = new MainPageViewModel(page);<br>}</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3fc58796e93b" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>