@@ -52,8 +52,8 @@ <h1><a href="index.html">Machine Learning</a></h1>
52
52
< br />
53
53
< ul >
54
54
< li > What is useful for</ li >
55
- < li > How to integrate</ li >
56
55
< li > Available plugins</ li >
56
+ < li > How to integrate</ li >
57
57
< li > A little code</ li >
58
58
</ ul >
59
59
</ section >
@@ -111,46 +111,161 @@ <h3>Native</h3>
111
111
< li style ="color:green "> Total control</ li >
112
112
< li style ="color:darkred "> No PHP machine learning libraries</ li >
113
113
< li style ="color:darkred "> Training in PHP is slow</ li >
114
+ < li style ="color:darkred "> CMS not good for training</ li >
114
115
</ ul >
115
116
</ section >
116
117
< section class ="white ">
117
118
< h3 > External</ h3 >
118
119
< ul >
119
120
< li style ="color:green "> Performance</ li >
120
121
< li style ="color:green "> No stress</ li >
121
- < li style ="color:darkred "> Pay</ li >
122
+ < li style ="color:darkred "> Pay or maintain another system</ li >
123
+ </ ul >
124
+ </ section >
125
+ < section class ="white ">
126
+ < h2 > Takeaway</ h2 >
127
+ < ul >
128
+ < li >
129
+ < h3 style ="color:darkred "> Training/Algorithm (WP KO)</ h3 >
130
+ </ li >
131
+ < li >
132
+ < h3 style ="color:green "> Model (WP OK)</ h3 >
133
+ </ li >
134
+ < li >
135
+ < h3 > Rest API is our friend</ h3 >
136
+ </ li >
122
137
</ ul >
123
138
</ section >
124
139
< section >
125
140
< img src ="img/make_your_choice.jpg " width ="600px ">
126
141
</ section >
127
142
</ section >
128
143
129
- <!-- Measuring similarity between texts -->
130
- < section >
144
+ <!-- Example recommendation plugin for WP-->
145
+ < section data-background ="img/graph_viz.png " class ="white ">
146
+ < h2 > Let's write a model</ h2 >
147
+ < ul >
148
+ < li > < strong > Data:</ strong > blog posts</ li >
149
+ < li > < strong > Algorithm:</ strong > text similarity</ li >
150
+ < li > < strong > Model:</ strong > graph stored in < code > wp_postmeta</ code > </ li >
151
+ < li > < strong > Recommend!</ strong > </ li >
152
+ </ ul >
153
+ </ section >
154
+
155
+ < section >
156
+ < h2 > Algorithm</ h2 >
131
157
< section >
132
- < h2 > Algorithm</ h2 >
133
158
< div > Jaccard/Tanimoto index</ div >
134
- < img src ="img/tanimoto .png " />
159
+ < img width =" 80% " src ="img/tanimoto_php .png " />
135
160
</ section >
136
161
< section >
137
- < h2 > Algorithm</ h2 >
138
162
< div > Jaccard/Tanimoto index</ div >
139
- < pre > < code class ="hljs " data-trim >
140
- COMPUTE SIMILARITY AT POST SAVE
163
+ < pre > < code class ="hljs php " data-trim >
164
+ public static function similarity( $post_id_a, $post_id_b ) {
165
+
166
+ // Transform each post in a bag of words
167
+ $bow_a = self::post_2_bag_of_words( $post_id_a );
168
+ $bow_b = self::post_2_bag_of_words( $post_id_b );
169
+
170
+ // Compute Tanimoto
171
+ $intersection = array_unique( array_intersect( $bow_a, $bow_b ) );
172
+ $union = array_unique( array_merge( $bow_a, $bow_b ) );
173
+
174
+ return count( $intersection ) / count( $union );
175
+ }
141
176
</ code > </ pre >
177
+ </ section >
178
+ < section >
179
+ < div > Bag of Words</ div >
180
+ < pre > < code class ="hljs php " data-trim >
181
+ public static function post_2_bag_of_words( $post_id ) {
182
+
183
+ $post = get_post( $post_id );
184
+
185
+ // Take away HTML
186
+ $post_content = $post-> post_content;
187
+ $clean_content = strtolower( wp_strip_all_tags( $post_content ) );
188
+
189
+ // Take away punctuation
190
+ $clean_content = str_replace( array(".", ",", ":", ";", "!", "?", "'", '"', "(", ")" ), "", $clean_content );
191
+
192
+ // Split tokens
193
+ $tokens = array_unique( explode( " ", $clean_content ) );
194
+
195
+ // Take away stopwords
196
+ return array_diff( $tokens, self::$stopwords );
197
+ }
198
+ </ code > </ pre >
142
199
</ section >
143
200
</ section >
144
201
145
202
<!-- Build similarity graph -->
146
203
< section >
147
204
< h2 > Similarity graph</ h2 >
148
- < span >
149
- < img height ="200px " src ="img/similarity_graph.jpg " />
150
- </ span >
151
- < pre > < code class ="hljs " data-trim contenteditable >
152
- INSERT SIMILARITY AS A POST META
153
- </ code > </ pre >
205
+ < section >
206
+ < span >
207
+ < img width ="100% " src ="img/similarity_graph.jpg " />
208
+ </ span >
209
+ </ section >
210
+ < section >
211
+ < span >
212
+ < img width ="100% " src ="img/wp_recommendations_post_meta.png " />
213
+ </ span >
214
+ </ section >
215
+ < section >
216
+ < pre style ="width:100% "> < code class ="hljs php " data-trim contenteditable >
217
+ function dropout_update_recommendations( $post_id ) {
218
+
219
+ // Take latest 10 posts
220
+ $latest_posts = wp_get_recent_posts(
221
+ array(
222
+ 'numberposts' => 10,
223
+ 'post_type' => array( 'post', 'page' )
224
+ )
225
+ );
226
+ $similarities = array();
227
+
228
+ foreach( $latest_posts as $another_post ){
229
+
230
+ if( $another_post['ID'] !== $post_id ) {
231
+
232
+ // Measure similarity
233
+ $similarity = Dropout::similarity( $post_id, $another_post['ID'] );
234
+ $similarities[ $another_post['ID'] ] = $similarity;
235
+
236
+ // Update similarities for the other post
237
+ $already_computed_similarities = get_post_meta( $another_post['ID'], 'dropout_recommendations', true );
238
+ $already_computed_similarities[$post_id] = $similarity;
239
+ update_post_meta( $another_post['ID'], 'dropout_recommendations', $already_computed_similarities );
240
+ }
241
+ }
242
+
243
+ // Save recommendations for this post
244
+ update_post_meta( $post_id, 'dropout_recommendations', $similarities );
245
+ }
246
+ add_action( 'save_post', 'dropout_update_recommendations' );
247
+ </ code > </ pre >
248
+ </ section >
249
+ < section >
250
+ < pre > < code class ="hljs php " data-trim contenteditable >
251
+ function dropout_get_recommendations( $content ) {
252
+
253
+ $recommendations = get_post_meta( get_the_ID(), 'dropout_recommendations', true );
254
+
255
+ arsort( $recommendations ); // Sort by similarity
256
+
257
+ $html = '< h3 > See also</ h3 > < ul > ';
258
+ foreach( $recommendations as $recom_id => $similarity ) {
259
+ $recom_post = get_post( $recom_id );
260
+ $html .= '< li > < a href ="' . get_permalink($recom_post->ID) . ' "> ' . $recom_post-> post_title . '</ a > (' . $similarity .')</ li > ';
261
+ }
262
+ $html .= '</ ul > ';
263
+
264
+ return $content . $html;
265
+ }
266
+ add_filter( 'the_content', 'dropout_get_recommendations' );
267
+ </ code > </ pre >
268
+ </ section >
154
269
</ section >
155
270
156
271
<!-- Demo -->
0 commit comments