首页 文章 精选 留言 我的

精选列表

搜索[学习],共10000篇文章
优秀的个人博客,低调大师

1-学习GPRS_Air202(Air202开发板介绍)

这次准备出一期STM32+WIFI+GPRS的系统开发教程,推出的形式是基础教程(公开)+系统教程 来点欢乐 https://v.youku.com/v_show/id_XMzE1OTIxODE3Mg.html 最终达到的目标: STM32采集温湿度传感器(DHT11)的数据,通过WIFI模块或GPRS模块远程发给APP和上位机,APP和上位机远程控制开发板的指示灯 系统教程视频教程:http://list.youku.com/albumlist/show/id_51982883.html (视频播单) 系统教程第一节:项目演示 https://v.youku.com/v_show/id_XMzk0MDQ4NjU4MA==.html?spm=a2h3j.8428770.3416059.1 系统教程第一节:下载WIFI程序实现远程采集和控制 https://v.youku.com/v_show/id_XMzk0MDQ5Njc2OA==.html?spm=a2h3j.8428770.3416059.1 https://www.cnblogs.com/yangfengwu/p/9966702.html 系统教程第一节:下载GPRS程序实现远程采集和控制 https://v.youku.com/v_show/id_XMzk0MDUwMjI4MA==.html?spm=a2h3j.8428770.3416059.1 https://www.cnblogs.com/yangfengwu/p/9966901.html 系统教程第二节:购买阿里云服务器 https://v.youku.com/v_show/id_XMzk0MDc4MDQxMg==.html?spm=a2h3j.8428770.3416059.1 详细文档:(视频为早期视频,具体请参考详细文档) https://www.cnblogs.com/yangfengwu/p/9953703.html 系统教程第三节:云端安装MQTT服务器,修改用户名密码 视频教程: https://v.youku.com/v_show/id_XMzk0MDc4MzAwMA==.html?spm=a2h3j.8428770.3416059.1 详细文档: https://www.cnblogs.com/yangfengwu/p/9953920.html 系统教程第四节:C#控制台安装MQTT,实现MQTT调试助手 https://v.youku.com/v_show/id_XMzk0MDc4NjY4OA==.html?spm=a2h3j.8428770.3416059.1 系统教程第五节:建立C#工程,自己下载和安装MQTT包,实现MQTT调试助手 https://v.youku.com/v_show/id_XMzk0MDg1NjM2OA==.html?spm=a2h3j.8428770.3416059.1 系统教程第六节:C#DLL打包合成EXE软件 https://v.youku.com/v_show/id_XMzk0MDg2MDY4NA==.html?spm=a2h3j.8428770.3416059.1 系统教程第七节:建立APP工程(Android Studio),导入MQTT,二维码,图表,SmartConfig的jar包,Listview,动态权限 https://v.youku.com/v_show/id_XMzk0MDg2MjM3Mg==.html?spm=a2h3j.8428770.3416059.1 系统教程第八节:Activity控制界面设计,界面跳转,携带数据,Activity加载模式 https://v.youku.com/v_show/id_XMzk0MDg5ODAyNA==.html?spm=a2h3j.8428770.3416059.1 系统教程第九节:Achartengine动态曲线显示(1) https://v.youku.com/v_show/id_XMzk0MzMwNTM0NA==.html?spm=a2h3j.8428770.3416059.1 系统教程第九节:Achartengine动态曲线显示(2) https://v.youku.com/v_show/id_XMzk0MDkwNDcyOA==.html?spm=a2h3j.8428770.3416059.1 系统教程第十节-AndroidStudio编写MQTT通信程序,支持断线重连,测试通信 https://v.youku.com/v_show/id_XMzk0MjI1MTUzNg==.html?spm=a2h3j.8428770.3416059.1 系统教程第十一节-AndroidStudio编写SmartConfig程序,绑定WIFI实现远程通信 https://v.youku.com/v_show/id_XMzk0MjUxMzA1Ng==.html?spm=a2h3j.8428770.3416059.1 系统教程第十二节-AndroidStudio数据库存储设备信息 https://v.youku.com/v_show/id_XMzk0MjUzNDEzMg==.html?spm=a2h3j.8428770.3416059.1 系统教程第十三节-AndroidStudio编写扫描二维码程序,绑定GPRS设备实现远程通信 https://v.youku.com/v_show/id_XMzk0MjU2MDMwOA==.html?spm=a2h0j.11185381.listitem_page1.5~A 系统教程第十四节-编写8266模块SmartConfig和MQTT程序,和APP测试绑定通信 https://v.youku.com/v_show/id_XMzk0MjU3Nzg4NA==.html?spm=a2h3j.8428770.3416059.1 系统教程第十五节-编写GPRS的MQTT透传程序,测试远程通信,生成量产.lod文件 https://v.youku.com/v_show/id_XMzk0MjU5NjIwMA==.html?spm=a2h3j.8428770.3416059.1 系统教程第十六节-总结 https://v.youku.com/v_show/id_XMzk0MzU2MjEyNA==.html?spm=a2h3j.8428770.3416059.1 基础教程资料链接 链接:https://pan.baidu.com/s/1-SRfsKGQ7rZVvFmp1ObHWw密码:p9qs 基础教程源码链接如果失效,请在淘宝介绍中下载,由于链接很容易失效,如果失效请联系卖家,谢谢 https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-18540610442.6.36a74814ZSaRsu&id=569295486025 现在看一下原理图 这一期教程后期打算出STM32的基础教程 WIFI模块的开发以LUA和SDK为主,Air202的开发以LUA为主 (LUA开发是趋势,用单片机去AT指令配置既麻烦又不符合项目开发) 基础教程源码请在淘宝介绍中下载,由于链接很容易失效,如果失效请联系卖家,谢谢 https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-18540610442.6.36a74814ZSaRsu&id=569295486025 http://www.cnblogs.com/yangfengwu/p/8948935.html

优秀的个人博客,低调大师

java学习笔记--内部类:(参考java核心技术卷1and转载)

做JavaEE即网站的 基本不接触内部类 做安卓的 基本天天接触内部类 内部类是定义在另一个类中的类 可以分为这四类: 局部内部类 成员内部类 与外部类有直接联系 静态内部类 与外部类没有直接联系 匿名内部类 特点: 1. 内部类可以访问外部类定义所在的作用域的数据,包括私有的数据 2. 内部类可以对同一个包中的其他类隐藏 设计成private同一个包的其他类无法访问,一般都是内部类private 内部类里的数据是public类型 3. 用匿名内部类定义一个回调函数可以节省大量代码 什么是回调函数? 简单意思就是自己定义一个类 交给其他类来调用 比如 A去超市向B买东西,B告诉A 没货 然后A留了一个电话给B说 到了告诉我,一段时间后 A收到电话去取货。 内部类既可以访问自身的数据域 也可以访问创建它的外部类对象的数据域 因为内部类的对象有个隐式的引用,指向创建它的外部对象(这个引用是不可见的) 内部类可以为私有类 只有外部类的方法可以构造,其他常规类只可以具有包内可见或者公有可见性 内部类的所有静态域都必须是final的,因为每个外部对象都有单独的内部类实例 如果或者域不是final 那么它可能就不唯一了。 内部类不能有static方法(没强制要求 但不推荐) 编译器会把内部类翻译成分隔外部类名和内部类名的文件例如:Talk内部的Time类被翻译成类文件Talk分隔外部类名和内部类名的文件例如:Talk内部的Time类被翻译成类文件TalkTime.class 内部类可以继承与外部类不一样的继承父类或者接口 局部内部类: 局部内部类 不能用public和private访问修饰符 他的作用域被限定在这个声明这个局部类的块中 局部类有个优势,就是对外部世界完全隐藏 内部类除了可以访问他们的外部类 ,还可以访问局部变量 不过和这些变量事实上都是final的 之前在电脑上的笔记 就直接粘贴了 /* 内部类:一个类定义在另外一个类的内部,那么该类就称作为内部类。 内部类的class文件名: 外部类$内部类. 好处:便于区分该class文件是属于哪个外部类的。 内部类的类别: 1. 成员内部类: 成员内部类的访问方式: 方式一:在外部类提供一个方法创建内部类的对象进行访问。 方式2二:在其他类直接创建内部类的对象。 格式:外部类.内部类 变量名 = new 外部类().new 内部类(); 注意: 如果是一个静态内部类,那么在其他类创建 的格式: 外部类.内部类 变量名 = new 外部类.内部类(); 内部类的应用场景: 我们在描述A事物的时候,发现描述的A事物内部还存在 另外一个比较复杂的事物B时候,而且这个比较复杂事物B还需要访问A事物的属性 等数据,那么这时候我们就可以使用内部类描述B事物。 比如: 人--->心脏 class 人{ 血 氧气 等.... class 心脏{ } } 内部类的好处:内部类可以直接访问外部类的所有成员。 内部类要注意的细节: 1. 如果外部类与内部类存在同名的成员变量时,在内部类中默认情况下是访问 内部类的成员变量。可以通过"外部类.this.成员变量名" 指定访问外部类的成员 2. 私有的成员内部类只能在外部类提供一个方法创建内部类的对象进行访问, 不能在其他类创建对象了。 3. 成员内部类一旦出现了静态的成员,那么该类也必须 使用static修饰。 创建静态类举例: Outer.Inner zz=new Outer.Inner(); /* 局部内部类: 在一个类 的方法内部定义另外一个类, 那么另外一个类就称作为局部内部类。 局部内部类要注意的细节: 1.如果局部 内部类(可以是匿名内部类)访问了一个局部变量,那么该局部变量必须使用final修饰 */ 局部变量在方法结束后就被回收了 但是方法内创造的类还存在着 这个时候 如果一个局部内部类访问一个局部变量的时候,那么就让该局部内部类 访问这个局部 变量 的复制品。 所以要对局部变量加 final这样子就不可以被修改的复制品 举例: class A{ public void zz(){ final int x=10; class test{ public void xx(){ System.out.println("这个是局部内部类的print方法.."+x); } } test qq=new test(); qq.xx(); } } class Demo2{ public static void main(String[] args){ A xx=new A(); xx.zz(); } } abstract class A{ public abstract void xx(); } class D{ public void zz(){ /*new A(){ public void xx(){ System.out.println("11"); } }.xx();*/ /*A aa=new A(){//多态 //匿名内部类 :匿名内部类只是没有类名,其他的一概成员都是具备的。 // 匿名内部类与Animal是继承 的关系。 目前是创建Animal子类的对象. public void xx(){ System.out.print("qq"); } }; aa.xx(); */ } } 记住 匿名类必须是继承或者实现 因为他没有名字 只能借用父亲的 A不是接口吗为什么可以实例化 其实这个A不是接口因为它是接用了父亲名字的匿名类 举一个实现的例子: interface A{ public void xx(); } class Demo2{ public static void main(String[] args){ /*new A(){ public void xx(){ System.out.print("xxx"); } }.xx();*/ zz(new A(){ public void xx(){ System.out.print("xZZ"); } }); } public static void zz(A zz){ zz.xx(); } } //形参类型是一个接口引用.. 匿名内部类总结: 匿名内部类是局部内部类 匿名函数虽然没有名字,但也是可以有构造函数的,它用构造函数块来代替 问:为什么匿名函数没有构造函数? 答:因为匿名类没有名字,而构造函数需要把类名作为方法名才能看成构造函数。 原来是因为匿名类的构造函数特殊处理机制,一般类(也就是具有显式名字的类)的所 有构造函数默认都是调用父类的无参构造的,而匿名类因为没有名字,只能由构造代码 块代替,也就无所谓的有参和无参构造函数了,它在初始化时直接调用了父类的同参数 构造,然后再调用了自己的构造代码块。 必须要强调注意的是 如果内部类调用了所在方法的参数或者局部变量,那么这些变量都必须为final的,这是为了维持变量的一致性,因为当你传递一个参数给内部类的时候 ,内部类会自动把这个参数拷贝一份到自身的变量,这是我们看不到的,如果我们对该变量进行操作,那么对原参数是不影响的,并不是对原参数进行操作行为,而是对原参数的复制品进行操作 内部类里的变量和外部环境的变量不同步,指向了不同的对象。 因此,编译器才会要求我们给传参的局部变量加上final(内部类用到了外部变量 (不是类中的成员变量)则外部变量要加final),防止这种不同步情况的发生。 具体的看这位大佬的博客 为什么需要final 为什么要拷贝 局部变量是位于方法内部的,因此局部变量是在虚拟机栈上,也就意味着这个变量无法进行共享,匿名内部类也就无法直接访问,因此只能通过值传递的方式,传递到匿名内部类中。 那一定需要拷贝吗? 答:不是的。 成员变量,对应的在虚拟机里是在堆的位置,而且无论在这个类的哪个地方,我们只需要通过 this.dog,就可以获得这个变量。因此,在创建内部类时,无需进行拷贝,甚至都无需将这个成员变量传递给内部类。 意思就是: 匿名内部类来自外部闭包环境的自由变量必须是final的,除非自由变量来自类的成员变量。 问:*局部内部类在访问他所在方法中的局部变量必须用final修饰,为什么?* 答:因为当调用这个方法时,局部变量如果没有用final修饰,他的生命周期和方法的生命周期是一样的,当方法弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有马上消失想用这个局部变量,就没有了,如果用final修饰会在类加载的时候进入常量池,即使方法弹栈,常量池的常量还在,也可以继续使用 匿名内部类不能在匿名类里面定义接口。 匿名内部类不能定义静态初始化代码块 内部类中不能定义任何静态的东西。 参考:java 内部类为什么不能用静态方法 非static的内部类,在外部类加载的时候,并不会加载它,所以它里面不能有静态 变量或者 静态方法。static类型的属性和方法,在类加载的时候就会存在于内 存中。要使用某个类的static属性或者方法,那么这个类必须要加载到jvm中。 基于以上两点,可以看出,如果一个非static的内部类如果具有static的属性或 者方法,那么就会出现一种情况:内部类未加载,但是却试图在内存中创建static 的属性和方法,这当然是错误的。原因:类还不存在,但却希望操作它的属性 和方法。 总结原因:因为要访问非静态内部类 你首先得实例化内部类 而静态可以直接通过类名来访问 你说非静态内部类没有类名无法访问 而且 都实例化了 你定义静态有何意义?静态是为了不用不用实例化 直接调用 结论: 1. 匿名内部类是局部内部类 2. 匿名内部类不能有构造函数 (可以用构造块代替) 就只有它没有 其他可以有 3. 匿名内部类不能有静态方法或成员 4. 匿名类可以直接访问成员变量 因为成员变量是在堆里的 5. 匿名类如果在一个函数内访问一个局部变量则需要加final 因为局部变量在栈中 所以jvm自动帮我们传值给匿名类 所以在匿名类中操作的其实是复制品 所以需要final保持一致 6. 内部类可以直接访问 成员变量 因为内部类对象必定会捕获一个指向那个外围类对象的引用 但外围类要访问内部类的成员属性和方法则需要通过内部类实例来访问。 7. 成员内部类可以有构造函数 分为非静态内部类 和静态内部类 8. 成员内部类中不能存在任何static的变量和方法; 9. 成员内部类是依附于外围类的,所以只有先创建了外围类才能够创建内部类。 10. 推荐使用getxxx()来获取成员内部类,尤其是该内部类的构造函数无参数时 。 11. 非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围内,但是静态内部类却没有。没有这个引用就意味着: 1、 它的创建是不需要依赖于外围类的。 2、 它不能使用任何外围类的非static成员变量和方法。 12. 在类中 非静态内部类和匿名内部类都可以访问成员变量 因为成员变量是在堆中 两个内部类内部隐含地保存着指向外部的引用,所以没有拷贝成员变量 可以直接操作。 14. 静态内部类跟静态方法一样,只能访问外部类的静态的成员变量和方法,不能访问非静态的方法和属性,但是普通内部类可以访问任意外部类的成员变量和方法 15. 静态内部类可以声明普通成员变量和方法,而普通内部类不能声明static成员变量和方法。 16. 静态内部类使用场景一般是当外部类需要使用内部类,而内部类无需外部类资源,并且内部类可以单独创建的时候会考虑采用静态内部类的设计 17. 外部类实例不能访问静态类 18. 静态类内部可以定义普通方法 而且要使用该方法得实例化该静态类 19. 静态内部类可以直接访问自己里面的静态成员或者方法 具体的还是看大佬的博客吧 这两篇挺好的 匿名内部类 内部类

优秀的个人博客,低调大师

SparkML机器学习之特征工程(二)特征转化(Binarizer、StandardScaler、MaxAbsScaler、Normaliz...

特征转化 为什么要转化数据呢,就是要让它成为有效的特征,因为原始数据是很多脏数据无用数据的。常用的方法是标准化,归一化,特征的离散化等等。比如我输入的数据是句子,我得把它切分为一个个单词进行分析,这就是一种转化。 连续型数据处理之二值化:Binarizer 假设淘宝现在有个需求,我得根据年龄来进行物品推荐,把50以上的人分为老年,50以下分为非老年人,那么我们根据二值化可以很简单的把50以上的定为1,50以下的定为0。这样就方便我们后续的推荐了。Binarizer就是根据阈值进行二值化,大于阈值的为1.0,小于等于阈值的为0.0 package ml.test import org.apache.spark.ml.feature.Binarizer import org.apache.spark.sql.SparkSession /** * Created by liuyanling on 2018/3/19 */ object BinarizerDemo { def main(args: Array[String]): Unit = { var spark = SparkSession.builder().appName("BinarizerDemo").master("local[2]").getOrCreate(); val array = Array((1,34.0),(2,56.0),(3,58.0),(4,23.0)) //将数组转为DataFrame val df = spark.createDataFrame(array).toDF("id","age") //初始化Binarizer对象并进行设定:setThreshold是设置我们的阈值,InputCol是设置需要进行二值化的输入列,setOutputCol设置输出列 val binarizer = new Binarizer().setThreshold(50.0).setInputCol("age").setOutputCol("binarized_feature") //transform方法将DataFrame二值化。 val binarizerdf = binarizer.transform(df) //show是用于展示结果 binarizerdf.show } } 输出结果: +---+----+-----------------+ | id| age|binarized_feature| +---+----+-----------------+ | 1|34.0| 0.0| | 2|56.0| 1.0| | 3|58.0| 1.0| | 4|23.0| 0.0| +---+----+-----------------+ 连续型数据处理之给定边界离散化:Bucketizer 现在淘宝的需求变了,他们觉得把人分为50以上和50以下太不精准了,应该分为20岁以下,20-30岁,30-40岁,36-50岁,50以上,那么就得用到数值离散化的处理方法了。离散化就是把特征进行适当的离散处理,比如上面所说的年龄是个连续的特征,但是我把它分为不同的年龄阶段就是把它离散化了,这样更利于我们分析用户行为进行精准推荐。Bucketizer能方便的将一堆数据分成不同的区间。 object BucketizerDemo { def main(args: Array[String]): Unit = { var spark = SparkSession.builder().appName("BucketizerDemo").master("local[2]").getOrCreate(); val array = Array((1,13.0),(2,16.0),(3,23.0),(4,35.0),(5,56.0),(6,44.0)) //将数组转为DataFrame val df = spark.createDataFrame(array).toDF("id","age") // 设定边界,分为5个年龄组:[0,20),[20,30),[30,40),[40,50),[50,正无穷) // 注:人的年龄当然不可能正无穷,我只是为了给大家演示正无穷PositiveInfinity的用法,负无穷是NegativeInfinity。 val splits = Array(0, 20, 30, 40, 50, Double.PositiveInfinity) //初始化Bucketizer对象并进行设定:setSplits是设置我们的划分依据 val bucketizer = new Bucketizer().setSplits(splits).setInputCol("age").setOutputCol("bucketizer_feature") //transform方法将DataFrame二值化。 val bucketizerdf = bucketizer.transform(df) //show是用于展示结果 bucketizerdf.show } } 输出结果: +---+----+------------------+ | id| age|bucketizer_feature| +---+----+------------------+ | 1|13.0| 0.0| | 2|16.0| 0.0| | 3|23.0| 1.0| | 4|35.0| 2.0| | 5|56.0| 4.0| | 6|44.0| 3.0| +---+----+------------------+ 连续型数据处理之给定分位数离散化:QuantileDiscretizer 有时候我们不想给定分类标准,可以让spark自动给我们分箱。 object QuantileDiscretizerDemo { def main(args: Array[String]): Unit = { var spark = SparkSession.builder().appName("QuantileDiscretizerDemo").master("local[2]").getOrCreate(); val array = Array((1,13.0),(2,14.0),(3,22.0),(4,35.0),(5,44.0),(6,56.0),(7,21.0)) val df = spark.createDataFrame(array).toDF("id","age") //和Bucketizer类似:将连续数值特征转换离散化。但这里不再自己定义splits(分类标准),而是定义分几箱就可以了。 val quantile = new QuantileDiscretizer().setNumBuckets(5).setInputCol("age").setOutputCol("quantile_feature") //因为事先不知道分桶依据,所以要先fit,相当于对数据进行扫描一遍,取出分位数来,再transform进行转化。 val quantiledf = quantile.fit(df).transform(df) //show是用于展示结果 quantiledf.show } } 标准化 对于同一个特征,不同的样本中的取值可能会相差非常大,一些异常小或异常大的数据会误导模型的正确训练;另外,如果数据的分布很分散也会影响训练结果。以上两种方式都体现在方差会非常大。此时,我们可以将特征中的值进行标准差标准化,即转换为均值为0,方差为1的正态分布。如果特征非常稀疏,并且有大量的0(现实应用中很多特征都具有这个特点),Z-score 标准化的过程几乎就是一个除0的过程,结果不可预料。所以在训练模型之前,一定要对特征的数据分布进行探索,并考虑是否有必要将数据进行标准化。基于特征值的均值(mean)和标准差(standard deviation)进行数据的标准化。它的计算公式为:标准化数据=(原数据-均值)/标准差。标准化后的变量值围绕0上下波动,大于0说明高于平均水平,小于0说明低于平均水平。 StandardScaler object StandardScalerDemo { def main(args: Array[String]): Unit = { val spark = SparkSession.builder().master("local[2]").getOrCreate() val df = spark.read.format("libsvm").load("libsvm_data.txt") //setWithMean是否减均值。setWithStd是否将数据除以标准差。这里就是没有减均值但有除以标准差 df.printSchema() val scaler =new StandardScaler().setInputCol("features").setOutputCol("scaledFeatures").setWithMean(false).setWithStd(true) // 计算均值方差等参数 val scalermodel = scaler.fit(df) // 标准化 scalermodel.transform(df).show() } } libsvm_data.txt label 标签,就是属于哪一类,即你要分类的种类,通常是一些整数。 index 是有顺序的索引,通常是连续的整数。就是指特征编号,必须按照升序排列 value 就是特征值,训练,通常是一堆实数组成。 格式:标签 第一维特征编号:第一维特征值 第二维特征编号:第二维特征值 …例: 0 1:1 2:2 1 1:2 2:4 归一化 为什么数据需要归一化?以房价预测为案例,房价(y)通常与离市中心距离(x1)、面积(x2)、楼层(x3)有关,设y=ax1+bx2+cx3,那么abc就是我们需要重点解决的参数。但是有个问题,面积一般数值是比较大的,100平甚至更多,而距离一般都是几公里而已,b参数只要一点变化都能对房价产生巨大影响,而a的变化对房价的影响相对就小很多了。显然这会影响最终的准确性,毕竟距离可是个非常大的影响因素啊。 所以, 需要使用特征的归一化, 取值跨度大的特征数据, 我们浓缩一下, 跨度小的括展一下, 使得他们的跨度尽量统一。归一化就是将所有特征值都等比地缩小到0-1或者-1到1之间的区间内。其目的是为了使特征都在相同的规模中。 绝对值最大标准化:MaxAbsScaler import org.apache.spark.ml.feature.MaxAbsScaler import org.apache.spark.ml.linalg.Vectors import org.apache.spark.sql.SparkSession /** * Created by LYL on 2018/3/20. */ object MaxAbsScalerDemo { def main(args: Array[String]): Unit = { val spark = SparkSession.builder().appName("MaxAbsScalerDemo").master("local[2]").getOrCreate() val dataFrame = spark.createDataFrame(Seq( (0, Vectors.dense(10.0, 0.1, -8.0)), (1, Vectors.dense(100.0, 1.0, -4.0)), (2, Vectors.dense(1000.0, 10.0, 8.0)) )).toDF("id", "features") val maxabs = new MaxAbsScaler().setInputCol("features").setOutputCol("maxabs_features") // fit作用是把所有值都扫描一遍,计算出最大最小值,比如1000的话那么absMax=1000。最后返回MaxAbsScalerModel val scalerModel = maxabs.fit(dataFrame) // 使用每个特征的最大值的绝对值将输入向量的特征值都缩放到[-1,1]范围内 val scalerdf = scalerModel.transform(dataFrame) scalerdf.show } } 运行结果: +---+-----------------+----------------+ | id| features| maxabs_features| +---+-----------------+----------------+ | 0| [10.0,0.1,-8.0]|[0.01,0.01,-1.0]| | 1| [100.0,1.0,-4.0]| [0.1,0.1,-0.5]| | 2|[1000.0,10.0,8.0]| [1.0,1.0,1.0]| +---+-----------------+----------------+ 归一化之最小最大值标准化MinMaxScaler import org.apache.spark.ml.feature.MinMaxScaler import org.apache.spark.ml.linalg.Vectors import org.apache.spark.sql.SparkSession /** * Created by LYL on 2018/3/20. */ object MinMaxScalerDemo { def main(args: Array[String]): Unit = { val spark = SparkSession.builder().appName("MinMaxScalerDemo").master("local[2]").getOrCreate() val dataFrame = spark.createDataFrame(Seq( (0, Vectors.dense(2.0, 0.9, -2.0)), (1, Vectors.dense(3.0, -2.0, -3.0)), (2, Vectors.dense(4.0, -2.0, 2.0)) )).toDF("id", "features") val maxabs = new MinMaxScaler().setInputCol("features").setOutputCol("minmax_features") val scalerModel = maxabs.fit(dataFrame) // 将所有值都缩放到[0,1]范围内 val scalerdf = scalerModel.transform(dataFrame) scalerdf.show } } 运行结果为: +---+---------------+---------------+ | id| features|minmax_features| +---+---------------+---------------+ | 0| [2.0,0.9,-2.0]| [0.0,1.0,0.2]| | 1|[3.0,-2.0,-3.0]| [0.5,0.0,0.0]| | 2| [4.0,-2.0,2.0]| [1.0,0.0,1.0]| +---+---------------+---------------+ 正则化Normalizer 为什么要有正则化?就是为了防止过拟合。来看一下正则化是怎么计算的: def main(args: Array[String]): Unit = { val spark = SparkSession.builder().master("local[2]").getOrCreate() val dataFrame = spark.createDataFrame(Seq( (0, Vectors.dense(1.0, 0.5, -1.0)), (1, Vectors.dense(2.0, 1.0, 1.0)), (2, Vectors.dense(4.0, 10.0, 2.0)) )).toDF("id", "features") //setP是指L1正则化还是L2正则化,比如1.0就是上面说到的L1正则化,计算如下:1/(1+0.5+1) val normalizer = new Normalizer().setInputCol("features").setOutputCol("normalizer_features").setP(1.0) normalizer.transform(dataFrame).show(truncate = false) } 输出结果为: +---+--------------+-------------------+ |id |features |normalizer_features| +---+--------------+-------------------+ |0 |[1.0,0.5,-1.0]|[0.4,0.2,-0.4] | |1 |[2.0,1.0,1.0] |[0.5,0.25,0.25] | |2 |[4.0,10.0,2.0]|[0.25,0.625,0.125] | +---+--------------+-------------------+ N-gram N-Gram认为语言中每个单词只与其前面长度 N-1 的上下文有关。主要分为bigram和trigram,bigram假设下一个词的出现依赖它前面的一个词,trigram假设下一个词的出现依赖它前面的两个词。在SparkML中用NGram类实现,setN(2)为bigram,setN(3)为trigram。 def main(args: Array[String]): Unit = { val spark = SparkSession.builder().master("local[2]").getOrCreate() val wordDataFrame = spark.createDataFrame(Seq( (0, Array("Hi", "I", "heard", "about", "Spark")), (1, Array("I", "wish", "Java", "could", "use", "case", "classes")), (2, Array("Logistic", "regression", "models", "are", "neat")) )).toDF("id", "words") val ngram2 = new NGram().setN(2).setInputCol("words").setOutputCol("ngrams") val ngram3 = new NGram().setN(3).setInputCol("words").setOutputCol("ngrams") ngram2.transform(wordDataFrame).show(false) ngram3.transform(wordDataFrame).show(false) } 输出结果为: +---+------------------------------------------+------------------------------------------------------------------+ |id |words |ngrams | +---+------------------------------------------+------------------------------------------------------------------+ |0 |[Hi, I, heard, about, Spark] |[Hi I, I heard, heard about, about Spark] | |1 |[I, wish, Java, could, use, case, classes]|[I wish, wish Java, Java could, could use, use case, case classes]| |2 |[Logistic, regression, models, are, neat] |[Logistic regression, regression models, models are, are neat] | +---+------------------------------------------+------------------------------------------------------------------+ 18/03/24 11:23:32 INFO CodeGenerator: Code generated in 14.198881 ms +---+------------------------------------------+--------------------------------------------------------------------------------+ |id |words |ngrams | +---+------------------------------------------+--------------------------------------------------------------------------------+ |0 |[Hi, I, heard, about, Spark] |[Hi I heard, I heard about, heard about Spark] | |1 |[I, wish, Java, could, use, case, classes]|[I wish Java, wish Java could, Java could use, could use case, use case classes]| |2 |[Logistic, regression, models, are, neat] |[Logistic regression models, regression models are, models are neat] | +---+------------------------------------------+--------------------------------------------------------------------------------+ 多项式转化PolynomialExpansion 有时候要对特征值进行一些多项式的转化,比如平方啊,三次方啊等等,那就用到了PolynomialExpansion。 object PolynomialExpansionDemo { def main(args: Array[String]): Unit = { val spark = SparkSession.builder().master("local[2]").getOrCreate() val dataFrame = spark.createDataFrame(Seq( (0, Vectors.dense(1.0, 5.0)), (1, Vectors.dense(2.0, 1.0)), (2, Vectors.dense(4.0, 8.0)) )).toDF("id", "features") //setDegree表示多项式最高次幂 比如1.0,5.0可以是 三次:1.0^3 5.0^3 1.0+5.0^2 二次:1.0^2+5.0 1.0^2 5.0^2 1.0+5.0 一次:1.0 5.0 val po = new PolynomialExpansion().setDegree(3).setInputCol("features").setOutputCol("Polynomial_features") po.transform(dataFrame).show(truncate = false) } } 输出结果为: +---+---------+-----------------------------------------------+ |id |features |Polynomial_features | +---+---------+-----------------------------------------------+ |0 |[1.0,5.0]|[1.0,1.0,1.0,5.0,5.0,5.0,25.0,25.0,125.0] | |1 |[2.0,1.0]|[2.0,4.0,8.0,1.0,2.0,4.0,1.0,2.0,1.0] | |2 |[4.0,8.0]|[4.0,16.0,64.0,8.0,32.0,128.0,64.0,256.0,512.0]| +---+---------+-----------------------------------------------+ Tokenizer分词器 当我们的输入数据为文本(句子)的时候,我们会想把他们切分为单词再进行数据处理,这时候就要用到Tokenizer类了。 object TokenizerDemo { def main(args: Array[String]): Unit = { val spark = SparkSession.builder().master("local[2]").appName("TokenizerDemo").getOrCreate() val dataFrame = spark.createDataFrame(Seq((0, "Hello I am LYL"), (1, "I Love Bigdata"), (2, "1 2 3 4"))).toDF("id", "sentence") // Tokenization(分词器)是一个接受文本(通常是句子)输入,然后切分成单词。 val tokenizer = new Tokenizer().setInputCol("sentence").setOutputCol("words") tokenizer.transform(dataFrame).show() // RegexTokenizer(正则化分词器)基于正则表达式匹配提供了更多高级的分词功能。将gaps参数设置为false,表明使用正则表达式匹配标记,而不是使用分隔符。 // 此处\\d表示匹配数字。 val regextokenizer = new RegexTokenizer().setInputCol("sentence").setOutputCol("words").setGaps(false).setPattern("\\d") regextokenizer.transform(dataFrame).show() //使用udf函数 统计单词个数 val wordcount = udf { (word: Seq[String]) => word.length } tokenizer.transform(dataFrame).select("words").withColumn("wordcount", wordcount(col("words"))).show() } 输出结果为: +---+--------------+-------------------+ | id| sentence| words| +---+--------------+-------------------+ | 0|Hello I am LYL|[hello, i, am, lyl]| | 1|I Love Bigdata| [i, love, bigdata]| | 2| 1 2 3 4| [1, 2, 3, 4]| +---+--------------+-------------------+ +---+--------------+------------+ | id| sentence| words| +---+--------------+------------+ | 0|Hello I am LYL| []| | 1|I Love Bigdata| []| | 2| 1 2 3 4|[1, 2, 3, 4]| +---+--------------+------------+ +-------------------+---------+ | words|wordcount| +-------------------+---------+ |[hello, i, am, lyl]| 4| | [i, love, bigdata]| 3| | [1, 2, 3, 4]| 4| +-------------------+---------+ SQLTransformer 我们都很喜欢sql语句,简单好用又熟悉,那么Spark ML很人性化的为我们提供了SQLTransformer类,使得我们能用我们熟悉的SQL来做特征转化。它支持SparkSql中的所有select选择语句,sum(),count(),group by,order by等等都可以用!形如"SELECT ...FROM __THIS__"。'__THIS__'代表输入数据的基础表。 def main(args: Array[String]): Unit = { val spark = SparkSession.builder().master("local[2]").getOrCreate() val df = spark.createDataFrame(Seq((1, "lyl", 90), (2, "ddd", 88), (3, "ccc", 95))) .toDF("id", "name", "score") //__THIS__代表输入数据的基础表 在这里就是指df val sqltransformer1 = new SQLTransformer().setStatement("select id from __THIS__") val sqltransformer2 = new SQLTransformer().setStatement("select sum(score)/3 as average from __THIS__") sqltransformer1.transform(df).show() sqltransformer2.transform(df).show() } 输出结果为: +---+ | id| +---+ | 1| | 2| | 3| +---+ |average| +-------+ | 91.0| +-------+

优秀的个人博客,低调大师

Ansible-playbook roles用docker容器安装redis主从(学习笔记三十一)

docker版本 09:49:09#dockerversion Clientversion:0.11.1 ClientAPIversion:1.11 Goversion(client):go1.2.1 Gitcommit(client):fb99f99/0.11.1 Serverversion:0.11.1 ServerAPIversion:1.11 Gitcommit(server):fb99f99/0.11.1 Goversion(server):go1.2.1 Laststableversion:1.1.2,pleaseupdatedocker ansible版本 09:51:55#ansible--version ansible1.4.3 1、查看已有的docker镜像 09:39:26#dockerimages REPOSITORYTAGIMAGEIDCREATEDVIRTUALSIZE ubuntu3.06cee552765289weeksago369.8MB centos53.0e08d23b091899weeksago840.9MB centos63.0e94a3b24a19b9weeksago415.9MB 2、查看当前运行的docker容器 09:39:47#dockerps-a CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES 846efb9e4d7aubuntu:3.0/usr/sbin/sshd-D2weeksagoUp6days0.0.0.0:49167->22/tcpubuntu-test1 b9a9e6f2caedcentos6:3.0/usr/sbin/sshd-D3weeksagoUp6days0.0.0.0:49166->22/tcpzabbix-server 978fff134b18centos6:3.0/usr/sbin/sshd-D5weeksagoUp6days0.0.0.0:49165->22/tcpcentos6-test5 root@ip-10-10-10-10:/etc/ansible/roles/redis_install/templates 3、加载测试容器 由于是做redis主从,所以需要2个容器 09:39:50#timedockerinspect$(dockerrun-d-p22--name="redis-master"centos6:3.0/usr/sbin/sshd-D)|grep-iaddress|awk-F'"''{print$4}' 172.17.0.5 real 0m6.369s user 0m0.036s sys 0m0.049s root@ip-10-10-10-10:/etc/ansible/roles/redis_install/templates 09:40:25#timedockerinspect$(dockerrun-d-p22--name="redis-slave"centos6:3.0/usr/sbin/sshd-D)|grep-iaddress|awk-F'"''{print$4}' 172.17.0.6 real 0m12.567s user 0m0.047s sys 0m0.060s 然后把新容器的ip加入到ansible的hosts里 root@ip-10-10-10-10:/etc/ansible/roles/redis_install/templates 09:40:46#echo"172.17.0.5">>/etc/ansible/hosts root@ip-10-10-10-10:/etc/ansible/roles/redis_install/templates 09:40:58#echo"172.17.0.6">>/etc/ansible/hosts root@ip-10-10-10-10:/etc/ansible/roles/redis_install/templates 4、ansible安装redis的信息 09:52:11#cat/etc/ansible/roles/redis_install/vars/main.yml redis_dir:/data redis_version:2.6.17 redis_port:6379 redis_conf_dir:/data/redis-2.6.17/conf redis_db_dir:/data/redis-2.6.17/db redis_log_dir:/data/redis-2.6.17/log 5、下面是redis的playbook结构 09:55:12#tree/etc/ansible/roles/redis_install/etc/ansible/roles/redis_delete /etc/ansible/roles/redis_install ├──files │└──redis-2.6.17.tar.gz ├──handlers ├──meta │└──main.yml ├──tasks │├──copy.yml │├──delete.yml │├──install.yml │└──main.yml ├──templates │└──redis.conf └──vars └──main.yml /etc/ansible/roles/redis_delete ├──files ├──handlers ├──meta │└──main.yml ├──tasks │├──delete.yml │└──main.yml ├──templates │└──delete_redis.sh └──vars └──main.yml 12directories,13files 6、playbook安装redis的内容是 09:57:09#catredis_install.yml --- -hosts:"`host`" remote_user:"`user`" gather_facts:True roles: -common -redis_install 7、playbook删除redis的内容是 09:57:31#catredis_delete.yml --- -hosts:"`host`" remote_user:"`user`" gather_facts:True roles: -redis_delete 下面是安装redis主从 8、安装redis master 09:43:11#timeansible-playbookredis_install.yml--extra-vars"host=172.17.0.5user=root"-k SSHpassword: PLAY[172.17.0.5]************************************************************* GATHERINGFACTS*************************************************************** ok:[172.17.0.5] TASK:[common|Installinitializtionrequiresoftware]*********************** changed:[172.17.0.5] TASK:[redis_install|CopyRedisSoftwareToRedhatClient]****************** ok:[172.17.0.5] TASK:[redis_install|CreateRedisInstallDir]****************************** ok:[172.17.0.5] TASK:[redis_install|UncompressionRedisSoftwareToRedhatClient]********* changed:[172.17.0.5] TASK:[redis_install|CopyRedisConfigToRedhatClient]******************** changed:[172.17.0.5] TASK:[redis_install|CreateSoftLinkInRedhatClient]********************* changed:[172.17.0.5]=>(item=redis-cli) changed:[172.17.0.5]=>(item=redis-server) TASK:[redis_install|CheckBootStartInRedhatClient]********************* failed:[172.17.0.5]=>{"changed":true,"cmd":"grep-c'/usr/bin/redis-server/data/redis-2.6.17/conf/redis_6379.conf'/etc/rc.local","delta":"0:00:00.007160","end":"2014-08-1309:45:18.660617","item":"","rc":1,"start":"2014-08-1309:45:18.653457"} stdout:0 ...ignoring TASK:[redis_install|AddBootStartInRedhatClient]*********************** changed:[172.17.0.5] TASK:[redis_install|StartRedisServiceInRedhatClient]****************** changed:[172.17.0.5] TASK:[redis_install|DeleteRediscompressionSoftwareInRedhatClient]**** changed:[172.17.0.5] PLAYRECAP******************************************************************** 172.17.0.5:ok=11changed=8unreachable=0failed=0 real 0m12.757s user 0m3.453s sys 0m0.497s 9、查看redis master安装情况 09:48:39#ssh172.17.0.5 root@172.17.0.5'spassword: Lastlogin:WedAug1309:45:282014from172.17.42.1 root@06762530db8c:~ 09:48:43#ps-ef|grepredis root2941009:45?00:00:00/usr/bin/redis-server/data/redis-2.6.17/conf/redis_6379.conf root343329009:48pts/000:00:00grepredis root@06762530db8c:~ 09:48:46#cat/etc/rc.local #!/bin/sh # #Thisscriptwillbeexecuted*after*alltheotherinitscripts. #Youcanputyourowninitializationstuffinhereifyoudon't #wanttodothefullSysVstyleinitstuff. touch/var/lock/subsys/local /usr/bin/redis-server/data/redis-2.6.17/conf/redis_6379.conf root@06762530db8c:~ 09:48:52#redis-cli-h172.17.0.5-p6379 redis172.17.0.5:6379>keys* (emptylistorset) redis172.17.0.5:6379> 10、安装redis slave 09:45:20#timeansible-playbookredis_install.yml--extra-vars"host=172.17.0.6user=rootredis_master_ip=172.17.0.5redis_master_port=6379"-k SSHpassword: PLAY[172.17.0.6]************************************************************* GATHERINGFACTS*************************************************************** ok:[172.17.0.6] TASK:[common|Installinitializtionrequiresoftware]*********************** changed:[172.17.0.6] TASK:[redis_install|CopyRedisSoftwareToRedhatClient]****************** changed:[172.17.0.6] TASK:[redis_install|CreateRedisInstallDir]****************************** ok:[172.17.0.6] TASK:[redis_install|UncompressionRedisSoftwareToRedhatClient]********* changed:[172.17.0.6] TASK:[redis_install|CopyRedisConfigToRedhatClient]******************** changed:[172.17.0.6] TASK:[redis_install|CreateSoftLinkInRedhatClient]********************* changed:[172.17.0.6]=>(item=redis-cli) changed:[172.17.0.6]=>(item=redis-server) TASK:[redis_install|CheckBootStartInRedhatClient]********************* failed:[172.17.0.6]=>{"changed":true,"cmd":"grep-c'/usr/bin/redis-server/data/redis-2.6.17/conf/redis_6379.conf'/etc/rc.local","delta":"0:00:00.006751","end":"2014-08-1309:49:07.569522","item":"","rc":1,"start":"2014-08-1309:49:07.562771"} stdout:0 ...ignoring TASK:[redis_install|AddBootStartInRedhatClient]*********************** changed:[172.17.0.6] TASK:[redis_install|StartRedisServiceInRedhatClient]****************** changed:[172.17.0.6] TASK:[redis_install|DeleteRediscompressionSoftwareInRedhatClient]**** changed:[172.17.0.6] PLAYRECAP******************************************************************** 172.17.0.6:ok=11changed=9unreachable=0failed=0 real 1m48.579s user 0m6.781s sys 0m0.654s 11、查看redis slave安装情况 09:59:24#ssh172.17.0.6 root@172.17.0.6'spassword: root@dfec766fbaa7:~ 09:59:28#ll total0 root@dfec766fbaa7:~ 09:59:31#ps-ef|grepredis root1971009:49?00:00:00/usr/bin/redis-server/data/redis-2.6.17/conf/redis_6379.conf root227212009:59pts/000:00:00grepredis 09:59:49#grepslave/data/redis-2.6.17/conf/redis_6379.conf|egrep-v"^#" slaveof172.17.0.56379 slave-serve-stale-datayes slave-read-onlyyes slave-priority100 client-output-buffer-limitslave256mb64mb60 root@dfec766fbaa7:~ 10:00:09#redis-cli-h172.17.0.6-p6379 redis172.17.0.6:6379>keys* (emptylistorset) redis172.17.0.6:6379>info #Server redis_version:2.6.17 redis_git_sha1:00000000 redis_git_dirty:0 redis_mode:standalone os:Linux2.6.32-431.17.1.el6.x86_64x86_64 arch_bits:64 multiplexing_api:epoll gcc_version:4.4.7 process_id:197 run_id:81207df2727abe534ae606afc0cb80016f75a422 tcp_port:6379 uptime_in_seconds:685 uptime_in_days:0 hz:10 lru_clock:280339 #Clients connected_clients:2 client_longest_output_list:0 client_biggest_input_buf:0 blocked_clients:0 #Memory used_memory:878072 used_memory_human:857.49K used_memory_rss:7569408 used_memory_peak:877280 used_memory_peak_human:856.72K used_memory_lua:31744 mem_fragmentation_ratio:8.62 mem_allocator:jemalloc-3.2.0 #Persistence loading:0 rdb_changes_since_last_save:0 rdb_bgsave_in_progress:0 rdb_last_save_time:1407894548 rdb_last_bgsave_status:ok rdb_last_bgsave_time_sec:-1 rdb_current_bgsave_time_sec:-1 aof_enabled:0 aof_rewrite_in_progress:0 aof_rewrite_scheduled:0 aof_last_rewrite_time_sec:-1 aof_current_rewrite_time_sec:-1 aof_last_bgrewrite_status:ok #Stats total_connections_received:1 total_commands_processed:70 instantaneous_ops_per_sec:0 rejected_connections:0 expired_keys:0 evicted_keys:0 keyspace_hits:0 keyspace_misses:0 pubsub_channels:0 pubsub_patterns:0 latest_fork_usec:0 #Replication role:slave master_host:172.17.0.5 master_port:6379 master_link_status:up master_last_io_seconds_ago:1 master_sync_in_progress:0 slave_priority:100 slave_read_only:1 connected_slaves:0 #CPU used_cpu_sys:0.24 used_cpu_user:0.10 used_cpu_sys_children:0.00 used_cpu_user_children:0.00 #Keyspace 可以从上面的Replication里看到主从做好了,信息如下图 然后去redis master里查看主从信息 12、redis 主从测试 A.redis master插入key redis172.17.0.5:6379>setmaster1 OK redis172.17.0.5:6379>setslave0 OK redis172.17.0.5:6379>getmaster "1" redis172.17.0.5:6379>getslave "0" B.redis slave读取key redis172.17.0.6:6379>keys* 1)"master" 2)"slave" redis172.17.0.6:6379>getmaster "1" redis172.17.0.6:6379>getslave "0" 可以看到主从建立完成 下面是redis slave的日志情况 10:08:04#cat/data/redis-2.6.17/log/redis_6379.log _._ _.-``__''-._ _.-```.`_.''-._Redis2.6.17(00000000/0)64bit .-``.-```.```\/_.,_''-._ (',.-`|`,)Runninginstandalonemode |`-._`-...-`__...-.``-._|'`_.-'|Port:6379 |`-._`._/_.-'|PID:197 `-._`-._`-./_.-'_.-' |`-._`-._`-.__.-'_.-'_.-'| |`-._`-.__.-'_.-'|http://redis.io `-._`-._`-.__.-'_.-'_.-' |`-._`-._`-.__.-'_.-'_.-'| |`-._`-.__.-'_.-'| `-._`-._`-.__.-'_.-'_.-' `-._`-.__.-'_.-' `-.__.-' `-.__.-' [197]13Aug09:49:08.878#Serverstarted,Redisversion2.6.17 [197]13Aug09:49:08.879#WARNINGovercommit_memoryissetto0!Backgroundsavemayfailunderlowmemorycondition.Tofixthisissueadd'vm.overcommit_memory=1'to/etc/sysctl.confandthenrebootorrunthecommand'sysctlvm.overcommit_memory=1'forthistotakeeffect. [197]13Aug09:49:08.879*Theserverisnowreadytoacceptconnectionsonport6379 [197]13Aug09:49:09.879*ConnectingtoMASTER172.17.0.5:6379 [197]13Aug09:49:09.879*MASTER<->SLAVEsyncstarted [197]13Aug09:49:09.881*NonblockingconnectforSYNCfiredtheevent. [197]13Aug09:49:09.881*MasterrepliedtoPING,replicationcancontinue... [197]13Aug09:49:10.035*MASTER<->SLAVEsync:receiving18bytesfrommaster [197]13Aug09:49:10.035*MASTER<->SLAVEsync:LoadingDBinmemory [197]13Aug09:49:10.035*MASTER<->SLAVEsync:Finishedwithsuccess [197]13Aug10:04:56.980*1changesin900seconds.Saving... [197]13Aug10:04:56.982*Backgroundsavingstartedbypid233 [233]13Aug10:04:57.226*DBsavedondisk [233]13Aug10:04:57.227*RDB:6MBofmemoryusedbycopy-on-write [197]13Aug10:04:57.293*Backgroundsavingterminatedwithsuccess 13、删除redis安装 无论redis主从,删除都是一样的命令 09:57:32#timeansible-playbookredis_delete.yml--extra-vars"host=172.17.0.5user=root"-k SSHpassword: PLAY[172.17.0.5]************************************************************* GATHERINGFACTS*************************************************************** ok:[172.17.0.5] TASK:[redis_delete|StopRedisServiceInRedhatClient]******************** changed:[172.17.0.5] TASK:[redis_delete|DeleteRedisSoftLineInRedhatClient]**************** changed:[172.17.0.5]=>(item=redis-cli) changed:[172.17.0.5]=>(item=redis-server) TASK:[redis_delete|DeleteRedisDirInRedhatClient]********************** changed:[172.17.0.5] TASK:[redis_delete|DeleteBootStartInRedhatClient]********************* changed:[172.17.0.5] PLAYRECAP******************************************************************** 172.17.0.5:ok=5changed=4unreachable=0failed=0 real 0m6.929s user 0m1.942s sys 0m0.250s root@ip-10-10-10-10:/etc/ansible 10:09:18#timeansible-playbookredis_delete.yml--extra-vars"host=172.17.0.6user=root"-k SSHpassword: PLAY[172.17.0.6]************************************************************* GATHERINGFACTS*************************************************************** ok:[172.17.0.6] TASK:[redis_delete|StopRedisServiceInRedhatClient]******************** changed:[172.17.0.6] TASK:[redis_delete|DeleteRedisSoftLineInRedhatClient]**************** changed:[172.17.0.6]=>(item=redis-cli) changed:[172.17.0.6]=>(item=redis-server) TASK:[redis_delete|DeleteRedisDirInRedhatClient]********************** changed:[172.17.0.6] TASK:[redis_delete|DeleteBootStartInRedhatClient]********************* changed:[172.17.0.6] PLAYRECAP******************************************************************** 172.17.0.6:ok=5changed=4unreachable=0failed=0 real 0m5.897s user 0m1.726s sys 0m0.258s 15、删除后测试 A.redis master上 10:09:55#ifconfig eth0Linkencap:EthernetHWaddrC6:3A:D2:D9:DD:D9 inetaddr:172.17.0.5Bcast:0.0.0.0Mask:255.255.0.0 inet6addr:fe80::c43a:d2ff:fed9:ddd9/64Scope:Link UPBROADCASTRUNNINGMTU:1500Metric:1 RXpackets:13236errors:0dropped:0overruns:0frame:0 TXpackets:12843errors:0dropped:0overruns:0carrier:0 collisions:0txqueuelen:1000 RXbytes:26106313(24.8MiB)TXbytes:906412(885.1KiB) loLinkencap:LocalLoopback inetaddr:127.0.0.1Mask:255.0.0.0 inet6addr:::1/128Scope:Host UPLOOPBACKRUNNINGMTU:16436Metric:1 RXpackets:196errors:0dropped:0overruns:0frame:0 TXpackets:196errors:0dropped:0overruns:0carrier:0 collisions:0txqueuelen:0 RXbytes:9665(9.4KiB)TXbytes:9665(9.4KiB) root@06762530db8c:~ 10:09:56#ps-ef|grepredis root431329010:09pts/000:00:00grepredis root@06762530db8c:~ 10:09:59#cat/etc/rc.local #!/bin/sh # #Thisscriptwillbeexecuted*after*alltheotherinitscripts. #Youcanputyourowninitializationstuffinhereifyoudon't #wanttodothefullSysVstyleinitstuff. touch/var/lock/subsys/local root@06762530db8c:~ 10:10:01#ll/data/ total4 drwxr-xr-x2rootroot4096Jun510:21soft root@06762530db8c:~ B. redis slave上 10:08:09#ifconfig eth0Linkencap:EthernetHWaddrBE:97:0C:B2:02:D9 inetaddr:172.17.0.6Bcast:0.0.0.0Mask:255.255.0.0 inet6addr:fe80::bc97:cff:feb2:2d9/64Scope:Link UPBROADCASTRUNNINGMTU:1500Metric:1 RXpackets:13062errors:0dropped:0overruns:0frame:0 TXpackets:12704errors:0dropped:0overruns:0carrier:0 collisions:0txqueuelen:1000 RXbytes:25967216(24.7MiB)TXbytes:842881(823.1KiB) loLinkencap:LocalLoopback inetaddr:127.0.0.1Mask:255.0.0.0 inet6addr:::1/128Scope:Host UPLOOPBACKRUNNINGMTU:16436Metric:1 RXpackets:86errors:0dropped:0overruns:0frame:0 TXpackets:86errors:0dropped:0overruns:0carrier:0 collisions:0txqueuelen:0 RXbytes:5288(5.1KiB)TXbytes:5288(5.1KiB) root@dfec766fbaa7:~ 10:10:32#ps-ef|grepredis root319212010:10pts/000:00:00grepredis root@dfec766fbaa7:~ 10:10:37#cat/etc/rc.local #!/bin/sh # #Thisscriptwillbeexecuted*after*alltheotherinitscripts. #Youcanputyourowninitializationstuffinhereifyoudon't #wanttodothefullSysVstyleinitstuff. touch/var/lock/subsys/local root@dfec766fbaa7:~ 10:10:39#ll/data/ total4 drwxr-xr-x2rootroot4096Jun510:21soft root@dfec766fbaa7:~ 如果大家想使用我的例子,可以从github里下载(地址是https://github.com/dl528888/ansible-examples/tree/master/redis_install),然后放到/etc/ansible目录里,下面是内容 转载自:http://blog.51cto.com/dl528888/1539251

优秀的个人博客,低调大师

(ElasticsSearch学习)歌词检索Demo的实现:一. 爬取歌词信息,写入ES

1.说明 爬虫采用Java的Jsoup ElasticSearch请在阿里云官网购买,采用客户端x-pack-transport 歌词网站来源:http://www.kuwo.cn/artist/index 2. 歌词网站分析 此处采用了比较笨的一种方式,即逐个分析每个请求的url,这样可以方便代码编写,就不用模拟器了(如需使用模拟器可参考使用cdp4j模拟点击事件等,但简单试了下不是很好用,且效率低) a) 歌手获取分析 在http://www.kuwo.cn/artist/index 查看分页按钮的click事件,从js中找到分页请求的url从click事件的artist.js中找到相关url如下图所示其中pn参数即为页码参数 var b = host + "/artist/indexAjax?category=" + index + "&a

优秀的个人博客,低调大师

DC学院爬虫学习笔记(六):浏览器抓包及headers设置

爬虫的一般思路: 抓取网页、分析请求 解析网页、寻找数据 储存数据、多页处理 - 分析具体网页请求: 1. 观察以下网址翻页后的URL: http://www.zkh360.com/zkh_catalog/3.html 可以看到,有些网址翻页后URL是不变的,那该怎么爬取,请看下文。 2. 使用谷歌浏览器分析网页的真实请求 谷歌浏览器——检查——Network 首先清空请求列表,点击下一页(第2页) 在请求列表里查找真实的请求,可发现包含商品信息的真实请求为: http://www.zkh360.com/Product/SearchProduct?catalogueId=3&pageIndex=2&pageSize=20 箭头所指的地方就是真实请求 以下是第2、3、4页的请求,通过对比可以发现网站是通过pageIndex参数控制翻页的,并且pageSize参数删去之后并不会对请求产生影响 第2页:http://www.zkh360.com/Product/SearchProduct?catalogueId=3&pageIndex=2&pageSize=20 第3页:http://www.zkh360.com/Product/SearchProduct?catalogueId=3&pageIndex=3&pageSize=20 第4页:http://www.zkh360.com/Product/SearchProduct?catalogueId=3&pageIndex=4&pageSize=20 有关参数的信息可以在Hearders的Query String Parameters里查找到 翻页后URL不发生变化的网站的数据一般都是通过Ajax或者JavaScript加载的,可以在过滤器的XHR或者JS中找到真实请求 3. 寻找真实请求的三个步骤 分析:使用谷歌浏览器开发者工具分析网页的请求 测试:测试URL请求中每个参数的作用,找出控制翻页等功能的参数 重复:多次重复寻找符合爬虫需要的真实请求 实战:爬取知乎 通过爬取知乎“轮子哥”——vczh关注的人分析Ajax或者JavaScript加载的数据的真实请求并展示这种爬取方法的具体过程。 1. 寻找真实请求的测试 首先,进入“轮子哥——vczh”关注的人的页面(注意:需要先登录个人知乎账号) 通过禁止JavaScript加载的方法发现页面不能正常加载,确认该页面的翻页是通过JavaScript加载数据实现的 使用谷歌浏览器开发者工具寻找包含关注人信息的真实请求,可以发现真实请求是以“followees”开头的请求,其返回一个JSON格式的数据,该数据对应下一页的“他关注的人”: 双击这个请求,返回一个JSON格式的数据,可以通过安装JSONView插件在浏览器中更好地显示该数据 接下来便可以尝试爬取该请求的数据 2. 尝试爬取真实请求的数据 首先使用requests.get()尝试爬取数据 # -*- coding:utf-8 -*- import requests url = 'https://www.zhihu.com/api/v4/members/excited-vczh/followees?include=data%5B*%5D.answer_count%2Carticles_count%2Cgender%2Cfollower_count%2Cis_followed%2Cis_following%2Cbadge%5B%3F(type%3Dbest_answerer)%5D.topics&offset=20&limit=20' response = requests.get(url).text print(response) <html><body><h1>500 Server Error</h1> An internal server error occured. </body></html> 可以发现返回了“500 Server Error”,即由于网站反爬虫的原因,服务器返回了“500服务错误” 该问题可以通过添加hearders请求头信息解决 3. 添加hearders请求头信息模拟浏览器访问 请求头信息承载了关于客户端浏览器、请求页面、服务器等相关的信息,用来告知服务器发起请求的客户端的具体信息 知乎的反爬虫机制是通过核对请求头信息实现的,所以需要在使用requests请求数据的时候加上所需的请求头 对比知乎的请求头信息和常见的请求头信息,发现知乎请求头多了authorization和X-UDID的信息 在爬虫程序中添加请求头信息,即添加headers # -*- coding:utf-8 -*- import requests headers = { 'authorization':'Bearer 2|1:0|10:1519311205|4:z_c0|92:Mi4xeVFXVEF3QUFBQUFBVUd2WmJrTXJEU2NBQUFDRUFsVk5aV2EyV2dBdzY2cTlRY0JHTkc0TkpMalZwOXBkRkowby13|d5a54e1ffbdf3097b4c79eb2dbf297e9c6b55971566d830ce33f8852601375ee ', #括号中填上你的authorization 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36',#括号中填上你的User-Agent } url = 'https://www.zhihu.com/api/v4/members/excited-vczh/followees?include=data%5B*%5D.answer_count%2Carticles_count%2Cgender%2Cfollower_count%2Cis_followed%2Cis_following%2Cbadge%5B%3F(type%3Dbest_answerer)%5D.topics&offset=20&limit=20' response= requests.get(url, headers = headers).json() ##print(response) 注:刚才写的时候出问题了,说是User-Agent问题,查了半天,发现是在最前面多了个空格。。 运行程序,成功返回数据 4. 使用pandas把数据保存入库 pandas DataFrame的from_dict()方法可以很方便地把爬取到的数据保存为DataFrame格式的结构化数据 import pandas as pd response= requests.get(url, headers = headers).json()['data'] #添加上['data']是因为关注人的信息是保存在data下面的,只需要这一部分的数据 df = pd.DataFrame.from_dict(response) df.to_csv('user.csv') 5. 定义函数实现翻页爬取 定义一个get_user_data()函数,实现翻页爬取功能,并添加上爬取时间间隔以免由于爬取太频繁给服务器造成负担 import time user_data = [] def get_user_data(page): for i in range(page): url = 'https://www.zhihu.com/api/v4/members/excited-vczh/followees?include=data%5B*%5D.answer_count%2Carticles_count%2Cgender%2Cfollower_count%2Cis_followed%2Cis_following%2Cbadge%5B%3F(type%3Dbest_answerer)%5D.topics&offset={}&limit=20'.format(i*20) response = requests.get(url, headers=headers).json()['data'] user_data.extend(response) #把response数据添加进user_data print('正在爬取第%s页' % str(i+1)) time.sleep(1) #设置爬取网页的时间间隔为1秒 if __name__ == '__main__': get_user_data(10) df = pd.DataFrame.from_dict(user_data) df.to_csv('users2.csv') 正在爬取第1页 正在爬取第2页 正在爬取第3页 正在爬取第4页 正在爬取第5页 正在爬取第6页 正在爬取第7页 正在爬取第8页 正在爬取第9页 正在爬取第10页 ok,成功解决

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册