自然语言处理---用隐马尔科夫模型(HMM)实现词性标注---1998年1月份人民日报语料---learn---test---evaluation---Demo---java实现
先放上一张Demo的测试图
- 测试的句子及每个分词的词性标注为: 目前/t 这/rzv 条/q 高速公路/n 之间/f 的/ude1 路段/n 已/d 紧急/a 封闭/v 。/w
需要基础知识
- HMM模型(隐马尔可夫模型)
- 模型的定义
隐马尔科夫模型(hidden Markov model)是关于时序的概率模型,是最简单的动态贝叶斯网络
- 模型的参数
HMM模型由Pi、A、B 唯一决定 Pi、A、B 成为HMM模型的三要素
- HMM用在词性标注问题
- 对于下面这句话可以用HMM进行建模
目前/t 这/rzv 条/q 高速公路/n 之间/f 的/ude1 路段/n 已/d 紧急/a 封闭/v 。/w
因此 可以通过训练语料来根据词性以及分词还有两者之间的关系进行统计获得三种概率
- 维特比算法
- 在给定已知分词的句子时如何进行词性标注呢
这就是HMM模型中的预测问题
此时采用维特比算法
注:对维特比算法的举例理解
a b c d 表示的是四种状态
1 2 3 是三个观测时间节点
在t=3的时刻要计算到达此时的4种状态的所有路径,例如,到达a状态的有从t=1,t=2的4*4=16种情况,要找到概率最大的一条路径记录下来;对于其他的状态点也是这样计算下去保存最优路径。
算法中步骤3中的式子表示两个时刻的距离,每次记录的是根据之间的概率最大记住前一时刻的某一状态。
整个工程的流程
详细内容(含源代码)
- 语料情况
- 语料划分
取前面约80%作为train语料 后面约20%作为测试语料
- 创建分词表和中文词性表
- public class DoIt {
- List<String> wordlist;
- List<String> labellist;
- public DoIt() {
- wordlist = new ArrayList<String>();
- labellist = new ArrayList<String>();
- }
- public int[] creatlist(String train) throws IOException{
- System.out.println("----- 创建List -----");
- System.out.println(".......... . . .");
- File file = new File(train);
- int[] twonum = new int[2];
- if(!file.exists()) {
- throw new IOException(file + "不存在!!!");
- }
- if(!file.isFile()) {
- throw new IOException(file + "不是文件!!!");
- }
- BufferedReader br = new BufferedReader(
- new InputStreamReader(
- new FileInputStream(file)));
- String str = null;
- while((str = br.readLine()) != null) {
- String[] strarray = str.split(" ");
- for (String substr: strarray) {
- String[] tempstr = substr.split("/");
- if (tempstr.length == 2) {
- String word = tempstr[0];
- String label = tempstr[1];
- if(!wordlist.contains(word)) {
- wordlist.add(word);
- }
- if(!labellist.contains(label)) {
- labellist.add(label);
- }
- }
- }
- }
- br.close();
- twonum[0] = wordlist.size();
- twonum[1] = labellist.size();
- listtodocument(labellist, "labellist.dat"); //写文件
- listtodocument(wordlist, "wordlist.dat");
- System.out.println("----- 创建List完成 -----");
- return twonum;
- }
- //list 写到 文件
- public void listtodocument(List<String> list, String filename) throws IOException{
- PrintWriter pw = new PrintWriter(filename);
- for (String string: list) {
- pw.print(string + " ");
- }
- pw.flush();
- pw.close();
- }
- }
- 训练 得到模型的关键三个关键参数
- public class DoIt {
- List<String> wordlist;
- List<String> labellist;
- public DoIt() {
- wordlist = new ArrayList<String>();
- labellist = new ArrayList<String>();
- }
- public void learn(String train, String model, int[] twonum) throws IOException{
- System.out.println("----- 开始训练 -----");
- //System.out.println(twonum[0] +"---------" + twonum[1]);
- int wordnum = twonum[0];
- int labelnum = twonum[1];
- double[] pi = new double[labelnum];
- double[][] A = new double[labelnum][labelnum];
- double[][] B = new double[labelnum][wordnum];
- for (int i = 0; i < labelnum; i++) {
- pi[i] = 1;
- for (int j = 0; j < labelnum; j++) {
- A[i][j] = 1;
- }
- for (int k = 0; k < wordnum; k++) {
- B[i][k] = 1;
- }
- }
- File file = new File(train);
- if(!file.exists()) {
- throw new IOException(file + "不存在!!!");
- }
- if(!file.isFile()) {
- throw new IOException(file + "不是文件!!!");
- }
- BufferedReader br = new BufferedReader(
- new InputStreamReader(
- new FileInputStream(file)));
- PrintWriter pw = new PrintWriter(model);
- String str = null;
- int frontindex = -1;
- int rowpi = 0;
- while((str = br.readLine()) != null) {
- rowpi ++;
- System.out.println("--learn读取到文件的行号: " + rowpi);
- String[] strarray = str.split(" ");
- for (String substr: strarray) {
- String[] tempstr = substr.split("/");
- if (tempstr.length == 2) {
- String word = tempstr[0];
- String label = tempstr[1];
- int wordindex = wordlist.indexOf(word);
- int labelindex = labellist.indexOf(label);
- B[labelindex][wordindex] += 1;
- if (frontindex != -1) {
- A[frontindex][labelindex] += 1;
- }
- frontindex = labelindex;
- }
- }
- String firstlabel = strarray[0].split("/")[1];
- int firstlabelindex = labellist.indexOf(firstlabel);
- // System.out.println(firstlabel);
- pi[firstlabelindex] += 1;
- }
- System.out.println("----- 写参数到model -----");
- //计算概率 写入model文件
- int factor = 1000;
- pw.println(3);
- pw.println(4);
- pw.println(labelnum + 4);
- for (int i = 0; i < labelnum; i++) {
- pw.print(factor * pi[i] / rowpi + " ");
- }
- pw.println();
- double rowsumA = 0;
- //pw.println("A");
- for (int i = 0; i < labelnum; i++) {
- for (int j = 0; j < labelnum; j++) {
- rowsumA += A[i][j];
- }
- for (int j = 0; j < labelnum; j++) {
- pw.print(factor * A[i][j] / rowsumA + " ");
- }
- rowsumA = 0;
- pw.println();
- }
- double rowsumB = 0;
- //pw.println("B");
- for (int i = 0; i < labelnum; i++) {
- for (int k = 0; k < wordnum; k++) {
- rowsumB += B[i][k];
- }
- for (int k = 0; k < wordnum; k++) {
- pw.print(factor * B[i][k] / rowsumB + " ");
- }
- rowsumB = 0;
- pw.println();
- }
- pw.flush();
- br.close();
- pw.close();
- System.out.println("--- 文件写入完毕 训练完成 ---");
- }
- //训练 写 参数 到model文件中
- public void tomodel(String allfile, String train, String model) throws IOException{
- //int[] twonum = creatlist(train);
- int[] twonum = creatlist(allfile);
- learn(train, model, twonum);
- }
- //训练的入口
- public void pleaselearn(String filename) throws IOException{
- double start = System.currentTimeMillis();
- String train = filename;
- String model = "model.dat";
- String allfile = "dataa.dat";
- tomodel(allfile, train, model);
- double end = System.currentTimeMillis();
- System.out.println("训练用时(s): " + (end - start) / 1000);
- }
- }
- 测试 读入模型的参数和测试文本进行译码操作 并将结果与源测试文件的内容以行为单位写入结果
- public class tDoIt {
- List<String> wordlist;
- List<String> labellist;
- public tDoIt() {
- wordlist = new ArrayList<String>();
- labellist = new ArrayList<String>();
- }
- //进行测试
- public void test(String model, String test, String result) throws IOException{
- System.out.println("----- 开始测试 -----");
- String[] wordd = readdocument("wordlist.dat");
- for (String stri: wordd) {
- wordlist.add(stri);
- }
- String[] label = readdocument("labellist.dat");
- for (String strii: label) {
- labellist.add(strii);
- }
- File filemodel = new File(model);
- File filetest = new File(test);
- if(!filemodel.exists()) {
- throw new IOException(filemodel + "不存在!!!");
- }
- if(!filemodel.isFile()) {
- throw new IOException(filemodel + "不是文件!!!");
- }
- if(!filetest.exists()) {
- throw new IOException(filetest + "不存在!!!");
- }
- if(!filetest.isFile()) {
- throw new IOException(filetest + "不是文件!!!");
- }
- BufferedReader brmodel = new BufferedReader(
- new InputStreamReader(
- new FileInputStream(filemodel)));
- BufferedReader brtest = new BufferedReader(
- new InputStreamReader(
- new FileInputStream(filetest)));
- String[] rowpi = null;
- String[] rowA = null;
- String[] rowB = null;
- String strmodel = null;
- int rownumpi = tempreadfile(filemodel)[0];
- int rownumA = tempreadfile(filemodel)[1];
- int rownumB = tempreadfile(filemodel)[2];
- double[] pi = new double[rownumB - rownumA];
- double[][] A = new double[rownumB - rownumA][];
- double[][] B = new double[rownumB - rownumA][];
- int j = 0, k = 0;
- for (int i = 0; (strmodel = brmodel.readLine()) != null; i++) {
- if(i >= rownumpi && i < rownumA) {
- rowpi = strmodel.split(" ");
- pi = strtodouble(rowpi);
- }else if (i >= rownumA && i < rownumB) {
- rowA = strmodel.split(" ");
- A[j++] = strtodouble(rowA);
- }else if(i >= rownumB){
- rowB = strmodel.split(" ");
- B[k++] = strtodouble(rowB);
- }
- }
- StringBuilder strbd;
- PrintWriter pw = new PrintWriter(result);
- String teststr = null;
- int row = 1;
- while((teststr = brtest.readLine()) != null) {
- pw.println(teststr);
- System.out.println("--test读取到文件的行号: " + row++);
- String[] strarray = teststr.split(" ");
- strbd = new StringBuilder();
- for (String substr: strarray) {
- String[] tempstr = substr.split("/");
- if (tempstr.length == 2) {
- String word = tempstr[0];
- strbd.append(word + " ");
- }
- }
- int[] labelindex = viterbi(strbd.toString(), pi, A, B);
- String[] strwords = strbd.toString().split(" ");
- for (int i = 0; i < labelindex.length; i++) {
- pw.print(strwords[i] + "/" + labellist.get(labelindex[i]) + " ");
- }
- pw.println();
- }
- pw.flush();
- brmodel.close();
- brtest.close();
- pw.close();
- }
- // viterbi
- public int[] viterbi(String string, double[] pi, double[][] A, double[][] B) throws IOException{
- String[] words = string.split(" ");
- double[][] delta = new double[words.length][pi.length];
- int[][] way = new int[words.length][pi.length];
- int[] labelindex = new int[words.length];
- for (int i = 0; i < pi.length; i++) {
- delta[0][i] = pi[i] * B[i][wordlist.indexOf(words[0])];
- }
- for (int t = 1; t < words.length; t++) {
- for (int i = 0; i < pi.length; i++) {
- for (int j = 0; j < pi.length; j++) {
- if(delta[t][i] < delta[t-1][j] * A[j][i] * B[i][wordlist.indexOf(words[t])]) {
- delta[t][i] = delta[t-1][j] * A[j][i] * B[i][wordlist.indexOf(words[t])];
- way[t][i] = j;
- }
- }
- }
- }
- double max = delta[words.length - 1][0];
- labelindex[words.length - 1] = 0;
- for (int i = 0; i < pi.length; i++) {
- if (delta[words.length - 1][i] > max) {
- max = delta[words.length - 1][i];
- labelindex[words.length - 1] = i;
- }
- }
- for (int t = words.length - 2; t >= 0; t--) {
- labelindex[t] = way[t + 1][labelindex[t + 1]];
- }
- return labelindex;
- }
- // 读文件到数组
- public String[] readdocument(String filename) throws IOException{
- BufferedReader br = new BufferedReader(
- new InputStreamReader(
- new FileInputStream(filename)));
- String[] strarray = br.readLine().split(" ");
- br.close();
- return strarray;
- }
- //读取文件前的三个参数
- public int[] tempreadfile(File file) throws IOException {
- int[] threenum = new int[3];
- BufferedReader br = new BufferedReader(
- new InputStreamReader(
- new FileInputStream(file)));
- int i = 0;
- String str;
- while((str = br.readLine()) != null) {
- if(i > 2) {
- break;
- }
- threenum[i++] = Integer.parseInt(str);
- }
- br.close();
- return threenum;
- }
- //转String 为 double类型
- public double[] strtodouble(String[] strarray) {
- double[] dbs = new double[strarray.length];
- for (int i = 0; i < strarray.length; i++) {
- dbs[i] = Double.valueOf(strarray[i]);
- }
- return dbs;
- }
- //测试的入口
- public void pleasetest(String filename, String resultname) throws IOException{
- double start = System.currentTimeMillis();
- String test = filename;
- String model = "model.dat";
- String result = resultname;
- test(model, test, result);
- double end = System.currentTimeMillis();
- System.out.println("测试用时(min): " + (end - start) / 1000 / 60);
- }
- }
- 得到result.dat文件 格式如下
- 进行评估 读入结果文件 统计 分词个数与正确标注的分词个数 求解准确率 输出结果
- public class eDoIt {
- public void evaluation(String filename) throws IOException{
- File file = new File(filename);
- if (!file.exists()) {
- throw new IOException(file + "不存在!!!");
- }
- if (!file.isFile()) {
- throw new IOException(file + "不是文件");
- }
- BufferedReader br = new BufferedReader(
- new InputStreamReader(
- new FileInputStream(file)));
- int sum = 0;
- int correct = 0;
- String str;
- String[] strarray;
- int flag = -1;
- int k = 1;
- while(true) {
- str = null;
- strarray = new String[2];
- for (int i = 0; i < 2; i++) {
- str = br.readLine();
- if (str != null) {
- strarray[i] = str;
- }else {
- flag = 1;
- break;
- }
- }
- if (flag > 0)
- break;
- String[] temp1 = strarray[1].split(" ");
- String[] temp2 = strarray[0].split(" ");
- for (int i = 0; i < temp1.length; i++) {
- if (temp1[i].split("/").length == 2 && temp2[i].split("/").length == 2){
- sum++;
- String[] str1 = temp1[i].split("/");
- String[] str2 = temp2[i].split("/");
- if (str1[1].equals(str2[1])) {
- correct++;
- }
- }
- }
- }
- double accuracy = 100.0 * correct / sum;
- System.out.println("总单词的个数:" + sum + "\n正确标注的单词个数:" + correct);
- System.out.println("准确率为:" + accuracy + "%");
- br.close();
- }
- }
- 评估结果如下
- 采用训练好的模型参数写一个进行词性标注的交互Demo
- public class dDoIt {
- List<String> wordlist;
- List<String> labellist;
- public dDoIt() {
- wordlist = new ArrayList<String>();
- labellist = new ArrayList<String>();
- }
- //进行decode
- public void decode(String model) throws Exception{
- Scanner console;
- System.out.println("[MADE BY XINGLICHAO]");
- System.out.println("词性标注系统加载中...");
- System.out.println("------------------------------------");
- String[] wordd = readdocument("wordlist.dat");
- for (String stri: wordd) {
- wordlist.add(stri);
- }
- String[] label = readdocument("labellist.dat");
- for (String strii: label) {
- labellist.add(strii);
- }
- File filemodel = new File(model);
- if(!filemodel.exists()) {
- throw new IOException(filemodel + "不存在!!!");
- }
- if(!filemodel.isFile()) {
- throw new IOException(filemodel + "不是文件!!!");
- }
- BufferedReader brmodel = new BufferedReader(
- new InputStreamReader(
- new FileInputStream(filemodel)));
- String[] rowpi = null;
- String[] rowA = null;
- String[] rowB = null;
- String strmodel = null;
- int rownumpi = tempreadfile(filemodel)[0];
- int rownumA = tempreadfile(filemodel)[1];
- int rownumB = tempreadfile(filemodel)[2];
- double[] pi = new double[rownumB - rownumA];
- double[][] A = new double[rownumB - rownumA][];
- double[][] B = new double[rownumB - rownumA][];
- int j = 0, k = 0;
- for (int i = 0; (strmodel = brmodel.readLine()) != null; i++) {
- if(i >= rownumpi && i < rownumA) {
- rowpi = strmodel.split(" ");
- pi = strtodouble(rowpi);
- }else if (i >= rownumA && i < rownumB) {
- rowA = strmodel.split(" ");
- A[j++] = strtodouble(rowA);
- }else if(i >= rownumB){
- rowB = strmodel.split(" ");
- B[k++] = strtodouble(rowB);
- }
- }
- while(true) {
- System.out.println("依次输入句子的各个分词并以空格分离:");
- System.out.println("[结束使用 请按 0 ]");
- System.out.println("------------------------------------");
- console = new Scanner(System.in);
- try {
- String str = console.nextLine();
- if (str.equals("0")) {
- brmodel.close();
- console.close();
- System.out.println();
- System.out.println("应用结束...");
- System.exit(0);
- }
- long start = System.currentTimeMillis();
- int[] labelindex = viterbi(str, pi, A, B);
- String[] strwords = str.split(" ");
- System.out.println();
- System.out.println("------------------------------------");
- System.out.println("标注结果:");
- for (int i = 0; i < labelindex.length; i++) {
- System.out.print(strwords[i] + "/" + labellist.get(labelindex[i]) + " ");
- }
- System.out.println();
- long end = System.currentTimeMillis();
- System.out.println("\n[本次标注用时 " + (end-start) + " ms]");
- System.out.println("------------------------------------");
- }catch(Exception e) {
- System.out.println("\n你的分词超出了我的能力范围!!");
- System.out.println("------------------------------------");
- }
- }
- }
- // viterbi
- public int[] viterbi(String string, double[] pi, double[][] A, double[][] B) throws IOException{
- String[] words = string.split(" ");
- double[][] delta = new double[words.length][pi.length];
- int[][] way = new int[words.length][pi.length];
- int[] labelindex = new int[words.length];
- for (int i = 0; i < pi.length; i++) {
- delta[0][i] = pi[i] * B[i][wordlist.indexOf(words[0])];
- }
- for (int t = 1; t < words.length; t++) {
- for (int i = 0; i < pi.length; i++) {
- for (int j = 0; j < pi.length; j++) {
- if(delta[t][i] < delta[t-1][j] * A[j][i] * B[i][wordlist.indexOf(words[t])]) {
- delta[t][i] = delta[t-1][j] * A[j][i] * B[i][wordlist.indexOf(words[t])];
- way[t][i] = j;
- }
- }
- }
- }
- double max = delta[words.length - 1][0];
- labelindex[words.length - 1] = 0;
- for (int i = 0; i < pi.length; i++) {
- if (delta[words.length - 1][i] > max) {
- max = delta[words.length - 1][i];
- labelindex[words.length - 1] = i;
- }
- }
- for (int t = words.length - 2; t >= 0; t--) {
- labelindex[t] = way[t + 1][labelindex[t + 1]];
- }
- return labelindex;
- }
- // 读文件到数组
- public String[] readdocument(String filename) throws IOException{
- BufferedReader br = new BufferedReader(
- new InputStreamReader(
- new FileInputStream(filename)));
- String[] strarray = br.readLine().split(" ");
- br.close();
- return strarray;
- }
- //读取文件前的三个参数
- public int[] tempreadfile(File file) throws IOException {
- int[] threenum = new int[3];
- BufferedReader br = new BufferedReader(
- new InputStreamReader(
- new FileInputStream(file)));
- int i = 0;
- String str;
- while((str = br.readLine()) != null) {
- if(i > 2) {
- break;
- }
- threenum[i++] = Integer.parseInt(str);
- }
- br.close();
- return threenum;
- }
- //转String 为 double类型
- public double[] strtodouble(String[] strarray) {
- double[] dbs = new double[strarray.length];
- for (int i = 0; i < strarray.length; i++) {
- dbs[i] = Double.valueOf(strarray[i]);
- }
- return dbs;
- }
- }
- 续..........
在进行test时 标注的速度慢 由于数据较大 一次进行读取测试 时间花费太长 所以 想到将文件按行切分成多个文件 分别进行测试 最后 再将得到的结果小文件 整合成一个大文件用于评估
按行切分文件 与 合并文件 点这里
Github:https://github.com/xinglicha0/Chinese-word-tagging-system-based-on-Hmm
自然语言处理---用隐马尔科夫模型(HMM)实现词性标注---1998年1月份人民日报语料---learn---test---evaluation---Demo---java实现的更多相关文章
- 隐马尔科夫模型HMM(一)HMM模型
隐马尔科夫模型HMM(一)HMM模型基础 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数(TODO) 隐马尔科夫模型HMM(四)维特比 ...
- 隐马尔科夫模型HMM
崔晓源 翻译 我们通常都习惯寻找一个事物在一段时间里的变化规律.在很多领域我们都希望找到这个规律,比如计算机中的指令顺序,句子中的词顺序和语音中的词顺序等等.一个最适用的例子就是天气的预测. 首先,本 ...
- 隐马尔科夫模型 HMM(Hidden Markov Model)
本科阶段学了三四遍的HMM,机器学习课,自然语言处理课,中文信息处理课:如今学研究生的自然语言处理,又碰见了这个老熟人: 虽多次碰到,但总觉得一知半解,对其了解不够全面,借着这次的机会,我想要直接搞定 ...
- 隐马尔科夫模型HMM学习最佳范例
谷歌路过这个专门介绍HMM及其相关算法的主页:http://rrurl.cn/vAgKhh 里面图文并茂动感十足,写得通俗易懂,可以说是介绍HMM很好的范例了.一个名为52nlp的博主(google ...
- 猪猪的机器学习笔记(十七)隐马尔科夫模型HMM
隐马尔科夫模型HMM 作者:樱花猪 摘要: 本文为七月算法(julyedu.com)12月机器学习第十七次课在线笔记.隐马尔可夫模型(Hidden Markov Model,HMM)是统计模型,它用来 ...
- 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率
隐马尔科夫模型HMM(一)HMM模型 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数(TODO) 隐马尔科夫模型HMM(四)维特比算法 ...
- 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数
隐马尔科夫模型HMM(一)HMM模型 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数(TODO) 隐马尔科夫模型HMM(四)维特比算法 ...
- 隐马尔科夫模型HMM(四)维特比算法解码隐藏状态序列
隐马尔科夫模型HMM(一)HMM模型 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数 隐马尔科夫模型HMM(四)维特比算法解码隐藏状态 ...
- 用hmmlearn学习隐马尔科夫模型HMM
在之前的HMM系列中,我们对隐马尔科夫模型HMM的原理以及三个问题的求解方法做了总结.本文我们就从实践的角度用Python的hmmlearn库来学习HMM的使用.关于hmmlearn的更多资料在官方文 ...
- 机器学习之隐马尔科夫模型HMM(六)
摘要 隐马尔可夫模型(Hidden Markov Model,HMM)是统计模型,它用来描述一个含有隐含未知参数的马尔科夫过程.其难点是从可观察的参数中确定该过程的隐含参数,然后利用这些参数来作进一步 ...
随机推荐
- HGOI20180814 (NOIP 模拟Day1)
100pts=40+60+0 rank 56 若串联那么显然是这样: 若并联那么显然是这样: 串联时C<1,并联时C>1,贪心策略<1时尽可能串联,>1时尽可能并联 考虑这样一 ...
- 洛谷 P4568 [JLOI2011]飞行路线 解题报告
P4568 [JLOI2011]飞行路线 题目描述 Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在\(n\)个城市设有业务,设这些城市分别标记为0到\(n−1\ ...
- Java后台面试 常见问题
Java后台面试 常见问题 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米.百度.阿里.京东.新浪.CVTE.乐视家的研发岗offer.我找的是java后台开发,把常见的问题分享 ...
- spring的controller默认是单例还是多例
转: spring的controller默认是单例还是多例 先看看spring的bean作用域有几种,分别有啥不同. spring bean作用域有以下5个: singleton:单例模式,当spri ...
- error while loading shared libraries: libmysqlcppconn.so.7: cannot open shared object file: No such file or directory
1. 即使libmysqlcppconn.so.7和与之相关存在,也报这个错误. 解决方法:临时添加LD_LIBRARY_PATH, 假使 libmysqlcppconn.so在/usr/local/ ...
- ubuntu14的unity desktop显示异常
在多用户下,卸载compiz后某个单一用户出现菜单栏和任务栏图标消失的情况. 这时,需要在图形界面下重置compiz $dconf reset -f /org/compiz/ 重启unity $set ...
- 如何构建 Redis 高可用架构?
温国兵 民工哥技术之路 今天 1 .题记 Redis 是一个开源的使用 ANSI C 语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value 数据库,并提供多种语言的 API. 如今,互 ...
- 口琴练习部分 - 多孔单音奏法 & 简单伴奏
多孔单音奏法(口含5个孔) 加入伴奏 理论知识 - 盖住 理论知识 - 松开 舌头一抬一合形成一个伴奏 高级一点的伴奏练习 正拍伴奏: 当要吹吸某一个音时,舌头先离开琴格,然后迅速盖上.
- 质数——6N±1法
6N±1法求素数 任何一个自然数,总可以表示成为如下的形式之一: 6N,6N+1,6N+2,6N+3,6N+4,6N+5 (N=0,1,2,…) 显然,当N≥1时,6N,6N+2,6N+3,6N+4都 ...
- Linux命令(二)关机重启