Keep and carry on.
post @ 2015-03-22

设计模式之组合模式 (Composite Pattern)

使用组合模式的目的

GoF 的观点

Composite objects into tree structures to represent part-whole hieraches. Composite lets clients treat individual objects and compositions of objects uniformly.

当有数个对象的集合,它们彼此之间有"部分-整体"的关系,并且你想用一致的方式对待这些对象时,就需要组合模式.  

所谓整体/部分关系 是什么?

比如图形界面,一个顶层组件(Frame or Panel)包含着其他组件(像菜单,文字面板,滚动条…)所以你的GUI包含了若干部分,但是当你显示它的时候,你认为它是一个整体.你告诉顶层的组件显示,然后就放手不管,由顶层组件负责显示所有相关的部分.我们称这种包含其他组件的组件为组合对象(composite)而称没有包含其他组件的组件为叶节点对象.

用一致的方式对待 (treat individual objects and compositions of objecets uniformly)

组合和叶节点之间有共同的方法可以调用(比如,我们可以让组合对象或者叶节点对象显示setVisiable(),而组合对象会让他所有的组件显示setVisiable()).

应用

当有如下需求时使用 composite pattern:  

  • 你需要表示部分/整体结构
  • 你需要让clients能够忽略 组合对象(compositions)和 普通对象(leaf).clients 会用一致的方式处理组合对象和普通对象.

类图

类图

参与者

the key to the Composite pattern is an abstract class that represents both primitives and their containers.

组合模式的关键 在于定义一个抽象类,它定义了leaf 和 composite的共有操作

  • Component
    • 声明了组合模式的接口
    • 在适当的时候实现了接口的实现类的通用行为
    • 声明了用于访问和管理子组件(child component)的接口
    • ( 可选) 在递归结构中定义了访问组件的父组件的接口,并在适当的时候实现它
  • Leaf
    • 代表了叶子对象,叶子对象没有子对象,是组合模式中最基本的单位
    • 定义了基本对象的操作
  • Composite
    • 定义了复合对象,复合对象可以包含其他复合对象和基本对象
    • 存储子复合对象
    • 实现了Composition类中和子对象相关的操作
  • Client
    • 通过Component接口操作组合对象

效果

  • 优点:

    • 使用户代码更简单.clients 能用一致的方法处理组合对象和普通对象.clients不知道(也不应该关心)自己处理的是组合对象还是基本对象.这简化了用户代码,因为定义组合功能的那么些类中不需要写一些充斥着选择语句的函数. 不需要写一大堆if语句来保证对正确的对象调用了正确的方法,通常,只要对整个结构调用一个方法并执行操作就可以了.
    • 使得更容易增加新类型的组件 新定义的Composite或leaf子类自动的与已有的结构和客户代码一起工作,客户程序不需要因为新增加的Component类儿改变
  • 缺点:

    • 由于新的Leaf和composite类都要继承Component类,所以每个对象都有相同的接口.而Component中定义的操作Leaf类的接口对于leaf类没用,而且万一组合中有些对象的行为不太一样,这样的设计就失去了安全性.所以要在 透明性安全性之间做一个 trade-off ,为了保持透明性,组合内所有的对象都必须实现相同的接口,否则客户就必须操心哪个对象是用哪个接口,这就失去了组合模式的意义.

怎么解决这个缺点呢?

  • 可以覆盖这样的方法为空方法,或者返回false/null.
  • 可以直接抛出异常( 如果调用了不支持的操作)
  • 可以对不同的对象使用不同的接口,需要客户先检查每个对象的类型,然后才进行方法调用

示例代码

component接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package boqingan;
import java.util.Iterator;
public abstract class MenuComponent{
public void add(MenuComponent menuComponent){
throw new UnsupportedOperationException();
}
public void remove(MenuComponent menuComponent){
throw new UnsupportedOperationException();
}
public MenuComponent getChild(int i){
throw new UnsupportedOperationException();
}
public String getName(){
throw new UnsupportedOperationException();
}
public String getDescription(){
throw new UnsupportedOperationException();
}
public double getPrice(){
throw new UnsupportedOperationException();
}
public boolean isVegetarian(){
throw new UnsupportedOperationException();
}
public void print(){
throw new UnsupportedOperationException();
}
public Iterator createIterator(){
throw new UnsupportedOperationException();
}
}
Leaf类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package boqingan;
import java.util.Iterator;
// 这是组合模式(Composite pattern 中的 leaf)
public class MenuItem extends MenuComponent{
private String name;
private String description;
private boolean vegetarian;
private double price;
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public boolean isVegetarian() {
return vegetarian;
}
public double getPrice() {
return price;
}
public MenuItem(String name, String description, boolean vegetarian,
double price) {
super();
this.name = name;
this.description = description;
this.vegetarian = vegetarian;
this.price = price;
}
public void print(){
System.out.print(" "+getName());
if(isVegetarian()){
System.out.print("(v)");
}
System.out.println(", "+getPrice());
System.out.println(" ----"+getDescription());
}
public Iterator createIterator(){
return new NullIterator();
}
}
composite类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package boqingan;
import java.util.*;
// 实现组合(Composite)菜单
public class Menu extends MenuComponent{
protected ArrayList menuComponents = new ArrayList();
protected String name;
protected String description;
public Menu(String name ,String description){
this.name = name;
this.description = description;
}
public void add(MenuComponent mc){
menuComponents.add(mc);
}
public void remove(MenuComponent mc){
menuComponents.remove(mc);
}
public MenuComponent getChild(int i){
return (MenuComponent)menuComponents.get(i);
}
public String getName(){
return name;
}
public String getDescription(){
return description;
}
public void print(){
System.out.print(" \n" + getName());
System.out.println(" ," + getDescription());
System.out.println("---------");
Iterator iterator = menuComponents.iterator();
while (iterator.hasNext()){
MenuComponent menuComponent = (MenuComponent)iterator.next();
menuComponent.print();
}
}
public Iterator createIterator(){
return new CompositeIterator(menuComponents.iterator());
}
}
clients类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package boqingan;
import java.util.*;
public class Waitress {
MenuComponent allMenus;
public Waitress(MenuComponent allMenus){
this.allMenus = allMenus;
}
public void printMenu(){
allMenus.print();
}
public void printVegetarianMenu(){
Iterator iterator = allMenus.createIterator();
System.out.println("\n VEGETARIAN MENU \n---");
while( iterator.hasNext()){
MenuComponent menuComponent = (MenuComponent)iterator.next();
try {
if(menuComponent.isVegetarian()){
menuComponent.print();
}
}catch (UnsupportedOperationException e){}
}
}
}

###更多代码详见github

Read More
post @ 2015-03-10

推荐系统的分类(Taxonomy of Recommender Systems)

推荐算法

###1. Non-Personalized summary Statistics

  • External Community Data
    –Best-seller;Most popular;Trending Hot
  • summary of Community Ratings
    –Best-liked 例如: 音乐排行榜

###2. Content-Based Filtering (基于内容的过滤)
–information filtering 信息过滤
–knowledge-based 基于知识

User Rating X item Attributes => Model
Model applied to new items via attributes
alternative : knowledge-based
-Item attributes form model of item space
–users navigate/browse that space
例如:

 - Personalized news feeds  
- Artist or Genre music feeds

###3. Collaborative Filtering (协同过滤)

  • User-User
    Select neighborhood of similar-taste people
    variant: select people you know/trust
    Use their opinions
  • Item-Item
    Pre-compute similarity among items via ratings
    use own ratings to triangulate for recommendations

  • Dimensionality Reduction (奇异值分解 SVD)
    create lower dimensional matrix through mathmetic methods
    intuition: taste yields a lower-dimensionality matrix
    Compress and use a taste representation

Personalized Collaborative Filtering

  • Use opinions of others to predict/recommend
  • User-model – set of ratings
  • item-model – set of ratings
  • common core: sparse matrix of ratings
    –Fill in missing values(predict)
    –Select promising cells(recommend)
  • Several different techniques

###4. Others
–Critique/Interview Based Recommendations
–Hybrid Techniques

From The Abstrct to the Specific(从抽象到具体)

Basic Model

--User  
--Ratings  
--Item  

注意评估

为了更好的理解每种算法的好处,我们会花大量的时间来评估
1.推荐的准确度
2 推荐的有用性 
3.计算性能
Read More
post @ 2015-03-10

原文地址

One morning in April, we each directed our browsers to Amazon.com’s website. Not only did the site greet us by name, the home page opened with a host of suggested purchases. It directed Joe to Barry Greenstein’s Ace on the River: An Advanced Poker Guide, Jonah Lehrer’s Imagine: How Creativity Works, and Michael Lewis’s Boomerang: Travels in the New Third World. For John it selected Dave Barry’s Only Travel Guide You’ll Ever Need, the spy novel Mission to Paris, by Alan Furst, and the banking exposé The Big Short: Inside the Doomsday Machine, also by Michael Lewis.

By now, online shoppers are accustomed to getting these personalized suggestions. Netflix suggests videos to watch. TiVo records programs on its own, just in case we’re interested. And Pandora builds personalized music streams by predicting what we’ll want to listen to.

All of these suggestions come from recommender systems. Driven by computer algorithms, recommenders help consumers by selecting products they will probably like and might buy based on their browsing, searches, purchases, and preferences. Designed to help retailers boost sales, recommenders are a huge and growing business. Meanwhile, the field of recommender system development has grown from a couple of dozen researchers in the mid-1990s to hundreds of researchers today—working for universities, the large online retailers, and dozens of other companies whose sole focus is on these types of systems.

Over the years, recommenders have evolved considerably. They started as relatively crude and often inaccurate predictors of behavior. But the systems improved quickly as more and different types of data about website users became available and they were able to apply innovative algorithms to that data. Today, recommenders are extremely sophisticated and specialized systems that often seem to know you better than you know yourself. And they’re expanding beyond retail sites. Universities use them to steer students to courses. Cellphone companies rely on them to predict which users are in danger of switching to another provider. And conference organizers have tested them for assigning papers to peer reviewers.

The two of us have been building and studying recommender systems since their early days, initially as academic researchers working on the GroupLens Project. Begun in 1992, GroupLens sorted through messages in Usenet discussion forums and pointed users to threads they might be interested in but had not yet discovered on their own. Several years later, we founded Net Perceptions, the leading recommender company during the first Internet boom. Our experience, therefore, gives us a lot of insight into what’s going on behind the scenes at Amazon and other online retailers, even though those companies seldom speak publicly about exactly how their recommendations work. (In this article, our analysis is based on educated observation and deduction, not on any inside information.) Here’s what we know.

Have you ever wondered what you look like to Amazon? Here is the cold, hard truth: You are a very long row of numbers in a very, very large table. This row describes everything you’ve looked at, everything you’ve clicked on, and everything you’ve purchased on the site; the rest of the table represents the millions of other Amazon shoppers. Your row changes every time you enter the site, and it changes again with every action you take while you’re there. That information in turn affects what you see on each page you visit and what e-mail and special offers you receive from the company.

Over the years, the developers of recommender systems have tried a variety of approaches to gather and parse all that data. These days, they’ve mostly settled on what is called the personalized collaborative recommender. That type of recommender is at the heart of Amazon, Netflix, Facebook’s friend suggestions, and Last.fm, a popular music website based in the United Kingdom. They’re “personalized” because they track each user’s behavior—pages viewed, purchases, and ratings—to come up with recommendations; they aren’t bringing up canned sets of suggestions. And they’re “collaborative” because they treat two items as being related based on the fact that lots of other customers have purchased or stated a preference for those items, rather than by analyzing sets of product features or keywords.

Personalized collaborative recommenders, in some form or another, have been around since at least 1992. In addition to the GroupLens project, another early recommender was MIT’s Ringo, which took lists of albums from users and suggested other music they might like.

GroupLens and Ringo both used a simple collaborative algorithm known as a “user-user” algorithm. This type of algorithm computes the “distance” between pairs of users based on how much they agree on items they have both rated. For instance, if Jim and Jane each give the movie Tron five stars, their distance is zero. If Jim then gives Tron: Legacy five stars, while Jane rates it three stars, their distance increases. Users whose tastes are relatively “near” each other according to these calculations are said to share a “neighborhood.”

But the user-user approach doesn’t work that well. For one thing, it’s not always easy to form neighborhoods that make sense: Many pairs of users have only a few ratings in common or none at all, and in the case of movies, these few ratings in common tend to be of blockbusters that nearly everyone likes. Also, because the distance between users can change rapidly, user-user algorithms have to do most of their calculations on the spot, and that can take more time than someone clicking around a website is going to hang around.

So most recommenders today rely on an “item-item” algorithm, which calculates the distance between each pair of books or movies or what have you according to how closely users who have rated them agree. People who like books by Tom Clancy are likely to rate books by Clive Cussler highly, so books by Clancy and Cussler are in the same neighborhood. Distances between pairs of items, which may be based on the ratings of thousands or millions of users, tend to be relatively stable over time, so recommenders can precompute distances and generate recommendations more quickly. Both Amazon and Netflix have said publicly that they use variants of an item-item algorithm, though they keep the details secret.

One problem with both user-user and item-item algorithms is the inconsistency of ratings. Users often do not rate the same item the same way if offered the chance to rate it again. Tastes change, moods change, memories fade. MIT conducted one study in the late 1990s that showed an average change of one point on a seven-point scale a year after a user’s original rating. Researchers are trying different ways to incorporate such variables into their models; for example, some recommenders will ask users to rerate items when their original ratings seem out of sync with everything else the recommender knows about them.

But the user-user and item-item algorithms have a bigger problem than consistency: They’re too rigid. That is, they can spot people who prefer the same item but then miss potential pairs who prefer very similar items. Let’s say you’re a fan of Monet’s water lily paintings. Of the 250 or so paintings of water lilies that the French impressionist did, which is your favorite? Among a group of Monet fans, each person may like a different water lily painting best, but the basic algorithms might not recognize their shared taste for Monet.

About a decade ago, researchers figured out a way to factor in such sets of similar items—a process called dimensionality reduction. This method is much more computationally intensive than the user-user and item-item algorithms, so its adoption has been slower. But as computers have gotten faster and cheaper, it has been gaining ground.

To understand how dimensionality reduction works, let’s consider your taste in food and how it compares with that of a million other people. You can represent those tastes in a huge matrix, where each person’s taste makes up its own row and each of the thousands of columns is a different food. Your row might show that you gave grilled filet mignon five stars, braised short ribs four and a half stars, fried chicken wings two stars, cold tofu rolls one star, roasted portobello mushroom five stars, steamed edamame with sea salt four stars, and so forth.

A recommender using the matrix wouldn’t really care about your particular rating of a particular food, however. Instead, it wants to understand your preferences in general terms, so that it can apply this knowledge to a wide variety of foods. For instance, given the above, the recommender might conclude that you like beef, salty things, and grilled dishes, dislike chicken and anything fried, are neutral on vegetables, and so on. The number of such taste attributes or dimensions would be much smaller than the number of possible foods—there might be 50 or 100 dimensions in all. And by looking at those dimensions, a recommender could quickly determine whether you’d like a new food—say, salt‑crusted prime rib—by comparing its dimensions (salty, beef, not chicken, not fried, not vegetable, not grilled) against your profile. This more general representation allows the recommender to spot users who prefer similar yet distinct items. And it substantially compresses the matrix, making the recommender more efficient.

It’s a pretty cool solution. But how do you find those taste dimensions? Not by asking a chef. Instead, these systems use a mathematical technique called singular value decomposition to compute the dimensions. The technique involves factoring the original giant matrix into two “taste matrices”—one that includes all the users and the 100 taste dimensions and another that includes all the foods and the 100 taste dimensions—plus a third matrix that, when multiplied by either of the other two, re-creates the original matrix.

Unlike the food example above, the dimensions that get computed are neither describable nor intuitive; they are pure abstract values, and try as you might, you’ll never identify one that represents, say, “salty.” And that’s okay, as long as those values ultimately yield accurate recommendations. The main drawback to this approach is that the time it takes to factor the matrix grows quickly with the number of customers and products—a matrix of 250 million customers and 10 million products would take 1 billion times as long to factor as a matrix of 250 000 customers and 10 000 products. And the process needs to be repeated frequently. The matrix starts to grow stale as soon as new ratings are received; at a company like Amazon, that happens every second. Fortunately, even a slightly stale matrix works reasonably well. And researchers have been devising new algorithms that provide good approximations to singular value decomposition with substantially faster calculation times.

screen shot example of amazon.com Recommendation odyssey: An Amazon user interested in 2001: A Space Odyssey sees suggestions from three different collaborative recommenders. Click on the image for the full illustration view.
By now, you have a basic idea of how an online retailer sizes you up and tries to match your tastes to those of others whenever you shop at its site. Recommenders have two other features that dramatically affect the recommendations you see: First, beyond figuring out how similar you are to other shoppers, the recommender has to figure out what you actually like. Second, the system operates according to a set of business rules that help ensure its recommendations are both helpful to you and profitable for the retailer.

For example, consider the recommender used for Amazon’s online art store, which at last count had more than 9 million prints and posters for sale. Amazon’s art store assesses your preferences in a few ways. It asks you to rate particular artworks on a five-star scale, and it also notes which paintings you enlarge, which you look at multiple times, which you place on a wish list, and which you actually buy. It also tracks which paintings are on your screen at the time as well as others you look at during your session. The retailer uses the path you’ve traveled through its website—the pages you’ve viewed and items you’ve clicked on—to suggest complementary works, and it combines your purchase data with your ratings to build a profile of your long-term preferences.

Companies like Amazon collect an immense amount of data like this about their customers. Nearly any action taken while you are logged in is stored for future use. Thanks to browser cookies, companies can even maintain records on anonymous shoppers, eventually linking the data to a customer profile when the anonymous shopper creates an account or signs in. This explosion of data collection is not unique to online vendors—Walmart is famous for its extensive mining of cash register receipt data. But an online shop is much better positioned to view and record not just your purchases but what items you considered, looked at, and rejected. Throughout much of the world, all of this activity is fair game; only in Europe do data privacy laws restrict such practices to a degree.

Of course, regardless of the law, any customer will react badly if his or her data is used inappropriately. Amazon learned this lesson the hard way back in September 2000, when certain customers discovered they were being quoted higher prices because the website had identified them as regular customers, rather than as shoppers who had entered anonymously or from a comparison-shopping site. Amazon claimed this was just a random price test and the observed relationship to being a regular customer was coincidental, but it nevertheless stopped the practice.

The business rules around these systems are designed to prevent recommenders from making foolish suggestions and also to help online retailers maximize sales without losing your trust. At their most basic level, these systems avoid what’s known as the supermarket paradox. For example, nearly everyone who walks into a supermarket likes bananas and will often buy some. So shouldn’t the recommender simply recommend bananas to every customer? The answer is no, because it wouldn’t help the customer, and it wouldn’t increase banana sales. So a smart supermarket recommender will always include a rule to explicitly exclude recommending bananas.

That example may sound simplistic, but in one of our early experiences, our system kept recommending the Beatles’ “White Album” to nearly every visitor. Statistically this was a great recommendation: The customers had never purchased this item from the e-commerce site, and most customers rated it highly. And yet the recommendation was useless. Everyone who was interested in the “White Album” already owned a copy.

Most recommender rules are more subtle, of course. When John recently searched for an action movie on Netflix, for instance, he wasn’t offered The Avengers, because the blockbuster was not yet available for rental, and so the suggestion wouldn’t have profited Netflix. Instead it steered him to Iron Man 2, which was available for streaming.

Other business rules prevent recommenders from suggesting loss leaders—products that sell below cost to draw people into the site—or conversely encourage them to recommend products that are overstocked. During our time at Net Perceptions, we worked with a client who did just that: He used his recommender system to identify—with considerable success—potential customers for his overstocked goods.

This kind of thing quickly gets tricky, however. A system that simply pushes high-margin products isn’t going to earn the customers’ trust. It’s like going to a restaurant where the waiter steers you toward a particular fish dish. Is it really his favorite? Or did the chef urge the staff to push out the fish before its sell-by date?

To build trust, the more sophisticated recommender systems strive for some degree of transparency by giving customers an idea of why a particular item was recommended and letting them correct their profiles if they don’t like the recommendations they’re getting.

You can, for instance, delete information from your Amazon profile about things you purchased as gifts; after all, those don’t reflect your tastes. You can also find out why certain products have been offered through the recommender. After Amazon selected Jonathan Franzen’s novel Freedom for John, he clicked on the link labeled “Explain.” He then got a brief explanation that certain books on John’s Amazon wish list had triggered the recommendation. But as John hadn’t read any of the wish list books, he discounted the Freedom suggestion. Explanations like these let users know how reliable a given recommendation is.

But profile adjustments and explanations often aren’t enough to keep a system on track. Recently Amazon bombarded Joe with e-mails for large-screen HDTVs—as many as three a week for months. Besides sending him more e-mail on the topic than he could possibly want, the retailer didn’t recognize that he’d already purchased a TV through his wife’s account. What’s more, the e-mails did not offer an obvious way for Joe to say, “Thanks, but I’m not interested.” Eventually, Joe unsubscribed from certain Amazon e-mails; he doesn’t miss the messages, and he has more time to actually watch that TV.

So how well do recommenders ultimately work? They certainly are increasing online sales; analyst Jack Aaronson of the Aaronson Group estimates that investments in recommenders bring in returns of 10 to 30 percent, thanks to the increased sales they drive. And they still have a long way to go.

Right now the biggest challenge for those of us who study recommender systems is to figure out how best to judge the new approaches and algorithms. It’s not as simple as benchmarking a microprocessor, because different recommenders have very different goals.

The easiest way to evaluate an algorithm is to look at the difference between its predictions and the actual ratings users give. For instance, if John gives the teen-romance novel Twilight one star, Amazon might note that it had predicted he would give it two stars, based on the ratings of other similar users, and so its recommender was off by a star. But sellers care much more about errors on highly rated items than errors on low-rated items, because the highly rated items are the ones users are more likely to buy; John is never going to purchase Twilight, so scoring this rating contributes little to understanding how well the recommender works.

Another common measure is the extent to which recommendations match actual purchases. This analysis can also be misleading, however, because it erroneously rewards the recommender for items users managed to find on their own—precisely the items they don’t need recommendations for!

Given the shortcomings of these approaches, researchers have been working on new metrics that look not just at accuracy but also at other attributes, such as serendipity and diversity.

Serendipity rewards unusual recommendations, particularly those that are valuable to one user but not as valuable to other similar users. An algorithm tuned to serendipity would note that the “White Album” appears to be a good recommendation for nearly everyone and would therefore look for a recommendation that’s less common—perhaps Joan Armatrading’s Love and Affection. This less-popular recommendation wouldn’t be as likely to hit its target, but when it did, it would be a much happier surprise to the user.

Looking at the diversity of a recommender’s suggestions is also revealing. For instance, a user who loves Dick Francis mysteries might nevertheless be disappointed to get a list of recommendations all written by Dick Francis. A truly diverse list of recommendations could include books by different authors and in different genres, as well as movies, games, and other products.

Recommender systems research has all sorts of new ground to break, far beyond fine-tuning existing systems. Researchers today are considering to what extent a recommender should help users explore parts of a site’s collection they haven’t looked into—say, sending book buyers over to Amazon’s clothing department rather than recommending safe items they may be more comfortable with. Going beyond the retail world, recommenders could help expose people to new ideas; even if we disagree with some of them, the overall effect might be positive in that it would help reduce the balkanization of society. Whether recommenders can do that without annoying us or making us distrustful remains to be seen.

But one thing is clear: Recommender systems are only going to get better, collect more data about you, and show up in new and surprising places. And as for you, if you liked this article, Amazon will be happy to recommend entire books on recommender systems that you might also like.

This article originally appeared in print as “Recommended for You.”

About the authors

Joseph A. Konstan and John Riedl ARE both professors of computer science at the University of Minnesota. As codirectors of GroupLens Research, Konstan, an IEEE Senior Member, and Riedl, an IEEE Fellow, helped create the MovieLens recommender system. The pair’s scariest recommender moment came during an interview on “ABC Nightline.” Just before a station break, MovieLens pitched the 1950s film noir Sunset Boulevard to host Robert Krulwich. Konstan and Riedl had to wait until they were back on the air to hear his verdict on the suggestion: He loved it!u

Read More

Linear regression with one variable 单变量线性回归


假设你有个盆友要卖房子,你现在知道一些房子的面积和价钱,要帮你朋友预测他的房子能卖多少钱;
这个问题如何解决呢?
这个问题属于机器学习中的监督学习中的预测问题.这个问题的模型是:

traning set –> algrithm –> hypothese function

其中 hypothese function 就是 一个拟合函数,通过训练不断的调整它的参数,从而用它来逼近训练集的真实值 features –> hypothese function –> predicitons


线性回归的概念

在统计学中,线性回归(Linear Regression)是利用称为线性回归方程的最小平方函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析。这种函数是一个或多个称为回归系数的模型参数的线性组合.
回归分析中,只包括一个自变量和一个因变量,且二者的关系可用一条直线近似表示,这种回归分析称为一元线性回归分析。


拟合的概念

所谓拟合是指已知某函数的若干离散函数值{f1,f2,…,fn},通过调整该函数中若干待定系数f(λ1, λ2,…,λn),使得该函数与已知点集的差别(最小二乘意义)最小。如果待定函数是线性,就叫线性拟合或者线性回归(主要在统计中),否则叫作非线性拟合或者非线性回归。表达式也可以是分段函数,这种情况下叫作样条拟合。
一组观测结果的数字统计与相应数值组的吻合。形象的说,拟合就是把平面上一系列的点,用一条光滑的曲线连接起来。因为这条曲线有无数种可能,从而有各种拟合方法。拟合的曲线一般可以用函数表示。根据这个函数的不同有不同的拟合名字。

在这个例子中 只有一个自变量就是 房屋面积size, 只有一个因变量是房屋的价钱 price,所以这是一元线性回归问题.

假设 拟合方程为:
$$ h_θ(x) = θ_0+θ_1x $$

#####现在要做的就是训练这个方程,即调整该方程中的待定系数 $θ_0$,$θ_1$,使得该函数的函数值与已知点集的差别最小.

那么如何表示这个差别 呢? 这里用一种方法叫 “最小二乘法
来表达这个差别,下面这个方程叫做 Cost Function:
$$ J(\theta_0,\theta1) = \frac{1}{2m}\sum{i=1}^{m}(h_\theta(x^i)-y^i)^2 $$

现在就是要求上面方程的最小值,minimise $J(\theta_0,\theta_1)$ is our goal!
当该方程最小时,h(x)和已知点集的差别最小.

怎样求得 J(θ) 的最小值呢,这里我们用到一个算法 梯度下降 算法:

梯度下降算法简介

Gradient Desent 梯度下降方法 : 可用来最小化很多函数
方法大略为:

1. Start with some $\theta_0,\theta_1$ (we can say $θ_0$ = 0 $θ_1$ = 0)
2. Keep changing ** $θ_0,θ_1$ ** to reduce J($\theta_0,\theta_1$) untill we hopefully end up at a minimum.

Gradient Desent Algorthm:

repeat untill convergence{
$$
\theta_j := \theta_j - \alpha \frac{\partial}{\partial \theta_j}J(\theta_0,\theta_1)
$$
// for(j=0;j<=1;++j)
// 这里要注意 θ_0 和 θ_1 要同步更新
}

其中 $\alpha$ 叫做 学习速率( learning rate) .相当于 梯度下降的速率(即每一步减少多少)也就是步长(foot step length)

而 $\frac{\partial}{\partial \theta}J(\theta_0,\theta_1)$ 是該costfunction的斜率,乘以$\alpha$就是$\theta_i$每次减少的值.
可见 $\alpha$的选择很重要
$\alpha$太大会让$\theta_i$每次减少太多从而永远到不了最低点.
$\alpha$ 太小会让$\theta_i$每次减少的太少从而下降速度太慢.

梯度下降会趋向于一个局部极小值,即使学习速率是固定的.
因为当靠近极小值时,斜率 $\frac{\partial}{\partial \theta}J(\theta_0,\theta_1)$会变小, gradient descent会自动的take smaller steps,所以不必改变$\alpha$的值

有了gradient descent ,我们就能用他来求线性回归了.


用梯度下降法求cost function 的最小值


$$
J(\theta_0,\theta1) = \frac{1}{2m}\sum{i=1}^{m}(h\theta(x^i)-y^i)^2
$$
$$
h
θ(x) = θ_0+θ_1x
$$

核心是求出 $\frac{\partial}{\partial \theta_0} J(\theta_0,\theta_1)$ 和 $\frac{\partial}{\partial \theta_1} J(\theta_0,\theta_1)$

$$
\frac{\partial}{\partial \theta_0} J(\theta_0,\theta_1)=\frac{\partial}{\partial \theta0} (\frac{1}{2m} \sum{i=1}^m(\theta_0+\theta1x-y^i)^2)\
=\frac{1}{m}\sum
{i=1}^m(\theta_0+\theta_1x-y^i)
$$
$$
\frac{\partial}{\partial \theta_1} J(\theta_0,\theta_1)=\frac{\partial}{\partial \theta1} (\frac{1}{2m} \sum{i=1}^m(\theta_0+\theta1x-y^i)^2)\
=\frac{1}{m}\sum
{i=1}^m(\theta_0+\theta_1x-y^i)x_i
$$

于是代入算法:
repeat untill convergence($\theta不再改变$) {
$$
temp_1:= \theta0-\alpha\frac{1}{m}\sum{i=1}^m(\theta_0+\theta_1x-y^i)\
temp_2:= \theta1 -\alpha\frac{1}{m}\sum{i=1}^m(\theta_0+\theta_1x-y^i)x_i\
\theta_0 := temp_1\
\theta_1 := temp_2
$$
//这两个要同步更新(用temp存起来然后更新)
}


这样当$\theta不再改变$时就跳出循环我们就的到了$$ h_θ(x) = θ_0+θ_1x $$这个拟合函数,就可以用它来预测房价了,这个过程就是

通过调整该函数中若干待定系数f(λ1, λ2,…,λn),使得该函数与已知点集的差别(最小二乘意义)最小

上面这种梯度下降叫做 Batch gradient descent
“batch”: Each step of gradient descent uses all the training examples.
上面这种梯度下降批处理梯度下降,因为每一步都用到了所有训练数据.


下一节将 多变量线性回归

Read More

[TOC]

Machine Learning by Andrew NG from Stanford

最近开始学习机器学习,从standford的Andrew Ng讲授的入门课程开始。

教师的简介:

  • 吴恩达1976年出生于伦敦,他的英文名叫Andrew Ng,吴恩达年轻时候在香港和新加坡度过。1992年吴恩达就读新加坡莱佛士书院,并于1997年获得了卡内基梅隆大学的计算机科学学士学位。之后他在1998年获得了麻省理工学院的硕士学位,并于2002年获得了加州大学伯克利分校的博士学位,并从这年开始在斯坦福大学工作。他(2002年)住在加利福尼亚州的帕洛阿尔托。

  • 吴恩达是斯坦福大学计算机科学系和电子工程系副教授,人工智能实验室主任。吴恩达主要成就在机器学习和人工智能领域,他是人工智能和机器学习领域最权威的学者之一。

  • 2010年,时任斯坦福大学教授的吴恩达加入谷歌开发团队XLab——这个团队已先后为谷歌开发无人驾驶汽车和谷歌眼镜两个知名项目。

  • 吴恩达与谷歌顶级工程师开始合作建立全球最大的“神经网络”,这个神经网络能以与人类大脑学习新事物相同的方式来学习现实生活。谷歌将这个项目命名为“谷歌大脑”。

  • 吴恩达最知名的是,所开发的人工神经网络通过观看一周YouTube视频,自主学会识别哪些是关于猫的视频。这个案例为人工智能领域翻开崭新一页。吴恩达表示,未来将会在谷歌无人驾驶汽车上使用该项技术,来识别车前面的动物或者小孩,从而及时躲避。

  • 2014年5月16日,百度宣布吴恩达加入百度,担任百度公司首席科学家,负责百度研究院的领导工作,尤其是Baidu Brain计划。

  • 2014年5月19日,百度宣布任命吴恩达博士为百度首席科学家,全面负责百度研究院。这是中国互联网公司迄今为止引进的最重量级人物。消息一经公布,就成为国际科技界的关注话题。美国权威杂志《麻省理工科技评论》(MIT Technology Review)甚至用充满激情的笔调对未来给予展望:“百度将领导一个创新的软件技术时代,更加了解世界。”

这门课通俗易懂,很适合入门。

课程地址戳这里


机器学习的定义


  • Arthur Samuel (1959). Machine Learning: Field of study that gives computers the ability to learn without being explicitly programmed.
  • Tom Mitchell (1998) Well-posed Learning Problem: A computer program is said to learn from experience E with respect to some task T and some performance measure P, if its performance on T, as measured by P, improves with experience E.

  • 机器学习是近20多年兴起的一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。机器学习理论主要是设计和分析一些让计算机可以自动“学习”的算法。机器学习算法是一类从数据中自动分析获得规律,并利用规律对未知数据进行预测的算法。因为学习算法中涉及了大量的统计学理论,机器学习与统计推断学联系尤为密切,也被称为统计学习理论。算法设计方面,机器学习理论关注可以实现的,行之有效的学习算法。很多推论问题属于无程序可循难度,所以部分的机器学习研究是开发容易处理的近似算法。机器学习已经有了十分广泛的应用,例如:数据挖掘、计算机视觉、自然语言处理、生物特征识别、搜索引擎、医学诊断、检测信用卡欺诈、证券市场分析、DNA序列测序、语音和手写识别、战略游戏和机器人运用。

机器学习的发展历史


机器学习是人工智能研究较为年轻的分支,它的发展过程大体上可分为4个时期。

  • 第一阶段是在20世纪50年代中叶到60年代中叶,属于热烈时期。
  • 第二阶段是在20世纪60年代中叶至70年代中叶,被称为机器学习的冷静时期。
  • 第三阶段是从20世纪70年代中叶至80年代中叶,称为复兴时期。
  • 机器学习的最新阶段始于1986年。

机器学习进入新阶段的重要表现在下列诸方面:

  • 1) 机器学习已成为新的边缘学科并在高校形成一门课程。它综合应用心理学、生物学和神经生理学以及数学、自动化和计算机科学形成机器学习理论基础。

  • 2) 结合各种学习方法,取长补短的多种形式的集成学习系统研究正在兴起。特别是连接学习符号学习的耦合可以更好地解决连续性信号处理中知识与技能的获取与求精问题而受到重视。

  • 3) 机器学习与人工智能各种基础问题的统一性观点正在形成。例如学习与问题求解结合进行、知识表达便于学习的观点产生了通用智能系统SOAR的组块学习。类比学习与问题求解结合的基于案例方法已成为经验学习的重要方向。

  • 4) 各种学习方法的应用范围不断扩大,一部分已形成商品。归纳学习的知识获取工具已在诊断分类型专家系统中广泛使用。连接学习在声图文识别中占优势。分析学习已用于设计综合型专家系统。遗传算法与强化学习在工程控制中有较好的应用前景。与符号系统耦合的神经网络连接学习将在企业的智能管理与智能机器人运动规划中发挥作用。

  • 5) 与机器学习有关的学术活动空前活跃。国际上除每年一次的机器学习研讨会外,还有计算机学习理论会议以及遗传算法会议。


#机器学习主要方法

  • supervised learning (监督学习)
    特点: 正确的答案已经给机器了,机器知道什么是正确的(right answer given)
目标:学习从输入x到输出y的映射。方法是:给定某个依赖于一组参数的模型:  

  $$  y = g(x|theta) $$
其中g(.)是模型,theta是模型的参数。对于回归 y 是数值,对于分类,y 是类编码.  机器学习优化参数theta,使得逼近误差最小,也就是说,我们的估计要尽可能的接近训练集中给定的正确值(最小二乘法等).  

监督学习主要有两类: 

* 1. regression(回归)
   用于 prediction 预测 , 输出的是连续(continuous)的值  

* 2. classification(分类)
    用于 classify 分类, 输出的是离散的(discrete)值

  • unsupervised learning(非监督学习)

    特点:没有给定right answer,机器得靠自己去推断。

    目标:发现输入数据中的规律。输入空间存在某种结构,使得特定的模式比其他模式更常出现,而我们希望知道那些经常发生,那些不常发生。在统计学中,这成为density estimation 密度估计, 密度估计的一种方法是聚类(clusturing),其目标是发现输入数据的簇或分组。


  • reinforcement learning(增强学习)

  • Reinforcement learning is an area of machine learning inspired by behaviorist psychology, concerned with how software agents ought to take actions in an environment so as to maximize some notion of cumulative reward. The problem, due to its generality, is studied in many other disciplines, such as game theory, control theory, operations research, information theory, simulation-based optimization, statistics, and genetic algorithms. In the operations research and control literature, the field where reinforcement learning methods are studied is called approximate dynamic programming. The problem has been studied in the theory of optimal control, though most studies there are concerned with existence of optimal solutions and their characterization, and not with the learning or approximation aspects. In economics and game theory, reinforcement learning may be used to explain how equilibrium may arise under bounded rationality.

Read More

#0-1背包问题

##问题描述:

从前有个程序员跑到了森林里,他发现地上有好几块宝石,大小不一,价值各异,我嘞个嚓嚓!发了诶!再也不用加班了有木有!!可惜啊,由于长期编码不锻炼身体,这哥们只能拿得动 c 公斤的东西,那么问题来了,他怎么拿才能赚得最多,买房买车迎娶白富美走上人生巅峰?

##问题分析:

咋拿呢? 作为一个程序猿, 他无耻的想到了动态规划四个字,为什么用动态规划呢?
先形式化描述:

假设宝石数量n=3,每块的重量分别是 w{6,5,4} 价值分别是 v{15,14,18},背包容量c为11,求怎么拿能使背包中价值最大?

看到最大有没有想到最优子结构呢?
这个问题,只要智商大于0,都能看出来拿 1,3号宝石,最大的价值为33。

现在假设他已经拿了第3块宝石,那么现在只能拿 c-$w_3$ = 11-4 = 7重量的宝石,于是问题变为c=7,n=2,重量{6,5}价值{5,4}的0-1背包问题,
这就是子问题,显然剩下的两块只能拿一块,显然拿第一块获利最多,即n=2时,他拿的是第1块宝石,这就是传说中的“全局最优解包含局部最优解”。

现在来理一理思路:当n=2时,我们要求的是前2个宝石, 装到体积为7的背包里能达到的最大价值;当n=3时,我们要求的是前3个宝石, 装到体积为11的背包里能达到的最大价值。有没有发现规律!
我们定义:d(i,j)为前i个物品放入容量为c的背包中的最大价值
那么上面的两句话就是 d(2,7) and d(3,11) ,前面说道:动态规划方法的关键在于正确地写出基本的递推关系式和恰当的边界条件。要做到这一点,就必须将原问题分解为几个相互联系的阶段,恰当的选取状态变量决策变量及定义最优值函数,从而把一个大问题转化成一组同类的子问题,然后逐个求解。 那么状态是如何转移的呢?
从d(3,11) 怎么转换为d(2,7) 呢?这就涉及到 第3个宝石的放与不放的问题了:如果不装入,那么价值不变 即d(3,11) = d(2,11),如果放入呢,那么价值就变为 d( 3,11 ) = d( 2 , 10-$w_3$ )+$v_3$
那么决策变量是什么呢? 决策变量就是要求价值是最大的,即
d(3,11) = max{ d(2,11) , d(2, 7)+18}
形式化一下:
d(n,capacity) = max{ d(n-1,capacity) , d( n-1 , capacity-$weight_n$) + $value_n$ }

但是这个递归式不能完整描述所有情况,因为前面的假设是所有单个宝石的重量都比背包的容量小(即都能装入背包),如果有的宝石重量比背包的容量大就不能装了,所以 递归方程要改为:

$$
d(n,capacity) = max(d(n-1,capacity),d(n-1,capacity-weight_n) + value_n), capacity>= w_n
$$

$$
d(n,capacity) = d(n-1,capacity), capacity < w_n
$$

边界条件是什么呢? 对于初始情况,第一个物品有2中选择,放或者不放,
放的话 d(1,capacity) = $v_1$ , 不放的话 d(1,capacity) = 0

那么初始状态方程就是

$$
d(1,capacity) =
\begin{cases}
v_1, & \text{capacity >= w_1}\
0, & \text{capacity < w_1}
\end{cases}
$$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<iostream>
using namespace std;
int max_value(const int n,int capacity,int *value,int *weight,int **max){
// 先初始化边界条件
for(int i = 0; i < capacity;++i){
if(capacity < weight[i]) {
max[0][i] = 0;
}else{
max[0][i] = value[0];
}
}
// 然后从前往后填表
for(int row = 1; row < n; ++row){
for( int current_capacity = 0; current_capacity < capacity; ++ current_capacity ){
if(weight[current_capacity] > current_capacity){
max[row][current_capacity] = max[row-1][current_capacity];
}else{
max[row][current_capacity] = max[row-1][current_capacity] > max[row-1][current_capacity-weight[current_capacity]] + value[current_capacity] ? max[row-1][current_capacity] : max[row-1][current_capacity-weight[current_capacity]];
}
}
}
return max[n][capacity];
}
Read More

动态规划的思想

动态规划与分治法类似,也是将问题分解为若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。分治法在问题较大且相互不独立的情况下,由于分解得到的子问题数目太多,各个递归子问题被重复计算多次,求解过程呈幂级数增长,其时间复杂度为n的指数时间。与分治法不同,动态规划方法采用自底向上的递推方式求解,并且经分解得到的子问题往往不是相互独立的,根据子问题的相关性,在每步列出可能的局部解中选出能产生最佳解的部分,并将计算过程填表,只要某个子问题被解决,将不会被多次计算,从而减少了算法的时间复杂度。

求解问题时每次决策依赖于当前状态,又随即引起状态的转移,决策序列在变化的状态中逐步产生,这种用多阶段最优化决策方式解决问题的过程称为动态规划。

递推关系(状态转移方程)是实现由分解后的子问题向最终问题求解转化的纽带
填表技术是把计算过的所有子问题的解都记录下来,由于将原问题分解后的各个子问题可能存在重复性,所以当以后重复遇到该子问题时,只需要查表继续问题的求解,而不需要重复计算,这样就节省了很多计算时间,这就是动态规划的精髓。

动态规划建立在最优原则的基础上,在每一步决策上列出各种可能的局部解,按某些条件舍弃肯定不能得到最优解的局部解,通过逐步筛选,减少计算量。依据最优性原理,寻找最优判断序列,不论初始状态如何,下一次决策必须相对前一次决策产生的新状态构成最优序列。每一步都经过筛选,以每一步的最优性来保证全局的最优性。

动态规划的基本要素

1.最优子结构

当前问题的最优解包含了其子问题的最优解时,称为具有最优子结构。

动态规划方法的关键在于正确地写出基本的递推关系式和恰当的边界条件。要做到这一点,就必须将原问题分解为几个相互联系的阶段,恰当的选取状态变量决策变量及定义最优值函数,从而把一个大问题转化成一组同类的子问题,然后逐个求解。即从边界条件开始,逐阶段递推寻优,在每一个子问题的求解中,均利用它前面的子问题的最优化结果,依次进行,最后一个子问题所得的最优解就是整个问题的最优解,这样就说明具有最优子结构。

2.子问题重叠性

在用递归算法自顶向下解此问题时,每次产生的子问题并不总是新问题,有些子问题被反复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只解一次,保存起来,查找的时候只是用常数时间,所以通常不同的子问题个数随问题的大小呈多项式增长。因此用动态规划算法通常只需要多项式时间,从而获得较高的解题效率。

动态规划的应用步骤

1.找出最优解的性质,并刻画其结构特征

2.递归的定义最优值

3.自底向上的方式计算出最优值

4.根据计算最优值时得到的信息,构造最优解

Read More

今天在写博客的时候遇到了输入数学公式的问题。不想用图片,想用Latex语法写。
但是上传到github page不能显示。
于是想到了和我的博客评论一样的思路(我的博客使用的是Disqus外挂评论,因为本质上Github Page支持的都是静态页面),那么是不是有什么外挂Javascript的方案支持跨浏览器的内容渲染呢?于是再次验证了这一行的铁律:凡是你想到的都有人实现过了,可以用MathJax渲染。
搜索后发现需要在pelican的theme文件中找到一个base.html文件。在其<head>中加入

1
2
3
<script type="text/javascript"
src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>

OK,完美解决。

如何解决不能用 $…$ 来写行内公式呢?

1
2
3
4
5
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});
</script>

参见官方文档


用Jekyll的大体一样:
在Jekyll文件结构中,根模板的位置在_layout中(看过web框架代码的人应该比较好理解Jekyll的文件布局),在安装了某些模板插件的Jekyll目录下,有可能位于:

_include/themes/yourtheme/default.html

总之认准文件名default.html,然后替换默认的Markdown引擎为kramdown
编辑_config.yml, markdown: kramdown

sudo gem install kramdown

现在你可以在\$\$和\$\$之间书写数学公式的语法了。


参考资料:

  1. 基于 ASCIIMathML.js 的 is-programmer 博客数学公式书写及显示
  1. MathJax:不错的数学公式显示引擎
  1. Pelican数学公式显示
  1. Mathjax与LaTex公式简介
Read More

以搜索ls命令源码为例,先搜索命令所在包,命令如下:

1
2
lpj@lpj-linux:~$ which ls
/bin/ls

用命令搜索该软件所在包,代码如下:

1
2
lpj@lpj-linux:~$ dpkg -S /bin/ls
coreutils: /bin/ls

从上一步中可以知道ls命令的实现在包coreutils中,用apt安装(说安装有些歧义,主要是区分apt-get -d)该包的源代码然后解压,代码如下:

1
2
3
sudo apt-get source coreutils
cd /usr/src/coreutils-XXX #XXX表示版本号
sudo tar zxvf coreutils-XXX.tar.gz

或者只下载源码,然后手动打补丁再解压,代码如下:

1
2
3
4
5
6
7
sudo apt-get -d source coreutils
cd /usr/src
tar zxvf coreutils-XXX.tar.gz
gzip -d coreutils-XXX.diff.gz #这一步会生成coreutils-XXX.diff文件
patch -p0 < coreutils-XXX.diff
cd coreutils-XXX
tar zxvf coreutils-XXX.tar.gz

OK,这几步执行完后,就可以进入/usr/src/coreutils-XXX/coreutils-XXX/src 中查看各命令对应的源代码了

Read More

Compliers note–chapter one

一、语言处理器

  • 编译器:把某语言写的程序翻译为等价的用另一种语言写的程序
  • 解释器:直接利用用户提供的输入执行源程序中指定的操作
  • 区 别

    编译器产生的机器语言目标程序通常比一个解释器快很多

    解释器的错误诊断效果通常比编译器更好,因为它逐个语句的执行源程序

  • 预处理器:把源程序聚合在一起,将宏转换成源语言

  • 汇编器 : 把汇编语言汇编成 可重定位机器代码
  • 链接器: 大型程序经常被分成多个部分编译,可重定位的机器代码有必要和其他可重定位的目标文件以及库文件链接到一起,一个文件中的代码可能指向另一个文件中的位置,链接器可以解决外部内存地址的问题。
  • 加载器:把所有可执行目标文件放到内存中执行

二.一个编译器的结构

编译的过程可分为两个部分: 分析部分(前端)和综合部分(后端

  • 前端 : 把源程序分解成为多个要素,并在这些要素上加语法结构,检查语法错误,创建中间表示,构建符号表

前端图

  • 后端: 根据中间表示和符号表中的信息来构造用户期待的目标程序

    后端图

Read More
⬆︎TOP