1 人工智能与机器学习
1.1 谈谈人工智能
人工智能(Artificial Intelligence),英文缩写为AI。它是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。
人工智能是 计算机 科学的一个分支,它企图了解智能的实质,并生产出一种新的能以 人类智能 相似的方式做出反应的智能机器,该领域的研究包括机器人、语言识别、图像识别、自然语言处理和 专家系统 等。人工智能从诞生以来,理论和技术日益成熟,应用领域也不断扩大,可以设想,未来人工智能带来的科技产品,将会是人类 智慧 的 “ 容器” 。 人工智能可以对人的意识、思维的信息过程的模拟。人工智能不是人的智能,但能像人那样思考、也可能超过人的智能。
1.2 人工智能的三次浪潮
- 1956 Artificial Intelligence提出
1950-1970 符号主义流派:专家系统占主导地位 1950 :图灵设计国际象棋程序 1962 : IBM 的跳棋程序战胜人类高手(人工智能第一次浪潮)
- 1980-2000统计主义流派:主要用统计模型解决问题
1993 : SVM 模型 1997 : IBM 深蓝战胜象棋选手卡斯帕罗夫(人工智能第二次浪潮)
- 2010-至今神经网络、深度学习、大数据流派
2006 DNN (深度神经网络) 2016 : Google AlphaGO 战胜围棋选手李世石(人工智能第三次浪潮)
1.3 机器学习
1.3.1 什么是机器学习
机器学习,它正是这样一门学科,它致力于研究如何通过计算( CPU 和 GPU 计算)的手段,利用经验来改善(计算机)系统自身的性能。 它是人工智能的核心,是使计算机具有智能的根本途径,应用遍及人工智能各领域。 数据 + 机器学习算法 = 机器学习模型 有了学习算法我们就可以把经验数据提供给它,它就能基于这些数据产生模型。
1.3.2 人工智能、机器学习、深度学习的关系
机器学习是人工智能的一个分支,深度学习是实现机器学习的一种技术。
2 智能分类
2.1 需求分析
通过机器学习,当用户录入一篇文章或从互联网爬取一篇文章时可以预测其归属的类型。
2.2 智能分类的执行流程
3 IK分词器
3.1 IK分词器简介
IK Analyzer 是一个开源的 , 基于 java 语言开发的轻量级的中文分词工具包。从 2006 年 12 月推出 1.0 版开始 ,IKAnalyzer 已经推出了 4 个大版本。最初 , 它是以开源项目 Luence 为 应用主体的, 结合词典分词和文法分析算法的中文分词组件。从 3.0 版本开始 ,IK 发展为面 向 Java 的公用分词组件 , 独立于 Lucene 项目 , 同时提供了对 Lucene 的默认优化实现。 在 2012 版本中 ,IK 实现了简单的分词歧义排除算法 , 标志着 IK 分词器从单纯的词典分词向模拟语义分词衍化。
3.2 快速入门
(1)创建工程引入依赖
com.janeluoikanalyzer2012_u6
(2)编写代码
package cn.test.demo;import org.wltea.analyzer.core.IKSegmenter;import org.wltea.analyzer.core.Lexeme;import java.io.IOException;import java.io.StringReader;public class Test {public static void main(String[] args) throws IOException {String text="基于java语言开发的轻量级的中文分词工具包";StringReader sr=new StringReader(text);IKSegmenter ik=new IKSegmenter(sr, true);Lexeme lex=null;while((lex=ik.next())!=null){System.out.print(lex.getLexemeText()+" ");}}}
IKSegmenter 的第一个构造参数为StringReader类型 。 StringReader是装饰Reader的类,其用法是读取一个String字符串IKSegmenter 的第二个构造参数userSmart 为切分粒度 true表示最大切分 false表示最细切分Lexeme: 词单位类
3.3 构建分词语料库
需求:在CSDN上抓取各类文章,并以分词形式保存,词之间用空格分隔。 步骤:
(1)修改tensquare_common模块的pom.xml ,引入依赖
com.janeluoikanalyzer2012_u6
(2)修改tensquare_common模块 ,创建分词工具类
package util;import org.wltea.analyzer.core.IKSegmenter;import org.wltea.analyzer.core.Lexeme;import java.io.IOException;import java.io.StringReader;/*** 分词工具类*/public class IKUtil {/*** 根据文本返回分词后的文本* @param content* @return*/public static String split(String content,String splitChar) throwsIOException {StringReader sr=new StringReader(content);IKSegmenter ik=new IKSegmenter(sr, true);Lexeme lex=null;StringBuilder sb=new StringBuilder("");while((lex=ik.next())!=null){sb.append(lex.getLexemeText()+splitChar);//拼接}return sb.toString();}}
(3)修改tensquare_common模块,创建HTML工具类(资源中已提供),用于将文本中的html标签剔除
package util;import java.util.regex.Matcher;import java.util.regex.Pattern;/*** html标签处理工具类*/public class HTMLUtil {public static String delHTMLTag(String htmlStr){String regEx_script="]*" />]*?>[\\s\\S]*?"; //定义style的正则表达式String regEx_html="]+>"; //定义HTML标签的正则表达式Patternp_script=Pattern.compile(regEx_script,Pattern.CASE_INSENSITIVE);Matcher m_script=p_script.matcher(htmlStr);htmlStr=m_script.replaceAll(""); //过滤script标签Patternp_style=Pattern.compile(regEx_style,Pattern.CASE_INSENSITIVE);Matcher m_style=p_style.matcher(htmlStr);htmlStr=m_style.replaceAll(""); //过滤style标签Patternp_html=Pattern.compile(regEx_html,Pattern.CASE_INSENSITIVE);Matcher m_html=p_html.matcher(htmlStr);htmlStr=m_html.replaceAll(""); //过滤html标签return htmlStr.trim(); //返回文本字符串}}
(4)修改tensquare_crawler模块,创建ArticleTxtPipeline,用于负责将爬取的内容存入文本文件
package com.tensquare.crawler.pipeline;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component;import org.springframework.stereotype.Repository;import us.codecraft.webmagic.ResultItems;import us.codecraft.webmagic.Task;import us.codecraft.webmagic.pipeline.Pipeline;import util.HTMLUtil;import util.IKUtil;import java.io.File;import java.io.FileNotFoundException;import java.io.IOException;import java.io.PrintWriter;import java.util.Map;import java.util.UUID;/*** 入库类(分词后保存为txt)*/@Componentpublic class ArticleTxtPipeline implements Pipeline {@Value("${ai.dataPath}")private String dataPath;private String channelId;//频道IDpublic void setChannelId(String channelId) {this.channelId = channelId;}@Overridepublic void process(ResultItems resultItems, Task task) {String title = resultItems.get("title");//获取标题String content= HTMLUtil.delHTMLTag(resultItems.get("content"));//获取正文并删除html标签try {//将标题+正文分词后保存到相应的文件夹PrintWriter printWriter=new PrintWriter(newFile(dataPath+"/"+channelId+ "/"+UUID.randomUUID()+".txt"));printWriter.print(IKUtil.split(title+" "+content," "));printWriter.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}
(5)在配置文件application.yml中添加配置
ai:#语料库目录dataPath : E:\\article
(6)修改ArticleTask类,新增爬取db 和web的任务
package com.tensquare.crawler.task;import com.tensquare.crawler.pipeline.ArticleTxtPipeline;import com.tensquare.crawler.processor.ArticleProcessor;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.stereotype.Component;import us.codecraft.webmagic.Spider;import us.codecraft.webmagic.scheduler.RedisScheduler;/*** 文章任务类*/@Componentpublic class ArticleTask {//@Autowired//private ArticlePipeline articlePipeline;@Autowiredprivate ArticleTxtPipeline articleTxtPipeline;@Autowiredprivate RedisScheduler redisScheduler;/*** 爬取ai数据*/@Scheduled(cron="0 38 10 * * ?")public void aiTask(){System.out.println("爬取AI文章");Spider spider = Spider.create(new ArticleProcessor());spider.addUrl("https://blog.csdn.net/nav/ai");articleTxtPipeline.setChannelId("ai");spider.addPipeline(articleTxtPipeline);spider.setScheduler(redisScheduler);spider.start();spider.stop();}/*** 爬取db数据*/@Scheduled(cron="20 17 11 * * ?")public void dbTask(){System.out.println("爬取DB文章");Spider spider = Spider.create(new ArticleProcessor());spider.addUrl("https://blog.csdn.net/nav/db");articleTxtPipeline.setChannelId("db");spider.addPipeline(articleTxtPipeline);spider.setScheduler(redisScheduler);spider.start();spider.stop();}/*** 爬取web数据*/@Scheduled(cron="20 27 11 * * ?")public void webTask(){System.out.println("爬取WEB文章");Spider spider = Spider.create(new ArticleProcessor());spider.addUrl("https://blog.csdn.net/nav/web");articleTxtPipeline.setChannelId("web");spider.addPipeline(articleTxtPipeline);spider.setScheduler(redisScheduler);spider.start();spider.stop();}}
3.4 分词语料库合并
(1)创建模块tensquare_ai ,引入tensquare_common依赖 ,创建启动类
package com.tensquare.ai;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.scheduling.annotation.EnableScheduling;@SpringBootApplication@EnableSchedulingpublic class AiApplication {public static void main(String[] args) {SpringApplication.run(AiApplication.class, args);}}
(2)在tensquare_common创建文件工具类 FileUtil (资源中提供),用于文本文件的读取,合并,以及获取某目录下的文本文件名称
package com.tensquare.ai.util;import java.io.*;import java.util.ArrayList;import java.util.List;/*** 文件工具类*/public class FileUtil {/*** 将多个文本文件合并为一个文本文件* @param outFileName* @param inFileNames* @throws IOException*/public static void merge(String outFileName ,ListinFileNames) throws IOException {FileWriter writer = new FileWriter(outFileName, false);for(String inFileName :inFileNames ){try {String txt= readToString(inFileName);writer.write(txt);System.out.println(txt);}catch (Exception e){}}writer.close();}/*** 查找某目录下的所有文件名称* @param path* @return*/public static List getFiles(String path) {List files = new ArrayList();File file = new File(path);File[] tempList = file.listFiles();for (int i = 0; i < tempList.length; i++) {if (tempList[i].isFile()) {//如果是文件files.add(tempList[i].toString());}if (tempList[i].isDirectory()) {//如果是文件夹files.addAll( getFiles(tempList[i].toString()) );}}return files;}/*** 读取文本文件内容到字符串* @param fileName* @return*/public static String readToString(String fileName) throws IOException{String encoding = "UTF‐8";File file = new File(fileName);Long filelength = file.length();byte[] filecontent = new byte[filelength.intValue()];FileInputStream in = new FileInputStream(file);in.read(filecontent);in.close();return new String(filecontent, encoding);}}
(3)创建application.yml
ai:#语料库汇总文本文件wordLib : E:\\article.txt#语料库目录dataPath : E:\\article
(4)创建服务类
@Servicepublic class Word2VecService {//模型分词路径@Value("${ai.wordLib}")private String wordLib;//爬虫分词后的数据路径@Value("${ai.dataPath}")private String dataPath;/*** 合并*/public void mergeWord(){List fileNames = FileUtil.getFiles(dataPath);try {FileUtil.merge(wordLib,fileNames);} catch (IOException e) {e.printStackTrace();}}}
(5)创建任务类TrainTask
/*** 训练任务类*/@Componentpublic class TrainTask {@Autowiredprivate Word2VecService word2VecService;/*** 训练模型*/@Scheduled(cron="0 30 16 * * ?")public void trainModel(){System.out.println("开始合并语料库......");word2VecService.mergeWord();System.out.println("合并语料库结束‐‐‐‐‐‐");}}